On Oct 31, 2007, at 5:52 PM, Oleg Morajko wrote:

Let me clarify the context of the problem. I'm implementing a MPI piggyback mechanism that should allow for attaching extra data to any MPI message. The idea is to wrap MPI communication calls with PMPI interface (or with dynamic instrumentation or whatsoever) and add/receive extra data in a non expensive way. The best solution I have found so far is dynamic datatype wrapping. That is when a user calls MPI_Send (datatype, count) I create dynamically a new structure type that contains an array [count] of datatype and extra data. To avoid copying the original send buffer I use absolute addresses to define displacaments in the structure. This works fine for all P2P calls and MPI_Bcast. And definitely it has performance benefits when compared to copying bufferers or sending an additional message in a different communicator. Or would you expect something different?

The only problem are collective calls like MPI_Gather when a root process receives an array of data items. There is no problem to wrap the message on the sender side (for each task), but the question is how to define a datatype that points both to original receive buffer and extra buffer for piggybacked data AND has an adecuate extent to work as an array element.

The real problem is that a structure datatype { original data, extra data} does not have a constant displacement between the original data and extra data. Eg. consider original data = receive buffer in MPI_Gather and extra data is an array of ints somewhere in memory). So it cannot be directly used as an array datatype.

I guess I don't see why this is a problem...? If you're already making a specific datatype for this communication, MPI's datatype primitives are flexible enough to allow what you describe. Keep in mind that you can nest datatypes (e.g., with TYPE_CREATE_STRUCT).

But for collectives, I think you need to decide exactly what information you want to generate / save. Specifically, if you're piggybacking on collectives, you are stuck using the same communication pattern as that collective. I.e., if the application calls MPI_REDUCE with MPI_SUM, I imagine you'll have a difficult time piggybacking your data on that reduction without it being summed across all the processes.

There are a few other canonical solutions to the "need to save extra data about every communication" technique:

- for small messages, do what you're doing: a) make a new/specific datatype for p2p messages or b) memcpy the user+extra data into a small contiguous buffer and then just send that (and memcpy out on the receiver). If making datatypes is cheap in MPI, then a) is effectively the same as b), and potentially more optimized/tuned.

- for large messages, don't bother making a new datatype -- just send around another message with your extra data. The performance impact will be minimal because it's already a long message; don't force the MPI do to additional copies with a non-contiguous datatype if you can avoid it.

- for collectives, if you can't piggyback (e.g., REDUCE with SUM and others), just send around another short message. Yes, you'll take a performance hit for this.

- depending on what data you're piggybacking / collecting, it may be possible to implement a "lazy" collection scheme in the meta/PMPI layer. E.g., for when you send separate messages with your meta data, always use non-blocking sends. The receiver PMPI layer can lazily collect this data and match it with application sends/receives after the fact (i.e., don't be trapped into thinking that you have to do the match exactly when the application data is actually sent or received -- it could be done after that).

Hope that helps.


Any solution? It could be complex, I don't mind ;)


On 11/1/07, George Bosilca <bosi...@eecs.utk.edu> wrote: The MPI standard defines the upper bound and the upper bound for
similar problems. However, even with all the functions in the MPI
standard we cannot describe all types of data. There is always a
solution, but sometimes one has to ask if the performance gain is
worth the complexity introduced.


As I said there is always a solution. In fact there are 2 solution,
one somehow optimal the other ... as bad as you can imagine.

The bad approach:
  1. Use an MPI_Type_struct to create exactly what you want, element
by element (i.e single pair). This can work in all cases. 2. If the sizeof(int) == sizeof(double) then the displacement inside
each tuple (double_i, int_i) is constant. Therefore, you can start by
creating one "single element" type and then use for each send the
correct displacement in the array (added to the send buffer,
respectively to the receive one).

   george.

On Oct 31, 2007, at 1:40 PM, Oleg Morajko wrote:

> Hello,
>
> I have the following problem. There areI two arrays somewere in the
> program:
>
> double weights [MAX_SIZE];
> ...
> int       values [MAX_SIZE];
> ...
>
> I need to be able to send a single pair { weights [i], values [i] }
> with a single MPI_Send call Or receive it directly into both arrays
> at at given index i. How can I define a datatype that spans this
> pair over both arrays?
>
> The only additional constraint it the fact that the memory location
> of both arrays is fixed and cannot be changed and I should avoid
> extra copies.
>
> Is it possible?
>
> Any help welcome,
> Oleg Morajko
>
>
> _______________________________________________
> users mailing list
> us...@open-mpi.org
> http://www.open-mpi.org/mailman/listinfo.cgi/users


_______________________________________________
users mailing list
us...@open-mpi.org
http://www.open-mpi.org/mailman/listinfo.cgi/users


_______________________________________________
users mailing list
us...@open-mpi.org
http://www.open-mpi.org/mailman/listinfo.cgi/users


--
Jeff Squyres
Cisco Systems

Reply via email to