Инициализировать массив с помощью openmpi один раз

Я пытаюсь запустить некоторые тесты, используя данные обработки OPENmpi в массиве, разделив работу по узлам (вторая часть — с матрицами). Сейчас у меня возникают некоторые проблемы, потому что массив данных каждый раз инициализируется, и я не знаю, как этого избежать.

Как, используя ANSI C, я могу создать массив переменной длины, используя OPENmpi один раз? Я пытался сделать его статическим и глобальным, но ничего.

#define NUM_THREADS 4
#define NUM_DATA 1000

static int *list = NULL;

int main(int argc, char *argv[]) {
  int numprocs, rank, namelen;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int n = NUM_DATA*NUM_DATA;
  printf("hi\n");
  int i;
  if(list == NULL)
  {
     printf("ho\n");
     list = malloc(n*sizeof(int));

    for(i = 0 ; i < n; i++)
    {
      list[i] = rand() % 1000;
    }
  }

  int position;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Get_processor_name(processor_name, &namelen);
  printf("Process %d on %s out of %d\n", rank,processor_name, numprocs);

  clock_t start = clock();

  position = n / NUM_THREADS * rank;
  search(list,position, n / NUM_THREADS * (rank + 1));

  printf("Time elapsed: %f seconds\n",  ((double)clock() - (double)start) /(double) CLOCKS_PER_SEC);

  free(list);

  MPI_Finalize();
  return 0;
}

person amischiefr    schedule 26.09.2010    source источник
comment
Вместо того, чтобы давать нам такой длинный код, не могли бы вы более подробно описать, каковы ваши цели, как вы пытаетесь их реализовать и с какими проблемами вы сталкиваетесь при использовании вашего подхода?   -  person Jens Gustedt    schedule 26.09.2010


Ответы (1)


Вероятно, самый простой способ — заставить процесс ранга 0 выполнять инициализацию, в то время как другие процессы блокируются. Затем, как только инициализация будет завершена, пусть все они начнут свою работу.

Базовый пример, пытающийся вызвать вашу функцию поиска (NB: это сухое кодирование):

#define NUM_THREADS 4
#define NUM_DATA 1000

int main(int argc, char *argv[]) {
   int *list;
   int numprocs, rank, namelen, i, n;
   int chunksize,offset;
   char processor_name[MPI_MAX_PROCESSOR_NAME];

   n= NUM_DATA * NUM_DATA;

   MPI_Status stat;
   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Get_processor_name(processor_name, &namelen);

   //note you'll need to handle n%NUM_THREADS !=0, but i'm ignoring that for now
   chunksize = n / NUM_THREADS; 

   if (rank == 0) {
      //Think of this as a master process
      //Do your initialization in this process
      list = malloc(n*sizeof(int));

      for(i = 0 ; i < n; i++)
      {
         list[i] = rand() % 1000;
      }

      // Once you're ready, send each slave process a chunk to work on
      offset = chunksize;
      for(i = 1; i < numprocs; i++) {
         MPI_Send(&list[offset], chunksize, MPI_INT, i, 0, MPI_COMM_WORLD);
         offset += chunksize
      }

      search(list, 0, chunksize);

      //If you need some sort of response back from the slaves, do a recv loop here
   } else {

      // If you're not the master, you're a slave process, so wait to receive data

      list = malloc(chunksize*sizeof(int));  
      MPI_Recv(list, chunksize, MPI_INT, 0, 0, MPI_COMM_WORLD, &stat);

      // Now you can do work on your portion
      search(list, 0, chunksize);

      //If you need to send something back to the master, do it here.
   }

   MPI_Finalize();
}
person Dusty    schedule 26.09.2010
comment
Спасибо Дасти, это именно то, что я искал. Я даже не думал о том, чтобы нулевой ранг был мастером, а остальные рабочими, вместо этого я был ослеплен поиском чего-то другого. - person amischiefr; 27.09.2010
comment
Без проблем. Мастер ранга 0 — это действительно распространенная концепция в MPI, поэтому я должен быть осторожен, чтобы не сделать наоборот и иногда использовать его как единственный инструмент. = Д - person Dusty; 27.09.2010