• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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