1[section:skeleton_and_content Separating structure from content] 2 3When communicating data types over MPI that are not fundamental to MPI 4(such as strings, lists, and user-defined data types), Boost.MPI must 5first serialize these data types into a buffer and then communicate 6them; the receiver then copies the results into a buffer before 7deserializing into an object on the other end. For some data types, 8this overhead can be eliminated by using [classref 9boost::mpi::is_mpi_datatype `is_mpi_datatype`]. However, 10variable-length data types such as strings and lists cannot be MPI 11data types. 12 13Boost.MPI supports a second technique for improving performance by 14separating the structure of these variable-length data structures from 15the content stored in the data structures. This feature is only 16beneficial when the shape of the data structure remains the same but 17the content of the data structure will need to be communicated several 18times. For instance, in a finite element analysis the structure of the 19mesh may be fixed at the beginning of computation but the various 20variables on the cells of the mesh (temperature, stress, etc.) will be 21communicated many times within the iterative analysis process. In this 22case, Boost.MPI allows one to first send the "skeleton" of the mesh 23once, then transmit the "content" multiple times. Since the content 24need not contain any information about the structure of the data type, 25it can be transmitted without creating separate communication buffers. 26 27To illustrate the use of skeletons and content, we will take a 28somewhat more limited example wherein a master process generates 29random number sequences into a list and transmits them to several 30slave processes. The length of the list will be fixed at program 31startup, so the content of the list (i.e., the current sequence of 32numbers) can be transmitted efficiently. The complete example is 33available in `example/random_content.cpp`. We being with the master 34process (rank 0), which builds a list, communicates its structure via 35a [funcref boost::mpi::skeleton `skeleton`], then repeatedly 36generates random number sequences to be broadcast to the slave 37processes via [classref boost::mpi::content `content`]: 38 39 40 // Generate the list and broadcast its structure 41 std::list<int> l(list_len); 42 broadcast(world, mpi::skeleton(l), 0); 43 44 // Generate content several times and broadcast out that content 45 mpi::content c = mpi::get_content(l); 46 for (int i = 0; i < iterations; ++i) { 47 // Generate new random values 48 std::generate(l.begin(), l.end(), &random); 49 50 // Broadcast the new content of l 51 broadcast(world, c, 0); 52 } 53 54 // Notify the slaves that we're done by sending all zeroes 55 std::fill(l.begin(), l.end(), 0); 56 broadcast(world, c, 0); 57 58 59The slave processes have a very similar structure to the master. They 60receive (via the [funcref boost::mpi::broadcast 61`broadcast()`] call) the skeleton of the data structure, then use it 62to build their own lists of integers. In each iteration, they receive 63via another `broadcast()` the new content in the data structure and 64compute some property of the data: 65 66 67 // Receive the content and build up our own list 68 std::list<int> l; 69 broadcast(world, mpi::skeleton(l), 0); 70 71 mpi::content c = mpi::get_content(l); 72 int i = 0; 73 do { 74 broadcast(world, c, 0); 75 76 if (std::find_if 77 (l.begin(), l.end(), 78 std::bind1st(std::not_equal_to<int>(), 0)) == l.end()) 79 break; 80 81 // Compute some property of the data. 82 83 ++i; 84 } while (true); 85 86 87The skeletons and content of any Serializable data type can be 88transmitted either via the [memberref 89boost::mpi::communicator::send `send`] and [memberref 90boost::mpi::communicator::recv `recv`] members of the 91[classref boost::mpi::communicator `communicator`] class 92(for point-to-point communicators) or broadcast via the [funcref 93boost::mpi::broadcast `broadcast()`] collective. When 94separating a data structure into a skeleton and content, be careful 95not to modify the data structure (either on the sender side or the 96receiver side) without transmitting the skeleton again. Boost.MPI can 97not detect these accidental modifications to the data structure, which 98will likely result in incorrect data being transmitted or unstable 99programs. 100 101[endsect:skeleton_and_content] 102