• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //          Copyright Alain Miniussi 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 // Authors: Alain Miniussi
7 
8 #include <boost/mpi/detail/offsets.hpp>
9 #include <boost/mpi/detail/antiques.hpp>
10 
11 namespace boost { namespace mpi {
12 namespace detail {
13 
14 // Convert a sequence of sizes [S0..Sn] to a sequence displacement
15 // [O0..On] where O[0] = 0 and O[k+1] = O[k]+S[k].
16 void
sizes2offsets(int const * sizes,int * offsets,int n)17 sizes2offsets(int const* sizes, int* offsets, int n)
18 {
19   offsets[0] = 0;
20   for(int i = 1; i < n; ++i) {
21     offsets[i] = offsets[i-1] + sizes[i-1];
22   }
23 }
24 
25 // Convert a sequence of sizes [S0..Sn] to a sequence displacement
26 // [O0..On] where O[0] = 0 and O[k+1] = O[k]+S[k].
27 void
sizes2offsets(std::vector<int> const & sizes,std::vector<int> & offsets)28 sizes2offsets(std::vector<int> const& sizes, std::vector<int>& offsets)
29 {
30   int sz = sizes.size();
31   offsets.resize(sz);
32   sizes2offsets(c_data(sizes), c_data(offsets), sz);
33 }
34 
35 // Given a sequence of sizes (typically the number of records dispatched
36 // to each process in a scater) and a sequence of displacements (typically the
37 // slot index at with those record starts), convert the later to a number
38 // of skipped slots.
39 void
offsets2skipped(int const * sizes,int const * offsets,int * skipped,int n)40 offsets2skipped(int const* sizes, int const* offsets, int* skipped, int n)
41 {
42   skipped[0] = 0;
43   for(int i = 1; i < n; ++i) {
44     skipped[i] -= offsets[i-1] + sizes[i-1];
45   }
46 }
47 
48 // Reconstruct offsets from sizes assuming no padding.
49 // Only takes place if on the root process and if
50 // displs are not already provided.
51 // If memory was allocated, returns a pointer to it
52 // otherwise null.
53 int*
make_offsets(communicator const & comm,int const * sizes,int const * displs,int root)54 make_offsets(communicator const& comm, int const* sizes, int const* displs, int root)
55 {
56   if (root == -1 || root == comm.rank()) {
57     assert(sizes);
58     if (!displs) {
59       int nproc = comm.size();
60       int* offsets = new int[nproc];
61       displs = offsets;
62       sizes2offsets(sizes, offsets, nproc);
63       return offsets;
64     } else {
65       return 0;
66     }
67   } else {
68     return 0;
69   }
70 }
71 
72 // Reconstruct skip slots from sizes and offsets.
73 // Only takes place if on the root process and if
74 // displs are provided.
75 // If memory was allocated, returns a pointer to it
76 // otherwise null.
77 int*
make_skipped_slots(communicator const & comm,int const * sizes,int const * displs,int root)78 make_skipped_slots(communicator const& comm, int const* sizes, int const* displs, int root)
79 {
80   if (root == -1 || root == comm.rank()) {
81     assert(sizes);
82     if (displs) {
83       int nproc = comm.size();
84       int* skipped = new int[nproc];
85       std::copy(displs, displs+nproc, skipped);
86       offsets2skipped(sizes, displs, skipped, nproc);
87       return skipped;
88     } else {
89       return 0;
90     }
91   } else {
92     return 0;
93   }
94 }
95 }
96 }}
97