LCOV - code coverage report
Current view: top level - test - HDF5ArrayTest.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 174 174 100.0 %
Date: 2016-06-29 12:30:40 Functions: 50 50 100.0 %

          Line data    Source code
       1             : #ifdef DASH_ENABLE_HDF5
       2             : 
       3             : #include <libdash.h>
       4             : 
       5             : #include <limits.h>
       6             : #include <gtest/gtest.h>
       7             : 
       8             : #include "HDF5ArrayTest.h"
       9             : #include "TestBase.h"
      10             : #include "TestLogHelpers.h"
      11             : 
      12             : 
      13             : typedef int value_t;
      14             : typedef dash::Array<value_t, long> array_t;
      15             : 
      16             : namespace dio = dash::io::hdf5;
      17             : 
      18             : using dash::io::hdf5::StoreHDF;
      19             : using dash::io::hdf5::HDF5FileOptions;
      20             : using dash::io::hdf5::HDF5InputStream;
      21             : using dash::io::hdf5::HDF5OutputStream;
      22             : using dash::io::hdf5::dataset;
      23             : using dash::io::hdf5::modify_dataset;
      24             : using dash::io::hdf5::store_pattern;
      25             : using dash::io::hdf5::restore_pattern;
      26             : using dash::io::hdf5::setpattern_key;
      27             : 
      28             : /**
      29             :  * Fill an dash array with a signatures that contains
      30             :  * the global coordinates and a secret which can be the unit id
      31             :  * for example
      32             :  */
      33             : template <
      34             :   typename T,
      35             :   typename IndexT,
      36             :   typename PatternT >
      37          44 : void fill_array(dash::Array<T, IndexT, PatternT> & array, T secret = 0)
      38             : {
      39             :   std::function< void(const T &, IndexT)>
      40    12583470 :   f = [&array, &secret](T el, IndexT i) {
      41     4194490 :     auto coords = array.pattern().coords(i);
      42             :     // hack
      43    12583470 :     *(array.begin() + i) = coords[0] + secret;
      44     4194578 :   };
      45          44 :   dash::for_each_with_index(
      46             :     array.begin(),
      47             :     array.end(),
      48             :     f);
      49          44 : }
      50             : 
      51             : /**
      52             :  * Counterpart to fill_array which checks if the given array satisfies
      53             :  * the desired signature
      54             :  */
      55             : template <
      56             :   typename T,
      57             :   typename IndexT,
      58             :   typename PatternT >
      59          40 : void verify_array(dash::Array<T, IndexT, PatternT> & array,
      60             :                   T secret = 0)
      61             : {
      62             :   std::function< void(const T &, IndexT)>
      63     8388940 :   f = [&array, &secret](T el, IndexT i) {
      64     4194470 :     auto coords  = array.pattern().coords(i);
      65     8388940 :     auto desired = coords[0] + secret;
      66     4194470 :     ASSERT_EQ_U(
      67             :       desired,
      68             :       el);
      69          80 :   };
      70          40 :   dash::for_each_with_index(
      71             :     array.begin(),
      72             :     array.end(),
      73             :     f);
      74          40 : }
      75             : 
      76          20 : TEST_F(HDF5ArrayTest, StoreLargeDashArray)
      77             : {
      78             :   // Pattern for arr2 array
      79           4 :   size_t nunits           = dash::Team::All().size();
      80           4 :   size_t tilesize         = 512 * 512;
      81           4 :   size_t blocks_per_unit  = 4; //32;
      82           4 :   size_t size             = nunits * tilesize * blocks_per_unit;
      83           4 :   long   mbsize_total     = (size * sizeof(value_t)) / (tilesize);
      84           4 :   long   mbsize_unit      = mbsize_total / nunits;
      85             : 
      86             :   // Add some randomness to the data
      87           4 :   std::srand(time(NULL));
      88           4 :   int local_secret = std::rand() % 1000;
      89           4 :   int myid         = dash::myid();
      90             : 
      91             :   {
      92             :     // Create first array
      93           8 :     array_t arr1(size, dash::TILE(tilesize));
      94             : 
      95             :     // Fill Array
      96           4 :     fill_array(arr1, local_secret);
      97             : 
      98           4 :     dash::barrier();
      99             : 
     100             :     DASH_LOG_DEBUG("Estimated memory per rank: ", mbsize_unit, "MB");
     101             :     DASH_LOG_DEBUG("Estimated memory total: ", mbsize_total, "MB");
     102             :     DASH_LOG_DEBUG("Array filled, begin hdf5 store");
     103             : 
     104           4 :     StoreHDF::write(arr1, _filename, _dataset);
     105           4 :     dash::barrier();
     106             :   }
     107             :   DASH_LOG_DEBUG("Array successfully written ");
     108             : 
     109             :   // Create second array
     110           8 :   dash::Array<value_t> arr2;
     111           4 :   dash::barrier();
     112           4 :   StoreHDF::read(arr2, _filename, _dataset);
     113             : 
     114           4 :   dash::barrier();
     115           4 :   verify_array(arr2, local_secret);
     116           4 : }
     117             : 
     118          20 : TEST_F(HDF5ArrayTest, AutoGeneratePattern)
     119             : {
     120             :   {
     121           8 :     auto array_a = dash::Array<int>(dash::size() * 2);
     122             :     // Fill
     123           4 :     fill_array(array_a);
     124           4 :     dash::barrier();
     125             : 
     126             :     // Set option
     127           8 :     auto fopts = StoreHDF::get_default_options();
     128           4 :     fopts.store_pattern = false;
     129             : 
     130           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     131           4 :     dash::barrier();
     132             :   }
     133           8 :   dash::Array<int> array_b;
     134           4 :   StoreHDF::read(array_b, _filename, _dataset);
     135           4 :   dash::barrier();
     136             : 
     137             :   // Verify
     138           4 :   verify_array(array_b);
     139           4 : }
     140             : 
     141             : // Import data into a already allocated array
     142             : // because array_a and array_b are allocated the same way
     143             : // it is expected that each unit remains its local ranges
     144          20 : TEST_F(HDF5ArrayTest, PreAllocation)
     145             : {
     146           4 :   int ext_x = dash::size() * 2;
     147             :   {
     148           8 :     auto array_a = dash::Array<int>(ext_x);
     149             :     // Fill
     150           4 :     fill_array(array_a, dash::myid());
     151           4 :     dash::barrier();
     152             : 
     153             :     // Set option
     154           8 :     auto fopts = StoreHDF::get_default_options();
     155           4 :     fopts.store_pattern = false;
     156             : 
     157           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     158           4 :     dash::barrier();
     159             :   }
     160           8 :   auto array_b = dash::Array<int>(ext_x);
     161           4 :   StoreHDF::read(array_b, _filename, _dataset);
     162           4 :   dash::barrier();
     163             : 
     164             :   // Verify
     165           4 :   verify_array(array_b, dash::myid());
     166           4 : }
     167             : 
     168             : // Test Stream API
     169          20 : TEST_F(HDF5ArrayTest, OutputStreamOpen)
     170             : {
     171             :   {
     172           8 :     auto array_a = dash::Array<long>(dash::size() * 2);
     173             : 
     174           4 :     fill_array(array_a);
     175           4 :     dash::barrier();
     176             : 
     177           8 :     auto os  = HDF5OutputStream(_filename);
     178           8 :     os   << dio::dataset(_dataset)
     179           4 :          << array_a;
     180             :   }
     181           4 :   dash::barrier();
     182             :   // Import data
     183           8 :   dash::Array<long> array_b;
     184           8 :   auto is = HDF5InputStream(_filename);
     185           4 :   is >> dio::dataset(_dataset) >> array_b;
     186             : 
     187           4 :   verify_array(array_b);
     188           4 : }
     189             : 
     190          20 : TEST_F(HDF5ArrayTest, UnderfilledPattern)
     191             : {
     192           4 :   int   ext_x = dash::size() * 5 + 1;
     193             :   long  tilesize;
     194             :   {
     195           8 :     auto array_a = dash::Array<int>(ext_x);
     196           4 :     tilesize     = array_a.pattern().blocksize(0);
     197             :     // Fill
     198           4 :     fill_array(array_a);
     199           4 :     dash::barrier();
     200             :     // Set option
     201           8 :     auto fopts = StoreHDF::get_default_options();
     202             :     // Important as recreation should create equal pattern
     203           4 :     fopts.store_pattern = true;
     204             : 
     205           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     206           4 :     dash::barrier();
     207             :   }
     208           8 :   dash::Array<int> array_b;
     209           4 :   StoreHDF::read(array_b, _filename, _dataset);
     210           4 :   dash::barrier();
     211             : 
     212             :   // Verify
     213             :   // Check extents
     214           4 :   DASH_ASSERT_EQ(
     215             :     ext_x,
     216             :     array_b.size(),
     217             :     "Array extent does not match input array");
     218             :   // Check tilesize
     219           4 :   DASH_ASSERT_EQ(
     220             :     tilesize,
     221             :     array_b.pattern().blocksize(0),
     222             :     "Tilesizes do not match");
     223             :   // Verify data
     224           4 :   verify_array(array_b);
     225           4 : }
     226             : 
     227          20 : TEST_F(HDF5ArrayTest, UnderfilledPatPreAllocate)
     228             : {
     229           4 :   int ext_x = dash::size() * 5 + 1;
     230             :   {
     231           8 :     auto array_a = dash::Array<int>(ext_x);
     232             :     // Fill
     233           4 :     fill_array(array_a);
     234           4 :     dash::barrier();
     235             :     // Set option
     236           8 :     auto fopts = StoreHDF::get_default_options();
     237           4 :     fopts.store_pattern = false;
     238             : 
     239           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     240           4 :     dash::barrier();
     241             :   }
     242           8 :   auto array_b = dash::Array<int>(ext_x);
     243           4 :   StoreHDF::read(array_b, _filename, _dataset);
     244           4 :   dash::barrier();
     245             : 
     246             :   // Verify
     247             :   // Check extents
     248           4 :   DASH_ASSERT_EQ(
     249             :     ext_x,
     250             :     array_b.size(),
     251             :     "Array extent does not match input array");
     252             :   // Verify data
     253           4 :   verify_array(array_b);
     254           4 : }
     255             : 
     256          20 : TEST_F(HDF5ArrayTest, MultipleDatasets)
     257             : {
     258           4 :         int    ext_x    = dash::size() * 5;
     259           4 :         int    secret_a = 10;
     260           4 :         double secret_b = 3;
     261             :         {
     262           8 :     auto array_a = dash::Array<int>(ext_x);
     263           8 :                 auto array_b = dash::Array<double>(ext_x*2);
     264             : 
     265             :     // Fill
     266           4 :     fill_array(array_a, secret_a);
     267           4 :                 fill_array(array_b, secret_b);
     268           4 :     dash::barrier();
     269             : 
     270             :     // Set option
     271           8 :     auto fopts = StoreHDF::get_default_options();
     272           4 :     fopts.overwrite_file = false;
     273             : 
     274           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     275           4 :                 StoreHDF::write(array_b, _filename, "datasettwo", fopts);
     276           4 :     dash::barrier();
     277             :   }
     278           8 :   dash::Array<int>    array_c;
     279           8 :         dash::Array<double> array_d;
     280           4 :         StoreHDF::read(array_c, _filename, _dataset);
     281           4 :         StoreHDF::read(array_d, _filename, "datasettwo");
     282             : 
     283           4 :   dash::barrier();
     284             : 
     285             :   // Verify data
     286           4 :   verify_array(array_c, secret_a);
     287           4 :   verify_array(array_d, secret_b);
     288           4 : }
     289             : 
     290          20 : TEST_F(HDF5ArrayTest, ModifyDataset)
     291             : {
     292           4 :         int    ext_x    = dash::size() * 5;
     293           4 :         double secret_a = 10;
     294           4 :         double secret_b = 3;
     295             :         {
     296           8 :     auto array_a = dash::Array<double>(ext_x);
     297           8 :                 auto array_b = dash::Array<double>(ext_x);
     298             : 
     299             :     // Fill
     300           4 :     fill_array(array_a, secret_a);
     301           4 :                 fill_array(array_b, secret_b);
     302           4 :     dash::barrier();
     303             : 
     304             :     // Set option
     305           8 :     auto fopts = StoreHDF::get_default_options();
     306           4 :     fopts.overwrite_file = false;
     307             : 
     308           4 :     StoreHDF::write(array_a, _filename, _dataset, fopts);
     309           4 :                 dash::barrier();
     310             :                 // overwrite first data
     311           4 :                 fopts.modify_dataset = true;
     312           4 :                 StoreHDF::write(array_b, _filename, _dataset, fopts);
     313           4 :     dash::barrier();
     314             :   }
     315           8 :   dash::Array<double>    array_c;
     316           4 :         StoreHDF::read(array_c, _filename, _dataset);
     317             : 
     318           4 :   dash::barrier();
     319             : 
     320             :   // Verify data
     321           4 :   verify_array(array_c, secret_b);
     322           4 : }
     323             : 
     324          20 : TEST_F(HDF5ArrayTest, StreamCreationFlags)
     325             : {
     326           4 :         int    ext_x    = dash::size() * 5;
     327           4 :         double secret = 10;
     328             :         {
     329           8 :     auto array_a = dash::Array<double>(ext_x);
     330             : 
     331             :     // Fill
     332           4 :     fill_array(array_a, secret);
     333           4 :     dash::barrier();
     334             : 
     335             :     // Set option
     336             : 
     337           8 :                 HDF5OutputStream os(_filename, HDF5FileOptions::Append);
     338           8 :                 os << dio::dataset("settwo")
     339          12 :                          << dio::setpattern_key("custom_dash_pattern")
     340          12 :        << dio::store_pattern()
     341           4 :                          << array_a
     342          12 :                          << dio::modify_dataset()
     343           4 :                          << array_a;
     344             : 
     345           4 :                 dash::barrier();
     346             :   }
     347           8 :   dash::Array<double>    array_b;
     348           8 :         HDF5InputStream is(_filename);
     349           8 :         is >> dio::dataset("settwo")
     350          12 :                  >> dio::setpattern_key("custom_dash_pattern")
     351          12 :      >> dio::restore_pattern()
     352           4 :      >> array_b;
     353             : 
     354           4 :   dash::barrier();
     355             : 
     356             :   // Verify data
     357           4 :   verify_array(array_b, secret);
     358          16 : }
     359             : 
     360             : 
     361             : #endif // DASH_ENABLE_HDF5
     362             : 
     363             : 

Generated by: LCOV version 1.12