title: MPI and threads
body: <p>I am a beginner at MPI and I would like to use threads with MPI in the following way. Certain processes (all even procs) spawn threads and do a blocking wait to receive a message. The number of threads spawned per proc is a command line argument.  So if there are 4 procs, processes 0 and 2 spawn a thread. Now, I want both process 0 and 2 to send message to all the threads. For instance, process 0 sends message to itself AND to process 2, and proc 2 sends it to proc 0 and itself.
  Here is what my code looks like, and it apparently does not do what is desired. It just waits to receive message. Where am I going wrong?</p>
  
  <p>Thanks! </p>
  
  <pre><code>  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, &amp;rank);
      printf("Rank %d is waiting in thread %d for my message\n", rank, fd-&gt;id);
  
      if(rank%2 ==0){
              MPI_Recv(mystr, 10, MPI_CHAR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &amp;status);
              printf("Thread %d on rank %d received %s\n", fd-&gt;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(&amp;pthread_custom_attr);
      fd=(struct_t *)malloc(sizeof(struct_t)*n);
  
      MPI_Comm_rank(MPI_COMM_WORLD, &amp;rank);
      MPI_Comm_size(MPI_COMM_WORLD, &amp;size);
  
      /* Start up thread */
      for (i=0; i&lt;n; i++)
      {
              fd[i].id=i;
       //       printf("My rank is %d and I created thread #%d\n", rank, i);
              pthread_create(&amp;threads[i], &amp;pthread_custom_attr, hello, (void *)(fd+i));
      }
  
      /* Synchronize the completion of each thread. */
      for (i=0; i&lt;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(&amp;argc, &amp;argv, MPI_THREAD_MULTIPLE, &amp;provided);
      MPI_Comm_rank(MPI_COMM_WORLD, &amp;rank);
      MPI_Comm_size(MPI_COMM_WORLD, &amp;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 &lt; 1) || (n &gt; 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();
  }
  </code></pre>