diff --git a/build.sh b/build.sh index a7402af1ccb52673c3203fb4e43d8589262e34a0..281e94a24dcefce2be50ea5894f071d5c655668b 100755 --- a/build.sh +++ b/build.sh @@ -17,6 +17,20 @@ git clone git@git.mpi-cbg.de:openfpm/openfpm_data.git openfpm_data git clone git@git.mpi-cbg.de:openfpm/openfpm_pdata.git openfpm_pdata git clone git@git.mpi-cbg.de:openfpm/openfpm_vcluster.git openfpm_vcluster +# Go in the right branch + +cd openfpm_pdata +git checkout Release_0.9.0 +cd .. + +cd openfpm_data +git checkout Release_0.9.0 +cd .. + +cd openfpm_vcluster +git checkout Release_0.9.0 +cd .. + cd "$1/openfpm_io" echo "Compiling on $2" diff --git a/configure.ac b/configure.ac index 284a37c97a119d3e914ba9b30f1db02422ada29c..ba69661c99e6395154f65023149e7bf13000450f 100755 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,11 @@ CXXFLAGS+=" -march=native -mtune=native -Wno-unused-local-typedefs -Wextra -Wno- NVCCFLAGS=" " INCLUDES_PATH=" " +AC_LANG_PUSH([C++]) +AC_CHECK_HEADER(mpi.h,[],[echo "mpi.h not found" + exit 200]) +AC_LANG_POP([C++]) + # set default prefix if test "$prefix" = "NONE"; then prefix="/usr/local" diff --git a/gc_out2_test.html b/gc_out2_test.html index 319e97c1073dc24c7157aa3fb3bafc079bb04826..16f6147e1cae865ac05b60a01a8385b70007554f 100644 --- a/gc_out2_test.html +++ b/gc_out2_test.html @@ -38,7 +38,8 @@ vAxis: {title: 'Y Axis'}, hAxis: {title: 'X Axis'}, seriesType: 'bars'}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_out3_test.html b/gc_out3_test.html index 10eb9edf701d0be9d38a031bd44d82fb86325125..3eaf8466eb869c19006628900982ec5dd46783ac 100644 --- a/gc_out3_test.html +++ b/gc_out3_test.html @@ -38,7 +38,8 @@ vAxis: {title: 'Y Axis'}, hAxis: {title: 'X Axis'}, seriesType: ''}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_out4_test.html b/gc_out4_test.html index 6c00c1528bd98a9e230b67e500d473a0e35e77f7..f851830c498ab3315b7e8585f9d0cb6ac2e27b47 100644 --- a/gc_out4_test.html +++ b/gc_out4_test.html @@ -38,7 +38,8 @@ vAxis: {title: ''}, hAxis: {title: ''}, seriesType: ''}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_out5_test.html b/gc_out5_test.html index d579b983fd6d526304e4da5d47013efe38fd1629..4ef5259fdec336339185223f522efd6d0e93930d 100644 --- a/gc_out5_test.html +++ b/gc_out5_test.html @@ -38,7 +38,8 @@ vAxis: {title: ''}, hAxis: {title: ''}, seriesType: ''}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_out6_test.html b/gc_out6_test.html index 2f1de14b260a6846797d77efb8e7918819be2a4e..8b1afbb0f181a8cab8efceb11bc61e786a851d64 100644 --- a/gc_out6_test.html +++ b/gc_out6_test.html @@ -38,7 +38,8 @@ vAxis: {title: ''}, hAxis: {title: ''}, seriesType: ''}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_out7_test.html b/gc_out7_test.html index 81d5a5e1310b0ba1fccd09719610b6de48cc88da..b157cd50033ee4c2af1833d719f7d38d4996ea54 100644 --- a/gc_out7_test.html +++ b/gc_out7_test.html @@ -79,11 +79,14 @@ hAxis: {title: 'X Axis'}, seriesType: 'bars', series: {3: {type: 'line'}}}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); $("#export_svg1").on("click", function (event) {exportToSVG.apply(this,[1]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div1'));chart.draw(data1, options1); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div1')); +chart.draw(data1, options1); $("#export_svg2").on("click", function (event) {exportToSVG.apply(this,[2]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div2'));chart.draw(data2, options2); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div2')); +chart.draw(data2, options2); }</script> </head> <body> diff --git a/gc_out_test.html b/gc_out_test.html index 60c941aefd4bea476acfda2414a5267a20092f5f..b65719ef3b2d79be7ccad9ed89d3b0fe9ce04126 100644 --- a/gc_out_test.html +++ b/gc_out_test.html @@ -39,7 +39,8 @@ hAxis: {title: 'X Axis'}, seriesType: 'bars', series: {3: {type: 'line'}}}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_plot2_out_test.html b/gc_plot2_out_test.html index 7cf93912e963e4e7fae09443a93d12a72f8a8184..f48dbf2078e27c13cdce1be8f88222b2029c8627 100644 --- a/gc_plot2_out_test.html +++ b/gc_plot2_out_test.html @@ -45,7 +45,8 @@ curveType: 'function', lineWidth: 1, intervals: { 'style':'area' }}; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/gc_plot_out_test.html b/gc_plot_out_test.html index 4a105cd7a115d370f2058780ad75f2951154c370..a52ce00093bec66089e37e2099e7899cc5492169 100644 --- a/gc_plot_out_test.html +++ b/gc_plot_out_test.html @@ -47,7 +47,8 @@ intervals: { 'style':'area' }, interval: {'i2': { 'color': '#4374E0', 'style':'bars', 'lineWidth':4, 'fillOpacity':1 } } }; $("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); -var chart = new google.visualization.ComboChart(document.getElementById('chart_div0'));chart.draw(data0, options0); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(data0, options0); }</script> </head> <body> diff --git a/m4/acx_mpi.m4 b/m4/acx_mpi.m4 old mode 100755 new mode 100644 diff --git a/src/CSVWriter/CSVWriter.hpp b/src/CSVWriter/CSVWriter.hpp index 974818ac64d0fa9586d5cd449e3b75d7603f50b2..de38b2df7c55c08db99928640b5fa377946624a3 100644 --- a/src/CSVWriter/CSVWriter.hpp +++ b/src/CSVWriter/CSVWriter.hpp @@ -16,7 +16,7 @@ #include <boost/mpl/range_c.hpp> #include <boost/mpl/for_each.hpp> #include "csv_multiarray.hpp" -#include "util.hpp" +#include "util/util.hpp" #include "is_csv_writable.hpp" #define CSV_WRITER 0x30000 diff --git a/src/CSVWriter/CSVWriter_unit_tests.hpp b/src/CSVWriter/CSVWriter_unit_tests.hpp index f1fa26538a009a2a6461c1c6e433a06a769a769a..bacfe6c249cb3604f7bb33852149f0470f792002 100644 --- a/src/CSVWriter/CSVWriter_unit_tests.hpp +++ b/src/CSVWriter/CSVWriter_unit_tests.hpp @@ -9,6 +9,11 @@ BOOST_AUTO_TEST_SUITE( csv_writer_test ) BOOST_AUTO_TEST_CASE( csv_writer_particles ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + { // Allocate a property vector auto v_prp = allocate_openfpm_prp(16); @@ -29,7 +34,7 @@ BOOST_AUTO_TEST_CASE( csv_writer_particles ) // Write the CSV csv_writer.write("csv_out.csv",v_pos,v_prp); - bool test = compare("csv_out.csv","csv_out_test.csv"); + bool test = compare("csv_out.csv","test_data/csv_out_test.csv"); BOOST_REQUIRE_EQUAL(true,test); } @@ -53,7 +58,7 @@ BOOST_AUTO_TEST_CASE( csv_writer_particles ) // Write the CSV csv_writer.write("csv_out_unk.csv",v_pos,v_prp); - bool test = compare("csv_out_unk.csv","csv_out_unk_test.csv"); + bool test = compare("csv_out_unk.csv","test_data/csv_out_unk_test.csv"); BOOST_REQUIRE_EQUAL(true,test); } diff --git a/src/CSVWriter/is_csv_writable.hpp b/src/CSVWriter/is_csv_writable.hpp index 556fa9e36c0b77e122833af37426687968591432..b7268b09d9cb62b3f9671c146d06147f1f4cd25a 100644 --- a/src/CSVWriter/is_csv_writable.hpp +++ b/src/CSVWriter/is_csv_writable.hpp @@ -9,111 +9,132 @@ #define OPENFPM_IO_SRC_CSVWRITER_IS_CSV_WRITABLE_HPP_ - +//! Indicate if the property T is writable in CSV template<typename T> struct is_csv_writable { + //! as default if not recognized is not writable enum { value = false }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<float> { + //! float is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<double> { + //! double is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<char> { + //! char is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned char> { + //! unsigned char is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<short> { + //! short is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned short> { + //! unsigned is writable enum { value = true }; }; - +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<int> { + //! int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned int> { + //! unsigned int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<long int> { + //! long int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned long int> { + //! unsigned long int is writable enum { value = true }; }; - +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<bool> { + //! bool is writable enum { value = true diff --git a/src/GraphMLWriter/GraphMLWriter_unit_tests.hpp b/src/GraphMLWriter/GraphMLWriter_unit_tests.hpp index 8b2a92694ed93d16f923aeda6292d7d675e35459..6c9b8c452f7c6da66a91a38c5acc8100744fe4d9 100644 --- a/src/GraphMLWriter/GraphMLWriter_unit_tests.hpp +++ b/src/GraphMLWriter/GraphMLWriter_unit_tests.hpp @@ -12,7 +12,7 @@ #include "GraphMLWriter.hpp" #include "Graph/CartesianGraphFactory.hpp" -#include "util.hpp" +#include "util/util.hpp" BOOST_AUTO_TEST_SUITE( graphml_writer_test ) @@ -77,6 +77,11 @@ const std::string ne_cp::attributes::name[] = {"x","y","z","double_num","long_nu BOOST_AUTO_TEST_CASE( graphml_writer_use) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + Graph_CSR<ne_cp,ne_cp> g_csr2; // Add 4 vertex and connect @@ -114,7 +119,7 @@ BOOST_AUTO_TEST_CASE( graphml_writer_use) // check that match - bool test = compare("test_graph2.graphml","test_graph2_test.graphml"); + bool test = compare("test_graph2.graphml","test_data/test_graph2_test.graphml"); BOOST_REQUIRE_EQUAL(true,test); //! Create a graph @@ -138,7 +143,7 @@ BOOST_AUTO_TEST_CASE( graphml_writer_use) // check that match - test = compare("test_graph.graphml","test_graph_test.graphml"); + test = compare("test_graph.graphml","test_data/test_graph_test.graphml"); BOOST_REQUIRE_EQUAL(true,test); } diff --git a/src/HDF5_wr/HDF5_reader.hpp b/src/HDF5_wr/HDF5_reader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d5b4a2ffd0e595220e3048988a5383656f814a0e --- /dev/null +++ b/src/HDF5_wr/HDF5_reader.hpp @@ -0,0 +1,25 @@ +/* + * HDF5_loader.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_HPP_ + +#include "VCluster/VCluster.hpp" + +template <unsigned int type> +class HDF5_reader +{ + void load() + { + std::cerr << __FILE__ << ":" << __LINE__ << " Error: we do not know how to write this type of data" << std::endl; + } +}; + +#include "HDF5_reader_vd.hpp" +#include "HDF5_reader_gd.hpp" + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_HPP_ */ diff --git a/src/HDF5_wr/HDF5_reader_gd.hpp b/src/HDF5_wr/HDF5_reader_gd.hpp new file mode 100644 index 0000000000000000000000000000000000000000..33f34b090c25b7bdc37cc58f1037ae680bb9a278 --- /dev/null +++ b/src/HDF5_wr/HDF5_reader_gd.hpp @@ -0,0 +1,249 @@ +/* + * HDF5_reader_gr.hpp + * + * Created on: May 2, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_GD_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_GD_HPP_ + + +#include "Packer_Unpacker/Pack_selector.hpp" +#include "Packer_Unpacker/Packer.hpp" +#include "Packer_Unpacker/Unpacker.hpp" +#include "util/GBoxes.hpp" + +template <> +class HDF5_reader<GRID_DIST> +{ + template<typename device_grid> void load_block(long int bid, + hssize_t mpi_size_old, + int * metadata_out, + openfpm::vector<size_t> & metadata_accum, + hid_t plist_id, + hid_t dataset_2, + openfpm::vector<device_grid> & loc_grid_old, + openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext_old) + { + hsize_t offset[1]; + hsize_t block[1]; + + if (bid < mpi_size_old && bid != -1) + { + offset[0] = metadata_accum.get(bid); + block[0] = metadata_out[bid]; + } + else + { + offset[0] = 0; + block[0] = 0; + } + + hsize_t count[1] = {1}; + + //Select file dataspace + hid_t file_dataspace_id_2 = H5Dget_space(dataset_2); + + H5Sselect_hyperslab(file_dataspace_id_2, H5S_SELECT_SET, offset, NULL, count, block); + + hsize_t mdim_2[1] = {block[0]}; + + //Create data space in memory + hid_t mem_dataspace_id_2 = H5Screate_simple(1, mdim_2, NULL); + + // allocate the memory + HeapMemory pmem; + //pmem.allocate(req); + ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(block[0],pmem)); + mem.incRef(); + + // Read the dataset. + H5Dread(dataset_2, H5T_NATIVE_CHAR, mem_dataspace_id_2, file_dataspace_id_2, plist_id, (char *)mem.getPointer()); + + mem.allocate(pmem.size()); + + Unpack_stat ps; + + openfpm::vector<device_grid> loc_grid_old_unp; + openfpm::vector<GBoxes<device_grid::dims>> gdb_ext_old_unp; + + Unpacker<typename std::remove_reference<decltype(loc_grid_old)>::type,HeapMemory>::unpack(mem,loc_grid_old_unp,ps,1); + Unpacker<typename std::remove_reference<decltype(gdb_ext_old)>::type,HeapMemory>::unpack(mem,gdb_ext_old_unp,ps,1); + + for (size_t i = 0; i < loc_grid_old_unp.size(); i++) + loc_grid_old.add(loc_grid_old_unp.get(i)); + + for (size_t i = 0; i < gdb_ext_old_unp.size(); i++) + gdb_ext_old.add(gdb_ext_old_unp.get(i)); + + mem.decRef(); + delete &mem; + + } + +public: + + template<typename device_grid> inline void load(const std::string & filename, + openfpm::vector<device_grid> & loc_grid_old, + openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext_old) + { + Vcluster & v_cl = create_vcluster(); + + MPI_Comm comm = v_cl.getMPIComm(); + MPI_Info info = MPI_INFO_NULL; + + int mpi_rank = v_cl.getProcessUnitID(); + //int mpi_size = v_cl.getProcessingUnits(); + + // Set up file access property list with parallel I/O access + hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist_id, comm, info); + + //Open a file + hid_t file = H5Fopen (filename.c_str(), H5F_ACC_RDONLY, plist_id); + H5Pclose(plist_id); + + //Open dataset + hid_t dataset = H5Dopen (file, "metadata", H5P_DEFAULT); + + //Create property list for collective dataset read + plist_id = H5Pcreate(H5P_DATASET_XFER); + H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + + //Select file dataspace + hid_t file_dataspace_id = H5Dget_space(dataset); + + hssize_t mpi_size_old = H5Sget_select_npoints (file_dataspace_id); + + //if (mpi_rank == 0) + //printf ("\nOld MPI size: %llu\n", mpi_size_old); + + //Where to read metadata + int metadata_out[mpi_size_old]; + + for (int i = 0; i < mpi_size_old; i++) + { + metadata_out[i] = 0; + } + + //Size for data space in memory + hsize_t mdim[1] = {(size_t)mpi_size_old}; + + //Create data space in memory + hid_t mem_dataspace_id = H5Screate_simple(1, mdim, NULL); + +/* + if (mpi_rank == 0) + { + hssize_t size; + + size = H5Sget_select_npoints (mem_dataspace_id); + printf ("\nmemspace_id size: %llu\n", size); + size = H5Sget_select_npoints (file_dataspace_id); + printf ("dataspace_id size: %llu\n", size); + } +*/ + // Read the dataset. + H5Dread(dataset, H5T_NATIVE_INT, mem_dataspace_id, file_dataspace_id, plist_id, metadata_out); +/* + if (mpi_rank == 0) + { + std::cout << "Metadata_out[]: "; + for (int i = 0; i < mpi_size_old; i++) + { + std::cout << metadata_out[i] << " "; + } + std::cout << " " << std::endl; + } +*/ + + openfpm::vector<size_t> metadata_accum; + metadata_accum.resize(mpi_size_old); + + metadata_accum.get(0) = 0; + for (int i = 1 ; i < mpi_size_old ; i++) + metadata_accum.get(i) = metadata_accum.get(i-1) + metadata_out[i-1]; + + //Open dataset + hid_t dataset_2 = H5Dopen (file, "grid_dist", H5P_DEFAULT); + + //Create property list for collective dataset read + plist_id = H5Pcreate(H5P_DATASET_XFER); + H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + + ///////////////////////////////////// + + openfpm::vector<size_t> n_block; + n_block.resize(v_cl.getProcessingUnits()); + + + for(size_t i = 0 ; i < n_block.size() ; i++) + n_block.get(i) = mpi_size_old / v_cl.getProcessingUnits(); + + size_t rest_block = mpi_size_old % v_cl.getProcessingUnits(); + + // std::cout << "MPI size old: " << mpi_size_old << std::endl; + //std::cout << "MPI size: " << v_cl.getProcessingUnits() << std::endl; + + + // std::cout << "Rest block: " << rest_block << std::endl; + + size_t max_block; + + if (rest_block != 0) + max_block = n_block.get(0) + 1; + else + max_block = n_block.get(0); + + //for(size_t i = 0 ; i < n_block.size() ; i++) + for(size_t i = 0 ; i < rest_block ; i++) + n_block.get(i) += 1; + + + //for(size_t i = 0 ; i < n_block.size() ; i++) + //std::cout << "n_block.get(i): " << n_block.get(i) << std::endl; + + size_t start_block = 0; + size_t stop_block = 0; + + + if (v_cl.getProcessUnitID() != 0) + { + for(size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++) + start_block += n_block.get(i); + } + + stop_block = start_block + n_block.get(v_cl.getProcessUnitID()); + +// std::cout << "ID: " << v_cl.getProcessUnitID() << "; Start block: " << start_block << "; " << "Stop block: " << stop_block << std::endl; + + if (mpi_rank >= mpi_size_old) + load_block(start_block,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,loc_grid_old,gdb_ext_old); + else + { + size_t n_bl = 0; + size_t lb = start_block; + for ( ; lb < stop_block ; lb++, n_bl++) + load_block(lb,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,loc_grid_old,gdb_ext_old); + + if (n_bl < max_block) + load_block(-1,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,loc_grid_old,gdb_ext_old); + } + + //////////////////////////////////// + + //std::cout << "LOAD: sum: " << sum << std::endl; + + // Close the dataset. + H5Dclose(dataset); + H5Dclose(dataset_2); + // Close the file. + H5Fclose(file); + H5Pclose(plist_id); + } + +}; + + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_GD_HPP_ */ diff --git a/src/HDF5_wr/HDF5_reader_vd.hpp b/src/HDF5_wr/HDF5_reader_vd.hpp new file mode 100644 index 0000000000000000000000000000000000000000..41109782295fdab5d40ac4b042a5c5c6a58519df --- /dev/null +++ b/src/HDF5_wr/HDF5_reader_vd.hpp @@ -0,0 +1,244 @@ +/* + * HDF5_reader_vd.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_VD_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_VD_HPP_ + + +template <> +class HDF5_reader<VECTOR_DIST> +{ +private: + + template<unsigned int dim, typename St,typename prp> + bool load_block(long int bid, + hssize_t mpi_size_old, + int * metadata_out, + openfpm::vector<size_t> metadata_accum, + hid_t plist_id, + hid_t dataset_2, + size_t & g_m, + openfpm::vector<Point<dim,St>> & v_pos, + openfpm::vector<prp> & v_prp) + { + hsize_t offset[1]; + hsize_t block[1]; + + if (bid < mpi_size_old && bid != -1) + { + offset[0] = metadata_accum.get(bid); + block[0] = metadata_out[bid]; + } + else + { + offset[0] = 0; + block[0] = 0; + } + + hsize_t count[1] = {1}; + + + //Select file dataspace + hid_t file_dataspace_id_2 = H5Dget_space(dataset_2); + if (file_dataspace_id_2 < 0) {return false;} + + herr_t err = H5Sselect_hyperslab(file_dataspace_id_2, H5S_SELECT_SET, offset, NULL, count, block); + if (err < 0) {return false;} + + hsize_t mdim_2[1] = {block[0]}; + + + //Create data space in memory + hid_t mem_dataspace_id_2 = H5Screate_simple(1, mdim_2, NULL); + if (mem_dataspace_id_2 < 0) {return false;} + + size_t sum = 0; + + for (int i = 0; i < mpi_size_old; i++) + sum += metadata_out[i]; + + // allocate the memory + HeapMemory pmem; + + ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(block[0],pmem)); + mem.incRef(); + + // Read the dataset. + err = H5Dread(dataset_2, H5T_NATIVE_CHAR, mem_dataspace_id_2, file_dataspace_id_2, plist_id, (char *)mem.getPointer()); + if (err < 0) {return false;} + + mem.allocate(pmem.size()); + + Unpack_stat ps; + + openfpm::vector<Point<dim, St>> v_pos_unp; + + openfpm::vector<prp> v_prp_unp; + + Unpacker<decltype(v_pos_unp),HeapMemory>::unpack(mem,v_pos_unp,ps,1); + Unpacker<decltype(v_prp_unp),HeapMemory>::unpack(mem,v_prp_unp,ps,1); + + mem.decRef(); + delete &mem; + + for (size_t i = 0; i < v_pos_unp.size(); i++) + v_pos.add(v_pos_unp.get(i)); + + for (size_t i = 0; i < v_prp_unp.size(); i++) + v_prp.add(v_prp_unp.get(i)); + + g_m = v_pos.size(); + + H5Sclose(file_dataspace_id_2); + H5Sclose(mem_dataspace_id_2); + + return true; + } + +public: + + template<unsigned int dim, typename St, typename prp> inline bool load(const std::string & filename, + openfpm::vector<Point<dim,St>> & v_pos, + openfpm::vector<prp> & v_prp, + size_t & g_m) + { + Vcluster & v_cl = create_vcluster(); + + v_pos.clear(); + v_prp.clear(); + + g_m = 0; + + MPI_Comm comm = v_cl.getMPIComm(); + MPI_Info info = MPI_INFO_NULL; + + int mpi_rank = v_cl.getProcessUnitID(); + + // Set up file access property list with parallel I/O access + hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + if (plist_id == -1) {return false;} + herr_t err = H5Pset_fapl_mpio(plist_id, comm, info); + if (err < 0) + return false; + + //Open a file + hid_t file = H5Fopen (filename.c_str(), H5F_ACC_RDONLY, plist_id); + if (file < 0) {return false;} + H5Pclose(plist_id); + + //Open dataset + hid_t dataset = H5Dopen (file, "metadata", H5P_DEFAULT); + if (dataset < 0) {return false;} + + //Create property list for collective dataset read + plist_id = H5Pcreate(H5P_DATASET_XFER); + if (plist_id == -1) {return false;} + H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + + //Select file dataspace + hid_t file_dataspace_id = H5Dget_space(dataset); + if (file_dataspace_id < 0) {return false;} + + hssize_t mpi_size_old = H5Sget_select_npoints (file_dataspace_id); + if (mpi_size_old < 0) {return false;} + + //Where to read metadata + int metadata_out[mpi_size_old]; + + for (int i = 0; i < mpi_size_old; i++) + {metadata_out[i] = 0;} + + //Size for data space in memory + hsize_t mdim[1] = {(size_t)mpi_size_old}; + + //Create data space in memory + hid_t mem_dataspace_id = H5Screate_simple(1, mdim, NULL); + if (mem_dataspace_id < 0) {return false;} + + // Read the dataset. + err = H5Dread(dataset, H5T_NATIVE_INT, mem_dataspace_id, file_dataspace_id, plist_id, metadata_out); + if (err < 0) {return false;} + + openfpm::vector<size_t> metadata_accum; + metadata_accum.resize(mpi_size_old); + + metadata_accum.get(0) = 0; + for (int i = 1 ; i < mpi_size_old ; i++) + metadata_accum.get(i) = metadata_accum.get(i-1) + metadata_out[i-1]; + + //Open dataset + hid_t dataset_2 = H5Dopen (file, "vector_dist", H5P_DEFAULT); + if (dataset_2 < 0) {return false;} + + //Create property list for collective dataset read + plist_id = H5Pcreate(H5P_DATASET_XFER); + if (plist_id == -1) {return false;} + + err = H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + if (err < 0) {return false;} + + openfpm::vector<size_t> n_block; + n_block.resize(v_cl.getProcessingUnits()); + + + for(size_t i = 0 ; i < n_block.size() ; i++) + n_block.get(i) = mpi_size_old / v_cl.getProcessingUnits(); + + size_t rest_block = mpi_size_old % v_cl.getProcessingUnits(); + + size_t max_block; + + if (rest_block != 0) + max_block = n_block.get(0) + 1; + else + max_block = n_block.get(0); + + //for(size_t i = 0 ; i < n_block.size() ; i++) + for(size_t i = 0 ; i < rest_block ; i++) + n_block.get(i) += 1; + + size_t start_block = 0; + size_t stop_block = 0; + + + if (v_cl.getProcessUnitID() != 0) + { + for(size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++) + start_block += n_block.get(i); + } + + stop_block = start_block + n_block.get(v_cl.getProcessUnitID()); + + if (mpi_rank >= mpi_size_old) + load_block(start_block,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,g_m,v_pos,v_prp); + else + { + size_t n_bl = 0; + size_t lb = start_block; + for ( ; lb < stop_block ; lb++, n_bl++) + load_block(lb,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,g_m,v_pos,v_prp); + + if (n_bl < max_block) + load_block(-1,mpi_size_old,metadata_out,metadata_accum,plist_id,dataset_2,g_m,v_pos,v_prp); + } + + // Close open object + H5Sclose(mem_dataspace_id); + H5Sclose(file_dataspace_id); + // Close the dataset. + H5Dclose(dataset); + H5Dclose(dataset_2); + // Close the file. + H5Fclose(file); + H5Pclose(plist_id); + + return true; + } +}; + + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_READER_VD_HPP_ */ diff --git a/src/HDF5_wr/HDF5_wr.hpp b/src/HDF5_wr/HDF5_wr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..69fa3936cccb8d76065ce8e00812678f6fa21b2a --- /dev/null +++ b/src/HDF5_wr/HDF5_wr.hpp @@ -0,0 +1,19 @@ +/* + * HDF5_wr.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_WR_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_WR_HPP_ + + +#define VECTOR_DIST 1 +#define GRID_DIST 2 + +#include "HDF5_writer.hpp" +#include "HDF5_reader.hpp" + + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_WR_HPP_ */ diff --git a/src/HDF5_wr/HDF5_writer.hpp b/src/HDF5_wr/HDF5_writer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..95b686cf9a4867d49d3110dddfef79ba492670c1 --- /dev/null +++ b/src/HDF5_wr/HDF5_writer.hpp @@ -0,0 +1,29 @@ +/* + * HDF5_writer.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_HPP_ + + +#include "VCluster/VCluster.hpp" +#include <hdf5.h> + +template <unsigned int type> +class HDF5_writer +{ + + void save() + { + std::cerr << __FILE__ << ":" << __LINE__ << " Error: we do not know how to write this type of data" << std::endl; + } + +}; + +#include "HDF5_writer_vd.hpp" +#include "HDF5_writer_gd.hpp" + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_HPP_ */ diff --git a/src/HDF5_wr/HDF5_writer_gd.hpp b/src/HDF5_wr/HDF5_writer_gd.hpp new file mode 100644 index 0000000000000000000000000000000000000000..592624b83f52a428e17e551712cecafb825ef8c1 --- /dev/null +++ b/src/HDF5_wr/HDF5_writer_gd.hpp @@ -0,0 +1,177 @@ +/* + * HDF5_writer_gd.hpp + * + * Created on: May 2, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_GD_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_GD_HPP_ + + +#include "Packer_Unpacker/Pack_selector.hpp" +#include "Packer_Unpacker/Packer.hpp" +#include "Packer_Unpacker/Unpacker.hpp" +#include "util/GBoxes.hpp" + +template <> +class HDF5_writer<GRID_DIST> +{ +public: + + template<typename device_grid> + inline void save(const std::string & filename, + const openfpm::vector<device_grid> & loc_grid, + const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext) const + { + Vcluster & v_cl = create_vcluster(); + + //Pack_request vector + size_t req = 0; + + //Pack request + Packer<typename std::remove_reference<decltype(loc_grid)>::type,HeapMemory>::packRequest(loc_grid,req); + Packer<typename std::remove_reference<decltype(gdb_ext)>::type,HeapMemory>::packRequest(gdb_ext,req); + + //std::cout << "Req: " << req << std::endl; + + // allocate the memory + HeapMemory pmem; + //pmem.allocate(req); + ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(req,pmem)); + mem.incRef(); + + //Packing + + Pack_stat sts; + + Packer<typename std::remove_reference<decltype(loc_grid)>::type,HeapMemory>::pack(mem,loc_grid,sts); + Packer<typename std::remove_reference<decltype(gdb_ext)>::type,HeapMemory>::pack(mem,gdb_ext,sts); + + /***************************************************************** + * Create a new file with default creation and access properties.* + * Then create a dataset and write data to it and close the file * + * and dataset. * + *****************************************************************/ + + int mpi_rank = v_cl.getProcessUnitID(); + int mpi_size = v_cl.getProcessingUnits(); + + MPI_Comm comm = v_cl.getMPIComm(); + MPI_Info info = MPI_INFO_NULL; + + // Set up file access property list with parallel I/O access + + hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist_id, comm, info); + + // Create a new file collectively and release property list identifier. + hid_t file = H5Fcreate (filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id); + H5Pclose(plist_id); + + size_t sz = pmem.size(); + //std::cout << "Pmem.size: " << pmem.size() << std::endl; + openfpm::vector<size_t> sz_others; + v_cl.allGather(sz,sz_others); + v_cl.execute(); + + size_t sum = 0; + + for (size_t i = 0; i < sz_others.size(); i++) + sum += sz_others.get(i); + + //Size for data space in file + hsize_t fdim[1] = {sum}; + + //Size for data space in file + hsize_t fdim2[1] = {(size_t)mpi_size}; + + //Create data space in file + hid_t file_dataspace_id = H5Screate_simple(1, fdim, NULL); + + //Create data space in file + hid_t file_dataspace_id_2 = H5Screate_simple(1, fdim2, NULL); + + //Size for data space in memory + hsize_t mdim[1] = {pmem.size()}; + + //Create data space in memory + hid_t mem_dataspace_id = H5Screate_simple(1, mdim, NULL); + + //if (mpi_rank == 0) + //std::cout << "Total object size: " << sum << std::endl; + + //Create data set in file + hid_t file_dataset = H5Dcreate (file, "grid_dist", H5T_NATIVE_CHAR, file_dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + //Create data set 2 in file + hid_t file_dataset_2 = H5Dcreate (file, "metadata", H5T_NATIVE_INT, file_dataspace_id_2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + //H5Pclose(plist_id); + H5Sclose(file_dataspace_id); + H5Sclose(file_dataspace_id_2); + + hsize_t block[1] = {pmem.size()}; + + //hsize_t stride[1] = {1}; + + hsize_t count[1] = {1}; + + hsize_t offset[1] = {0}; + + for (int i = 0; i < mpi_rank; i++) + { + if (mpi_rank == 0) + offset[0] = 0; + else + offset[0] += sz_others.get(i); + } + + // std::cout << "MPI rank: " << mpi_rank << ", MPI size: " << mpi_size << ", Offset: " << offset[0] << ", Block: " << block[0] << std::endl; + + int metadata[mpi_size]; + + for (int i = 0; i < mpi_size; i++) + metadata[i] = sz_others.get(i); + + //Select hyperslab in the file. + file_dataspace_id = H5Dget_space(file_dataset); + H5Sselect_hyperslab(file_dataspace_id, H5S_SELECT_SET, offset, NULL, count, block); + + file_dataspace_id_2 = H5Dget_space(file_dataset_2); + + + //Create property list for collective dataset write. + plist_id = H5Pcreate(H5P_DATASET_XFER); + H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + + //Write a data set to a file + H5Dwrite(file_dataset, H5T_NATIVE_CHAR, mem_dataspace_id, file_dataspace_id, plist_id, (const char *)pmem.getPointer()); + + //Write a data set 2 to a file + H5Dwrite(file_dataset_2, H5T_NATIVE_INT, H5S_ALL, file_dataspace_id_2, plist_id, metadata); +/* + for (size_t i = 0; i < gdb_ext.size(); i++) + { + Box<dim,long int> box = gdb_ext.get(i).Dbox; + std::cout << "Dboxes saved: (" << box.getLow(0) << "; " << box.getLow(1) << "); (" << box.getHigh(0) << "; " << box.getHigh(1) << ")" << std::endl; + } + + for (size_t i = 0; i < loc_grid.size(); i++) + { + std::cout << "loc_grids saved: (" << loc_grid.get(i).getGrid().getBox().getLow(0) << "; " << loc_grid.get(i).getGrid().getBox().getLow(1) << "); (" << loc_grid.get(i).getGrid().getBox().getHigh(0) << "; " << loc_grid.get(i).getGrid().getBox().getHigh(1) << ")" << std::endl; + } +*/ + //Close/release resources. + H5Dclose(file_dataset); + H5Sclose(file_dataspace_id); + H5Dclose(file_dataset_2); + H5Sclose(file_dataspace_id_2); + H5Sclose(mem_dataspace_id); + H5Pclose(plist_id); + H5Fclose(file); + } + +}; + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_GD_HPP_ */ diff --git a/src/HDF5_wr/HDF5_writer_unit_tests.hpp b/src/HDF5_wr/HDF5_writer_unit_tests.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0fc72b14825d1864c690158be5b08d51c2cd4028 --- /dev/null +++ b/src/HDF5_wr/HDF5_writer_unit_tests.hpp @@ -0,0 +1,115 @@ +/* + * HDF5_writer_unit_test.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_UNIT_TESTS_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_UNIT_TESTS_HPP_ + +#include "HDF5_wr.hpp" + +#include "hdf5.h" + +BOOST_AUTO_TEST_SUITE( vd_hdf5_chckpnt_rstrt_test ) + +// Dimensionality +const size_t dim = 3; + +BOOST_AUTO_TEST_CASE( vector_dist_hdf5_save_test ) +{ + openfpm::vector<Point<3,float>> vpos; + openfpm::vector<aggregate<float[dim]>> vprp; + + // Put forces + + for (size_t i = 0 ; i < 1024 ; i++) + { + Point<3,float> p; + + p.get(0) = i; + p.get(1) = i+13; + p.get(2) = i+17; + + vpos.add(p); + + vprp.add(); + vprp.template get<0>(vprp.size()-1)[0] = p.get(0) + 100.0; + vprp.template get<0>(vprp.size()-1)[1] = p.get(1) + 200.0; + vprp.template get<0>(vprp.size()-1)[2] = p.get(2) + 300.0; + } + + HDF5_writer<VECTOR_DIST> h5; + + // Save the vector + h5.save("vector_dist.h5",vpos,vprp); + + HDF5_reader<VECTOR_DIST> h5r; + + openfpm::vector<Point<3,float>> vpos2; + openfpm::vector<aggregate<float[dim]>> vprp2; + + size_t g_m = 0; + h5r.load("vector_dist.h5",vpos2,vprp2,g_m); + + BOOST_REQUIRE_EQUAL(1024ul,vpos2.size()); + BOOST_REQUIRE_EQUAL(1024ul,vprp2.size()); + + BOOST_REQUIRE_EQUAL(1024ul,g_m); + + // Check that vpos == vpos2 and vprp2 == vprp2 + + bool check = true; + for (size_t i = 0 ; i < vpos.size() ; i++) + { + check &= (vpos.get(i) == vpos2.get(i)); + check &= (vprp.get_o(i) == vprp2.get_o(i)); + } + + BOOST_REQUIRE_EQUAL(check,true); +} + + + +BOOST_AUTO_TEST_CASE( vector_dist_hdf5_load_test ) +{ + Vcluster & v_cl = create_vcluster(); + + openfpm::vector<Point<3,float>> vpos; + openfpm::vector<aggregate<float[dim]>> vprp; + + HDF5_reader<VECTOR_DIST> h5; + + size_t g_m = 0; + + // Load the vector + h5.load("test_data/vector_dist_24.h5",vpos,vprp,g_m); + + /////////////////// Checking data /////////////////////// + + // Check total number of particles + size_t n_part = vpos.size(); + v_cl.sum(n_part); + v_cl.execute(); + + BOOST_REQUIRE_EQUAL(n_part,1024ul*24ul); + + BOOST_REQUIRE_EQUAL(vpos.size(),vprp.size()); + + bool check = true; + + for (size_t i = 0 ; i < vpos.size() ; i++) + { + check &= (vprp.template get<0>(i)[0] == vpos.template get<0>(i)[0] + 100.0); + check &= (vprp.template get<0>(i)[1] == vpos.template get<0>(i)[1] + 200.0); + check &= (vprp.template get<0>(i)[2] == vpos.template get<0>(i)[2] + 300.0); + } + + +} + +BOOST_AUTO_TEST_SUITE_END() + + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_UNIT_TESTS_HPP_ */ diff --git a/src/HDF5_wr/HDF5_writer_vd.hpp b/src/HDF5_wr/HDF5_writer_vd.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d4139624679969553eb06d71529e99993e687efe --- /dev/null +++ b/src/HDF5_wr/HDF5_writer_vd.hpp @@ -0,0 +1,161 @@ +/* + * HDF5_loader_vector_dist.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_VD_HPP_ +#define OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_VD_HPP_ + +#include "Packer_Unpacker/Pack_selector.hpp" +#include "Packer_Unpacker/Packer.hpp" +#include "Packer_Unpacker/Unpacker.hpp" + +template <> +class HDF5_writer<VECTOR_DIST> +{ +public: + + template<unsigned int dim, typename St, typename prp> + inline void save(const std::string & filename, + const openfpm::vector<Point<dim,St>> & v_pos, + const openfpm::vector<prp> & v_prp) const + { + Vcluster & v_cl = create_vcluster(); + + //Pack_request vector + size_t req = 0; + + //std::cout << "V_pos.size() before save: " << v_pos.size() << std::endl; + + //Pack request + Packer<typename std::remove_reference<decltype(v_pos)>::type,HeapMemory>::packRequest(v_pos,req); + Packer<typename std::remove_reference<decltype(v_prp)>::type,HeapMemory>::packRequest(v_prp,req); + + // allocate the memory + HeapMemory pmem; + //pmem.allocate(req); + ExtPreAlloc<HeapMemory> & mem = *(new ExtPreAlloc<HeapMemory>(req,pmem)); + mem.incRef(); + + //Packing + + Pack_stat sts; + + Packer<typename std::remove_reference<decltype(v_pos)>::type,HeapMemory>::pack(mem,v_pos,sts); + Packer<typename std::remove_reference<decltype(v_prp)>::type,HeapMemory>::pack(mem,v_prp,sts); + + /***************************************************************** + * Create a new file with default creation and access properties.* + * Then create a dataset and write data to it and close the file * + * and dataset. * + *****************************************************************/ + + int mpi_rank = v_cl.getProcessUnitID(); + int mpi_size = v_cl.getProcessingUnits(); + + MPI_Comm comm = v_cl.getMPIComm(); + MPI_Info info = MPI_INFO_NULL; + + // Set up file access property list with parallel I/O access + + hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist_id, comm, info); + + // Create a new file collectively and release property list identifier. + hid_t file = H5Fcreate (filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id); + H5Pclose(plist_id); + + size_t sz = pmem.size(); + //std::cout << "Pmem.size: " << pmem.size() << std::endl; + openfpm::vector<size_t> sz_others; + v_cl.allGather(sz,sz_others); + v_cl.execute(); + + size_t sum = 0; + + for (size_t i = 0; i < sz_others.size(); i++) + sum += sz_others.get(i); + + //Size for data space in file + hsize_t fdim[1] = {sum}; + + //Size for data space in file + hsize_t fdim2[1] = {(size_t)mpi_size}; + + //Create data space in file + hid_t file_dataspace_id = H5Screate_simple(1, fdim, NULL); + + //Create data space in file + hid_t file_dataspace_id_2 = H5Screate_simple(1, fdim2, NULL); + + //Size for data space in memory + hsize_t mdim[1] = {pmem.size()}; + + //Create data space in memory + hid_t mem_dataspace_id = H5Screate_simple(1, mdim, NULL); + + //Create data set in file + hid_t file_dataset = H5Dcreate (file, "vector_dist", H5T_NATIVE_CHAR, file_dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + //Create data set 2 in file + hid_t file_dataset_2 = H5Dcreate (file, "metadata", H5T_NATIVE_INT, file_dataspace_id_2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + //H5Pclose(plist_id); + H5Sclose(file_dataspace_id); + H5Sclose(file_dataspace_id_2); + + hsize_t block[1] = {pmem.size()}; + + //hsize_t stride[1] = {1}; + + hsize_t count[1] = {1}; + + hsize_t offset[1] = {0}; + + for (int i = 0; i < mpi_rank; i++) + { + if (mpi_rank == 0) + offset[0] = 0; + else + offset[0] += sz_others.get(i); + } + + int metadata[mpi_size]; + + for (int i = 0; i < mpi_size; i++) + metadata[i] = sz_others.get(i); + + //Select hyperslab in the file. + file_dataspace_id = H5Dget_space(file_dataset); + H5Sselect_hyperslab(file_dataspace_id, H5S_SELECT_SET, offset, NULL, count, block); + + file_dataspace_id_2 = H5Dget_space(file_dataset_2); + + + //Create property list for collective dataset write. + plist_id = H5Pcreate(H5P_DATASET_XFER); + H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE); + + //Write a data set to a file + H5Dwrite(file_dataset, H5T_NATIVE_CHAR, mem_dataspace_id, file_dataspace_id, plist_id, (const char *)pmem.getPointer()); + + //Write a data set 2 to a file + H5Dwrite(file_dataset_2, H5T_NATIVE_INT, H5S_ALL, file_dataspace_id_2, plist_id, metadata); + + + //Close/release resources. + H5Dclose(file_dataset); + H5Sclose(file_dataspace_id); + H5Dclose(file_dataset_2); + H5Sclose(file_dataspace_id_2); + H5Sclose(mem_dataspace_id); + H5Pclose(plist_id); + H5Fclose(file); + } + +}; + + +#endif /* OPENFPM_IO_SRC_HDF5_WR_HDF5_WRITER_VD_HPP_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 06d23e47432bcb80329066b221179a897c964bb6..e77305ed8a5f83ee2cf5f52031ed4993d54c2316 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,16 @@ -LINKLIBS = $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_IOSTREAMS_LIB) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_THREAD_LIB) $(HDF5_LDFLAGS) $(HDF5_LIBS) +LINKLIBS = $(PTHREAD_LIBS) $(HDF5_LDFLAGS) $(HDF5_LIBS) $(OPT_LIBS) $(BOOST_IOSTREAMS_LIB) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_THREAD_LIB) noinst_PROGRAMS = io -io_SOURCES = main.cpp ../../openfpm_vcluster/src/VCluster/VCluster.cpp ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp -io_CXXFLAGS = $(AM_CXXFLAGS) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include $(HDF5_CPPFLAGS) +io_SOURCES = main.cpp ../../openfpm_vcluster/src/VCluster/VCluster.cpp ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp +io_CXXFLAGS = $(AM_CXXFLAGS) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(HDF5_CPPFLAGS) $(BOOST_CPPFLAGS) -I/usr/local/include io_CFLAGS = $(CUDA_CFLAGS) -io_LDADD = $(LINKLIBS) +io_LDADD = $(LINKLIBS) -nobase_include_HEADERS = CSVWriter/csv_multiarray.hpp CSVWriter/CSVWriter.hpp CSVWriter/is_csv_writable.hpp \ -GraphMLWriter/GraphMLWriter.hpp util.hpp \ -VTKWriter/VTKWriter.hpp VTKWriter/byteswap_portable.hpp VTKWriter/VTKWriter_dist_graph.hpp VTKWriter/VTKWriter_graph.hpp VTKWriter/VTKWriter_point_set.hpp VTKWriter/VTKWriter_grids.hpp VTKWriter/VTKWriter_grids_st.hpp VTKWriter/VTKWriter_grids_util.hpp VTKWriter/VTKWriter_vector_box.hpp VTKWriter/is_vtk_writable.hpp HDF5_XdmfWriter/HDF5_XdmfWriter.hpp HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp \ -Plot/GoogleChart.hpp Plot/util.hpp +nobase_include_HEADERS = RawReader/RawReader.hpp RawReader/RawReader_unit_tests.hpp CSVWriter/csv_multiarray.hpp CSVWriter/CSVWriter.hpp CSVWriter/is_csv_writable.hpp \ +GraphMLWriter/GraphMLWriter.hpp util/util.hpp util/GBoxes.hpp \ +VTKWriter/VTKWriter.hpp VTKWriter/byteswap_portable.hpp VTKWriter/VTKWriter_dist_graph.hpp VTKWriter/VTKWriter_graph.hpp VTKWriter/VTKWriter_point_set.hpp VTKWriter/VTKWriter_grids.hpp VTKWriter/VTKWriter_grids_st.hpp VTKWriter/VTKWriter_grids_util.hpp VTKWriter/VTKWriter_vector_box.hpp VTKWriter/is_vtk_writable.hpp HDF5_wr/HDF5_wr.hpp HDF5_wr/HDF5_writer.hpp HDF5_wr/HDF5_writer_vd.hpp HDF5_wr/HDF5_writer_gd.hpp HDF5_wr/HDF5_reader_gd.hpp HDF5_wr/HDF5_reader.hpp HDF5_wr/HDF5_reader_vd.hpp \ +Plot/GoogleChart.hpp Plot/util.hpp .cu.o : diff --git a/src/Plot/GoogleChart.hpp b/src/Plot/GoogleChart.hpp index 38d20008241ced3d405db5ec8edddf9744942198..136e7b228c4ae2c7d9412616079a209d346f2353 100644 --- a/src/Plot/GoogleChart.hpp +++ b/src/Plot/GoogleChart.hpp @@ -68,7 +68,16 @@ struct GCoptions //! curve type std::string curveType = "function"; - //! copy operator + //! barWD + bool barWD = false; + + /*! \brief copy operator + * + * \param opt object to copy + * + * \return itself + * + */ GCoptions & operator=(const GCoptions & opt) { title = opt.title; @@ -87,6 +96,9 @@ struct GCoptions } }; +/*! \brief Google Graph + * + */ struct GGraph { //! TypeOfGraph @@ -98,6 +110,9 @@ struct GGraph //! option std::string option; + //! view in case we need a view + std::string view; + //! Google chart option GCoptions opt; }; @@ -243,6 +258,35 @@ class GoogleChart return data.str(); } + /*! \brief Construct a view option + * + * \param opt GoogleChart option + * + * \return the string + * + */ + std::string get_view_bar_option(const GCoptions & opt, size_t n_col) + { + if (opt.barWD == false) + return std::string(); + + std::stringstream str; + + str << "[0" << std::endl; + + for (size_t i = 1 ; i < n_col ; i++) + { + str << "," << i << ",{ calc: \"stringify\"," << std::endl; + str << "sourceColumn: " << i << "," << std::endl; + str << "type: \"string\"," << std::endl; + str << "role: \"annotation\" }"<< std::endl; + } + + str << "]" << std::endl; + + return str.str(); + } + std::string get_colums_bar_option(const GCoptions & opt) { std::stringstream str; @@ -311,19 +355,46 @@ class GoogleChart of << "};\n"; } + /*! \brief Add a view data variable + * + * \param of file out + * \param i id + * \param view string + * + */ + void addView(std::ofstream & of, size_t i, std::string view) + { + if (view.size() == 0) + return; + + of << "var view" << i << " = new google.visualization.DataView(data" << i << ");" << std::endl; + of << "view"<< i << ".setColumns("; + of << view << ");" << std::endl; + } + /*! \brief Add a draw div section * * \param of file out * \param i id + * \param draw_view draw a chart(true) or view(false) * */ - void addDrawDiv(std::ofstream & of, size_t i) + void addDrawDiv(std::ofstream & of, size_t i, bool draw_view) { of << "$(\"#export_svg" << i << "\").on(\"click\", function (event) {exportToSVG.apply(this,[" << i << "]);});\n"; of << "var chart = new google.visualization.ComboChart(document.getElementById('chart_div"; of << i; - of << "'));chart.draw(data"; - of << i; + of << "'));" << std::endl; + if (draw_view == true) + { + of << "chart.draw(data"; + of << i; + } + else + { + of << "chart.draw(view"; + of << i; + } of << ", options"; of << i; of << ");\n"; @@ -438,6 +509,7 @@ public: set_of_graphs.last().type = GGRAPH_COLUMS; set_of_graphs.last().data = get_points_plot_data(x,y,yn,opt,set_of_graphs.size()-1); set_of_graphs.last().option = get_colums_bar_option(opt); + set_of_graphs.last().view = get_view_bar_option(opt,y.get(0).size()); set_of_graphs.last().opt = opt; } @@ -599,7 +671,10 @@ public: addOption(of,i,set_of_graphs.get(i).option); for (size_t i = 0 ; i < set_of_graphs.size() ; i++) - addDrawDiv(of,i); + addView(of,i,set_of_graphs.get(i).view); + + for (size_t i = 0 ; i < set_of_graphs.size() ; i++) + addDrawDiv(of,i,set_of_graphs.get(i).view.size() == 0); of << begin_div; diff --git a/src/Plot/Plot_unit_tests.hpp b/src/Plot/Plot_unit_tests.hpp index 04841b931a9c64fcc29a7b6987ae626ad4d4d1fc..db2d2ecc9db4b35b8d5b10e6fb03d535e9104b9a 100644 --- a/src/Plot/Plot_unit_tests.hpp +++ b/src/Plot/Plot_unit_tests.hpp @@ -13,8 +13,72 @@ BOOST_AUTO_TEST_SUITE( plot_unit_test ) + +BOOST_AUTO_TEST_CASE( google_chart_bar_string ) +{ + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + + //! [Producing an Histogram graph] + + openfpm::vector<std::string> x; + openfpm::vector<openfpm::vector<size_t>> y; + openfpm::vector<std::string> yn; + + x.add("colum1"); + x.add("colum2"); + x.add("colum3"); + x.add("colum4"); + x.add("colum5"); + x.add("colum6"); + + // Each colum can have multiple data set (in this case 4 dataset) + // Each dataset can have a name + yn.add("dataset1"); + yn.add("dataset2"); + yn.add("dataset3"); + yn.add("dataset4"); + + // Each colums can have multiple data-set + y.add({2,3,5,6}); + y.add({5,6,1,6}); + y.add({2,1,6,9}); + y.add({1,6,3,2}); + y.add({3,3,0,6}); + y.add({2,1,4,6}); + + // Google charts options + GCoptions options; + + options.title = std::string("Example"); + options.yAxis = std::string("Y Axis"); + options.xAxis = std::string("X Axis"); + options.stype = std::string("bars"); + options.barWD = true; + + // it say that the colum4 must me represented with a line + options.stypeext = std::string("{3: {type: 'line'}}"); + + GoogleChart cg; + cg.AddHistGraph(x,y,yn,options); + cg.write("gc_out_sc.html"); + + //! [Producing an Histogram graph] + + bool test = compare("gc_out_sc.html","test_data/gc_out_sc_test.html"); + BOOST_REQUIRE_EQUAL(true,test); +} + + BOOST_AUTO_TEST_CASE( google_chart ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + //! [Producing an Histogram graph] openfpm::vector<std::string> x; @@ -66,6 +130,11 @@ BOOST_AUTO_TEST_CASE( google_chart ) BOOST_AUTO_TEST_CASE( google_chart2 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + openfpm::vector<std::string> x; openfpm::vector<openfpm::vector<float>> y; openfpm::vector<std::string> yn; @@ -110,6 +179,11 @@ BOOST_AUTO_TEST_CASE( google_chart2 ) BOOST_AUTO_TEST_CASE( google_chart3 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + openfpm::vector<std::string> x; openfpm::vector<openfpm::vector<float>> y; openfpm::vector<std::string> yn; @@ -153,6 +227,11 @@ BOOST_AUTO_TEST_CASE( google_chart3 ) BOOST_AUTO_TEST_CASE( google_chart4 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + openfpm::vector<std::string> x; openfpm::vector<openfpm::vector<float>> y; openfpm::vector<std::string> yn; @@ -189,6 +268,11 @@ BOOST_AUTO_TEST_CASE( google_chart4 ) BOOST_AUTO_TEST_CASE( google_chart5 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + openfpm::vector<std::string> x; openfpm::vector<openfpm::vector<float>> y; @@ -217,6 +301,11 @@ BOOST_AUTO_TEST_CASE( google_chart5 ) BOOST_AUTO_TEST_CASE( google_chart6 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + openfpm::vector<openfpm::vector<float>> y; // Each colums can have multiple data-set @@ -237,6 +326,11 @@ BOOST_AUTO_TEST_CASE( google_chart6 ) BOOST_AUTO_TEST_CASE( google_chart_with_inject_HTML ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + //! [Producing a set of histograms graphs] openfpm::vector<std::string> x; @@ -295,6 +389,11 @@ BOOST_AUTO_TEST_CASE( google_chart_with_inject_HTML ) BOOST_AUTO_TEST_CASE( google_chart_linear_plot ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + //! [Producing lines graph with style] openfpm::vector<std::string> x; @@ -357,6 +456,11 @@ BOOST_AUTO_TEST_CASE( google_chart_linear_plot ) BOOST_AUTO_TEST_CASE( google_chart_linear_plot2 ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + //! [Producing lines] openfpm::vector<std::string> x; @@ -410,6 +514,11 @@ double f(double x) BOOST_AUTO_TEST_CASE( plot_util ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + //! [fill a vector] openfpm::vector<double> x; diff --git a/src/RawReader/RawReader.hpp b/src/RawReader/RawReader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..706c84960ac1aa7568957df65fc9f31c5be1fc19 --- /dev/null +++ b/src/RawReader/RawReader.hpp @@ -0,0 +1,193 @@ +/*! \brief This class read a Grid raw data format + * + * A grid row data format is very simple. The first n numbers indicate the + * size in every dimension of the grid. The other is the data contained by the grid. + * In particular if we are in 3D and we are saving a 45x50x30 grid after the 3 numbers + * I am expecting 45x50x30 = 67500 objects of type T. There is no check the dimensionality + * is correct, neither the type is correct + * + * \tparam dim dimensionality of the grid + * \tparam T type of the grid + * + */ +#include <iostream> +#include <Grid/map_grid.hpp> +#include <fstream> + +#define FORTRAN_STYLE 1 +#define STRUCT_OF_ARRAY 2 + +/*! \brief This is the scalar case + * + * \tparam T scalar type + * + */ +template<unsigned int dim, typename Tg, typename Tr, unsigned int i> +struct meta_raw_read +{ + static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw) + { + auto it = gr.getIterator(); + + while (it.isNext()) + { + auto key = it.get(); + + raw.read((char *)&gr.template get<i>(key),sizeof(Tr)); + + ++it; + } + } +}; + +/*! \brief This is the vector case + * + * \tparam T vector type + * + */ +template<unsigned int dim, typename Tg, typename Tr ,unsigned int i, unsigned int nv> +struct meta_raw_read<dim,Tg,Tr[nv],i> +{ + static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw) + { + for (size_t k = 0 ; k < nv ; k++) + { + auto it = gr.getIterator(); + + while (it.isNext()) + { + auto key = it.get(); + + raw.read((char *)&gr.template get<i>(key)[k],sizeof(Tr)); + + ++it; + } + } + } +}; + +/*! \brief this class is a functor for "for_each" algorithm + * + * This class is a functor for "for_each" algorithm. For each + * element of the boost::vector the operator() is called. + * Is mainly used to read each property + * + * \tparam ele_g element that store the grid and its attributes + * \param St type of space where the grid live + * + */ +template<unsigned int dim, typename Tg> +struct raw_read +{ + //! Grid out + grid_cpu<dim,Tg> & gr; + + //! File stream + std::ifstream & fl; + + /*! \brief constructor + * + * \param gr grid to fill + * \param fl file from where to read + * + */ + raw_read(grid_cpu<dim,Tg> & gr,std::ifstream & fl) + :gr(gr),fl(fl) + {}; + + //! It read for each property + template<typename T> + void operator()(T& t) const + { + typedef typename boost::mpl::at<typename Tg::type,boost::mpl::int_<T::value>>::type Tr; + + meta_raw_read<dim,Tg,Tr,T::value>::read(gr,fl); + } +}; + +template <unsigned int dim, typename T, typename idx_type> +class GridRawReader +{ +public: + + //! Constructor + GridRawReader() {}; + + + /*! \brief Read a raw grid + * + * \param file raw file to read + * \param gr grid to fill + * \param opt option (FORTRAN_STYLE) + * \param skip skip N byte + * + */ + bool read(std::string file, grid_cpu<dim,T> & gr, size_t opt = 0, size_t skip = 0) + { + idx_type tmp; + std::ifstream raw; + raw.open (file, std::ios::binary ); + + if (raw.is_open() == false) + { + std::cerr << __FILE__ << ":" << __LINE__ << " error in opening the file: " << file << std::endl; + return false; + } + + // get length of file: + raw.seekg (0, std::ios::end); + size_t length = raw.tellg(); + raw.seekg (skip, std::ios::beg); + + if (opt & FORTRAN_STYLE) + raw.read((char *)&tmp,sizeof(idx_type)); + + size_t sz[dim]; + + for (size_t i = 0 ; i < dim ; i++) + { + sz[i] = 0; + raw.read((char *)&sz[i],sizeof(idx_type)); + } + + if (opt & FORTRAN_STYLE) + raw.read((char *)&tmp,sizeof(idx_type)); + + if (opt & FORTRAN_STYLE) + raw.read((char *)&tmp,sizeof(idx_type)); + + grid_sm<dim,void> gs(sz); + + size_t offset = 0; + if (opt & FORTRAN_STYLE) + offset += 2*sizeof(idx_type)*2; + + // Check the the file size make sense + if (length - dim*sizeof(idx_type) - offset - skip != gs.size()*sizeof(T) ) + { + std::cout << __FILE__ << ":" << __LINE__ << " Error the size of the raw file does not match with the calculated one" << std::endl; + return false; + } + + gr.setMemory(); + + // resize the grid + gr.resize(sz); + + if (!(opt & STRUCT_OF_ARRAY)) + { + // read the data + raw.read((char *)gr.getPointer(),gr.size()*sizeof(T)); + raw.close(); + } + else + { + // for each property + raw_read<dim,T> rr(gr,raw); + + boost::mpl::for_each< boost::mpl::range_c<int,0, T::max_prop> >(rr); + } + + return true; + } +}; diff --git a/src/RawReader/RawReader_unit_tests.hpp b/src/RawReader/RawReader_unit_tests.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ad59f0be70ac517586aace706249c863e0eda11 --- /dev/null +++ b/src/RawReader/RawReader_unit_tests.hpp @@ -0,0 +1,48 @@ +/* + * RawReader_unit_tests.hpp + * + * Created on: April 16, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_RAW_READER_UNIT_TESTS_HPP_ +#define OPENFPM_IO_RAW_READER_UNIT_TESTS_HPP_ + +#include "RawReader.hpp" + +BOOST_AUTO_TEST_SUITE( raw_reader_unit_test ) + + +BOOST_AUTO_TEST_CASE( raw_reader_read_test ) +{ + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + + grid_cpu<3,aggregate<float,float[3]>> read_bin_test; + + GridRawReader<3,aggregate<float,float[3]>,int> rr; + rr.read("test_data/raw_read_sv_test.bin",read_bin_test,FORTRAN_STYLE | STRUCT_OF_ARRAY,12); + + auto it = read_bin_test.getIterator(); + + while (it.isNext()) + { + auto key = it.get(); + + BOOST_REQUIRE_EQUAL(read_bin_test.template get<0>(key),1.5f); + + BOOST_REQUIRE_EQUAL(read_bin_test.template get<1>(key)[0],1.5f); + BOOST_REQUIRE_EQUAL(read_bin_test.template get<1>(key)[1],2.5f); + BOOST_REQUIRE_EQUAL(read_bin_test.template get<1>(key)[2],3.5f); + + ++it; + } +} + + + +BOOST_AUTO_TEST_SUITE_END() + +#endif /* OPENFPM_DATA_SRC_PLOT_PLOT_UNIT_TESTS_HPP_ */ diff --git a/src/VTKWriter/VTKWriter_dist_graph.hpp b/src/VTKWriter/VTKWriter_dist_graph.hpp index b340c6011d846103f6e7e48a0213e694f2a3d19c..d7b7ccdecff641bd085719cd304ed54595ad6a15 100644 --- a/src/VTKWriter/VTKWriter_dist_graph.hpp +++ b/src/VTKWriter/VTKWriter_dist_graph.hpp @@ -125,7 +125,11 @@ struct vtk_dist_vertex_node v_node += std::to_string(x[0]) + " " + std::to_string(x[1]) + " " + std::to_string(x[2]) + "\n"; } - //! It call the functor for each member + /*! \brief It call the functor for each attribute + * + * \param t attribute id + * + */ template<typename T> void operator()(T& t) { @@ -173,7 +177,11 @@ struct vtk_dist_vertex_node<G, false> { } - //! It call the functor for each member + /*! \brief It call the functor for each attribute + * + * \param t attribute id + * + */ template<typename T> void operator()(T& t) { @@ -391,10 +399,11 @@ public: /*! \brief For each vertex set the value * - * \tparam i vertex property to print * * \param g graph to output * + * \return get the point data string + * */ static std::string get_point_data(const Graph & g) { @@ -418,11 +427,11 @@ public: } /*! \brief For each edge set the value, set 1 on vertices, needed by vtk file format - * - * \tparam i edge property to print * * \param g graph to output * + * \return the cell-data string + * */ static std::string get_cell_data(const Graph & g) @@ -464,6 +473,8 @@ public: * * \param prop property id * + * \return the string with the property header + * */ static std::string get_point_property_header(size_t prop) { @@ -601,6 +612,8 @@ class dist_prop_output<false, Graph, i> * * \param g graph to print * + * \return the string with the point data + * */ static std::string get_point_data(Graph & g) { @@ -625,10 +638,11 @@ class dist_prop_output<false, Graph, i> /*! \brief For each edge output the property string * - * \param graph to print + * \param g graph to print + * + * \return the string containing cell-data * */ - static std::string get_cell_data(const Graph & g) { //! vertex node output string @@ -801,7 +815,11 @@ struct dist_prop_out_vertex { } - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { @@ -846,16 +864,19 @@ struct dist_prop_out_edge /*! \brief constructor * - * \param v_out string to fill with the vertex properties + * \param e_out string to fill with the edge properties + * \param g graph to write * */ dist_prop_out_edge(std::string & e_out, const Graph & g) : e_out(e_out), g(g) - { - } - ; + {}; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t index property + * + */ template<typename T> void operator()(T& t) const { @@ -930,6 +951,11 @@ class VTKWriter<Graph, DIST_GRAPH> return v_out; } + /*! \brief Get the VTK point info string + * + * \return the point info string + * + */ std::string get_point_info() { //! vertex property output string @@ -977,9 +1003,10 @@ class VTKWriter<Graph, DIST_GRAPH> /*! \brief Create the VTK point definition * - * \tparam s_type spatial type of the data * \tparam attr false x,y,z are set to 0 for each vertex * + * \return the point list string + * */ template<bool attr> std::string get_point_list() @@ -1018,11 +1045,11 @@ class VTKWriter<Graph, DIST_GRAPH> /*! \brief Create the VTK vertex definition * - * \tparam s_type spatial type of the data * \tparam attr false x,y,z are set to 0 for each vertex * + * \return the vertex list string + * */ - std::string get_vertex_list() { //! vertex node output string @@ -1114,11 +1141,12 @@ public: * \tparam prp_out which properties to output [default = -1 (all)] * * \param file path where to write - * \param name of the graph + * \param graph_name of the graph * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if it succeed + * */ - template<int prp = -1> bool write(std::string file, std::string graph_name = "Graph", file_type ft = file_type::ASCII) { diff --git a/src/VTKWriter/VTKWriter_graph.hpp b/src/VTKWriter/VTKWriter_graph.hpp index 417a135e4edffb1ace2b565ac3d409aabfdec84e..18d4667808aea9f99c298d72dcadecb16bc78728 100644 --- a/src/VTKWriter/VTKWriter_graph.hpp +++ b/src/VTKWriter/VTKWriter_graph.hpp @@ -91,17 +91,19 @@ struct vtk_vertex_node_array_scalar_selector<true> template<typename G, bool attr> struct vtk_vertex_node { - // Vertex spatial type information + //! Vertex spatial type information typedef typename G::V_type::s_type s_type; + //! Indicate if there is the information about the z coordinate bool z_set; + //! point to write s_type (&x)[3]; - // Vertex object container + //! Vertex object container typename G::V_container & vo; - // vertex node string + //! vertex node string std::string & v_node; /*! \brief Constructor @@ -110,6 +112,7 @@ struct vtk_vertex_node * * \param v_node std::string that is filled with the graph properties in the GraphML format * \param n_obj object container to access its properties for example encapc<...> + * \param x temporal buffer to store the point coordinates * */ vtk_vertex_node(std::string & v_node, typename G::V_container & n_obj, s_type (&x)[3]) @@ -123,7 +126,11 @@ struct vtk_vertex_node v_node += std::to_string(x[0]) + " " + std::to_string(x[1]) + " " + std::to_string(x[2]) + "\n"; } - //! It call the functor for each member + /*! \brief It call the functor for each member + * + * \param t property id + * + */ template<typename T> void operator()(T& t) { @@ -152,10 +159,10 @@ struct vtk_vertex_node template<typename G> struct vtk_vertex_node<G, false> { - // Vertex object container + //! Vertex object container typename G::V_container & vo; - // vertex node string + //! vertex node string std::string & v_node; /*! \brief Constructor @@ -172,7 +179,13 @@ struct vtk_vertex_node<G, false> } ; - //! It call the functor for each member + /*! \brief It call the functor for each member + * + * It set the position of vertex to zero + * + * \param t property id + * + */ template<typename T> void operator()(T& t) { @@ -192,10 +205,10 @@ struct vtk_vertex_node<G, false> template<typename G> struct vtk_edge_node { - // Vertex object container + //! Vertex object container typename G::E_container & vo; - // edge node string + //! edge node string std::string & e_node; /*! \brief Constructor @@ -204,7 +217,6 @@ struct vtk_edge_node * * \param e_node std::string that is filled with the graph properties in the GraphML format * \param n_obj object container to access the object properties for example encapc<...> - * \param n_prop number of properties * */ vtk_edge_node(std::string & e_node, typename G::E_container & n_obj) : @@ -215,7 +227,9 @@ struct vtk_edge_node /*! \brief Create a new node * - * \param vc node number + * \param v_c unused + * \param s source of the edge + * \param d destination of the edge * */ void new_node(size_t v_c, size_t s, size_t d) @@ -295,7 +309,7 @@ struct prop_output_array_scalar_selector_edge * * \param v_out Buffer to write into * \param g Graph - * \param p Property id + * \param edge to write */ template<typename ele_v, typename Graph, unsigned int i> static inline void write(std::string &v_out, const Graph &g, const typename Graph::E_container &edge) @@ -318,7 +332,7 @@ struct prop_output_array_scalar_selector_edge<true> * * \param v_out Buffer to write into * \param g Graph - * \param p Property id + * \param edge to write */ template<typename ele_v, typename Graph, unsigned int i> static inline void write(std::string &v_out, const Graph &g, const typename Graph::E_container &edge) @@ -388,12 +402,13 @@ class prop_output { public: - /*! \brief For each vertex set the value + /*! \brief Get the vtk point data section for a graph g + * + * \param g graph * - * \tparam i vertex property to print + * \return point data section string * */ - static std::string get_point_data(const Graph & g) { //! vertex node output string @@ -415,12 +430,13 @@ public: return v_out; } - /*! \brief For each edge set the value, set 1 on vertices, needed by vtk file format + /*! \brief Get the cell data section for a graph g + * + * \param g graph * - * \tparam i edge property to print + * \return the cell data section * */ - static std::string get_cell_data(const Graph & g) { //! vertex node output string @@ -456,16 +472,17 @@ public: return e_out; } - /*! \brief Given a Graph return the point data header for a typename T + /*! \brief Return the point header for the property prop * - * \tparam T type to write - * \param n_node number of the node + * \param prop property to write + * + * \return a string containing the header of the properties * */ static std::string get_point_property_header(size_t prop) { - //! vertex node output string + // vertex node output string std::string v_out; // Type of the property @@ -509,11 +526,11 @@ public: /*! \brief Given a Graph return the cell data header for a typename T * - * \tparam T type to write - * \param n_node number of the node + * \param prop property id + * + * \return the string with the cell property header * */ - static std::string get_cell_property_header(size_t prop) { //! edge node output string @@ -558,19 +575,21 @@ public: return e_out; } - /*! \brief Get the attributes name for vertex + /*! \brief Get the attributes name for the property i (template parameter) + * + * \return vertex attribute name * */ - static std::string get_attributes_vertex() { return Graph::V_type::attributes::name[i]; } - /*! \brief Get the attributes name for edge + /*! \brief Get the attributes name for edge property i (template parameter) + * + * \return edge attribute name * */ - static std::string get_attributes_edge() { return Graph::E_type::attributes::name[i]; @@ -593,12 +612,13 @@ public: template<typename Graph, unsigned int i> class prop_output<false, Graph, i> { - /*! \brief For each vertex set the value + /*! \brief Return the point data section for a graph g + * + * \param g graph * - * \tparam i vertex property to print + * \return the point data section string * */ - static std::string get_point_data(Graph & g) { //! vertex node output string @@ -620,18 +640,20 @@ class prop_output<false, Graph, i> return v_out; } - /*! \brief For each edge set the value + /*! \brief Return the cell data section for a graph g * - * \tparam i edge property to print + * \param g graph + * + * \return the cell data section * */ static std::string get_cell_data(const Graph & g) { - //! vertex node output string + // vertex node output string std::string e_out; - //! Get a vertex iterator + // Get a vertex iterator auto it_v = g.getVertexIterator(); // if there is the next element @@ -660,13 +682,12 @@ class prop_output<false, Graph, i> return e_out; } - /*! \brief Given a Graph return the point data header for a typename T + /*! \brief Given a Graph return the point data header for the property prop * - * \tparam T type to write - * - * \param n_node number of the node * \param prop id of the property * + * \return the string of the property header + * */ static std::string get_point_property_header(size_t prop) @@ -695,9 +716,11 @@ class prop_output<false, Graph, i> return v_out; } - /*! \brief Given a Graph return the cell data header for a typename T + /*! \brief Given a Graph return the cell data header * - * \param n_node number of the node + * \param prop property id + * + * \return the cell property header * */ @@ -746,18 +769,20 @@ class prop_output<false, Graph, i> } /*! \brief Get the attributes name for vertex + * + * \return get attributes vertex name * */ - static std::string get_attributes_vertex() { return Graph::V_type::attributes::name[i]; } /*! \brief Get the attributes name for edge + * + * \return get attributes edge name * */ - static std::string get_attributes_edge() { return Graph::E_type::attributes::name[i]; @@ -780,15 +805,16 @@ class prop_output<false, Graph, i> template<typename Graph> struct prop_out_vertex { - // property output string + //! property output string std::string & v_out; - // Graph that we are processing + //! Graph that we are processing const Graph & g; /*! \brief constructor * * \param v_out string to fill with the vertex properties + * \param g graph to output * */ prop_out_vertex(std::string & v_out, const Graph & g) : @@ -797,7 +823,11 @@ struct prop_out_vertex } ; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { @@ -834,15 +864,16 @@ struct prop_out_vertex template<typename Graph> struct prop_out_edge { - // property output string + //! property output string std::string & e_out; - // Graph that we are processing + //! Graph that we are processing const Graph & g; /*! \brief constructor * - * \param v_out string to fill with the vertex properties + * \param e_out string to fill with the edge properties + * \param g graph we are writing * */ prop_out_edge(std::string & e_out, const Graph & g) : @@ -851,7 +882,11 @@ struct prop_out_edge } ; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property index + * + */ template<typename T> void operator()(T& t) const { @@ -883,6 +918,7 @@ struct prop_out_edge template<typename Graph> class VTKWriter<Graph, VTK_GRAPH> { + //! graph we are writing const Graph & g; /*! \brief It get the vertex properties list @@ -947,11 +983,11 @@ class VTKWriter<Graph, VTK_GRAPH> /*! \brief Create the VTK point definition * - * \tparam s_type spatial type of the data * \tparam attr false x,y,z are set to 0 for each vertex * + * \return a string with the point list + * */ - template<bool attr> std::string get_point_list() { //! VTK spatial information @@ -988,11 +1024,9 @@ class VTKWriter<Graph, VTK_GRAPH> /*! \brief Create the VTK vertex definition * - * \tparam s_type spatial type of the data - * \tparam attr false x,y,z are set to 0 for each vertex + * \return a string with the vertex definition * */ - std::string get_vertex_list() { //! vertex node output string @@ -1087,11 +1121,12 @@ public: * \tparam prp_out which properties to output [default = -1 (all)] * * \param file path where to write - * \param name of the graph + * \param graph_name of the graph * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if it write correctly + * */ - template<int prp = -1> bool write(std::string file, std::string graph_name = "Graph", file_type ft = file_type::ASCII) { // Check that the Vertex type define x y and z attributes diff --git a/src/VTKWriter/VTKWriter_graph_util.hpp b/src/VTKWriter/VTKWriter_graph_util.hpp deleted file mode 100644 index 5729045f2b7eb317eecca9e083b8bbfbefa55285..0000000000000000000000000000000000000000 --- a/src/VTKWriter/VTKWriter_graph_util.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * VTKWriter_graph_util.hpp - * - * Created on: Mar 12, 2016 - * Author: i-bird - */ - -#ifndef OPENFPM_IO_SRC_VTKWRITER_VTKWRITER_GRAPH_UTIL_HPP_ -#define OPENFPM_IO_SRC_VTKWRITER_VTKWRITER_GRAPH_UTIL_HPP_ - - - - - -#endif /* OPENFPM_IO_SRC_VTKWRITER_VTKWRITER_GRAPH_UTIL_HPP_ */ diff --git a/src/VTKWriter/VTKWriter_grids.hpp b/src/VTKWriter/VTKWriter_grids.hpp index d08b7ba23c7f4b771d36a3e40619088005bbd5bb..46059296bd512cab4ce3d72bd4458ae231b583dc 100644 --- a/src/VTKWriter/VTKWriter_grids.hpp +++ b/src/VTKWriter/VTKWriter_grids.hpp @@ -63,26 +63,43 @@ struct prop_out_g //! grid that we are processing const openfpm::vector_std< ele_g > & vg; + //! File type + file_type ft; + + //! list of names for the properties + const openfpm::vector<std::string> & prop_names; + /*! \brief constructor * * \param v_out string to fill with the vertex properties * \param vg vector of elements to write + * \param prop_names properties name + * \param ft file type * */ - prop_out_g(std::string & v_out, const openfpm::vector_std< ele_g > & vg) - :v_out(v_out),vg(vg) + prop_out_g(std::string & v_out, const openfpm::vector_std< ele_g > & vg, const openfpm::vector<std::string> & prop_names ,file_type ft) + :v_out(v_out),vg(vg),ft(ft),prop_names(prop_names) {}; - //! It produce an output for each property + /*! It produce an output for each propert + * + * \param t prop-id + * + */ template<typename T> void operator()(T& t) const { typedef typename boost::mpl::at<typename ele_g::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype; typedef typename std::remove_all_extents<ptype>::type base_ptype; - meta_prop<boost::mpl::int_<T::value> ,ele_g,St, ptype, is_vtk_writable<base_ptype>::value > m(vg,v_out,file_type::ASCII); + meta_prop<boost::mpl::int_<T::value> ,ele_g,St, ptype, is_vtk_writable<base_ptype>::value > m(vg,v_out,prop_names,ft); } + /*! \brief Write the last property + * + * + * + */ void lastProp() { // Create point data properties @@ -185,9 +202,13 @@ class VTKWriter<pair,VECTOR_GRIDS> } /*! \brief Create the VTK point definition + * + * \param ft file type + * + * \return the string with the point list * */ - std::string get_point_list() + std::string get_point_list(file_type ft) { //! vertex node output string std::stringstream v_out; @@ -209,10 +230,7 @@ class VTKWriter<pair,VECTOR_GRIDS> p = it.get().toPoint(); p = pmul(p,vg.get(i).spacing) + vg.get(i).offset; - if (pair::first::dims == 2) - v_out << p.toString() << " 0.0" << "\n"; - else - v_out << p.toString() << "\n"; + output_point<pair::first::dims,typename pair::second>(p,v_out,ft); // increment the iterator and counter ++it; @@ -224,9 +242,11 @@ class VTKWriter<pair,VECTOR_GRIDS> } /*! \brief Create the VTK vertex definition + * + * \param ft file type * */ - std::string get_vertex_list() + std::string get_vertex_list(file_type ft) { //! vertex node output string std::string v_out; @@ -240,7 +260,7 @@ class VTKWriter<pair,VECTOR_GRIDS> while (it.isNext()) { - v_out += "1 " + std::to_string(k) + "\n"; + output_vertex(k,v_out,ft); ++k; ++it; @@ -280,10 +300,13 @@ public: * \param g Grid to add * \param offset grid offset * \param spacing spacing of the grid - * \param dom part of the spacethat is the domain + * \param dom part of the space that is the domain * */ - void add(const typename pair::first & g, const Point<pair::first::dims,typename pair::second> & offset, const Point<pair::first::dims,typename pair::second> & spacing, const Box<pair::first::dims,typename pair::second> & dom) + void add(const typename pair::first & g, + const Point<pair::first::dims,typename pair::second> & offset, + const Point<pair::first::dims,typename pair::second> & spacing, + const Box<pair::first::dims,typename pair::second> & dom) { ele_g<typename pair::first,typename pair::second> t(g,offset,spacing,dom); @@ -296,11 +319,16 @@ public: * * \param file path where to write * \param name of the graph + * \param prop_names properties name (can also be a vector of size 0) * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if the function write successfully + * */ - - template<int prp = -1> bool write(std::string file, std::string f_name = "grids" , file_type ft = file_type::ASCII) + template<int prp = -1> bool write(std::string file, + const openfpm::vector<std::string> & prop_names, + std::string f_name = "grids", + file_type ft = file_type::ASCII) { // Header for the vtk std::string vtk_header; @@ -336,20 +364,20 @@ public: point_prop_header = get_point_properties_list(); // Get point list - point_list = get_point_list(); + point_list = get_point_list(ft); // vertex properties header vertex_prop_header = get_vertex_properties_list(); // Get vertex list - vertex_list = get_vertex_list(); + vertex_list = get_vertex_list(ft); // Get the point data header point_data_header = get_point_data_header(); // For each property in the vertex type produce a point data - prop_out_g< ele_g<typename pair::first,typename pair::second>, typename pair::second > pp(point_data, vg); + prop_out_g< ele_g<typename pair::first,typename pair::second>, typename pair::second > pp(point_data, vg, prop_names, ft); if (prp == -1) boost::mpl::for_each< boost::mpl::range_c<int,0, pair::first::value_type::max_prop> >(pp); diff --git a/src/VTKWriter/VTKWriter_grids_util.hpp b/src/VTKWriter/VTKWriter_grids_util.hpp index be13dbbaeb6baf79f1102b0bf7b7fe3b98726518..8d52da2e223ba24fe6f69add91b3f8d1c4b898d3 100644 --- a/src/VTKWriter/VTKWriter_grids_util.hpp +++ b/src/VTKWriter/VTKWriter_grids_util.hpp @@ -12,7 +12,7 @@ #include "is_vtk_writable.hpp" #include "byteswap_portable.hpp" -/*! \brief Return the Attributes name (if they have) +/*! \brief Return the Attributes name from the type * * */ @@ -23,14 +23,22 @@ struct getAttrName * * \param i id of the attribute * \param oprp post-fix to add + * \param prop_names properties name + * + * \return the string with the property name * */ - static inline std::string get(size_t i, const std::string & oprp) + static inline std::string get(size_t i, const openfpm::vector<std::string> & prop_names, const std::string & oprp) { return ele_g::value_type::value_type::attributes::name[i] + oprp; } }; +/*! \brief Return the Attributes name from the type + * + * This is the case when the type has no name + * + */ template<typename ele_g> struct getAttrName<ele_g,false> { @@ -38,11 +46,21 @@ struct getAttrName<ele_g,false> * * \param i id of the attribute * \param oprp post-fix to add + * \param prop_names properties name + * + * \return return the string with the property name * */ - static inline std::string get(size_t i, const std::string & oprp) + static inline std::string get(size_t i, const openfpm::vector<std::string> & prop_names, const std::string & oprp) { - return std::string("attr" + std::to_string(i) + oprp); + if (i >= prop_names.size()) + { + return std::string("attr" + std::to_string(i) + oprp); + } + else + { + return prop_names.get(i) + oprp; + } } }; @@ -52,7 +70,7 @@ struct getAttrName<ele_g,false> * \param oprp prefix * */ -template<unsigned int i, typename ele_g, bool has_attributes> std::string get_point_property_header_impl(const std::string & oprp) +template<unsigned int i, typename ele_g, bool has_attributes> std::string get_point_property_header_impl(const std::string & oprp, const openfpm::vector<std::string> & prop_names) { //! vertex node output string std::string v_out; @@ -76,7 +94,7 @@ template<unsigned int i, typename ele_g, bool has_attributes> std::string get_po } // Create point data properties - v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; } } else @@ -94,16 +112,16 @@ template<unsigned int i, typename ele_g, bool has_attributes> std::string get_po // We check if it is a vector or scalar like type if (vtk_dims<ctype>::value == 1) - v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; else - v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; } return v_out; } // Create point data properties - v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; // Default lookup table v_out += "LOOKUP_TABLE default\n"; @@ -142,16 +160,19 @@ public: } else { + typedef decltype(vg.get(k).g.get_o(it.get()).template get<I::value>().get_vtk(0)) ctype_; + typedef typename std::remove_reference<ctype_>::type ctype; + // Print the properties for (size_t i1 = 0 ; i1 < vtk_dims<T>::value ; i1++) { - auto tmp = vg.get(k).g.get_o(it.get()).template get<I::value>().get_vtk(i1); + typename is_vtk_writable<ctype>::base tmp = vg.get(k).g.get_o(it.get()).template get<I::value>().get_vtk(i1); tmp = swap_endian_lt(tmp); v_out.append((const char *)&tmp,sizeof(tmp)); } if (vtk_dims<T>::value == 2) { - decltype(vg.get(k).g.get_o(it.get()).template get<I::value>().get_vtk(0)) zero = 0.0; + typename is_vtk_writable<ctype>::base zero = 0.0; zero = swap_endian_lt(zero); v_out.append((const char *)&zero,sizeof(zero)); } @@ -168,8 +189,20 @@ class prop_write_out<1,T> { public: + /*! \brief Write the property + * + * \param v_out output string of the property + * \param vg vector of properties + * \param k data-set to output + * \param it iterator with the point to output + * \param ft output type BINARY or ASCII + * + */ template<typename vector, typename iterator, typename I> static void write(std::string & v_out, vector & vg, size_t k, iterator & it, file_type ft) { + typedef decltype(vg.get(k).g.get_o(it.get()).template get<I::value>()) ctype_; + typedef typename std::remove_reference<ctype_>::type ctype; + if (ft == file_type::ASCII) { // Print the property @@ -177,7 +210,7 @@ public: } else { - auto tmp = vg.get(k).g.get_o(it.get()).template get<I::value>(); + typename is_vtk_writable<ctype>::base tmp = vg.get(k).g.get_o(it.get()).template get<I::value>(); tmp = swap_endian_lt(tmp); v_out.append((const char *)&tmp,sizeof(tmp)); } @@ -201,16 +234,17 @@ struct meta_prop * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names property names * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { // actual string size size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>(""); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("",prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -246,16 +280,17 @@ struct meta_prop<I, ele_g,St,T[N1],is_writable> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names properties name * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names , file_type ft) { // actual string size size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>(""); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("",prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -321,10 +356,11 @@ struct meta_prop<I, ele_g,St, T[N1][N2],is_writable> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names property names * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { for (size_t i1 = 0 ; i1 < N1 ; i1++) { @@ -334,7 +370,7 @@ struct meta_prop<I, ele_g,St, T[N1][N2],is_writable> size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("_" + std::to_string(i1) + "_" + std::to_string(i2)); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("_" + std::to_string(i1) + "_" + std::to_string(i2),prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -381,12 +417,50 @@ struct meta_prop<I,ele_g,St,T,false> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names properties name * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { } }; +template<unsigned int dims,typename T> inline void output_point(Point<dims,T> & p,std::stringstream & v_out, file_type ft) +{ + if (ft == file_type::ASCII) + { + if (dims == 2) + v_out << p.toString() << " 0.0" << "\n"; + else + v_out << p.toString() << "\n"; + } + else + { + for (size_t i = 0 ; i < dims ; i++) + { + // we use float so we have to convert to float + float tmp = p.get(i); + tmp = swap_endian_lt(tmp); + v_out.write((const char *)&tmp,sizeof(tmp)); + } + } +} + +inline void output_vertex(size_t k,std::string & v_out, file_type ft) +{ + if (ft == file_type::ASCII) + v_out += "1 " + std::to_string(k) + "\n"; + else + { + int tmp; + tmp = 1; + tmp = swap_endian_lt(tmp); + v_out.append((const char *)&tmp,sizeof(int)); + tmp = k; + tmp = swap_endian_lt(tmp); + v_out.append((const char *)&tmp,sizeof(int)); + } +} + #endif /* SRC_VTKWRITER_GRIDS_UTIL_HPP_ */ diff --git a/src/VTKWriter/VTKWriter_point_set.hpp b/src/VTKWriter/VTKWriter_point_set.hpp index 0c173c95ca008bf800a8b8fbb6d36db5c1c21ee7..50a96f46b0f0ec18e382c8393571e9d007d101cf 100644 --- a/src/VTKWriter/VTKWriter_point_set.hpp +++ b/src/VTKWriter/VTKWriter_point_set.hpp @@ -91,6 +91,9 @@ struct prop_out_v //! vector that we are processing const openfpm::vector_std< ele_v > & vv; + //! properties names + const openfpm::vector<std::string> & prop_names; + /*! \brief constructor * * \param v_out string to fill with the vertex properties @@ -98,18 +101,25 @@ struct prop_out_v * \param ft ASCII or BINARY format * */ - prop_out_v(std::string & v_out, const openfpm::vector_std< ele_v > & vv, file_type ft) - :ft(ft),v_out(v_out),vv(vv) + prop_out_v(std::string & v_out, + const openfpm::vector_std< ele_v > & vv, + const openfpm::vector<std::string> & prop_names, + file_type ft) + :ft(ft),v_out(v_out),vv(vv),prop_names(prop_names) {}; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { typedef typename boost::mpl::at<typename ele_v::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype; typedef typename std::remove_all_extents<ptype>::type base_ptype; - meta_prop<boost::mpl::int_<T::value> ,ele_v,St, ptype, is_vtk_writable<base_ptype>::value > m(vv,v_out,ft); + meta_prop<boost::mpl::int_<T::value> ,ele_v,St, ptype, is_vtk_writable<base_ptype>::value > m(vv,v_out,prop_names,ft); } void lastProp() @@ -258,30 +268,7 @@ class VTKWriter<pair,VECTOR_POINTS> Point<pair::first::value_type::dims,typename pair::first::value_type::coord_type> p; p = vps.get(i).g.get(it.get()); - if (ft == file_type::ASCII) - { - if (pair::first::value_type::dims == 2) - v_out << p.toString() << " 0.0" << "\n"; - else - v_out << p.toString() << "\n"; - } - else - { - for (size_t i = 0 ; i < pair::first::value_type::dims ; i++) - { - // we use float so we have to convert to float - float tmp = p.get(i); - tmp = swap_endian_lt(tmp); - v_out.write((const char *)&tmp,sizeof(tmp)); - } - - if (pair::first::value_type::dims == 2) - { - float tmp = 0.0; - tmp = swap_endian_lt(tmp); - v_out.write((const char *)&tmp,sizeof(tmp)); - } - } + output_point<pair::first::value_type::dims,typename pair::first::value_type::coord_type>(p,v_out,ft); // increment the iterator and counter ++it; @@ -317,18 +304,7 @@ class VTKWriter<pair,VECTOR_POINTS> while (it.isNext()) { - if (ft == file_type::ASCII) - v_out += "1 " + std::to_string(k) + "\n"; - else - { - int tmp; - tmp = 1; - tmp = swap_endian_lt(tmp); - v_out.append((const char *)&tmp,sizeof(int)); - tmp = k; - tmp = swap_endian_lt(tmp); - v_out.append((const char *)&tmp,sizeof(int)); - } + output_vertex(k,v_out,ft); ++k; ++it; @@ -371,11 +347,13 @@ public: * * \param vps vector of positions * \param vpp vector of properties - * \param mark additional information that divide the dataset into 2 - * (in general is used to mark real from ghost information) + * \param mark additional information that divide the dataset into 2 (in general is used to mark real from ghost information) + * \param opt_names optional parameter that indicate the names of the properties * */ - void add(const typename pair::first & vps, const typename pair::second & vpp,size_t mark) + void add(const typename pair::first & vps, + const typename pair::second & vpp, + size_t mark) { ele_vps<typename pair::first> t1(vps,mark); ele_vpp<typename pair::second> t2(vpp,mark); @@ -390,10 +368,16 @@ public: * * \param file path where to write * \param f_name name of the dataset + * \param prop_names properties names * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if the write complete successfully + * */ - template<int prp = -1> bool write(std::string file, std::string f_name = "points" , file_type ft = file_type::ASCII) + template<int prp = -1> bool write(std::string file, + const openfpm::vector<std::string> & prop_names, + std::string f_name = "points" , + file_type ft = file_type::ASCII) { // Header for the vtk std::string vtk_header; @@ -442,7 +426,7 @@ public: // For each property in the vertex type produce a point data - prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, ft); + prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, prop_names,ft); if (prp == -1) boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp); diff --git a/src/VTKWriter/VTKWriter_unit_tests.hpp b/src/VTKWriter/VTKWriter_unit_tests.hpp index 2c798ce8e2ff0cf5ba64c348418e2e73fb3eda50..e73d5400e2682f841443b2121aab1e24cd7aa740 100644 --- a/src/VTKWriter/VTKWriter_unit_tests.hpp +++ b/src/VTKWriter/VTKWriter_unit_tests.hpp @@ -127,6 +127,11 @@ const std::string vertex2::attributes::name[] = {"x","prp1","prp2"}; BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + // Create some graphs and output them // Graph @@ -199,12 +204,17 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D ) // check that match - bool test = compare("vtk_graph_v2.vtk","vtk_graph_v2_test.vtk"); + bool test = compare("vtk_graph_v2.vtk","test_data/vtk_graph_v2_test.vtk"); BOOST_REQUIRE_EQUAL(true,test); } BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D_edge ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + // Create some graphs and output them // Graph @@ -277,7 +287,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D_edge ) // check that match - bool test = compare("vtk_graph_v4.vtk","vtk_graph_v4_test.vtk"); + bool test = compare("vtk_graph_v4.vtk","test_data/vtk_graph_v4_test.vtk"); BOOST_REQUIRE_EQUAL(true,test); } @@ -334,6 +344,11 @@ const std::string vertex3::attributes::name[] = {"x","prp1","prp2"}; BOOST_AUTO_TEST_CASE( vtk_writer_use_graph2D ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + // Create some graphs and output them // Graph @@ -359,12 +374,17 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph2D ) // check that match - bool test = compare("vtk_graph_v3.vtk","vtk_graph_v3_test.vtk"); + bool test = compare("vtk_graph_v3.vtk","test_data/vtk_graph_v3_test.vtk"); BOOST_REQUIRE_EQUAL(true,test); } BOOST_AUTO_TEST_CASE( vtk_writer_use_graph) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + // Create some graphs and output them std::cout << "Graph unit test start" << "\n"; @@ -439,12 +459,17 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph) // check that match - bool test = compare("vtk_graph.vtk","vtk_graph_test.vtk"); + bool test = compare("vtk_graph.vtk","test_data/vtk_graph_test.vtk"); BOOST_REQUIRE_EQUAL(true,test); } BOOST_AUTO_TEST_CASE( vtk_writer_use_vector_box) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + // Create a vector of boxes openfpm::vector<Box<2,float>> vb; @@ -461,7 +486,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_vector_box) vtk_box.write("vtk_box.vtk"); // Check that match - bool test = compare("vtk_box.vtk","vtk_box_test.vtk"); + bool test = compare("vtk_box.vtk","test_data/vtk_box_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); // Create a vector of boxes @@ -480,7 +505,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_vector_box) vtk_box2.write("vtk_box_3D.vtk"); // Check that match - test = compare("vtk_box_3D.vtk","vtk_box_3D_test.vtk"); + test = compare("vtk_box_3D.vtk","test_data/vtk_box_3D_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); // Create a vector of boxes @@ -499,7 +524,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_vector_box) vtk_box3.write("vtk_box_3D_2.vtk"); // Check that match - test = compare("vtk_box_3D_2.vtk","vtk_box_3D_2_test.vtk"); + test = compare("vtk_box_3D_2.vtk","test_data/vtk_box_3D_2_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } @@ -596,6 +621,11 @@ void fill_grid_some_data_scal(grid_cpu<2,Point_test_scal<float>> & g) BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + { // Create box grids Point<2,float> offset1({0.0,0.0}); @@ -638,10 +668,11 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids.vtk",prp_names); // Check that match - bool test = compare("vtk_grids.vtk","vtk_grids_test.vtk"); + bool test = compare("vtk_grids.vtk","test_data/vtk_grids_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } @@ -696,7 +727,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.write("vtk_grids_st.vtk"); // Check that match - bool test = compare("vtk_grids_st.vtk","vtk_grids_st_test.vtk"); + bool test = compare("vtk_grids_st.vtk","test_data/vtk_grids_st_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } @@ -742,10 +773,11 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids_prp.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids_prp.vtk",prp_names); // Check that match - bool test = compare("vtk_grids_prp.vtk","vtk_grids_prp_test.vtk"); + bool test = compare("vtk_grids_prp.vtk","test_data/vtk_grids_prp_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } @@ -791,10 +823,11 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids_unk.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids_unk.vtk",prp_names); // Check that match - bool test = compare("vtk_grids_unk.vtk","vtk_grids_test.vtk"); + bool test = compare("vtk_grids_unk.vtk","test_data/vtk_grids_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } @@ -818,6 +851,11 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + { // Create 3 vectors with random particles openfpm::vector<Point<3,double>> v1ps; @@ -883,10 +921,11 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) vtk_v.add(v2ps,v2pp,88); vtk_v.add(v3ps,v3pp,90); - vtk_v.write("vtk_points.vtk"); + openfpm::vector<std::string> prp_names; + vtk_v.write("vtk_points.vtk",prp_names); // Check that match - bool test = compare("vtk_points.vtk","vtk_points_test.vtk"); + bool test = compare("vtk_points.vtk","test_data/vtk_points_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); @@ -894,18 +933,70 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,Point<3,float>>>>,VECTOR_POINTS> vtk_v2; vtk_v2.add(v1ps,v4pp,75); - vtk_v2.write("vtk_points_pp.vtk"); + vtk_v2.write("vtk_points_pp.vtk",prp_names); // Check that match - test = compare("vtk_points_pp.vtk","vtk_points_pp_test.vtk"); + test = compare("vtk_points_pp.vtk","test_data/vtk_points_pp_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } } +BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_properties ) +{ + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + + { + // Create 3 vectors with random particles + openfpm::vector<Point<3,double>> v1ps; + openfpm::vector<aggregate<float,float[3]>> v1pp; + + // set the seed + // create the random generator engine + SimpleRNG rng; + + // fill the vector with random data + v1ps.resize(100); + v1pp.resize(100); + + for (size_t i = 0 ; i < v1ps.size(); i++) + { + v1ps.template get<0>(i)[0] = rng.GetUniform(); + v1ps.template get<0>(i)[1] = rng.GetUniform(); + v1ps.template get<0>(i)[2] = rng.GetUniform(); + + + v1pp.template get<0>(i) = rng.GetUniform(); + v1pp.template get<1>(i)[0] = rng.GetUniform(); + v1pp.template get<1>(i)[1] = rng.GetUniform(); + v1pp.template get<1>(i)[2] = rng.GetUniform(); + } + + openfpm::vector<std::string> prop_names; + + // Create a writer and write adding names to the properties + VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,float[3]>>>,VECTOR_POINTS> vtk_v; + vtk_v.add(v1ps,v1pp,75); + openfpm::vector<std::string> prp_names({"scalar","vector"}); + vtk_v.write("vtk_points_with_prp_names.vtk",prp_names); + + // Check that match + bool test = compare("vtk_points_with_prp_names.vtk","test_data/vtk_points_with_prp_names_test.vtk"); + BOOST_REQUIRE_EQUAL(test,true); + + } +} BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_binary ) { + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + { // Create 3 vectors with random particles openfpm::vector<Point<3,double>> v1ps; @@ -971,21 +1062,25 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_binary ) vtk_v.add(v2ps,v2pp,88); vtk_v.add(v3ps,v3pp,90); - vtk_v.write("vtk_points_bin.vtk","vtk output",file_type::BINARY); + openfpm::vector<std::string> prp_names; + vtk_v.write("vtk_points_bin.vtk",prp_names,"vtk output",file_type::BINARY); + vtk_v.write("vtk_points_bin2.vtk",prp_names,"vtk output",file_type::BINARY); + // Check that match - bool test = compare("vtk_points_bin.vtk","vtk_points_bin_test.vtk"); + bool test = compare("vtk_points_bin.vtk","test_data/vtk_points_bin_test.vtk"); + BOOST_REQUIRE_EQUAL(test,true); + test = compare("vtk_points_bin2.vtk","test_data/vtk_points_bin_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); - // Create a writer and write VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,Point<3,float>>>>,VECTOR_POINTS> vtk_v2; vtk_v2.add(v1ps,v4pp,75); - vtk_v2.write("vtk_points_pp_bin.vtk","vtk output",file_type::BINARY); + vtk_v2.write("vtk_points_pp_bin.vtk",prp_names,"vtk output",file_type::BINARY); // Check that match - test = compare("vtk_points_pp_bin.vtk","vtk_points_pp_bin_test.vtk"); + test = compare("vtk_points_pp_bin.vtk","test_data/vtk_points_pp_bin_test.vtk"); BOOST_REQUIRE_EQUAL(test,true); } diff --git a/src/VTKWriter/VTKWriter_vector_box.hpp b/src/VTKWriter/VTKWriter_vector_box.hpp index 368c451c7cffa19de92ea98efa5a2acc345c761f..2786f21375bd13cffb1ed6147fb5aaa303759f63 100644 --- a/src/VTKWriter/VTKWriter_vector_box.hpp +++ b/src/VTKWriter/VTKWriter_vector_box.hpp @@ -11,7 +11,7 @@ #include <boost/math/special_functions/pow.hpp> #include "Space/Shape/HyperCube.hpp" #include <random> -#include "util.hpp" +#include "util/util.hpp" template <typename vector> class v_box diff --git a/src/VTKWriter/is_vtk_writable.hpp b/src/VTKWriter/is_vtk_writable.hpp index 44a5b9c6148f38bcc334dcb940f2b29cecbe160b..ec21bfc0dcd70465466ebaa8ce4e112db1111341 100644 --- a/src/VTKWriter/is_vtk_writable.hpp +++ b/src/VTKWriter/is_vtk_writable.hpp @@ -83,6 +83,8 @@ struct is_vtk_vector_dims<ObjType, typename Void< decltype(ObjType::dims) >::typ template<typename T> struct is_vtk_writable { + typedef T base; + //! It check if the object is vtk compatible enum { @@ -94,6 +96,8 @@ struct is_vtk_writable template<> struct is_vtk_writable<float> { + typedef float base; + //! float is vtk writable enum { @@ -105,6 +109,8 @@ struct is_vtk_writable<float> template<> struct is_vtk_writable<double> { + typedef double base; + //! double is vtk writable enum { @@ -116,6 +122,8 @@ struct is_vtk_writable<double> template<> struct is_vtk_writable<char> { + typedef char base; + //! char is vtk writable enum { @@ -127,6 +135,8 @@ struct is_vtk_writable<char> template<> struct is_vtk_writable<unsigned char> { + typedef unsigned char base; + //! unsigned char is vtk writable enum { @@ -138,6 +148,8 @@ struct is_vtk_writable<unsigned char> template<> struct is_vtk_writable<short> { + typedef short base; + //! short is vtk writable enum { @@ -149,6 +161,8 @@ struct is_vtk_writable<short> template<> struct is_vtk_writable<unsigned short> { + typedef unsigned short base; + //! unsigned short is vtk writable enum { @@ -160,6 +174,8 @@ struct is_vtk_writable<unsigned short> template<> struct is_vtk_writable<int> { + typedef int base; + //! int is vtk writable enum { @@ -171,6 +187,8 @@ struct is_vtk_writable<int> template<> struct is_vtk_writable<unsigned int> { + typedef unsigned int base; + //! unsigned int is vtk writable enum { @@ -182,6 +200,8 @@ struct is_vtk_writable<unsigned int> template<> struct is_vtk_writable<long int> { + typedef long base; + //! long int is vtk writable enum { @@ -193,6 +213,8 @@ struct is_vtk_writable<long int> template<> struct is_vtk_writable<unsigned long int> { + typedef unsigned long base; + //! unsigned long int is vtk writable enum { @@ -204,6 +226,8 @@ struct is_vtk_writable<unsigned long int> template<> struct is_vtk_writable<bool> { + typedef bool base; + //! bool is vtk writable enum { diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp b/src/garbage/HDF5_XdmfWriter.hpp similarity index 100% rename from src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp rename to src/garbage/HDF5_XdmfWriter.hpp diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp b/src/garbage/HDF5_XdmfWriter_point_set.hpp similarity index 81% rename from src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp rename to src/garbage/HDF5_XdmfWriter_point_set.hpp index 4d6d5b3dec1ec6b8b073fa5712eb11cafe321227..5be3e3a5cb7554d8f4732ec151f5327c55981953 100644 --- a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp +++ b/src/garbage/HDF5_XdmfWriter_point_set.hpp @@ -27,13 +27,13 @@ template<typename ele_v, bool has_name> struct H5_prop_out { - // HDF5 file + //! HDF5 file hid_t file_id; - // vector that we are processing + //! vector that we are processing ele_v & vv; - // Up to which element to write + //! Up to which element to write size_t stop; /*! \brief constructor @@ -45,7 +45,11 @@ struct H5_prop_out :file_id(file_id),vv(vv),stop(stop) {}; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { @@ -71,25 +75,31 @@ struct H5_prop_out template<typename ele_v> struct H5_prop_out<ele_v,false> { - // HDF5 file + //! HDF5 file hid_t file_id; - // vector that we are processing + //! vector that we are processing ele_v & vv; - // Up to which element to write + //! Up to which element to write size_t stop; /*! \brief constructor * - * \param v_out string to fill with the vertex properties + * \param file_id handle of the file + * \param vv element to write + * \param stop up to which element to write * */ H5_prop_out(hid_t file_id, ele_v & vv, size_t stop) :file_id(file_id),vv(vv),stop(stop) {}; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { @@ -99,6 +109,10 @@ struct H5_prop_out<ele_v,false> } }; +/*! \brief HDF5 writer for a point set + * + * + */ template <> class HDF5_XdmfWriter<H5_POINTSET> { @@ -118,18 +132,23 @@ public: /*! * - * \brief Write a set of particle position and properties into HDF5 + * \brief Write a set of particle positions and properties into HDF5 * * \tparam Pos Vector of positions type * \taparam Prp Vector of properties type * \tparam prp list of properties to output * - * \param pos Vector with the positions - * \param prp Vector with the properties + * \param file output file + * \param v_pos Vector with the positions + * \param v_prp Vector with the properties * \param stop size of the vector to output * */ - template<typename VPos, typename VPrp, int ... prp > bool write(const std::string & file, openfpm::vector<VPos> & v_pos, openfpm::vector<VPrp> & v_prp, size_t stop) + template<typename VPos, typename VPrp, int ... prp > + bool write(const std::string & file, + openfpm::vector<VPos> & v_pos, + openfpm::vector<VPrp> & v_prp, + size_t stop) { Vcluster & v_cl = create_vcluster(); diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp b/src/garbage/HDF5_XdmfWriter_unit_tests.hpp similarity index 100% rename from src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp rename to src/garbage/HDF5_XdmfWriter_unit_tests.hpp diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp b/src/garbage/HDF5_XdmfWriter_util.hpp similarity index 100% rename from src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp rename to src/garbage/HDF5_XdmfWriter_util.hpp diff --git a/src/main.cpp b/src/main.cpp index 12dbfcdf249309083e41306d5c09239367572c0d..795d036046b93972c66a76dac173ac6eed465481 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,13 +5,17 @@ #define BOOST_DISABLE_ASSERTS - #define BOOST_TEST_MODULE "C++ test module for OpenFPM_io project" #include <boost/test/included/unit_test.hpp> +#include "VCluster/VCluster.hpp" +#include "unit_test_init_cleanup_io.hpp" + #include "VCluster/VCluster.hpp" #include "CSVWriter/CSVWriter_unit_tests.hpp" #include "GraphMLWriter/GraphMLWriter_unit_tests.hpp" #include "VTKWriter/VTKWriter_unit_tests.hpp" //#include "HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp" #include "Plot/Plot_unit_tests.hpp" +#include "RawReader/RawReader_unit_tests.hpp" +#include "HDF5_wr/HDF5_writer_unit_tests.hpp" diff --git a/src/unit_test_init_cleanup_io.hpp b/src/unit_test_init_cleanup_io.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c4fbc1b3d5c133d6b96579c5fbac529947f52115 --- /dev/null +++ b/src/unit_test_init_cleanup_io.hpp @@ -0,0 +1,34 @@ +/* + * unit_test_init_cleanup.hpp + * + * Created on: May 1, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_UNIT_TEST_INIT_CLEANUP_IO_HPP_ +#define OPENFPM_IO_SRC_UNIT_TEST_INIT_CLEANUP_IO_HPP_ + + +struct ut_start +{ + //! + ut_start() + { + BOOST_TEST_MESSAGE("Initialize global VCluster"); + + openfpm_init(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv); + } + + ~ut_start() + { + BOOST_TEST_MESSAGE("Delete global VClster"); + openfpm_finalize(); + } +}; + +//____________________________________________________________________________// + +BOOST_GLOBAL_FIXTURE( ut_start ); + + +#endif /* OPENFPM_IO_SRC_UNIT_TEST_INIT_CLEANUP_IO_HPP_ */ diff --git a/src/util/GBoxes.hpp b/src/util/GBoxes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b63033b3f636e81eef8522661dabca1daf7b94a0 --- /dev/null +++ b/src/util/GBoxes.hpp @@ -0,0 +1,50 @@ +/* + * Gboxes.hpp + * + * Created on: May 2, 2017 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_UTIL_GBOXES_HPP_ +#define OPENFPM_IO_SRC_UTIL_GBOXES_HPP_ + + +/*! \brief This structure store the Box that define the domain inside the Ghost + domain box + * + \verbatim + + (Ghost + Domain) + +------------------+ + | | + | +------------+ <---------- (Domain) + | | | | + | | Domain | | + | | Box | | + | | | | + | | | | + | +------------+ | + | | + +------------------+ +(0,0) local coordinate ---> ( x, y ) + + \endverbatim + + * + * * Domain + * + * \tparam dim dimensionality + * + */ +template<unsigned int dim> +struct GBoxes +{ + //! Ghost + Domain ghost + Box<dim,long int> GDbox; + //! Domain box + Box<dim,long int> Dbox; + //! origin of GDbox in global grid coordinates + Point<dim,long int> origin; +}; + + +#endif /* OPENFPM_IO_SRC_UTIL_GBOXES_HPP_ */ diff --git a/src/util.hpp b/src/util/util.hpp similarity index 100% rename from src/util.hpp rename to src/util/util.hpp diff --git a/csv_out_test.csv b/test_data/csv_out_test.csv similarity index 100% rename from csv_out_test.csv rename to test_data/csv_out_test.csv diff --git a/csv_out_unk_test.csv b/test_data/csv_out_unk_test.csv similarity index 100% rename from csv_out_unk_test.csv rename to test_data/csv_out_unk_test.csv diff --git a/test_data/gc_out_sc_test.html b/test_data/gc_out_sc_test.html new file mode 100644 index 0000000000000000000000000000000000000000..c704abb8a4653bbb95e732b3eed2d6ba78eb67ba --- /dev/null +++ b/test_data/gc_out_sc_test.html @@ -0,0 +1,65 @@ +<html> + <head> + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> + <script type="text/javascript"> + google.charts.load('current', {'packages':['corechart']}); + google.charts.setOnLoadCallback(drawVisualization); + +function exportToSVG(i) +{ +var e = document.getElementById('chart_div'+i); +var svg = e.getElementsByTagName('svg')[0].parentNode.innerHTML; +var pos = svg.lastIndexOf("</svg>"); +pos += 6; +svg = svg.substring(0,4) + " xmlns='http://www.w3.org/2000/svg' xmlns:xlink= 'http://www.w3.org/1999/xlink' " + svg.substring(4,pos); +svgData = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg); +$(this).attr({'href': svgData,'target': '_blank'}); +} + + function drawVisualization() { +var data0 = new google.visualization.DataTable(); +data0.addColumn('string','X Axis'); +data0.addColumn('number','dataset1'); +data0.addColumn('number','dataset2'); +data0.addColumn('number','dataset3'); +data0.addColumn('number','dataset4'); +data0.addRows([ +['colum1',2,3,5,6], +['colum2',5,6,1,6], +['colum3',2,1,6,9], +['colum4',1,6,3,2], +['colum5',3,3,0,6], +['colum6',2,1,4,6], +]); +var options0= { +title : 'Example', +vAxis: {title: 'Y Axis'}, +hAxis: {title: 'X Axis'}, +seriesType: 'bars', +series: {3: {type: 'line'}}}; +var view0 = new google.visualization.DataView(data0); +view0.setColumns([0 +,1,{ calc: "stringify", +sourceColumn: 1, +type: "string", +role: "annotation" } +,2,{ calc: "stringify", +sourceColumn: 2, +type: "string", +role: "annotation" } +,3,{ calc: "stringify", +sourceColumn: 3, +type: "string", +role: "annotation" } +] +); +$("#export_svg0").on("click", function (event) {exportToSVG.apply(this,[0]);}); +var chart = new google.visualization.ComboChart(document.getElementById('chart_div0')); +chart.draw(view0, options0); +}</script> +</head> +<body> +<a href="#" download="graph1.svg" id="export_svg0"><button>Export data into svg</button></a><div id="chart_div0" style="width: 900px; height: 500px;"></div> +</body> +</html> diff --git a/test_data/raw_read_sv_test.bin b/test_data/raw_read_sv_test.bin new file mode 100644 index 0000000000000000000000000000000000000000..72ebe08fa554496f4257363ad24236f3b7237b2c Binary files /dev/null and b/test_data/raw_read_sv_test.bin differ diff --git a/test_graph2_test.graphml b/test_data/test_graph2_test.graphml similarity index 100% rename from test_graph2_test.graphml rename to test_data/test_graph2_test.graphml diff --git a/test_graph_test.graphml b/test_data/test_graph_test.graphml similarity index 100% rename from test_graph_test.graphml rename to test_data/test_graph_test.graphml diff --git a/test_data/vector_dist_24.h5 b/test_data/vector_dist_24.h5 new file mode 100644 index 0000000000000000000000000000000000000000..016650d4a39d830e6cb8b2c8579588cab0bc85ae Binary files /dev/null and b/test_data/vector_dist_24.h5 differ diff --git a/vtk_box_3D_2_test.vtk b/test_data/vtk_box_3D_2_test.vtk similarity index 100% rename from vtk_box_3D_2_test.vtk rename to test_data/vtk_box_3D_2_test.vtk diff --git a/vtk_box_3D_test.vtk b/test_data/vtk_box_3D_test.vtk similarity index 100% rename from vtk_box_3D_test.vtk rename to test_data/vtk_box_3D_test.vtk diff --git a/vtk_box_test.vtk b/test_data/vtk_box_test.vtk similarity index 100% rename from vtk_box_test.vtk rename to test_data/vtk_box_test.vtk diff --git a/vtk_graph_test.vtk b/test_data/vtk_graph_test.vtk similarity index 100% rename from vtk_graph_test.vtk rename to test_data/vtk_graph_test.vtk diff --git a/vtk_graph_v2_test.vtk b/test_data/vtk_graph_v2_test.vtk similarity index 100% rename from vtk_graph_v2_test.vtk rename to test_data/vtk_graph_v2_test.vtk diff --git a/vtk_graph_v3_test.vtk b/test_data/vtk_graph_v3_test.vtk similarity index 100% rename from vtk_graph_v3_test.vtk rename to test_data/vtk_graph_v3_test.vtk diff --git a/vtk_graph_v4_test.vtk b/test_data/vtk_graph_v4_test.vtk similarity index 100% rename from vtk_graph_v4_test.vtk rename to test_data/vtk_graph_v4_test.vtk diff --git a/vtk_grids_prp_test.vtk b/test_data/vtk_grids_prp_test.vtk similarity index 100% rename from vtk_grids_prp_test.vtk rename to test_data/vtk_grids_prp_test.vtk diff --git a/vtk_grids_st_test.vtk b/test_data/vtk_grids_st_test.vtk similarity index 100% rename from vtk_grids_st_test.vtk rename to test_data/vtk_grids_st_test.vtk diff --git a/vtk_grids_test.vtk b/test_data/vtk_grids_test.vtk similarity index 100% rename from vtk_grids_test.vtk rename to test_data/vtk_grids_test.vtk diff --git a/vtk_points_bin_test.vtk b/test_data/vtk_points_bin_test.vtk similarity index 100% rename from vtk_points_bin_test.vtk rename to test_data/vtk_points_bin_test.vtk diff --git a/vtk_points_pp_bin_test.vtk b/test_data/vtk_points_pp_bin_test.vtk similarity index 100% rename from vtk_points_pp_bin_test.vtk rename to test_data/vtk_points_pp_bin_test.vtk diff --git a/vtk_points_pp_test.vtk b/test_data/vtk_points_pp_test.vtk similarity index 100% rename from vtk_points_pp_test.vtk rename to test_data/vtk_points_pp_test.vtk diff --git a/vtk_points_test.vtk b/test_data/vtk_points_test.vtk similarity index 100% rename from vtk_points_test.vtk rename to test_data/vtk_points_test.vtk