robins35
robins35

Reputation: 681

MPI sending messages with MPI_Send and MPI_Reduce

so I am learning about parallel programming and am writing a program to calculate a global sum of a list of numbers. The list is split up into several sublists (depending on how many cores I have), and the lists are individually summed in parallel. After each core has its own sum, I use MPI_Reduce to send the values back to other cores, until they eventually make it back to root. Rather than just sending their values back to root directly (O(n)), we send them back, to other cores in parallel (O(log(n)), like this image illustrates: https://i.sstatic.net/mq4Uz.jpg

So, everything is working fine until like 54. I think I may be misunderstanding MPI_Reduce. I was under the impression MPI_Reduce simply took a value in one thread, and a value in another thread (destination thread), and executed an operation on the value, and then stored it in the same spot in the second thread. This is what I want at least. I want to take my_sum from the sending thread, and add it to the my_sum in the receiving thread. Can you use MPI_Reduce on the same addresses in different threads? They both have the same name.

Furthermore, I want to generate a binary tree representation like this: https://i.sstatic.net/jiS4Y.jpg

Where S02 means that the sum was sent to thread 2, and R03 means that the sum was received by thread 3. For this I am creating an array of structs for each step in the sums (log(n) steps). Each step occurs on lines 59 - 95, each iteration of the while loop is one step. Lines 64-74 are where the thread is sending it's sum to the destination thread, and recording the information in the array of structs.

I think I may be using MPI_Send the wrong way. I am using it like this:

MPI_Send(srInfo, 1, MPI_INT, root, 0, MPI_COMM_WORLD);

Where srInfo is an array of structs, so just a pointer to the first struct (right?). Will this not work because the memory is not shared?

Sorry I am very new to parallel programming, and just need help understanding this, thanks.

Upvotes: 1

Views: 1626

Answers (1)

Wesley Bland
Wesley Bland

Reputation: 9072

You might be misunderstanding what MPI_REDUCE is supposed to do at a higher level. Is there a reason that you really need to divide up your reduction manually? Usually, the MPI collectives are going to be better at optimizing for large scale communicators that you will be able to do on your own. I'd suggest just using the MPI_REDUCE function to do the reduction for all ranks.

So your code will do something like this:

  1. Divide up the work among all of your ranks somehow (could be reading from a file, being sent from some "root" process to all of the others, etc.).
  2. Each rank sums up its own values.
  3. Each rank enters into an MPI_REDUCE with its own value. This would look something like: MPI_Reduce(&myval, &sum, 1, MPI_INT, MPI_SUM, root, MPI_COMM_WORLD);

That should automatically do all of the summation for you in what is usually some sort of tree fashion.

Upvotes: 2

Related Questions