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 <stdexcept>
10 
11 #include <adios2.h>
12 
13 #include <gtest/gtest.h>
14 
15 #include "../SmallTestData.h"
16 
17 std::string engineName; // comes from command line
18 
19 // ADIOS2 BP write
TimeAggregation1D8(const std::string flushstepscount)20 void TimeAggregation1D8(const std::string flushstepscount)
21 {
22     // Each process would write a 1x8 array and all processes would
23     // form a mpiSize * Nx 1D array
24     const std::string fname = "BPTimeAggregation1D8_" + flushstepscount + ".bp";
25 
26     int mpiRank = 0, mpiSize = 1;
27     // Number of rows
28     const size_t Nx = 8;
29 
30     // Number of steps
31     const size_t NSteps = 10;
32 
33 #if ADIOS2_USE_MPI
34     MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
35     MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
36 #endif
37 
38     // Write test data using ADIOS2
39 
40 #if ADIOS2_USE_MPI
41     adios2::ADIOS adios(MPI_COMM_WORLD);
42 #else
43     adios2::ADIOS adios;
44 #endif
45     const std::string TestName =
46         "TimeAggregation1D8 flush every " + flushstepscount + " steps";
47     {
48         adios2::IO io = adios.DeclareIO("TestIO");
49 
50         io.SetParameter("FlushStepsCount", flushstepscount);
51 
52         // Declare 1D variables (NumOfProcesses * Nx)
53         // The local process' part (start, count) can be defined now or later
54         // before Write().
55         {
56             const adios2::Dims shape{static_cast<size_t>(Nx * mpiSize)};
57             const adios2::Dims start{static_cast<size_t>(Nx * mpiRank)};
58             const adios2::Dims count{Nx};
59 
60             auto var_iString = io.DefineVariable<std::string>("iString");
61             auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
62             auto var_i16 =
63                 io.DefineVariable<int16_t>("i16", shape, start, count);
64             auto var_i32 =
65                 io.DefineVariable<int32_t>("i32", shape, start, count);
66             auto var_i64 =
67                 io.DefineVariable<int64_t>("i64", shape, start, count);
68             auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
69             auto var_u16 =
70                 io.DefineVariable<uint16_t>("u16", shape, start, count);
71             auto var_u32 =
72                 io.DefineVariable<uint32_t>("u32", shape, start, count);
73             auto var_u64 =
74                 io.DefineVariable<uint64_t>("u64", shape, start, count);
75             auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
76             auto var_r64 =
77                 io.DefineVariable<double>("r64", shape, start, count);
78 
79             io.DefineAttribute<std::string>("TestName", TestName);
80         }
81 
82         if (!engineName.empty())
83         {
84             io.SetEngine(engineName);
85         }
86         else
87         {
88             // Create the BP Engine
89             io.SetEngine("BP4");
90         }
91 
92         io.AddTransport("file");
93         io.SetParameter("AggregatorRatio", "1");
94 
95         SmallTestData m_TestData;
96 
97         adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
98 
99         for (size_t step = 0; step < NSteps; ++step)
100         {
101             // Generate test data for each process uniquely
102             SmallTestData currentTestData = generateNewSmallTestData(
103                 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
104 
105             // Retrieve the variables that previously went out of scope
106             auto var_iString = io.InquireVariable<std::string>("iString");
107             auto var_i8 = io.InquireVariable<int8_t>("i8");
108             auto var_i16 = io.InquireVariable<int16_t>("i16");
109             auto var_i32 = io.InquireVariable<int32_t>("i32");
110             auto var_i64 = io.InquireVariable<int64_t>("i64");
111             auto var_u8 = io.InquireVariable<uint8_t>("u8");
112             auto var_u16 = io.InquireVariable<uint16_t>("u16");
113             auto var_u32 = io.InquireVariable<uint32_t>("u32");
114             auto var_u64 = io.InquireVariable<uint64_t>("u64");
115             auto var_r32 = io.InquireVariable<float>("r32");
116             auto var_r64 = io.InquireVariable<double>("r64");
117 
118             // Make a 1D selection to describe the local dimensions of the
119             // variable we write and its offsets in the global spaces
120             adios2::Box<adios2::Dims> sel({mpiRank * Nx}, {Nx});
121 
122             EXPECT_THROW(var_iString.SetSelection(sel), std::invalid_argument);
123             var_i8.SetSelection(sel);
124             var_i16.SetSelection(sel);
125             var_i32.SetSelection(sel);
126             var_i64.SetSelection(sel);
127             var_u8.SetSelection(sel);
128             var_u16.SetSelection(sel);
129             var_u32.SetSelection(sel);
130             var_u64.SetSelection(sel);
131             var_r32.SetSelection(sel);
132             var_r64.SetSelection(sel);
133 
134             // Write each one
135             // fill in the variable with values from starting index to
136             // starting index + count
137             bpWriter.BeginStep();
138             bpWriter.Put(var_iString, currentTestData.S1);
139             bpWriter.Put(var_i8, currentTestData.I8.data());
140             bpWriter.Put(var_i16, currentTestData.I16.data());
141             bpWriter.Put(var_i32, currentTestData.I32.data());
142             bpWriter.Put(var_i64, currentTestData.I64.data());
143             bpWriter.Put(var_u8, currentTestData.U8.data());
144             bpWriter.Put(var_u16, currentTestData.U16.data());
145             bpWriter.Put(var_u32, currentTestData.U32.data());
146             bpWriter.Put(var_u64, currentTestData.U64.data());
147             bpWriter.Put(var_r32, currentTestData.R32.data());
148             bpWriter.Put(var_r64, currentTestData.R64.data());
149             bpWriter.PerformPuts();
150 
151             bpWriter.EndStep();
152         }
153 
154         // Close the file
155         bpWriter.Close();
156     }
157 
158     {
159         adios2::IO io = adios.DeclareIO("ReadIO");
160 
161         if (!engineName.empty())
162         {
163             io.SetEngine(engineName);
164         }
165         else
166         {
167             // Create the BP Engine
168             io.SetEngine("BP4");
169         }
170 
171         adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
172 
173         auto var_iString = io.InquireVariable<std::string>("iString");
174         EXPECT_TRUE(var_iString);
175         ASSERT_EQ(var_iString.Shape().size(), 0);
176         ASSERT_EQ(var_iString.Steps(), NSteps);
177 
178         auto var_i8 = io.InquireVariable<int8_t>("i8");
179         EXPECT_TRUE(var_i8);
180         ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
181         ASSERT_EQ(var_i8.Steps(), NSteps);
182         ASSERT_EQ(var_i8.Shape()[0], mpiSize * Nx);
183 
184         auto var_i16 = io.InquireVariable<int16_t>("i16");
185         EXPECT_TRUE(var_i16);
186         ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
187         ASSERT_EQ(var_i16.Steps(), NSteps);
188         ASSERT_EQ(var_i16.Shape()[0], mpiSize * Nx);
189 
190         auto var_i32 = io.InquireVariable<int32_t>("i32");
191         EXPECT_TRUE(var_i32);
192         ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
193         ASSERT_EQ(var_i32.Steps(), NSteps);
194         ASSERT_EQ(var_i32.Shape()[0], mpiSize * Nx);
195 
196         auto var_i64 = io.InquireVariable<int64_t>("i64");
197         EXPECT_TRUE(var_i64);
198         ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
199         ASSERT_EQ(var_i64.Steps(), NSteps);
200         ASSERT_EQ(var_i64.Shape()[0], mpiSize * Nx);
201 
202         auto var_u8 = io.InquireVariable<uint8_t>("u8");
203         EXPECT_TRUE(var_u8);
204         ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
205         ASSERT_EQ(var_u8.Steps(), NSteps);
206         ASSERT_EQ(var_u8.Shape()[0], mpiSize * Nx);
207 
208         auto var_u16 = io.InquireVariable<uint16_t>("u16");
209         EXPECT_TRUE(var_u16);
210         ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
211         ASSERT_EQ(var_u16.Steps(), NSteps);
212         ASSERT_EQ(var_u16.Shape()[0], mpiSize * Nx);
213 
214         auto var_u32 = io.InquireVariable<uint32_t>("u32");
215         EXPECT_TRUE(var_u32);
216         ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
217         ASSERT_EQ(var_u32.Steps(), NSteps);
218         ASSERT_EQ(var_u32.Shape()[0], mpiSize * Nx);
219 
220         auto var_u64 = io.InquireVariable<uint64_t>("u64");
221         EXPECT_TRUE(var_u64);
222         ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
223         ASSERT_EQ(var_u64.Steps(), NSteps);
224         ASSERT_EQ(var_u64.Shape()[0], mpiSize * Nx);
225 
226         auto var_r32 = io.InquireVariable<float>("r32");
227         EXPECT_TRUE(var_r32);
228         ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
229         ASSERT_EQ(var_r32.Steps(), NSteps);
230         ASSERT_EQ(var_r32.Shape()[0], mpiSize * Nx);
231 
232         auto var_r64 = io.InquireVariable<double>("r64");
233         EXPECT_TRUE(var_r64);
234         ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
235         ASSERT_EQ(var_r64.Steps(), NSteps);
236         ASSERT_EQ(var_r64.Shape()[0], mpiSize * Nx);
237 
238         auto attr = io.InquireAttribute<std::string>("TestName");
239         EXPECT_TRUE(attr);
240         ASSERT_EQ(attr.Data().size() == 1, true);
241         ASSERT_EQ(attr.Type(), adios2::GetType<std::string>());
242         ASSERT_EQ(attr.Data().front(), TestName);
243 
244         // TODO: other types
245 
246         SmallTestData testData;
247 
248         std::string IString;
249         std::array<int8_t, Nx> I8;
250         std::array<int16_t, Nx> I16;
251         std::array<int32_t, Nx> I32;
252         std::array<int64_t, Nx> I64;
253         std::array<uint8_t, Nx> U8;
254         std::array<uint16_t, Nx> U16;
255         std::array<uint32_t, Nx> U32;
256         std::array<uint64_t, Nx> U64;
257         std::array<float, Nx> R32;
258         std::array<double, Nx> R64;
259 
260         const adios2::Dims start{mpiRank * Nx};
261         const adios2::Dims count{Nx};
262 
263         const adios2::Box<adios2::Dims> sel(start, count);
264 
265         var_i8.SetSelection(sel);
266         var_i16.SetSelection(sel);
267         var_i32.SetSelection(sel);
268         var_i64.SetSelection(sel);
269 
270         var_u8.SetSelection(sel);
271         var_u16.SetSelection(sel);
272         var_u32.SetSelection(sel);
273         var_u64.SetSelection(sel);
274 
275         var_r32.SetSelection(sel);
276         var_r64.SetSelection(sel);
277 
278         SmallTestData m_TestData;
279 
280         for (size_t t = 0; t < NSteps; ++t)
281         {
282             var_i8.SetStepSelection({t, 1});
283             var_i16.SetStepSelection({t, 1});
284             var_i32.SetStepSelection({t, 1});
285             var_i64.SetStepSelection({t, 1});
286 
287             var_u8.SetStepSelection({t, 1});
288             var_u16.SetStepSelection({t, 1});
289             var_u32.SetStepSelection({t, 1});
290             var_u64.SetStepSelection({t, 1});
291 
292             var_r32.SetStepSelection({t, 1});
293             var_r64.SetStepSelection({t, 1});
294 
295             // Generate test data for each rank uniquely
296             SmallTestData currentTestData = generateNewSmallTestData(
297                 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
298 
299             bpReader.Get(var_iString, IString, adios2::Mode::Sync);
300 
301             bpReader.Get(var_i8, I8.data());
302             bpReader.Get(var_i16, I16.data());
303             bpReader.Get(var_i32, I32.data());
304             bpReader.Get(var_i64, I64.data());
305 
306             bpReader.Get(var_u8, U8.data());
307             bpReader.Get(var_u16, U16.data());
308             bpReader.Get(var_u32, U32.data());
309             bpReader.Get(var_u64, U64.data());
310 
311             bpReader.Get(var_r32, R32.data());
312             bpReader.Get(var_r64, R64.data());
313 
314             bpReader.PerformGets();
315 
316             EXPECT_EQ(IString, currentTestData.S1);
317 
318             for (size_t i = 0; i < Nx; ++i)
319             {
320                 std::stringstream ss;
321                 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
322                 std::string msg = ss.str();
323 
324                 EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg;
325                 EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg;
326                 EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg;
327                 EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg;
328                 EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg;
329                 EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg;
330                 EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg;
331                 EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg;
332                 EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg;
333                 EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg;
334             }
335         }
336         bpReader.Close();
337     }
338 }
339 
TimeAggregation2D4x2(const std::string flushstepscount)340 void TimeAggregation2D4x2(const std::string flushstepscount)
341 {
342     // Each process would write a 2x4 array and all processes would
343     // form a 2D 2 * (numberOfProcess*Nx) matrix where Nx is 4 here
344     const std::string fname =
345         "BPTimeAggregation2D2x4_" + flushstepscount + ".bp";
346 
347     int mpiRank = 0, mpiSize = 1;
348     // Number of rows
349     const std::size_t Nx = 4;
350 
351     // Number of rows
352     const std::size_t Ny = 2;
353 
354     // Number of steps
355     const std::size_t NSteps = 10;
356 
357 #if ADIOS2_USE_MPI
358     MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
359     MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
360 #endif
361 
362     // Write test data using ADIOS2
363 
364 #if ADIOS2_USE_MPI
365     adios2::ADIOS adios(MPI_COMM_WORLD);
366 #else
367     adios2::ADIOS adios;
368 #endif
369     const std::string TestName =
370         "TimeAggregation2D4x2 flush every " + flushstepscount + " steps";
371 
372     {
373         adios2::IO io = adios.DeclareIO("TestIO");
374 
375         io.SetParameter("FlushStepsCount", flushstepscount);
376 
377         // Declare 2D variables (Ny * (NumOfProcesses * Nx))
378         // The local process' part (start, count) can be defined now or
379         // later
380         // before Write().
381         {
382             const adios2::Dims shape{Ny, static_cast<size_t>(Nx * mpiSize)};
383             const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
384             const adios2::Dims count{Ny, Nx};
385 
386             auto var_iString = io.DefineVariable<std::string>("iString");
387             auto var_i8 = io.DefineVariable<int8_t>("i8", shape, start, count);
388             auto var_i16 =
389                 io.DefineVariable<int16_t>("i16", shape, start, count);
390             auto var_i32 =
391                 io.DefineVariable<int32_t>("i32", shape, start, count);
392             auto var_i64 =
393                 io.DefineVariable<int64_t>("i64", shape, start, count);
394             auto var_u8 = io.DefineVariable<uint8_t>("u8", shape, start, count);
395             auto var_u16 =
396                 io.DefineVariable<uint16_t>("u16", shape, start, count);
397             auto var_u32 =
398                 io.DefineVariable<uint32_t>("u32", shape, start, count);
399             auto var_u64 =
400                 io.DefineVariable<uint64_t>("u64", shape, start, count);
401             auto var_r32 = io.DefineVariable<float>("r32", shape, start, count);
402             auto var_r64 =
403                 io.DefineVariable<double>("r64", shape, start, count);
404 
405             io.DefineAttribute<std::string>("TestName", TestName);
406         }
407 
408         if (!engineName.empty())
409         {
410             io.SetEngine(engineName);
411         }
412         else
413         {
414             // Create the BP Engine
415             io.SetEngine("BP4");
416         }
417 
418         io.AddTransport("file");
419         io.SetParameter("AggregatorRatio", "1");
420 
421         SmallTestData m_TestData;
422 
423         adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write);
424 
425         for (size_t step = 0; step < NSteps; ++step)
426         {
427             // Generate test data for each process uniquely
428             SmallTestData currentTestData = generateNewSmallTestData(
429                 m_TestData, static_cast<int>(step), mpiRank, mpiSize);
430 
431             // Retrieve the variables that previously went out of scope
432             auto var_iString = io.InquireVariable<std::string>("iString");
433             auto var_i8 = io.InquireVariable<int8_t>("i8");
434             auto var_i16 = io.InquireVariable<int16_t>("i16");
435             auto var_i32 = io.InquireVariable<int32_t>("i32");
436             auto var_i64 = io.InquireVariable<int64_t>("i64");
437             auto var_u8 = io.InquireVariable<uint8_t>("u8");
438             auto var_u16 = io.InquireVariable<uint16_t>("u16");
439             auto var_u32 = io.InquireVariable<uint32_t>("u32");
440             auto var_u64 = io.InquireVariable<uint64_t>("u64");
441             auto var_r32 = io.InquireVariable<float>("r32");
442             auto var_r64 = io.InquireVariable<double>("r64");
443 
444             // Make a 2D selection to describe the local dimensions of the
445             // variable we write and its offsets in the global spaces
446             adios2::Box<adios2::Dims> sel(
447                 {0, static_cast<size_t>(mpiRank * Nx)}, {Ny, Nx});
448             var_i8.SetSelection(sel);
449             var_i16.SetSelection(sel);
450             var_i32.SetSelection(sel);
451             var_i64.SetSelection(sel);
452             var_u8.SetSelection(sel);
453             var_u16.SetSelection(sel);
454             var_u32.SetSelection(sel);
455             var_u64.SetSelection(sel);
456             var_r32.SetSelection(sel);
457             var_r64.SetSelection(sel);
458 
459             // Write each one
460             // fill in the variable with values from starting index to
461             // starting index + count
462             bpWriter.BeginStep();
463             bpWriter.Put(var_iString, currentTestData.S1);
464             bpWriter.Put(var_i8, currentTestData.I8.data());
465             bpWriter.Put(var_i16, currentTestData.I16.data());
466             bpWriter.Put(var_i32, currentTestData.I32.data());
467             bpWriter.Put(var_i64, currentTestData.I64.data());
468             bpWriter.Put(var_u8, currentTestData.U8.data());
469             bpWriter.Put(var_u16, currentTestData.U16.data());
470             bpWriter.Put(var_u32, currentTestData.U32.data());
471             bpWriter.Put(var_u64, currentTestData.U64.data());
472             bpWriter.Put(var_r32, currentTestData.R32.data());
473             bpWriter.Put(var_r64, currentTestData.R64.data());
474             bpWriter.PerformPuts();
475 
476             bpWriter.EndStep();
477         }
478 
479         // Close the file
480         bpWriter.Close();
481     }
482 
483     {
484         adios2::IO io = adios.DeclareIO("ReadIO");
485 
486         if (!engineName.empty())
487         {
488             io.SetEngine(engineName);
489         }
490         else
491         {
492             // Create the BP Engine
493             io.SetEngine("BP4");
494         }
495         adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read);
496 
497         auto var_iString = io.InquireVariable<std::string>("iString");
498         EXPECT_TRUE(var_iString);
499         ASSERT_EQ(var_iString.Shape().size(), 0);
500         ASSERT_EQ(var_iString.Steps(), NSteps);
501 
502         auto var_i8 = io.InquireVariable<int8_t>("i8");
503         EXPECT_TRUE(var_i8);
504         ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray);
505         ASSERT_EQ(var_i8.Steps(), NSteps);
506         ASSERT_EQ(var_i8.Shape()[0], Ny);
507         ASSERT_EQ(var_i8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
508 
509         auto var_i16 = io.InquireVariable<int16_t>("i16");
510         EXPECT_TRUE(var_i16);
511         ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray);
512         ASSERT_EQ(var_i16.Steps(), NSteps);
513         ASSERT_EQ(var_i16.Shape()[0], Ny);
514         ASSERT_EQ(var_i16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
515 
516         auto var_i32 = io.InquireVariable<int32_t>("i32");
517         EXPECT_TRUE(var_i32);
518         ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray);
519         ASSERT_EQ(var_i32.Steps(), NSteps);
520         ASSERT_EQ(var_i32.Shape()[0], Ny);
521         ASSERT_EQ(var_i32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
522 
523         auto var_i64 = io.InquireVariable<int64_t>("i64");
524         EXPECT_TRUE(var_i64);
525         ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray);
526         ASSERT_EQ(var_i64.Steps(), NSteps);
527         ASSERT_EQ(var_i64.Shape()[0], Ny);
528         ASSERT_EQ(var_i64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
529 
530         auto var_u8 = io.InquireVariable<uint8_t>("u8");
531         EXPECT_TRUE(var_u8);
532         ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray);
533         ASSERT_EQ(var_u8.Steps(), NSteps);
534         ASSERT_EQ(var_u8.Shape()[0], Ny);
535         ASSERT_EQ(var_u8.Shape()[1], static_cast<size_t>(mpiSize * Nx));
536 
537         auto var_u16 = io.InquireVariable<uint16_t>("u16");
538         EXPECT_TRUE(var_u16);
539         ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray);
540         ASSERT_EQ(var_u16.Steps(), NSteps);
541         ASSERT_EQ(var_u16.Shape()[0], Ny);
542         ASSERT_EQ(var_u16.Shape()[1], static_cast<size_t>(mpiSize * Nx));
543 
544         auto var_u32 = io.InquireVariable<uint32_t>("u32");
545         EXPECT_TRUE(var_u32);
546         ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray);
547         ASSERT_EQ(var_u32.Steps(), NSteps);
548         ASSERT_EQ(var_u32.Shape()[0], Ny);
549         ASSERT_EQ(var_u32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
550 
551         auto var_u64 = io.InquireVariable<uint64_t>("u64");
552         EXPECT_TRUE(var_u64);
553         ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray);
554         ASSERT_EQ(var_u64.Steps(), NSteps);
555         ASSERT_EQ(var_u64.Shape()[0], Ny);
556         ASSERT_EQ(var_u64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
557 
558         auto var_r32 = io.InquireVariable<float>("r32");
559         EXPECT_TRUE(var_r32);
560         ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray);
561         ASSERT_EQ(var_r32.Steps(), NSteps);
562         ASSERT_EQ(var_r32.Shape()[0], Ny);
563         ASSERT_EQ(var_r32.Shape()[1], static_cast<size_t>(mpiSize * Nx));
564 
565         auto var_r64 = io.InquireVariable<double>("r64");
566         EXPECT_TRUE(var_r64);
567         ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray);
568         ASSERT_EQ(var_r64.Steps(), NSteps);
569         ASSERT_EQ(var_r64.Shape()[0], Ny);
570         ASSERT_EQ(var_r64.Shape()[1], static_cast<size_t>(mpiSize * Nx));
571 
572         auto attr = io.InquireAttribute<std::string>("TestName");
573         EXPECT_TRUE(attr);
574         ASSERT_EQ(attr.Data().size() == 1, true);
575         ASSERT_EQ(attr.Type(), adios2::GetType<std::string>());
576         ASSERT_EQ(attr.Data().front(), TestName);
577 
578         std::string IString;
579         std::array<int8_t, Nx * Ny> I8;
580         std::array<int16_t, Nx * Ny> I16;
581         std::array<int32_t, Nx * Ny> I32;
582         std::array<int64_t, Nx * Ny> I64;
583         std::array<uint8_t, Nx * Ny> U8;
584         std::array<uint16_t, Nx * Ny> U16;
585         std::array<uint32_t, Nx * Ny> U32;
586         std::array<uint64_t, Nx * Ny> U64;
587         std::array<float, Nx * Ny> R32;
588         std::array<double, Nx * Ny> R64;
589 
590         const adios2::Dims start{0, static_cast<size_t>(mpiRank * Nx)};
591         const adios2::Dims count{Ny, Nx};
592 
593         const adios2::Box<adios2::Dims> sel(start, count);
594 
595         var_i8.SetSelection(sel);
596         var_i16.SetSelection(sel);
597         var_i32.SetSelection(sel);
598         var_i64.SetSelection(sel);
599 
600         var_u8.SetSelection(sel);
601         var_u16.SetSelection(sel);
602         var_u32.SetSelection(sel);
603         var_u64.SetSelection(sel);
604 
605         var_r32.SetSelection(sel);
606         var_r64.SetSelection(sel);
607 
608         SmallTestData m_TestData;
609 
610         for (size_t t = 0; t < NSteps; ++t)
611         {
612             var_i8.SetStepSelection({t, 1});
613             var_i16.SetStepSelection({t, 1});
614             var_i32.SetStepSelection({t, 1});
615             var_i64.SetStepSelection({t, 1});
616 
617             var_u8.SetStepSelection({t, 1});
618             var_u16.SetStepSelection({t, 1});
619             var_u32.SetStepSelection({t, 1});
620             var_u64.SetStepSelection({t, 1});
621 
622             var_r32.SetStepSelection({t, 1});
623             var_r64.SetStepSelection({t, 1});
624 
625             bpReader.Get(var_iString, IString);
626 
627             bpReader.Get(var_i8, I8.data());
628             bpReader.Get(var_i16, I16.data());
629             bpReader.Get(var_i32, I32.data());
630             bpReader.Get(var_i64, I64.data());
631 
632             bpReader.Get(var_u8, U8.data());
633             bpReader.Get(var_u16, U16.data());
634             bpReader.Get(var_u32, U32.data());
635             bpReader.Get(var_u64, U64.data());
636 
637             bpReader.Get(var_r32, R32.data());
638             bpReader.Get(var_r64, R64.data());
639 
640             bpReader.PerformGets();
641 
642             // Generate test data for each rank uniquely
643             SmallTestData currentTestData = generateNewSmallTestData(
644                 m_TestData, static_cast<int>(t), mpiRank, mpiSize);
645 
646             EXPECT_EQ(IString, currentTestData.S1);
647 
648             for (size_t i = 0; i < Nx * Ny; ++i)
649             {
650                 std::stringstream ss;
651                 ss << "t=" << t << " i=" << i << " rank=" << mpiRank;
652                 std::string msg = ss.str();
653 
654                 EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg;
655                 EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg;
656                 EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg;
657                 EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg;
658                 EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg;
659                 EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg;
660                 EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg;
661                 EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg;
662                 EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg;
663                 EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg;
664             }
665         }
666         bpReader.Close();
667     }
668 }
669 
670 class BPTestTimeAggregation : public ::testing::TestWithParam<std::string>
671 {
672 public:
673     BPTestTimeAggregation() = default;
674 
675     SmallTestData m_TestData;
676 
SetUp()677     virtual void SetUp() {}
TearDown()678     virtual void TearDown() {}
679 };
680 
TEST_P(BPTestTimeAggregation,BPTimeAggregation1D8)681 TEST_P(BPTestTimeAggregation, BPTimeAggregation1D8)
682 {
683     TimeAggregation1D8(GetParam());
684 }
685 
TEST_P(BPTestTimeAggregation,BPTimeAggregation2D4x2)686 TEST_P(BPTestTimeAggregation, BPTimeAggregation2D4x2)
687 {
688     TimeAggregation2D4x2(GetParam());
689 }
690 
691 INSTANTIATE_TEST_SUITE_P(FlushStepsCount, BPTestTimeAggregation,
692                          ::testing::Values("1", "2", "3", "6", "8", "10"));
693 
main(int argc,char ** argv)694 int main(int argc, char **argv)
695 {
696 #if ADIOS2_USE_MPI
697     MPI_Init(nullptr, nullptr);
698 #endif
699 
700     int result;
701     ::testing::InitGoogleTest(&argc, argv);
702 
703     if (argc > 1)
704     {
705         engineName = std::string(argv[1]);
706     }
707     result = RUN_ALL_TESTS();
708 
709 #if ADIOS2_USE_MPI
710     MPI_Finalize();
711 #endif
712 
713     return result;
714 }
715