1 /*
2 * Distributed under the OSI-approved Apache License, Version 2.0. See
3 * accompanying file Copyright.txt for details.
4 */
5 #include <cstdint>
6 #include <cstring>
7
8 #include <iostream>
9 #include <numeric> //std::iota
10 #include <stdexcept>
11
12 #include <adios2.h>
13
14 #include <gtest/gtest.h>
15
16 #include "../SmallTestData.h"
17
18 std::string engineName; // comes from command line
19
20 class BPWriteReadTestADIOS2 : public ::testing::Test
21 {
22 public:
23 BPWriteReadTestADIOS2() = default;
24
25 SmallTestData m_TestData;
26 };
27
28 //******************************************************************************
29 // 1D 1x8 test data
30 //******************************************************************************
31
32 // ADIOS2 BP write, native ADIOS1 read
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead1D8)33 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead1D8)
34 {
35 // Each process would write a 1x8 array and all processes would
36 // form a mpiSize * Nx 1D array
37 const std::string fname("ADIOS2BPWriteRead1D8.bp");
38
39 int mpiRank = 0, mpiSize = 1;
40 // Number of rows
41 const size_t Nx = 8;
42
43 // Number of steps
44 const size_t NSteps = 3;
45
46 #if ADIOS2_USE_MPI
47 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
48 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
49 #endif
50
51 // Write test data using BP
52
53 #if ADIOS2_USE_MPI
54 adios2::ADIOS adios(MPI_COMM_WORLD);
55 #else
56 adios2::ADIOS adios;
57 #endif
58 {
59 adios2::IO io = adios.DeclareIO("TestIO");
60
61 // Test setting parameters
62 {
63 io.SetParameter("ProfileUnits", "Microseconds");
64 io.SetParameters("Threads=2, CollectiveMetadata = OFF");
65 adios2::Params parameters = io.Parameters();
66
67 auto ProfileUnits = parameters.find("ProfileUnits");
68 EXPECT_NE(ProfileUnits, parameters.end());
69 EXPECT_EQ(ProfileUnits->second, "Microseconds");
70
71 auto Threads = parameters.find("Threads");
72 EXPECT_NE(Threads, parameters.end());
73 EXPECT_EQ(Threads->second, "2");
74
75 auto CollectiveMetadata = parameters.find("CollectiveMetadata");
76 EXPECT_NE(CollectiveMetadata, parameters.end());
77 EXPECT_EQ(CollectiveMetadata->second, "OFF");
78
79 io.ClearParameters();
80
81 // should not find parameters anymore
82 parameters = io.Parameters();
83 CollectiveMetadata = parameters.find("CollectiveMetadata");
84 EXPECT_EQ(CollectiveMetadata, parameters.end());
85 }
86
87 // Declare 1D variables (NumOfProcesses * Nx)
88 // The local process' part (start, count) can be defined now or later
89 // before Write().
90 {
91 const adios2::Dims shape{static_cast<size_t>(Nx * mpiSize)};
92 const adios2::Dims start{static_cast<size_t>(Nx * mpiRank)};
93 const adios2::Dims count{Nx};
94
95 auto var_iString = io.DefineVariable<std::string>("iString");
96 auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
97 auto var_i16 =
98 io.DefineVariable<int16_t>("i16", shape, start, count);
99 auto var_i32 =
100 io.DefineVariable<int32_t>("i32", shape, start, count);
101 auto var_i64 =
102 io.DefineVariable<int64_t>("i64", shape, start, count);
103 auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
104 auto var_u16 =
105 io.DefineVariable<uint16_t>("u16", shape, start, count);
106 auto var_u32 =
107 io.DefineVariable<uint32_t>("u32", shape, start, count);
108 auto var_u64 =
109 io.DefineVariable<uint64_t>("u64", shape, start, count);
110 auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
111 auto var_r64 =
112 io.DefineVariable<double>("r64", shape, start, count);
113 }
114
115 if (!engineName.empty())
116 {
117 io.SetEngine(engineName);
118 }
119 else
120 {
121 // Create the BP Engine
122 io.SetEngine("BPFile");
123 }
124
125 io.SetParameter("AsyncThreads", "0");
126 io.AddTransport("file");
127
128 // QUESTION: It seems that BPFilterWriter cannot overwrite existing
129 // files
130 // Ex. if you tune Nx and NSteps, the test would fail. But if you clear
131 // the cache in
132 // ${adios2Build}/testing/adios2/engine/bp/ADIOS2BPWriteADIOS1Read1D8.bp.dir,
133 // then it works
134 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
135
136 for (size_t step = 0; step < NSteps; ++step)
137 {
138 // Generate test data for each process uniquely
139 SmallTestData currentTestData = generateNewSmallTestData(
140 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
141
142 // Retrieve the variables that previously went out of scope
143 auto var_iString = io.InquireVariable<std::string>("iString");
144 auto var_i8 = io.InquireVariable<int8_t>("i8");
145 auto var_i16 = io.InquireVariable<int16_t>("i16");
146 auto var_i32 = io.InquireVariable<int32_t>("i32");
147 auto var_i64 = io.InquireVariable<int64_t>("i64");
148 auto var_u8 = io.InquireVariable<uint8_t>("u8");
149 auto var_u16 = io.InquireVariable<uint16_t>("u16");
150 auto var_u32 = io.InquireVariable<uint32_t>("u32");
151 auto var_u64 = io.InquireVariable<uint64_t>("u64");
152 auto var_r32 = io.InquireVariable<float>("r32");
153 auto var_r64 = io.InquireVariable<double>("r64");
154
155 // Make a 1D selection to describe the local dimensions of the
156 // variable we write and its offsets in the global spaces
157 adios2::Box<adios2::Dims> sel({mpiRank * Nx}, {Nx});
158
159 EXPECT_THROW(var_iString.SetSelection(sel), std::invalid_argument);
160 var_i8.SetSelection(sel);
161 var_i16.SetSelection(sel);
162 var_i32.SetSelection(sel);
163 var_i64.SetSelection(sel);
164 var_u8.SetSelection(sel);
165 var_u16.SetSelection(sel);
166 var_u32.SetSelection(sel);
167 var_u64.SetSelection(sel);
168 var_r32.SetSelection(sel);
169 var_r64.SetSelection(sel);
170
171 // Write each one
172 // fill in the variable with values from starting index to
173 // starting index + count
174 bpWriter.BeginStep();
175
176 bpWriter.Put(var_iString, currentTestData.S1);
177 bpWriter.Put(var_i8, currentTestData.I8.data());
178 bpWriter.Put(var_i16, currentTestData.I16.data());
179 bpWriter.Put(var_i32, currentTestData.I32.data());
180 bpWriter.Put(var_i64, currentTestData.I64.data());
181 bpWriter.Put(var_u8, currentTestData.U8.data());
182 bpWriter.Put(var_u16, currentTestData.U16.data());
183 bpWriter.Put(var_u32, currentTestData.U32.data());
184 bpWriter.Put(var_u64, currentTestData.U64.data());
185 bpWriter.Put(var_r32, currentTestData.R32.data());
186 bpWriter.Put(var_r64, currentTestData.R64.data());
187 bpWriter.PerformPuts();
188
189 bpWriter.EndStep();
190 }
191
192 // Close the file
193 bpWriter.Close();
194 }
195
196 {
197 adios2::IO io = adios.DeclareIO("ReadIO");
198
199 if (!engineName.empty())
200 {
201 io.SetEngine(engineName);
202 }
203
204 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
205
206 EXPECT_EQ(bpReader.Steps(), NSteps);
207
208 auto var_iString = io.InquireVariable<std::string>("iString");
209 EXPECT_TRUE(var_iString);
210 ASSERT_EQ(var_iString.Shape().size(), 0);
211 ASSERT_EQ(var_iString.Steps(), NSteps);
212
213 auto var_i8 = io.InquireVariable<int8_t>("i8");
214 EXPECT_TRUE(var_i8);
215 ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
216 ASSERT_EQ(var_i8.Steps(), NSteps);
217 ASSERT_EQ(var_i8.Shape()[0], mpiSize * Nx);
218
219 auto var_i16 = io.InquireVariable<int16_t>("i16");
220 EXPECT_TRUE(var_i16);
221 ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
222 ASSERT_EQ(var_i16.Steps(), NSteps);
223 ASSERT_EQ(var_i16.Shape()[0], mpiSize * Nx);
224
225 auto var_i32 = io.InquireVariable<int32_t>("i32");
226 EXPECT_TRUE(var_i32);
227 ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
228 ASSERT_EQ(var_i32.Steps(), NSteps);
229 ASSERT_EQ(var_i32.Shape()[0], mpiSize * Nx);
230
231 auto var_i64 = io.InquireVariable<int64_t>("i64");
232 EXPECT_TRUE(var_i64);
233 ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
234 ASSERT_EQ(var_i64.Steps(), NSteps);
235 ASSERT_EQ(var_i64.Shape()[0], mpiSize * Nx);
236
237 auto var_u8 = io.InquireVariable<uint8_t>("u8");
238 EXPECT_TRUE(var_u8);
239 ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
240 ASSERT_EQ(var_u8.Steps(), NSteps);
241 ASSERT_EQ(var_u8.Shape()[0], mpiSize * Nx);
242
243 auto var_u16 = io.InquireVariable<uint16_t>("u16");
244 EXPECT_TRUE(var_u16);
245 ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
246 ASSERT_EQ(var_u16.Steps(), NSteps);
247 ASSERT_EQ(var_u16.Shape()[0], mpiSize * Nx);
248
249 auto var_u32 = io.InquireVariable<uint32_t>("u32");
250 EXPECT_TRUE(var_u32);
251 ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
252 ASSERT_EQ(var_u32.Steps(), NSteps);
253 ASSERT_EQ(var_u32.Shape()[0], mpiSize * Nx);
254
255 auto var_u64 = io.InquireVariable<uint64_t>("u64");
256 EXPECT_TRUE(var_u64);
257 ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
258 ASSERT_EQ(var_u64.Steps(), NSteps);
259 ASSERT_EQ(var_u64.Shape()[0], mpiSize * Nx);
260
261 auto var_r32 = io.InquireVariable<float>("r32");
262 EXPECT_TRUE(var_r32);
263 ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
264 ASSERT_EQ(var_r32.Steps(), NSteps);
265 ASSERT_EQ(var_r32.Shape()[0], mpiSize * Nx);
266
267 auto var_r64 = io.InquireVariable<double>("r64");
268 EXPECT_TRUE(var_r64);
269 ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
270 ASSERT_EQ(var_r64.Steps(), NSteps);
271 ASSERT_EQ(var_r64.Shape()[0], mpiSize * Nx);
272
273 // TODO: other types
274
275 SmallTestData testData;
276
277 std::string IString;
278 std::array<int8_t, Nx> I8;
279 std::array<int16_t, Nx> I16;
280 std::array<int32_t, Nx> I32;
281 std::array<int64_t, Nx> I64;
282 std::array<uint8_t, Nx> U8;
283 std::array<uint16_t, Nx> U16;
284 std::array<uint32_t, Nx> U32;
285 std::array<uint64_t, Nx> U64;
286 std::array<float, Nx> R32;
287 std::array<double, Nx> R64;
288
289 const adios2::Dims start{mpiRank * Nx};
290 const adios2::Dims count{Nx};
291
292 const adios2::Box<adios2::Dims> sel(start, count);
293
294 var_i8.SetSelection(sel);
295 var_i16.SetSelection(sel);
296 var_i32.SetSelection(sel);
297 var_i64.SetSelection(sel);
298
299 var_u8.SetSelection(sel);
300 var_u16.SetSelection(sel);
301 var_u32.SetSelection(sel);
302 var_u64.SetSelection(sel);
303
304 var_r32.SetSelection(sel);
305 var_r64.SetSelection(sel);
306
307 for (size_t t = 0; t < NSteps; ++t)
308 {
309 var_i8.SetStepSelection({t, 1});
310 var_i16.SetStepSelection({t, 1});
311 var_i32.SetStepSelection({t, 1});
312 var_i64.SetStepSelection({t, 1});
313
314 var_u8.SetStepSelection({t, 1});
315 var_u16.SetStepSelection({t, 1});
316 var_u32.SetStepSelection({t, 1});
317 var_u64.SetStepSelection({t, 1});
318
319 var_r32.SetStepSelection({t, 1});
320 var_r64.SetStepSelection({t, 1});
321
322 // Generate test data for each rank uniquely
323 SmallTestData currentTestData = generateNewSmallTestData(
324 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
325
326 bpReader.Get(var_iString, IString);
327
328 bpReader.Get(var_i8, I8.data());
329 bpReader.Get(var_i16, I16.data());
330 bpReader.Get(var_i32, I32.data());
331 bpReader.Get(var_i64, I64.data());
332
333 bpReader.Get(var_u8, U8.data());
334 bpReader.Get(var_u16, U16.data());
335 bpReader.Get(var_u32, U32.data());
336 bpReader.Get(var_u64, U64.data());
337
338 bpReader.Get(var_r32, R32.data());
339 bpReader.Get(var_r64, R64.data());
340
341 bpReader.PerformGets();
342
343 EXPECT_EQ(IString, currentTestData.S1);
344
345 for (size_t i = 0; i < Nx; ++i)
346 {
347 std::stringstream ss;
348 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
349 std::string msg = ss.str();
350
351 EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg;
352 EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg;
353 EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg;
354 EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg;
355 EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg;
356 EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg;
357 EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg;
358 EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg;
359 EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg;
360 EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg;
361 }
362 }
363 bpReader.Close();
364 }
365 }
366
367 //******************************************************************************
368 // 2D 2x4 test data
369 //******************************************************************************
370
371 // ADIOS2 BP write, native ADIOS1 read
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead2D2x4)372 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D2x4)
373 {
374 // Each process would write a 2x4 array and all processes would
375 // form a 2D 2 * (numberOfProcess*Nx) matrix where Nx is 4 here
376 const std::string fname("ADIOS2BPWriteRead2D2x4Test.bp");
377
378 int mpiRank = 0, mpiSize = 1;
379 // Number of rows
380 const std::size_t Nx = 4;
381
382 // Number of rows
383 const std::size_t Ny = 2;
384
385 // Number of steps
386 const std::size_t NSteps = 3;
387
388 #if ADIOS2_USE_MPI
389 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
390 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
391 #endif
392
393 // Write test data using ADIOS2
394
395 #if ADIOS2_USE_MPI
396 adios2::ADIOS adios(MPI_COMM_WORLD);
397 #else
398 adios2::ADIOS adios;
399 #endif
400 {
401 adios2::IO io = adios.DeclareIO("TestIO");
402
403 // Declare 2D variables (Ny * (NumOfProcesses * Nx))
404 // The local process' part (start, count) can be defined now or later
405 // before Write().
406 {
407 const adios2::Dims shape{Ny, static_cast<size_t>(Nx * mpiSize)};
408 const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
409 const adios2::Dims count{Ny, Nx};
410
411 auto var_iString = io.DefineVariable<std::string>("iString");
412 auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
413 auto var_i16 =
414 io.DefineVariable<int16_t>("i16", shape, start, count);
415 auto var_i32 =
416 io.DefineVariable<int32_t>("i32", shape, start, count);
417 auto var_i64 =
418 io.DefineVariable<int64_t>("i64", shape, start, count);
419 auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
420 auto var_u16 =
421 io.DefineVariable<uint16_t>("u16", shape, start, count);
422 auto var_u32 =
423 io.DefineVariable<uint32_t>("u32", shape, start, count);
424 auto var_u64 =
425 io.DefineVariable<uint64_t>("u64", shape, start, count);
426 auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
427 auto var_r64 =
428 io.DefineVariable<double>("r64", shape, start, count);
429 }
430
431 if (!engineName.empty())
432 {
433 io.SetEngine(engineName);
434 }
435 else
436 {
437 // Create the BP Engine
438 io.SetEngine("BPFile");
439 }
440 io.AddTransport("file");
441
442 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
443
444 for (size_t step = 0; step < NSteps; ++step)
445 {
446 // Generate test data for each process uniquely
447 SmallTestData currentTestData = generateNewSmallTestData(
448 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
449
450 // Retrieve the variables that previously went out of scope
451 auto var_iString = io.InquireVariable<std::string>("iString");
452 auto var_i8 = io.InquireVariable<int8_t>("i8");
453 auto var_i16 = io.InquireVariable<int16_t>("i16");
454 auto var_i32 = io.InquireVariable<int32_t>("i32");
455 auto var_i64 = io.InquireVariable<int64_t>("i64");
456 auto var_u8 = io.InquireVariable<uint8_t>("u8");
457 auto var_u16 = io.InquireVariable<uint16_t>("u16");
458 auto var_u32 = io.InquireVariable<uint32_t>("u32");
459 auto var_u64 = io.InquireVariable<uint64_t>("u64");
460 auto var_r32 = io.InquireVariable<float>("r32");
461 auto var_r64 = io.InquireVariable<double>("r64");
462
463 // Make a 2D selection to describe the local dimensions of the
464 // variable we write and its offsets in the global spaces
465 adios2::Box<adios2::Dims> sel(
466 {0, static_cast<size_t>(mpiRank * Nx)}, {Ny, Nx});
467 var_i8.SetSelection(sel);
468 var_i16.SetSelection(sel);
469 var_i32.SetSelection(sel);
470 var_i64.SetSelection(sel);
471 var_u8.SetSelection(sel);
472 var_u16.SetSelection(sel);
473 var_u32.SetSelection(sel);
474 var_u64.SetSelection(sel);
475 var_r32.SetSelection(sel);
476 var_r64.SetSelection(sel);
477
478 // Write each one
479 // fill in the variable with values from starting index to
480 // starting index + count
481 bpWriter.BeginStep();
482 bpWriter.Put(var_iString, currentTestData.S1);
483 bpWriter.Put(var_i8, currentTestData.I8.data());
484 bpWriter.Put(var_i16, currentTestData.I16.data());
485 bpWriter.Put(var_i32, currentTestData.I32.data());
486 bpWriter.Put(var_i64, currentTestData.I64.data());
487 bpWriter.Put(var_u8, currentTestData.U8.data());
488 bpWriter.Put(var_u16, currentTestData.U16.data());
489 bpWriter.Put(var_u32, currentTestData.U32.data());
490 bpWriter.Put(var_u64, currentTestData.U64.data());
491 bpWriter.Put(var_r32, currentTestData.R32.data());
492 bpWriter.Put(var_r64, currentTestData.R64.data());
493 bpWriter.PerformPuts();
494
495 bpWriter.EndStep();
496 }
497
498 // Close the file
499 bpWriter.Close();
500 }
501
502 {
503 adios2::IO io = adios.DeclareIO("ReadIO");
504
505 if (!engineName.empty())
506 {
507 io.SetEngine(engineName);
508 }
509
510 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
511
512 EXPECT_EQ(bpReader.Steps(), NSteps);
513 auto var_iString = io.InquireVariable<std::string>("iString");
514 EXPECT_TRUE(var_iString);
515 ASSERT_EQ(var_iString.Shape().size(), 0);
516 ASSERT_EQ(var_iString.Steps(), NSteps);
517
518 auto var_i8 = io.InquireVariable<int8_t>("i8");
519 EXPECT_TRUE(var_i8);
520 ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
521 ASSERT_EQ(var_i8.Steps(), NSteps);
522 ASSERT_EQ(var_i8.Shape()[0], Ny);
523 ASSERT_EQ(var_i8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
524
525 auto var_i16 = io.InquireVariable<int16_t>("i16");
526 EXPECT_TRUE(var_i16);
527 ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
528 ASSERT_EQ(var_i16.Steps(), NSteps);
529 ASSERT_EQ(var_i16.Shape()[0], Ny);
530 ASSERT_EQ(var_i16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
531
532 auto var_i32 = io.InquireVariable<int32_t>("i32");
533 EXPECT_TRUE(var_i32);
534 ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
535 ASSERT_EQ(var_i32.Steps(), NSteps);
536 ASSERT_EQ(var_i32.Shape()[0], Ny);
537 ASSERT_EQ(var_i32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
538
539 auto var_i64 = io.InquireVariable<int64_t>("i64");
540 EXPECT_TRUE(var_i64);
541 ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
542 ASSERT_EQ(var_i64.Steps(), NSteps);
543 ASSERT_EQ(var_i64.Shape()[0], Ny);
544 ASSERT_EQ(var_i64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
545
546 auto var_u8 = io.InquireVariable<uint8_t>("u8");
547 EXPECT_TRUE(var_u8);
548 ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
549 ASSERT_EQ(var_u8.Steps(), NSteps);
550 ASSERT_EQ(var_u8.Shape()[0], Ny);
551 ASSERT_EQ(var_u8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
552
553 auto var_u16 = io.InquireVariable<uint16_t>("u16");
554 EXPECT_TRUE(var_u16);
555 ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
556 ASSERT_EQ(var_u16.Steps(), NSteps);
557 ASSERT_EQ(var_u16.Shape()[0], Ny);
558 ASSERT_EQ(var_u16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
559
560 auto var_u32 = io.InquireVariable<uint32_t>("u32");
561 EXPECT_TRUE(var_u32);
562 ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
563 ASSERT_EQ(var_u32.Steps(), NSteps);
564 ASSERT_EQ(var_u32.Shape()[0], Ny);
565 ASSERT_EQ(var_u32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
566
567 auto var_u64 = io.InquireVariable<uint64_t>("u64");
568 EXPECT_TRUE(var_u64);
569 ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
570 ASSERT_EQ(var_u64.Steps(), NSteps);
571 ASSERT_EQ(var_u64.Shape()[0], Ny);
572 ASSERT_EQ(var_u64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
573
574 auto var_r32 = io.InquireVariable<float>("r32");
575 EXPECT_TRUE(var_r32);
576 ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
577 ASSERT_EQ(var_r32.Steps(), NSteps);
578 ASSERT_EQ(var_r32.Shape()[0], Ny);
579 ASSERT_EQ(var_r32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
580
581 auto var_r64 = io.InquireVariable<double>("r64");
582 EXPECT_TRUE(var_r64);
583 ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
584 ASSERT_EQ(var_r64.Steps(), NSteps);
585 ASSERT_EQ(var_r64.Shape()[0], Ny);
586 ASSERT_EQ(var_r64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
587
588 std::string IString;
589 std::array<int8_t, Nx * Ny> I8;
590 std::array<int16_t, Nx * Ny> I16;
591 std::array<int32_t, Nx * Ny> I32;
592 std::array<int64_t, Nx * Ny> I64;
593 std::array<uint8_t, Nx * Ny> U8;
594 std::array<uint16_t, Nx * Ny> U16;
595 std::array<uint32_t, Nx * Ny> U32;
596 std::array<uint64_t, Nx * Ny> U64;
597 std::array<float, Nx * Ny> R32;
598 std::array<double, Nx * Ny> R64;
599
600 const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
601 const adios2::Dims count{Ny, Nx};
602
603 const adios2::Box<adios2::Dims> sel(start, count);
604
605 var_i8.SetSelection(sel);
606 var_i16.SetSelection(sel);
607 var_i32.SetSelection(sel);
608 var_i64.SetSelection(sel);
609
610 var_u8.SetSelection(sel);
611 var_u16.SetSelection(sel);
612 var_u32.SetSelection(sel);
613 var_u64.SetSelection(sel);
614
615 var_r32.SetSelection(sel);
616 var_r64.SetSelection(sel);
617
618 for (size_t t = 0; t < NSteps; ++t)
619 {
620 var_i8.SetStepSelection({t, 1});
621 var_i16.SetStepSelection({t, 1});
622 var_i32.SetStepSelection({t, 1});
623 var_i64.SetStepSelection({t, 1});
624
625 var_u8.SetStepSelection({t, 1});
626 var_u16.SetStepSelection({t, 1});
627 var_u32.SetStepSelection({t, 1});
628 var_u64.SetStepSelection({t, 1});
629
630 var_r32.SetStepSelection({t, 1});
631 var_r64.SetStepSelection({t, 1});
632
633 bpReader.Get(var_iString, IString);
634
635 bpReader.Get(var_i8, I8.data());
636 bpReader.Get(var_i16, I16.data());
637 bpReader.Get(var_i32, I32.data());
638 bpReader.Get(var_i64, I64.data());
639
640 bpReader.Get(var_u8, U8.data());
641 bpReader.Get(var_u16, U16.data());
642 bpReader.Get(var_u32, U32.data());
643 bpReader.Get(var_u64, U64.data());
644
645 bpReader.Get(var_r32, R32.data());
646 bpReader.Get(var_r64, R64.data());
647
648 bpReader.PerformGets();
649
650 // Generate test data for each rank uniquely
651 SmallTestData currentTestData = generateNewSmallTestData(
652 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
653
654 EXPECT_EQ(IString, currentTestData.S1);
655
656 for (size_t i = 0; i < Nx * Ny; ++i)
657 {
658 std::stringstream ss;
659 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
660 std::string msg = ss.str();
661
662 EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg;
663 EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg;
664 EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg;
665 EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg;
666 EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg;
667 EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg;
668 EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg;
669 EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg;
670 EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg;
671 EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg;
672 }
673 }
674 bpReader.Close();
675 }
676 }
677
678 //******************************************************************************
679 // 2D 4x2 test data
680 //******************************************************************************
681
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead2D4x2)682 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D4x2)
683 {
684 // Each process would write a 4x2 array and all processes would
685 // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here
686 const std::string fname("ADIOS2BPWriteRead2D4x2Test.bp");
687
688 int mpiRank = 0, mpiSize = 1;
689 // Number of rows
690 const std::size_t Nx = 2;
691 // Number of cols
692 const std::size_t Ny = 4;
693
694 // Number of steps
695 const std::size_t NSteps = 3;
696
697 #if ADIOS2_USE_MPI
698 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
699 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
700 #endif
701
702 // Write test data using ADIOS2
703
704 #if ADIOS2_USE_MPI
705 adios2::ADIOS adios(MPI_COMM_WORLD);
706 #else
707 adios2::ADIOS adios;
708 #endif
709 {
710 adios2::IO io = adios.DeclareIO("TestIO");
711
712 // Declare 2D variables (4 * (NumberOfProcess * Nx))
713 // The local process' part (start, count) can be defined now or later
714 // before Write().
715 {
716 adios2::Dims shape{static_cast<unsigned int>(Ny),
717 static_cast<unsigned int>(mpiSize * Nx)};
718 adios2::Dims start{static_cast<unsigned int>(0),
719 static_cast<unsigned int>(mpiRank * Nx)};
720 adios2::Dims count{static_cast<unsigned int>(Ny),
721 static_cast<unsigned int>(Nx)};
722 auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
723 auto var_i16 =
724 io.DefineVariable<int16_t>("i16", shape, start, count);
725 auto var_i32 =
726 io.DefineVariable<int32_t>("i32", shape, start, count);
727 auto var_i64 =
728 io.DefineVariable<int64_t>("i64", shape, start, count);
729 auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
730 auto var_u16 =
731 io.DefineVariable<uint16_t>("u16", shape, start, count);
732 auto var_u32 =
733 io.DefineVariable<uint32_t>("u32", shape, start, count);
734 auto var_u64 =
735 io.DefineVariable<uint64_t>("u64", shape, start, count);
736 auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
737 auto var_r64 =
738 io.DefineVariable<double>("r64", shape, start, count);
739 }
740
741 if (!engineName.empty())
742 {
743 io.SetEngine(engineName);
744 }
745 else
746 {
747 // Create the BP Engine
748 io.SetEngine("BPFile");
749 }
750
751 io.AddTransport("file");
752
753 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
754
755 for (size_t step = 0; step < NSteps; ++step)
756 {
757 // Generate test data for each process uniquely
758 SmallTestData currentTestData = generateNewSmallTestData(
759 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
760
761 // Retrieve the variables that previously went out of scope
762 auto var_i8 = io.InquireVariable<int8_t>("i8");
763 auto var_i16 = io.InquireVariable<int16_t>("i16");
764 auto var_i32 = io.InquireVariable<int32_t>("i32");
765 auto var_i64 = io.InquireVariable<int64_t>("i64");
766 auto var_u8 = io.InquireVariable<uint8_t>("u8");
767 auto var_u16 = io.InquireVariable<uint16_t>("u16");
768 auto var_u32 = io.InquireVariable<uint32_t>("u32");
769 auto var_u64 = io.InquireVariable<uint64_t>("u64");
770 auto var_r32 = io.InquireVariable<float>("r32");
771 auto var_r64 = io.InquireVariable<double>("r64");
772
773 // Make a 2D selection to describe the local dimensions of the
774 // variable we write and its offsets in the global spaces
775 adios2::Box<adios2::Dims> sel(
776 {0, static_cast<unsigned int>(mpiRank * Nx)}, {Ny, Nx});
777 var_i8.SetSelection(sel);
778 var_i16.SetSelection(sel);
779 var_i32.SetSelection(sel);
780 var_i64.SetSelection(sel);
781 var_u8.SetSelection(sel);
782 var_u16.SetSelection(sel);
783 var_u32.SetSelection(sel);
784 var_u64.SetSelection(sel);
785 var_r32.SetSelection(sel);
786 var_r64.SetSelection(sel);
787
788 // Write each one
789 // fill in the variable with values from starting index to
790 // starting index + count
791 bpWriter.BeginStep();
792 bpWriter.Put(var_i8, currentTestData.I8.data());
793 bpWriter.Put(var_i16, currentTestData.I16.data());
794 bpWriter.Put(var_i32, currentTestData.I32.data());
795 bpWriter.Put(var_i64, currentTestData.I64.data());
796 bpWriter.Put(var_u8, currentTestData.U8.data());
797 bpWriter.Put(var_u16, currentTestData.U16.data());
798 bpWriter.Put(var_u32, currentTestData.U32.data());
799 bpWriter.Put(var_u64, currentTestData.U64.data());
800 bpWriter.Put(var_r32, currentTestData.R32.data());
801 bpWriter.Put(var_r64, currentTestData.R64.data());
802 bpWriter.EndStep();
803 }
804
805 // Close the file
806 bpWriter.Close();
807 }
808
809 {
810 adios2::IO io = adios.DeclareIO("ReadIO");
811
812 if (!engineName.empty())
813 {
814 io.SetEngine(engineName);
815 }
816
817 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
818
819 EXPECT_EQ(bpReader.Steps(), NSteps);
820
821 auto var_i8 = io.InquireVariable<int8_t>("i8");
822 EXPECT_TRUE(var_i8);
823 ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
824 ASSERT_EQ(var_i8.Steps(), NSteps);
825 ASSERT_EQ(var_i8.Shape()[0], Ny);
826 ASSERT_EQ(var_i8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
827
828 auto var_i16 = io.InquireVariable<int16_t>("i16");
829 EXPECT_TRUE(var_i16);
830 ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
831 ASSERT_EQ(var_i16.Steps(), NSteps);
832 ASSERT_EQ(var_i16.Shape()[0], Ny);
833 ASSERT_EQ(var_i16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
834
835 auto var_i32 = io.InquireVariable<int32_t>("i32");
836 EXPECT_TRUE(var_i32);
837 ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
838 ASSERT_EQ(var_i32.Steps(), NSteps);
839 ASSERT_EQ(var_i32.Shape()[0], Ny);
840 ASSERT_EQ(var_i32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
841
842 auto var_i64 = io.InquireVariable<int64_t>("i64");
843 EXPECT_TRUE(var_i64);
844 ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
845 ASSERT_EQ(var_i64.Steps(), NSteps);
846 ASSERT_EQ(var_i64.Shape()[0], Ny);
847 ASSERT_EQ(var_i64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
848
849 auto var_u8 = io.InquireVariable<uint8_t>("u8");
850 EXPECT_TRUE(var_u8);
851 ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
852 ASSERT_EQ(var_u8.Steps(), NSteps);
853 ASSERT_EQ(var_u8.Shape()[0], Ny);
854 ASSERT_EQ(var_u8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
855
856 auto var_u16 = io.InquireVariable<uint16_t>("u16");
857 EXPECT_TRUE(var_u16);
858 ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
859 ASSERT_EQ(var_u16.Steps(), NSteps);
860 ASSERT_EQ(var_u16.Shape()[0], Ny);
861 ASSERT_EQ(var_u16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
862
863 auto var_u32 = io.InquireVariable<uint32_t>("u32");
864 EXPECT_TRUE(var_u32);
865 ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
866 ASSERT_EQ(var_u32.Steps(), NSteps);
867 ASSERT_EQ(var_u32.Shape()[0], Ny);
868 ASSERT_EQ(var_u32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
869
870 auto var_u64 = io.InquireVariable<uint64_t>("u64");
871 EXPECT_TRUE(var_u64);
872 ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
873 ASSERT_EQ(var_u64.Steps(), NSteps);
874 ASSERT_EQ(var_u64.Shape()[0], Ny);
875 ASSERT_EQ(var_u64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
876
877 auto var_r32 = io.InquireVariable<float>("r32");
878 EXPECT_TRUE(var_r32);
879 ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
880 ASSERT_EQ(var_r32.Steps(), NSteps);
881 ASSERT_EQ(var_r32.Shape()[0], Ny);
882 ASSERT_EQ(var_r32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
883
884 auto var_r64 = io.InquireVariable<double>("r64");
885 EXPECT_TRUE(var_r64);
886 ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
887 ASSERT_EQ(var_r64.Steps(), NSteps);
888 ASSERT_EQ(var_r64.Shape()[0], Ny);
889 ASSERT_EQ(var_r64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
890
891 // If the size of the array is smaller than the data
892 // the result is weird... double and uint64_t would get
893 // completely garbage data
894 std::array<int8_t, Nx * Ny> I8;
895 std::array<int16_t, Nx * Ny> I16;
896 std::array<int32_t, Nx * Ny> I32;
897 std::array<int64_t, Nx * Ny> I64;
898 std::array<uint8_t, Nx * Ny> U8;
899 std::array<uint16_t, Nx * Ny> U16;
900 std::array<uint32_t, Nx * Ny> U32;
901 std::array<uint64_t, Nx * Ny> U64;
902 std::array<float, Nx * Ny> R32;
903 std::array<double, Nx * Ny> R64;
904
905 const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
906 const adios2::Dims count{Ny, Nx};
907
908 const adios2::Box<adios2::Dims> sel(start, count);
909
910 var_i8.SetSelection(sel);
911 var_i16.SetSelection(sel);
912 var_i32.SetSelection(sel);
913 var_i64.SetSelection(sel);
914
915 var_u8.SetSelection(sel);
916 var_u16.SetSelection(sel);
917 var_u32.SetSelection(sel);
918 var_u64.SetSelection(sel);
919
920 var_r32.SetSelection(sel);
921 var_r64.SetSelection(sel);
922
923 for (size_t t = 0; t < NSteps; ++t)
924 {
925 var_i8.SetStepSelection({t, 1});
926 var_i16.SetStepSelection({t, 1});
927 var_i32.SetStepSelection({t, 1});
928 var_i64.SetStepSelection({t, 1});
929
930 var_u8.SetStepSelection({t, 1});
931 var_u16.SetStepSelection({t, 1});
932 var_u32.SetStepSelection({t, 1});
933 var_u64.SetStepSelection({t, 1});
934
935 var_r32.SetStepSelection({t, 1});
936 var_r64.SetStepSelection({t, 1});
937
938 bpReader.Get(var_i8, I8.data());
939 bpReader.Get(var_i16, I16.data());
940 bpReader.Get(var_i32, I32.data());
941 bpReader.Get(var_i64, I64.data());
942
943 bpReader.Get(var_u8, U8.data());
944 bpReader.Get(var_u16, U16.data());
945 bpReader.Get(var_u32, U32.data());
946 bpReader.Get(var_u64, U64.data());
947
948 bpReader.Get(var_r32, R32.data());
949 bpReader.Get(var_r64, R64.data());
950
951 bpReader.PerformGets();
952
953 // Generate test data for each rank uniquely
954 SmallTestData currentTestData = generateNewSmallTestData(
955 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
956
957 for (size_t i = 0; i < Nx * Ny; ++i)
958 {
959 std::stringstream ss;
960 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
961 std::string msg = ss.str();
962
963 EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg;
964 EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg;
965 EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg;
966 EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg;
967 EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg;
968 EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg;
969 EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg;
970 EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg;
971 EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg;
972 EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg;
973 }
974 }
975 bpReader.Close();
976 }
977 }
978
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead10D2x2)979 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead10D2x2)
980 {
981 // Each process would write a 2x2x...x2 9D array and all processes would
982 // form a 10D NumberOfProcess x 2 x ... x 2) array
983 const std::string fname("ADIOS2BPWriteRead10D2x2Test.bp");
984
985 int mpiRank = 0, mpiSize = 1;
986 // Number of steps
987 const std::size_t NSteps = 3;
988
989 #if ADIOS2_USE_MPI
990 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
991 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
992 #endif
993
994 size_t NX = static_cast<unsigned int>(mpiSize);
995 size_t OX = static_cast<unsigned int>(mpiRank);
996 const adios2::Dims shape{NX, 2, 2, 2, 2, 2, 2, 2, 2, 2};
997 const adios2::Dims start{OX, 0, 0, 0, 0, 0, 0, 0, 0, 0};
998 const adios2::Dims count{1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
999
1000 std::array<double, 512> R64w, R64r;
1001 std::array<std::complex<double>, 512> CR64w, CR64r;
1002
1003 // Write test data using ADIOS2
1004
1005 #if ADIOS2_USE_MPI
1006 adios2::ADIOS adios(MPI_COMM_WORLD);
1007 #else
1008 adios2::ADIOS adios;
1009 #endif
1010 {
1011 adios2::IO io = adios.DeclareIO("TestIO");
1012
1013 // Declare 10D variables
1014 {
1015 auto var_r64 =
1016 io.DefineVariable<double>("r64", shape, start, count);
1017 auto var_c64 = io.DefineVariable<std::complex<double>>(
1018 "cr64", shape, start, count);
1019 }
1020
1021 if (!engineName.empty())
1022 {
1023 io.SetEngine(engineName);
1024 }
1025 else
1026 {
1027 // Create the BP Engine
1028 io.SetEngine("BPFile");
1029 }
1030
1031 io.AddTransport("file");
1032
1033 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
1034
1035 for (size_t step = 0; step < NSteps; ++step)
1036 {
1037 double d = mpiRank + 1 + step / 10.0;
1038 // Generate test data for each process uniquely
1039 std::for_each(R64w.begin(), R64w.end(), [&](double &v) {
1040 v = d;
1041 d += 0.0001;
1042 });
1043 std::for_each(CR64w.begin(), CR64w.end(),
1044 [&](std::complex<double> &v) {
1045 v.real(d);
1046 v.imag(d);
1047 });
1048
1049 // Retrieve the variables that previously went out of scope
1050 auto var_r64 = io.InquireVariable<double>("r64");
1051 auto var_cr64 = io.InquireVariable<std::complex<double>>("cr64");
1052
1053 // Make a 2D selection to describe the local dimensions of the
1054 // variable we write and its offsets in the global spaces
1055 adios2::Box<adios2::Dims> sel({start, count});
1056 var_r64.SetSelection(sel);
1057 var_cr64.SetSelection(sel);
1058
1059 // Write each one
1060 // fill in the variable with values from starting index to
1061 // starting index + count
1062 bpWriter.BeginStep();
1063 bpWriter.Put(var_r64, R64w.data());
1064 bpWriter.Put(var_cr64, CR64w.data());
1065 bpWriter.EndStep();
1066 }
1067
1068 // Close the file
1069 bpWriter.Close();
1070 }
1071
1072 {
1073 adios2::IO io = adios.DeclareIO("ReadIO");
1074
1075 if (!engineName.empty())
1076 {
1077 io.SetEngine(engineName);
1078 }
1079
1080 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
1081
1082 EXPECT_EQ(bpReader.Steps(), NSteps);
1083
1084 auto var_r64 = io.InquireVariable<double>("r64");
1085 EXPECT_TRUE(var_r64);
1086 ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
1087 ASSERT_EQ(var_r64.Steps(), NSteps);
1088 ASSERT_EQ(var_r64.Shape().size(), 10);
1089 ASSERT_EQ(var_r64.Shape()[0], NX);
1090 ASSERT_EQ(var_r64.Shape()[1], 2);
1091 ASSERT_EQ(var_r64.Shape()[2], 2);
1092 ASSERT_EQ(var_r64.Shape()[3], 2);
1093 ASSERT_EQ(var_r64.Shape()[4], 2);
1094 ASSERT_EQ(var_r64.Shape()[5], 2);
1095 ASSERT_EQ(var_r64.Shape()[6], 2);
1096 ASSERT_EQ(var_r64.Shape()[7], 2);
1097 ASSERT_EQ(var_r64.Shape()[8], 2);
1098 ASSERT_EQ(var_r64.Shape()[9], 2);
1099
1100 auto var_cr64 = io.InquireVariable<std::complex<double>>("cr64");
1101 EXPECT_TRUE(var_cr64);
1102 ASSERT_EQ(var_cr64.ShapeID(), adios2::ShapeID::GlobalArray);
1103 ASSERT_EQ(var_cr64.Steps(), NSteps);
1104 ASSERT_EQ(var_cr64.Shape().size(), 10);
1105 ASSERT_EQ(var_cr64.Shape()[0], NX);
1106 ASSERT_EQ(var_cr64.Shape()[1], 2);
1107 ASSERT_EQ(var_cr64.Shape()[2], 2);
1108 ASSERT_EQ(var_cr64.Shape()[3], 2);
1109 ASSERT_EQ(var_cr64.Shape()[4], 2);
1110 ASSERT_EQ(var_cr64.Shape()[5], 2);
1111 ASSERT_EQ(var_cr64.Shape()[6], 2);
1112 ASSERT_EQ(var_cr64.Shape()[7], 2);
1113 ASSERT_EQ(var_cr64.Shape()[8], 2);
1114 ASSERT_EQ(var_cr64.Shape()[9], 2);
1115
1116 const adios2::Box<adios2::Dims> sel(start, count);
1117
1118 var_r64.SetSelection(sel);
1119 var_cr64.SetSelection(sel);
1120
1121 for (size_t step = 0; step < NSteps; ++step)
1122 {
1123 var_r64.SetStepSelection({step, 1});
1124 var_cr64.SetStepSelection({step, 1});
1125 bpReader.Get(var_r64, R64r.data());
1126 bpReader.Get(var_cr64, CR64r.data());
1127 bpReader.PerformGets();
1128
1129 double d = mpiRank + 1 + step / 10.0;
1130 // Re-generate test data for each process uniquely that was written
1131 std::for_each(R64w.begin(), R64w.end(), [&](double &v) {
1132 v = d;
1133 d += 0.0001;
1134 });
1135 std::for_each(CR64w.begin(), CR64w.end(),
1136 [&](std::complex<double> &v) {
1137 v.real(d);
1138 v.imag(d);
1139 });
1140
1141 for (size_t i = 0; i < 512; ++i)
1142 {
1143 std::stringstream ss;
1144 ss << "t=" << step << " i=" << i << " rank=" << mpiRank;
1145 std::string msg = ss.str();
1146
1147 EXPECT_EQ(R64r[i], R64w[i]) << msg;
1148 EXPECT_EQ(CR64r[i], CR64w[i]) << msg;
1149 }
1150 }
1151 bpReader.Close();
1152 }
1153 }
1154
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead2D4x2_ReadMultiSteps)1155 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D4x2_ReadMultiSteps)
1156 {
1157 // Each process would write a 4x2 array and all processes would
1158 // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here
1159 const std::string fname("ADIOS2BPWriteRead2D4x2Test_ReadMultiSteps.bp");
1160
1161 int mpiRank = 0, mpiSize = 1;
1162 // Number of rows
1163 const std::size_t Nx = 2;
1164 // Number of cols
1165 const std::size_t Ny = 4;
1166
1167 // Number of steps
1168 const std::size_t NSteps = 5;
1169 const std::size_t tInitial = 2;
1170
1171 #if ADIOS2_USE_MPI
1172 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
1173 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
1174 #endif
1175
1176 // Write test data using ADIOS2
1177
1178 #if ADIOS2_USE_MPI
1179 adios2::ADIOS adios(MPI_COMM_WORLD);
1180 #else
1181 adios2::ADIOS adios;
1182 #endif
1183 {
1184 adios2::IO io = adios.DeclareIO("TestIO");
1185
1186 // Declare 2D variables (4 * (NumberOfProcess * Nx))
1187 // The local process' part (start, count) can be defined now or
1188 // later before Write().
1189 {
1190 adios2::Dims shape{Ny, static_cast<size_t>(mpiSize * Nx)};
1191 adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
1192 adios2::Dims count{Ny, Nx};
1193 auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
1194 auto var_i16 =
1195 io.DefineVariable<int16_t>("i16", shape, start, count);
1196 auto var_i32 =
1197 io.DefineVariable<int32_t>("i32", shape, start, count);
1198 auto var_i64 =
1199 io.DefineVariable<int64_t>("i64", shape, start, count);
1200 auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
1201 auto var_u16 =
1202 io.DefineVariable<uint16_t>("u16", shape, start, count);
1203 auto var_u32 =
1204 io.DefineVariable<uint32_t>("u32", shape, start, count);
1205 auto var_u64 =
1206 io.DefineVariable<uint64_t>("u64", shape, start, count);
1207 auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
1208 auto var_r64 =
1209 io.DefineVariable<double>("r64", shape, start, count);
1210 }
1211
1212 if (!engineName.empty())
1213 {
1214 io.SetEngine(engineName);
1215 }
1216 else
1217 {
1218 // Create the BP Engine
1219 io.SetEngine("BPFile");
1220 }
1221
1222 io.AddTransport("file");
1223
1224 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
1225
1226 for (size_t step = 0; step < NSteps; ++step)
1227 {
1228 // Generate test data for each process uniquely
1229 SmallTestData currentTestData = generateNewSmallTestData(
1230 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
1231
1232 // Retrieve the variables that previously went out of scope
1233 auto var_i8 = io.InquireVariable<int8_t>("i8");
1234 auto var_i16 = io.InquireVariable<int16_t>("i16");
1235 auto var_i32 = io.InquireVariable<int32_t>("i32");
1236 auto var_i64 = io.InquireVariable<int64_t>("i64");
1237 auto var_u8 = io.InquireVariable<uint8_t>("u8");
1238 auto var_u16 = io.InquireVariable<uint16_t>("u16");
1239 auto var_u32 = io.InquireVariable<uint32_t>("u32");
1240 auto var_u64 = io.InquireVariable<uint64_t>("u64");
1241 auto var_r32 = io.InquireVariable<float>("r32");
1242 auto var_r64 = io.InquireVariable<double>("r64");
1243
1244 // Make a 2D selection to describe the local dimensions of the
1245 // variable we write and its offsets in the global spaces
1246 adios2::Box<adios2::Dims> sel(
1247 {0, static_cast<unsigned int>(mpiRank * Nx)}, {Ny, Nx});
1248 var_i8.SetSelection(sel);
1249 var_i16.SetSelection(sel);
1250 var_i32.SetSelection(sel);
1251 var_i64.SetSelection(sel);
1252 var_u8.SetSelection(sel);
1253 var_u16.SetSelection(sel);
1254 var_u32.SetSelection(sel);
1255 var_u64.SetSelection(sel);
1256 var_r32.SetSelection(sel);
1257 var_r64.SetSelection(sel);
1258
1259 // Write each one
1260 // fill in the variable with values from starting index to
1261 // starting index + count
1262 bpWriter.BeginStep();
1263 bpWriter.Put(var_i8, currentTestData.I8.data());
1264 bpWriter.Put(var_i16, currentTestData.I16.data());
1265 bpWriter.Put(var_i32, currentTestData.I32.data());
1266 bpWriter.Put(var_i64, currentTestData.I64.data());
1267 bpWriter.Put(var_u8, currentTestData.U8.data());
1268 bpWriter.Put(var_u16, currentTestData.U16.data());
1269 bpWriter.Put(var_u32, currentTestData.U32.data());
1270 bpWriter.Put(var_u64, currentTestData.U64.data());
1271 bpWriter.Put(var_r32, currentTestData.R32.data());
1272 bpWriter.Put(var_r64, currentTestData.R64.data());
1273 bpWriter.EndStep();
1274 }
1275
1276 // Close the file
1277 bpWriter.Close();
1278 }
1279
1280 {
1281 adios2::IO io = adios.DeclareIO("ReadIO");
1282
1283 if (!engineName.empty())
1284 {
1285 io.SetEngine(engineName);
1286 }
1287
1288 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
1289
1290 EXPECT_EQ(bpReader.Steps(), NSteps);
1291
1292 auto var_i8 = io.InquireVariable<int8_t>("i8");
1293 EXPECT_TRUE(var_i8);
1294 ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
1295 ASSERT_EQ(var_i8.Steps(), NSteps);
1296 ASSERT_EQ(var_i8.Shape()[0], Ny);
1297 ASSERT_EQ(var_i8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1298
1299 auto var_i16 = io.InquireVariable<int16_t>("i16");
1300 EXPECT_TRUE(var_i16);
1301 ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
1302 ASSERT_EQ(var_i16.Steps(), NSteps);
1303 ASSERT_EQ(var_i16.Shape()[0], Ny);
1304 ASSERT_EQ(var_i16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1305
1306 auto var_i32 = io.InquireVariable<int32_t>("i32");
1307 EXPECT_TRUE(var_i32);
1308 ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
1309 ASSERT_EQ(var_i32.Steps(), NSteps);
1310 ASSERT_EQ(var_i32.Shape()[0], Ny);
1311 ASSERT_EQ(var_i32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1312
1313 auto var_i64 = io.InquireVariable<int64_t>("i64");
1314 EXPECT_TRUE(var_i64);
1315 ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
1316 ASSERT_EQ(var_i64.Steps(), NSteps);
1317 ASSERT_EQ(var_i64.Shape()[0], Ny);
1318 ASSERT_EQ(var_i64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1319
1320 auto var_u8 = io.InquireVariable<uint8_t>("u8");
1321 EXPECT_TRUE(var_u8);
1322 ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
1323 ASSERT_EQ(var_u8.Steps(), NSteps);
1324 ASSERT_EQ(var_u8.Shape()[0], Ny);
1325 ASSERT_EQ(var_u8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1326
1327 auto var_u16 = io.InquireVariable<uint16_t>("u16");
1328 EXPECT_TRUE(var_u16);
1329 ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
1330 ASSERT_EQ(var_u16.Steps(), NSteps);
1331 ASSERT_EQ(var_u16.Shape()[0], Ny);
1332 ASSERT_EQ(var_u16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1333
1334 auto var_u32 = io.InquireVariable<uint32_t>("u32");
1335 EXPECT_TRUE(var_u32);
1336 ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
1337 ASSERT_EQ(var_u32.Steps(), NSteps);
1338 ASSERT_EQ(var_u32.Shape()[0], Ny);
1339 ASSERT_EQ(var_u32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1340
1341 auto var_u64 = io.InquireVariable<uint64_t>("u64");
1342 EXPECT_TRUE(var_u64);
1343 ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
1344 ASSERT_EQ(var_u64.Steps(), NSteps);
1345 ASSERT_EQ(var_u64.Shape()[0], Ny);
1346 ASSERT_EQ(var_u64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1347
1348 auto var_r32 = io.InquireVariable<float>("r32");
1349 EXPECT_TRUE(var_r32);
1350 ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
1351 ASSERT_EQ(var_r32.Steps(), NSteps);
1352 ASSERT_EQ(var_r32.Shape()[0], Ny);
1353 ASSERT_EQ(var_r32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1354
1355 auto var_r64 = io.InquireVariable<double>("r64");
1356 EXPECT_TRUE(var_r64);
1357 ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
1358 ASSERT_EQ(var_r64.Steps(), NSteps);
1359 ASSERT_EQ(var_r64.Shape()[0], Ny);
1360 ASSERT_EQ(var_r64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
1361
1362 // If the size of the array is smaller than the data
1363 // the result is weird... double and uint64_t would get
1364 // completely garbage data
1365 std::array<int8_t, NSteps * Nx * Ny> I8;
1366 std::array<int16_t, NSteps * Nx * Ny> I16;
1367 std::array<int32_t, NSteps * Nx * Ny> I32;
1368 std::array<int64_t, NSteps * Nx * Ny> I64;
1369 std::array<uint8_t, NSteps * Nx * Ny> U8;
1370 std::array<uint16_t, NSteps * Nx * Ny> U16;
1371 std::array<uint32_t, NSteps * Nx * Ny> U32;
1372 std::array<uint64_t, NSteps * Nx * Ny> U64;
1373 std::array<float, NSteps * Nx * Ny> R32;
1374 std::array<double, NSteps * Nx * Ny> R64;
1375
1376 const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
1377 const adios2::Dims count{Ny, Nx};
1378
1379 const adios2::Box<adios2::Dims> sel(start, count);
1380
1381 var_i8.SetSelection(sel);
1382 var_i16.SetSelection(sel);
1383 var_i32.SetSelection(sel);
1384 var_i64.SetSelection(sel);
1385
1386 var_u8.SetSelection(sel);
1387 var_u16.SetSelection(sel);
1388 var_u32.SetSelection(sel);
1389 var_u64.SetSelection(sel);
1390
1391 var_r32.SetSelection(sel);
1392 var_r64.SetSelection(sel);
1393
1394 var_i8.SetStepSelection({tInitial, NSteps - tInitial});
1395 var_i16.SetStepSelection({tInitial, NSteps - tInitial});
1396 var_i32.SetStepSelection({tInitial, NSteps - tInitial});
1397 var_i64.SetStepSelection({tInitial, NSteps - tInitial});
1398
1399 var_u8.SetStepSelection({tInitial, NSteps - tInitial});
1400 var_u16.SetStepSelection({tInitial, NSteps - tInitial});
1401 var_u32.SetStepSelection({tInitial, NSteps - tInitial});
1402 var_u64.SetStepSelection({tInitial, NSteps - tInitial});
1403
1404 var_r32.SetStepSelection({tInitial, NSteps - tInitial});
1405 var_r64.SetStepSelection({tInitial, NSteps - tInitial});
1406
1407 bpReader.Get(var_i8, I8.data());
1408 bpReader.Get(var_i16, I16.data());
1409 bpReader.Get(var_i32, I32.data());
1410 bpReader.Get(var_i64, I64.data());
1411
1412 bpReader.Get(var_u8, U8.data());
1413 bpReader.Get(var_u16, U16.data());
1414 bpReader.Get(var_u32, U32.data());
1415 bpReader.Get(var_u64, U64.data());
1416
1417 bpReader.Get(var_r32, R32.data());
1418 bpReader.Get(var_r64, R64.data());
1419
1420 bpReader.PerformGets();
1421
1422 for (size_t t = tInitial; t < NSteps; ++t)
1423 {
1424 // Generate test data for each rank uniquely
1425 SmallTestData currentTestData = generateNewSmallTestData(
1426 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
1427
1428 for (size_t i = 0; i < Nx * Ny; ++i)
1429 {
1430 const size_t index = (t - tInitial) * Nx * Ny + i;
1431 std::stringstream ss;
1432 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
1433 std::string msg = ss.str();
1434
1435 EXPECT_EQ(I8[index], currentTestData.I8[i]) << msg;
1436 EXPECT_EQ(I16[index], currentTestData.I16[i]) << msg;
1437 EXPECT_EQ(I32[index], currentTestData.I32[i]) << msg;
1438 EXPECT_EQ(I64[index], currentTestData.I64[i]) << msg;
1439 EXPECT_EQ(U8[index], currentTestData.U8[i]) << msg;
1440 EXPECT_EQ(U16[index], currentTestData.U16[i]) << msg;
1441 EXPECT_EQ(U32[index], currentTestData.U32[i]) << msg;
1442 EXPECT_EQ(U64[index], currentTestData.U64[i]) << msg;
1443 EXPECT_EQ(R32[index], currentTestData.R32[i]) << msg;
1444 EXPECT_EQ(R64[index], currentTestData.R64[i]) << msg;
1445 }
1446 }
1447
1448 bpReader.Close();
1449 }
1450 }
1451
TEST_F(BPWriteReadTestADIOS2,ADIOS2BPWriteRead2D4x2_MultiStepsOverflow)1452 TEST_F(BPWriteReadTestADIOS2, ADIOS2BPWriteRead2D4x2_MultiStepsOverflow)
1453 {
1454 // Each process would write a 4x2 array and all processes would
1455 // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here
1456 const std::string fname("ADIOS2BPWriteRead2D4x2Test_Overflow.bp");
1457
1458 int mpiRank = 0, mpiSize = 1;
1459 // Number of rows
1460 const std::size_t Nx = 2;
1461 // Number of cols
1462 const std::size_t Ny = 4;
1463
1464 // Number of steps
1465 const std::size_t NSteps = 5;
1466 const std::size_t tInitial = 2;
1467
1468 #if ADIOS2_USE_MPI
1469 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
1470 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
1471 #endif
1472
1473 // Write test data using ADIOS2
1474
1475 #if ADIOS2_USE_MPI
1476 adios2::ADIOS adios(MPI_COMM_WORLD);
1477 #else
1478 adios2::ADIOS adios;
1479 #endif
1480 {
1481 adios2::IO io = adios.DeclareIO("TestIO");
1482
1483 // Declare 2D variables (4 * (NumberOfProcess * Nx))
1484 // The local process' part (start, count) can be defined now or
1485 // later before Write().
1486 {
1487 adios2::Dims shape{Ny, static_cast<size_t>(mpiSize * Nx)};
1488 adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
1489 adios2::Dims count{Ny, Nx};
1490 auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
1491 auto var_i16 =
1492 io.DefineVariable<int16_t>("i16", shape, start, count);
1493 auto var_i32 =
1494 io.DefineVariable<int32_t>("i32", shape, start, count);
1495 auto var_i64 =
1496 io.DefineVariable<int64_t>("i64", shape, start, count);
1497 auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
1498 auto var_u16 =
1499 io.DefineVariable<uint16_t>("u16", shape, start, count);
1500 auto var_u32 =
1501 io.DefineVariable<uint32_t>("u32", shape, start, count);
1502 auto var_u64 =
1503 io.DefineVariable<uint64_t>("u64", shape, start, count);
1504 auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
1505 auto var_r64 =
1506 io.DefineVariable<double>("r64", shape, start, count);
1507 }
1508
1509 if (!engineName.empty())
1510 {
1511 io.SetEngine(engineName);
1512 }
1513 else
1514 {
1515 // Create the BP Engine
1516 io.SetEngine("BPFile");
1517 }
1518
1519 io.AddTransport("file");
1520
1521 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
1522
1523 for (size_t step = 0; step < NSteps; ++step)
1524 {
1525 // Generate test data for each process uniquely
1526 SmallTestData currentTestData = generateNewSmallTestData(
1527 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
1528
1529 // Retrieve the variables that previously went out of scope
1530 auto var_i8 = io.InquireVariable<int8_t>("i8");
1531 auto var_i16 = io.InquireVariable<int16_t>("i16");
1532 auto var_i32 = io.InquireVariable<int32_t>("i32");
1533 auto var_i64 = io.InquireVariable<int64_t>("i64");
1534 auto var_u8 = io.InquireVariable<uint8_t>("u8");
1535 auto var_u16 = io.InquireVariable<uint16_t>("u16");
1536 auto var_u32 = io.InquireVariable<uint32_t>("u32");
1537 auto var_u64 = io.InquireVariable<uint64_t>("u64");
1538 auto var_r32 = io.InquireVariable<float>("r32");
1539 auto var_r64 = io.InquireVariable<double>("r64");
1540
1541 // Make a 2D selection to describe the local dimensions of the
1542 // variable we write and its offsets in the global spaces
1543 adios2::Box<adios2::Dims> sel(
1544 {0, static_cast<unsigned int>(mpiRank * Nx)}, {Ny, Nx});
1545 var_i8.SetSelection(sel);
1546 var_i16.SetSelection(sel);
1547 var_i32.SetSelection(sel);
1548 var_i64.SetSelection(sel);
1549 var_u8.SetSelection(sel);
1550 var_u16.SetSelection(sel);
1551 var_u32.SetSelection(sel);
1552 var_u64.SetSelection(sel);
1553 var_r32.SetSelection(sel);
1554 var_r64.SetSelection(sel);
1555
1556 // Write each one
1557 // fill in the variable with values from starting index to
1558 // starting index + count
1559 bpWriter.BeginStep();
1560 bpWriter.Put(var_i8, currentTestData.I8.data());
1561 bpWriter.Put(var_i16, currentTestData.I16.data());
1562 bpWriter.Put(var_i32, currentTestData.I32.data());
1563 bpWriter.Put(var_i64, currentTestData.I64.data());
1564 bpWriter.Put(var_u8, currentTestData.U8.data());
1565 bpWriter.Put(var_u16, currentTestData.U16.data());
1566 bpWriter.Put(var_u32, currentTestData.U32.data());
1567 bpWriter.Put(var_u64, currentTestData.U64.data());
1568 bpWriter.Put(var_r32, currentTestData.R32.data());
1569 bpWriter.Put(var_r64, currentTestData.R64.data());
1570 bpWriter.EndStep();
1571 }
1572
1573 // Close the file
1574 bpWriter.Close();
1575 }
1576
1577 {
1578 adios2::IO io = adios.DeclareIO("ReadIO");
1579
1580 if (!engineName.empty())
1581 {
1582 io.SetEngine(engineName);
1583 }
1584
1585 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
1586
1587 auto var_i8 = io.InquireVariable<int8_t>("i8");
1588 auto var_i16 = io.InquireVariable<int16_t>("i16");
1589 auto var_i32 = io.InquireVariable<int32_t>("i32");
1590 auto var_i64 = io.InquireVariable<int64_t>("i64");
1591
1592 auto var_u8 = io.InquireVariable<uint8_t>("u8");
1593 auto var_u16 = io.InquireVariable<uint16_t>("u16");
1594 auto var_u32 = io.InquireVariable<uint32_t>("u32");
1595 auto var_u64 = io.InquireVariable<uint64_t>("u64");
1596
1597 auto var_r32 = io.InquireVariable<float>("r32");
1598 auto var_r64 = io.InquireVariable<double>("r64");
1599 // If the size of the array is smaller than the data
1600 // the result is weird... double and uint64_t would get
1601 // completely garbage data
1602 std::array<int8_t, NSteps * Nx * Ny> I8;
1603 std::array<int16_t, NSteps * Nx * Ny> I16;
1604 std::array<int32_t, NSteps * Nx * Ny> I32;
1605 std::array<int64_t, NSteps * Nx * Ny> I64;
1606 std::array<uint8_t, NSteps * Nx * Ny> U8;
1607 std::array<uint16_t, NSteps * Nx * Ny> U16;
1608 std::array<uint32_t, NSteps * Nx * Ny> U32;
1609 std::array<uint64_t, NSteps * Nx * Ny> U64;
1610 std::array<float, NSteps * Nx * Ny> R32;
1611 std::array<double, NSteps * Nx * Ny> R64;
1612
1613 const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
1614 const adios2::Dims count{Ny, Nx};
1615
1616 const adios2::Box<adios2::Dims> sel(start, count);
1617
1618 var_i8.SetSelection(sel);
1619 var_i16.SetSelection(sel);
1620 var_i32.SetSelection(sel);
1621 var_i64.SetSelection(sel);
1622
1623 var_u8.SetSelection(sel);
1624 var_u16.SetSelection(sel);
1625 var_u32.SetSelection(sel);
1626 var_u64.SetSelection(sel);
1627
1628 var_r32.SetSelection(sel);
1629 var_r64.SetSelection(sel);
1630
1631 var_i8.SetStepSelection({tInitial, NSteps - tInitial + 1});
1632 var_i16.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1633 var_i32.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1634 var_i64.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1635
1636 var_u8.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1637 var_u16.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1638 var_u32.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1639 var_u64.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1640
1641 var_r32.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1642 var_r64.SetStepSelection({tInitial + 1, NSteps - tInitial + 1});
1643
1644 EXPECT_THROW(bpReader.Get(var_i8, I8.data()), std::invalid_argument);
1645 EXPECT_THROW(bpReader.Get(var_i16, I16.data()), std::invalid_argument);
1646 EXPECT_THROW(bpReader.Get(var_i32, I32.data()), std::invalid_argument);
1647 EXPECT_THROW(bpReader.Get(var_i64, I64.data()), std::invalid_argument);
1648
1649 EXPECT_THROW(bpReader.Get(var_u8, U8.data()), std::invalid_argument);
1650 EXPECT_THROW(bpReader.Get(var_u16, U16.data()), std::invalid_argument);
1651 EXPECT_THROW(bpReader.Get(var_u32, U32.data()), std::invalid_argument);
1652 EXPECT_THROW(bpReader.Get(var_u64, U64.data()), std::invalid_argument);
1653
1654 EXPECT_THROW(bpReader.Get(var_r32, R32.data()), std::invalid_argument);
1655 EXPECT_THROW(bpReader.Get(var_r64, R64.data()), std::invalid_argument);
1656 }
1657 }
1658
TEST_F(BPWriteReadTestADIOS2,OpenEngineTwice)1659 TEST_F(BPWriteReadTestADIOS2, OpenEngineTwice)
1660 {
1661 // Each process would write a 4x2 array and all processes would
1662 // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here
1663 const std::string fname("OpenTwice.bp");
1664
1665 #if ADIOS2_USE_MPI
1666 adios2::ADIOS adios(MPI_COMM_WORLD);
1667 #else
1668 adios2::ADIOS adios;
1669 #endif
1670 {
1671 adios2::IO io = adios.DeclareIO("TwoOpens");
1672
1673 if (!engineName.empty())
1674 {
1675 io.SetEngine(engineName);
1676 }
1677 else
1678 {
1679 // Create the BP Engine
1680 io.SetEngine("BPFile");
1681 }
1682
1683 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
1684
1685 EXPECT_THROW(io.Open(fname, adios2::Mode::Write),
1686 std::invalid_argument);
1687
1688 bpWriter.Close();
1689
1690 EXPECT_NO_THROW(io.Open(fname, adios2::Mode::Write));
1691 EXPECT_THROW(io.Open(fname, adios2::Mode::Read), std::invalid_argument);
1692 }
1693 }
1694
TEST_F(BPWriteReadTestADIOS2,ReadStartCount)1695 TEST_F(BPWriteReadTestADIOS2, ReadStartCount)
1696 {
1697 // Each process would write a 4x2 array and all processes would
1698 // form a 2D 4 * (NumberOfProcess * Nx) matrix where Nx is 2 here
1699 const std::string fname("ReadStartCount.bp");
1700
1701 int mpiRank = 0, mpiSize = 1;
1702
1703 const std::size_t Nx = 10;
1704
1705 #if ADIOS2_USE_MPI
1706 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
1707 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
1708 #endif
1709
1710 std::vector<int64_t> localData(Nx);
1711 std::iota(localData.begin(), localData.end(), mpiRank * Nx);
1712
1713 #if ADIOS2_USE_MPI
1714 adios2::ADIOS adios(MPI_COMM_WORLD);
1715 #else
1716 adios2::ADIOS adios;
1717 #endif
1718 {
1719 adios2::IO io = adios.DeclareIO("StartCountWrite");
1720 if (!engineName.empty())
1721 {
1722 io.SetEngine(engineName);
1723 }
1724
1725 io.DefineVariable<int64_t>(
1726 "range", {static_cast<std::size_t>(Nx * mpiSize)},
1727 {static_cast<std::size_t>(Nx * mpiRank)}, {Nx});
1728
1729 adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
1730
1731 bpWriter.Put<int64_t>("range", localData.data());
1732 bpWriter.Close();
1733 }
1734 // Reader
1735 {
1736 adios2::IO io = adios.DeclareIO("StartCountRead");
1737 if (!engineName.empty())
1738 {
1739 io.SetEngine(engineName);
1740 }
1741
1742 adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
1743 adios2::Variable<int64_t> varRange =
1744 io.InquireVariable<int64_t>("range");
1745
1746 const std::size_t gNx = static_cast<std::size_t>(Nx * mpiSize);
1747 std::vector<int64_t> globalData(gNx);
1748 bpReader.Get(varRange, globalData);
1749 bpReader.PerformGets();
1750
1751 std::vector<int64_t> iStartEndData;
1752 iStartEndData.reserve(gNx); // maximum possible
1753
1754 for (size_t i = 1; i < gNx; ++i)
1755 {
1756 varRange.SetSelection({{i}, {gNx - i}});
1757
1758 bpReader.Get("range", iStartEndData);
1759 bpReader.PerformGets();
1760
1761 for (size_t j = i; j < gNx; ++j)
1762 {
1763 EXPECT_EQ(globalData[j], iStartEndData[j - i]);
1764 }
1765 }
1766 bpReader.Close();
1767 }
1768 }
1769
1770 //******************************************************************************
1771 // main
1772 //******************************************************************************
1773
main(int argc,char ** argv)1774 int main(int argc, char **argv)
1775 {
1776 #if ADIOS2_USE_MPI
1777 MPI_Init(nullptr, nullptr);
1778 #endif
1779
1780 int result;
1781 ::testing::InitGoogleTest(&argc, argv);
1782
1783 if (argc > 1)
1784 {
1785 engineName = std::string(argv[1]);
1786 }
1787 result = RUN_ALL_TESTS();
1788
1789 #if ADIOS2_USE_MPI
1790 MPI_Finalize();
1791 #endif
1792
1793 return result;
1794 }
1795