libMesh
packed_range_test.C
Go to the documentation of this file.
1 #include "test_comm.h"
2 
3 // Ignore unused parameter warnings coming from cppuint headers
4 #include <libmesh/ignore_warnings.h>
5 #include <cppunit/extensions/HelperMacros.h>
6 #include <cppunit/TestCase.h>
7 #include <libmesh/restore_warnings.h>
8 
9 #include <libmesh/parallel.h>
10 #include <libmesh/null_output_iterator.h>
11 
12 #include <vector>
13 
14 // THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
15 // std::auto_ptr, which in turn produces -Wdeprecated-declarations
16 // warnings. These can be ignored in GCC as long as we wrap the
17 // offending code in appropriate pragmas. We can't get away with a
18 // single ignore_warnings.h inclusion at the beginning of this file,
19 // since the libmesh headers pull in a restore_warnings.h at some
20 // point. We also don't bother restoring warnings at the end of this
21 // file since it's not a header.
22 #include <libmesh/ignore_warnings.h>
23 
24 namespace libMesh {
25 namespace Parallel {
26 template <typename T>
27 class Packing<std::basic_string<T>> {
28 public:
29 
30  static const unsigned int size_bytes = 4;
31 
32  typedef T buffer_type;
33 
34  static unsigned int
35  get_string_len (typename std::vector<T>::const_iterator in)
36  {
37  unsigned int string_len = reinterpret_cast<const unsigned char &>(in[size_bytes-1]);
38  for (signed int i=size_bytes-2; i >= 0; --i)
39  {
40  string_len *= 256;
41  string_len += reinterpret_cast<const unsigned char &>(in[i]);
42  }
43  return string_len;
44  }
45 
46 
47  static unsigned int
48  packed_size (typename std::vector<T>::const_iterator in)
49  {
50  return get_string_len(in) + size_bytes;
51  }
52 
53  static unsigned int packable_size
54  (const std::basic_string<T> & s,
55  const void *)
56  {
57  return s.size() + size_bytes;
58  }
59 
60 
61  template <typename Iter>
62  static void pack (const std::basic_string<T> & b, Iter data_out,
63  const void *)
64  {
65  unsigned int string_len = b.size();
66  for (unsigned int i=0; i != size_bytes; ++i)
67  {
68  *data_out++ = (string_len % 256);
69  string_len /= 256;
70  }
71  std::copy(b.begin(), b.end(), data_out);
72  }
73 
74  static std::basic_string<T>
75  unpack (typename std::vector<T>::const_iterator in, void *)
76  {
77  unsigned int string_len = get_string_len(in);
78 
79  std::ostringstream oss;
80  for (unsigned int i = 0; i < string_len; ++i)
81  oss << reinterpret_cast<const unsigned char &>(in[i+size_bytes]);
82 
83  in += size_bytes + string_len;
84 
85  // std::cout << oss.str() << std::endl;
86  return std::string(oss.str());
87  }
88 
89 };
90 
91 
92 } // namespace Parallel
93 
94 } // namespace libMesh
95 
96 
97 
98 using namespace libMesh;
99 
100 class PackedRangeTest : public CppUnit::TestCase {
101 public:
102  CPPUNIT_TEST_SUITE( PackedRangeTest );
103 
104  CPPUNIT_TEST( testNullAllGather );
105  CPPUNIT_TEST( testNullSendReceive );
106  CPPUNIT_TEST( testContainerSendReceive );
107  // CPPUNIT_TEST( testAdapterSendReceive );
108  // CPPUNIT_TEST( testPointerAdapterSendReceive );
109 
110  CPPUNIT_TEST_SUITE_END();
111 
112 private:
113 
114 public:
115  void setUp()
116  {}
117 
118  void tearDown()
119  {}
120 
121 
122 
124  {
125  std::vector<processor_id_type> vals;
126 
127  std::vector<std::string> send(1);
128  if (TestCommWorld->rank() == 0)
129  send[0].assign("Hello");
130  else
131  send[0].assign("Goodbye");
132 
134  ((void *)(NULL), send.begin(), send.end(),
136  }
137 
138 
140  {
141  std::vector<processor_id_type> vals;
142 
143  std::vector<std::string> send(1);
144  const unsigned int my_rank = TestCommWorld->rank();
145  const unsigned int dest_rank =
146  (my_rank + 1) % TestCommWorld->size();
147  const unsigned int source_rank =
148  (my_rank + TestCommWorld->size() - 1) % TestCommWorld->size();
149 
150  {
151  std::ostringstream os;
152  os << my_rank;
153  send[0] = os.str();
154  }
155 
157  (dest_rank, (void *)(NULL), send.begin(), send.end(),
158  source_rank, (void *)(NULL),
160  (std::string*)NULL);
161  }
162 
163 
165  {
166  std::vector<processor_id_type> vals;
167 
168  std::vector<std::string> send(1), recv;
169 
170  const unsigned int my_rank = TestCommWorld->rank();
171  const unsigned int dest_rank =
172  (my_rank + 1) % TestCommWorld->size();
173  const unsigned int source_rank =
174  (my_rank + TestCommWorld->size() - 1) % TestCommWorld->size();
175 
176  {
177  std::ostringstream os;
178  os << my_rank;
179  send[0] = os.str();
180  }
181 
183  (dest_rank, (void *)(NULL), send.begin(), send.end(),
184  source_rank, (void *)(NULL),
185  std::back_inserter(recv),
186  (std::string*)NULL);
187 
188  CPPUNIT_ASSERT_EQUAL(recv.size(), std::size_t(1));
189 
190  std::string check;
191  {
192  std::ostringstream os;
193  os << source_rank;
194  check = os.str();
195  }
196 
197  CPPUNIT_ASSERT_EQUAL(recv[0], check);
198  }
199 
200 };
201 
void send(const unsigned int dest_processor_id, const T &data, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
unsigned int size() const
Definition: parallel.h:726
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:28
static std::basic_string< T > unpack(typename std::vector< T >::const_iterator in, void *)
void send_receive_packed_range(const unsigned int dest_processor_id, const Context1 *context1, RangeIter send_begin, const RangeIter send_end, const unsigned int source_processor_id, Context2 *context2, OutputIter out, const T *output_type, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send a range-of-pointers to one processor while simultaneously receiving another range from a (potent...
The libMesh namespace provides an interface to certain functionality in the library.
Define data types and (un)serialization functions for use when encoding a potentially-variable-size o...
Definition: parallel.h:582
void testContainerSendReceive()
static unsigned int packed_size(typename std::vector< T >::const_iterator in)
A do-nothing class for templated methods that expect output iterator arguments.
static void pack(const std::basic_string< T > &b, Iter data_out, const void *)
static unsigned int packable_size(const T &object, const Context *context)
static unsigned int get_string_len(typename std::vector< T >::const_iterator in)
unsigned int rank() const
Definition: parallel.h:724
void allgather_packed_range(Context *context, Iter range_begin, const Iter range_end, OutputIter out) const
Take a range of local variables, combine it with ranges from all processors, and write the output to ...
CPPUNIT_TEST_SUITE_REGISTRATION(PackedRangeTest)