struct serialization in C and transfer over MPI

mpi create struct c
mpi_bcast struct
mpi mpi_datatype
mpi_send a struct
custom mpi type
mpi indexed
mpi ring
mpi tag

I have defined a custom struct and wish to send it over to another MPI process using the MPI_Bsend (or MPI_Send).

Here is my struct:

struct car{
  int shifts;
  int topSpeed;
}myCar;

However, apart from primitive types MPI doesn't seem to support direct "transmission" of complex data types like the struct above. I have heard that I might have to use "serialization". How should I go about it and send over 'myCar' to process 5?

Jeremiah is right - MPI_Type_create_struct is the way to go here.

It's important to remember that MPI is a library, not built into the language; so it can't "see" what a structure looks like to serialize it by itself. So to send complex data types, you have to explicitly define its layout. In a language that does have native support for serialization, a set of MPI wrappers can concievably make use of that; mpi4py for instance makes use of python's pickle to transparently send complex data types; but in C, you have to roll up your sleeves and do it yourself.

For your structure, it looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <stddef.h>

typedef struct car_s {
        int shifts;
        int topSpeed;
} car;

int main(int argc, char **argv) {

    const int tag = 13;
    int size, rank;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (size < 2) {
        fprintf(stderr,"Requires at least two processes.\n");
        exit(-1);
    }

    /* create a type for struct car */
    const int nitems=2;
    int          blocklengths[2] = {1,1};
    MPI_Datatype types[2] = {MPI_INT, MPI_INT};
    MPI_Datatype mpi_car_type;
    MPI_Aint     offsets[2];

    offsets[0] = offsetof(car, shifts);
    offsets[1] = offsetof(car, topSpeed);

    MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_car_type);
    MPI_Type_commit(&mpi_car_type);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (rank == 0) {
        car send;
        send.shifts = 4;
        send.topSpeed = 100;

        const int dest = 1;
        MPI_Send(&send,   1, mpi_car_type, dest, tag, MPI_COMM_WORLD);

        printf("Rank %d: sent structure car\n", rank);
    }
    if (rank == 1) {
        MPI_Status status;
        const int src=0;

        car recv;

        MPI_Recv(&recv,   1, mpi_car_type, src, tag, MPI_COMM_WORLD, &status);
        printf("Rank %d: Received: shifts = %d topSpeed = %d\n", rank,
                 recv.shifts, recv.topSpeed);
    }

    MPI_Type_free(&mpi_car_type);
    MPI_Finalize();

    return 0;
}

struct serialization in C and transfer over MPI, I have defined a custom struct and want to send it over to another MPI process using the MPI_Bsend (or MPI_Send). Here is my struct: struct car{; int shifts;  Podcast #128: We chat with Kent C Dodds about why he loves React and discuss what life was like in the dark days before Git. Listen now.

c - MPI datatype alignment, MPI datatype alignment typedef struct customData{ double iv; double dv[5]; char cv[10]; } customData;. I create struct serialization in C and transfer over MPI. One of the main advantages of using Boost.MPI over MPIs C interface is that it is typesafe, more expressive and generally nice to use. Instead of packaging data by hand into buffers before sending them we can have Boost.Serialization handle this task for us. Let’s say we have the following structs that represent one and multidimensional Ranges:

Look at MPI_Type_create_struct to build a custom MPI datatype for your object. An example of using it is at http://beige.ucs.indiana.edu/I590/node100.html.

MPI, C, derived types, struct of vectors? - c++ - android, (e.g. http://www.open-mpi.org/doc/v1.5/man3/MPI_Type_struct.3.php) And I the example in this question: struct serialization in C and transfer over MPI, but I  boost/mpi/python/serialize.hpp // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com> // Use, modification and distribution is subject to the Boost

int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

OpenMPI will send count * sizeof(datatype) contiguous bytes starting at buf to allow sending things like int arrays. For example, if you declare a 10 int array int arr[10], you can send with

MPI_Send(arr, 10, MPI_INT, 1, 0, MPI_COMM_WORLD);

and receive similarly. Since buf is a void pointer we can abuse this to send structs by sending sizeof(my_struct) bytes and casting back as struct on the receiving end. Here is an example:

#include "mpi.h"
#include <stdio.h>

typedef struct 
{
    char a;
    int b;
    short c;
} my_struct;


int main (int argc, char *argv[])
{
    int  numtasks, taskid;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);


    if (taskid == 0) 
    {
        my_struct m;
        m.a = '!';
        m.b = 1234;
        m.c = 5678;

        MPI_Send(&m, sizeof(my_struct), MPI_CHAR, 1, 0, MPI_COMM_WORLD);
    }
    else 
    {
        my_struct m;
        MPI_Recv(&m, sizeof(my_struct), MPI_CHAR, 0, 0, MPI_COMM_WORLD, 
                 MPI_STATUS_IGNORE);
        printf("%c %d %d\n", m.a, m.b, m.c); 
    }

    MPI_Finalize();
}

Since C arrays store data contiguously, we can even send arrays of structs similarly to how we malloc an array of structs. So if you had a my_struct m_array[10] you would send (and receive similarly) with

MPI_Send(m_array, sizeof(my_struct) * 10, MPI_CHAR, 1, 0, MPI_COMM_WORLD);

[PDF] MPI Part 2, the transfer. • In the latter case, we need Recv(0). Completion depends in general on size of message and amount of system buffering. MPI Tutorial. University of Notre Dame. ². ±. Example: C Structures struct { char display[50]; The suggested approach may induce serialization of the communication. • The sends may  This paper describes several ideas for modernizing the C++ interface to MPI, providing a more natural syntax along with seamless support for user-defined types and C++ Standard Library constructs.

(PDF) Modernizing the C++ interface to MPI, Find, read and cite all the research you need on ResearchGate. To map these common C++ constructs into MPI, programmers must often write non-trivial boiler-​plate code and weaken the void serialize ( Archiver & ar, employee_record & rec, const unsigned int version) { struct object_traits<std::vector<T, Alloc> >{. I can't help but wonder why the the other two books didn't discuss serialization at all. After an unsuccessful web/book search I'm left wondering where I can find a good book/paper/tutorial on serializing data structures in C? Where or how did you learn it?

Network and Parallel Computing: IFIP International Conference, NPC , Besides standard-mode send and receive, MPI provides many other 2.3 Serialization Layer In order to support message-passing based on More unfortunately, it still limited to manipulate simple Plain Old Data (POD) types such as C-style structs. while cares nothing about how to store or transfer the serialized objects. One of the old-school C techniques consists in performing a memcpy kind of serialization. It’s pretty low-level and works very well in some specific circumstances. It’s pretty low-level and works very well in some specific circumstances.

[PDF] Boost.MPI, available from C, Fortran, and C++, for which there are many MPI implementations. MPI can build MPI data types for user-defined types using the Boost. MPI can transfer the shape (or "skeleton") of complexc data structures (​lists, maps, etc.) The inclusion of boost/serialization/string.hpp in the previous examples is very  Data serialization is the process of converting data objects present in complex data structures into a byte stream for storage, transfer and distribution purposes on physical devices. Computer systems may vary in their hardware architecture, OS, addressing mechanisms. Internal binary representations of data also vary accordingly in every environment.

Comments
  • Thank you for your very comprehensive and quick response. I really appreciate it. You've got me completely covered. (However I think you forgot to include <stddef.h> on the top cause otherwise the compiler gives errors..)
  • You're right - needed for the offsetof(). I've updated the code appropriately.
  • I am still a bit confused..!Suppose I define the MPI structure and now want to use it. The link you gave states: MPI_Type_create_struct(5, array_of_block_lengths, array_of_displacements, array_of_types, &new_type); Should I now do something like myCar=&new_type?
  • And more to the point...Could you please give me a simple but concrete example of creating and transmitting the specific struct?
  • Problem solved. The link you provided gives all the "theory" but may easily confuse amateur programmers due to the displacements and low level details. However it seems to precisely describe the mechanism underneath.
  • What are the downsides of this solution? Does MPI treat the data differently if it knows its structure and if yes then how?
  • I don't know how MPI sends MPI-created struct types but a reasonable implementation is to send the whole struct as I am doing with the custom type just used for calculating offsets. Sending smaller pieces increases granularity which may or may not speed things up depending on the overhead of each message and things like buffer sizes.