MPI и потоки - PullRequest
       14

MPI и потоки

1 голос
/ 24 августа 2011

Я новичок в MPI, и я хотел бы использовать потоки с MPI следующим образом. Некоторые процессы (все даже процессы) порождают потоки и блокируют ожидание получения сообщения. Количество потоков, порожденных за процесс, является аргументом командной строки Так что, если есть 4 процесса, процессы 0 и 2 порождают поток. Теперь я хочу, чтобы процессы 0 и 2 отправляли сообщения всем потокам. Например, процесс 0 отправляет сообщение себе и процессу 2, а proc 2 отправляет его процессу 0 и себе. Вот как выглядит мой код, и он, по-видимому, не выполняет желаемого. Он просто ждет получения сообщения. Куда я иду не так?

Спасибо!

  typedef struct {
     int id;
  } struct_t;

void *hello(void *arg)
{
    int rank;
    char mystr[10];
    MPI_Status status;
    struct_t *fd=(struct_t *)arg;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    printf("Rank %d is waiting in thread %d for my message\n", rank, fd->id);

    if(rank%2 ==0){
            MPI_Recv(mystr, 10, MPI_CHAR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
            printf("Thread %d on rank %d received %s\n", fd->id, rank, mystr);
    }

    return (NULL);
}

void spawn_thread(int n)
{
    int size,rank, i;
    pthread_t *threads;
    pthread_attr_t pthread_custom_attr;
    struct_t *fd;
    threads=(pthread_t *)malloc(n*sizeof(*threads));
    pthread_attr_init(&pthread_custom_attr);
    fd=(struct_t *)malloc(sizeof(struct_t)*n);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    /* Start up thread */
    for (i=0; i<n; i++)
    {
            fd[i].id=i;
     //       printf("My rank is %d and I created thread #%d\n", rank, i);
            pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)(fd+i));
    }

    /* Synchronize the completion of each thread. */
    for (i=0; i<n; i++)
    {
            pthread_join(threads[i],NULL);
    }
    free(fd);
}
 void main(int argc, char ** argv)
{
    int n,i, provided, claimed;
    int rank, size, errs;

    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (argc != 2)
    {
            printf ("Usage: %s n\n  where n is no. of threads\n",argv[0]);
            exit(1);
    }

    n=atoi(argv[1]);
    if ((n < 1) || (n > MAX_THREAD))
    {
            printf ("The no of thread should between 1 and %d.\n",MAX_THREAD);
            MPI_Abort(MPI_COMM_WORLD,-1);
    }

  if(rank%2 == 0)
            spawn_thread(n);

    if(rank%2 == 0){

                    printf("My rank is %d and I am sending Hello!\n", rank);
                    MPI_Send("HELLOOO", 10, MPI_CHAR, rank, 0, MPI_COMM_WORLD);
          }

    MPI_Finalize();
}

1 Ответ

1 голос
/ 24 августа 2011

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

Может быть следующее, если:

    if(rank%2 == 0){
      printf("My rank is %d and I am sending Hello!\n", rank);
      MPI_Send("HELLOOO", 10, MPI_CHAR, rank, 0, MPI_COMM_WORLD);
    }

должно быть так:

    if(rank%2 != 0)

Таким образом ваши нечетные ранжированные процессы 'хотя бы отправят команду?

В качестве альтернативы вам нужно переместить код 'join' вне функции spawn_thread и выполнить соединение после вызова send.

Надеюсь, это поможет.

...