3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-25 13:53:40 +01:00

hdf5 : clean up

- For users : only change is :
   H5::H5File in apps. to be replaced by triqs::h5::file, same API.

- using only the C API because :
   - it is cleaner, better documented, more examples.
   - it is the native hdf5 interface.
   - simplify the installation e.g. on mac. Indeed, hdf5 is
     usually installed without C++ interface, which is optional.
     E.g. EPD et al., brew by default.
     Also the infamous mpi+ hdf5_cpp bug, for which we have no clean solution.

- clean the notion of parent of a group. Not needed, better iterate function in C LT API.
- modified doc : no need for C++ bindings any more.
- modified cmake to avoid requiring CPP bindings.
This commit is contained in:
Olivier Parcollet 2014-06-08 21:47:32 +02:00
parent 36a60ce529
commit 4af1afbdaf
55 changed files with 904 additions and 753 deletions

View File

@ -230,9 +230,9 @@ link_libraries(${TRIQS_LIBRARY_LAPACK})
message( STATUS "-------- HDF5 detection -------------") message( STATUS "-------- HDF5 detection -------------")
# on weiss, it is 2.8.2 and we should not put HL, on 12.04 we need to put it... # on weiss, it is 2.8.2 and we should not put HL, on 12.04 we need to put it...
if ( ${CMAKE_VERSION} VERSION_LESS "2.8.6") # CHECK THIS BOUND, where are the cmake changelogs ?? if ( ${CMAKE_VERSION} VERSION_LESS "2.8.6") # CHECK THIS BOUND, where are the cmake changelogs ??
find_package(HDF5 REQUIRED C CXX ) find_package(HDF5 REQUIRED C )
else(${CMAKE_VERSION} VERSION_LESS "2.8.6") else(${CMAKE_VERSION} VERSION_LESS "2.8.6")
find_package(HDF5 REQUIRED C CXX HL ) find_package(HDF5 REQUIRED C HL)
endif(${CMAKE_VERSION} VERSION_LESS "2.8.6") endif(${CMAKE_VERSION} VERSION_LESS "2.8.6")
if(NOT HDF5_FOUND) if(NOT HDF5_FOUND)
message(FATAL_ERROR "Require hdf5 1.8.2 or higher. Set HDF5_HOME") message(FATAL_ERROR "Require hdf5 1.8.2 or higher. Set HDF5_HOME")
@ -244,7 +244,7 @@ message( STATUS " HDF5_LIBRARIES = ${HDF5_LIBRARIES} ")
mark_as_advanced(HDF5_DIR) # defined somewhere else ? what is it ? mark_as_advanced(HDF5_DIR) # defined somewhere else ? what is it ?
include_directories (SYSTEM ${HDF5_INCLUDE_DIR}) include_directories (SYSTEM ${HDF5_INCLUDE_DIR})
link_libraries (${HDF5_LIBRARIES} ) #${HDF5_CXX_LIBRARIES} ) link_libraries (${HDF5_LIBRARIES})
set(TRIQS_LIBRARY_HDF5 ${HDF5_LIBRARIES}) set(TRIQS_LIBRARY_HDF5 ${HDF5_LIBRARIES})
set(TRIQS_INCLUDE_HDF5 ${HDF5_INCLUDE_DIR}) set(TRIQS_INCLUDE_HDF5 ${HDF5_INCLUDE_DIR})
set(TRIQS_CXX_DEFINITIONS ${TRIQS_CXX_DEFINITIONS} ${HDF5_DEFINITIONS}) set(TRIQS_CXX_DEFINITIONS ${TRIQS_CXX_DEFINITIONS} ${HDF5_DEFINITIONS})

View File

@ -29,7 +29,7 @@ in the way scientific librairies are installed.
(e.g. currently the default version of mpi and hdf5 installed by brew are in conflict : (e.g. currently the default version of mpi and hdf5 installed by brew are in conflict :
the simple mpi "Hello World" crashes when linked with hdf5_cpp). the simple mpi "Hello World" crashes when linked with hdf5_cpp).
Moreover, because there is no notion of "distribution" (except in Enthought, which unfortunately is incomplete), Moreover, because there is no notion of "distribution"
the versions of the libraries are always changing e.g. in brew. the versions of the libraries are always changing e.g. in brew.
As a result, the installation instructions may work on one day, and suddenly stop to work As a result, the installation instructions may work on one day, and suddenly stop to work
the day after. the day after.
@ -58,15 +58,14 @@ on 10.8 and 10.9, (at least on the Mac of one of the developer !).
brew tap homebrew/science brew tap homebrew/science
brew install cmake brew install cmake
brew install gfortran brew install gfortran
brew install --enable-cxx hdf5 brew install hdf5
brew install gsl brew install gsl
brew install fftw brew install fftw
brew install open-mpi brew install open-mpi
brew install zmq brew install zmq
brew install python brew install python
#brew formula has been repaired, since boost installation of mpi.python is a complete mess #brew formula has been repaired
#which needs to be fixed manually (except in Debian/Ubuntu where it is correct).
### brew install boost --without-single --with-mpi --with-c++11 ### brew install boost --without-single --with-mpi --with-c++11
brew install http://ipht.cea.fr/triqs/formulas/boost.rb --without-single --with-mpi --with-c++11 -v brew install http://ipht.cea.fr/triqs/formulas/boost.rb --without-single --with-mpi --with-c++11 -v
@ -77,7 +76,6 @@ on 10.8 and 10.9, (at least on the Mac of one of the developer !).
pip install scipy pip install scipy
pip install mpi4py pip install mpi4py
pip install matplotlib pip install matplotlib
pip install breathe
pip install sphinxcontrib-doxylink pip install sphinxcontrib-doxylink
pip install tornado pip install tornado
pip install pyzmq pip install pyzmq
@ -91,17 +89,8 @@ on 10.8 and 10.9, (at least on the Mac of one of the developer !).
easy_install pyparsing==1.5.7 easy_install pyparsing==1.5.7
git clone https://github.com/mathjax/MathJax.git MathJax git clone https://github.com/mathjax/MathJax.git MathJax
NB : you need pyparsing <=1.5.7 since apparently v.2.0 works only for python 3. NB : you need pyparsing <=1.5.7 since apparently v.2.0 works only for python 3. (? still true ?)
7. If you wish to build the documentation locally,
configure TRIQS with the option -DPython_use_mpi4py=ON (workaround boost.mpi.python bug).
8. **Set up** the environment variable, e.g. in your ~/.bash_profile (workaround for issue #43) ::
export HDF5_DEBUG="all"
or your code will crash when launched without mpirun
(due to a bug in hdf5 C++/ openmpi, nothing to do with TRIQS, so we can not fix it).
Possible issues Possible issues
--------------- ---------------

View File

@ -51,9 +51,9 @@ Libraries
+------------------------+----------+------------------------------------------------------------------------+ +------------------------+----------+------------------------------------------------------------------------+
| boost | >= 1.49 | C++ librairies | | boost | >= 1.49 | C++ librairies |
+------------------------+----------+------------------------------------------------------------------------+ +------------------------+----------+------------------------------------------------------------------------+
| hdf5 | >= 1.8.0 | File storage system. Important: the *serial* version must be installed | | hdf5 | >= 1.8.2 | File storage system. Important: the *serial* version must be installed |
+------------------------+----------+------------------------------------------------------------------------+ +------------------------+----------+------------------------------------------------------------------------+
| python | >= 2.6.5 | The Python interpreter | | python | >= 2.7 | The Python interpreter |
+------------------------+----------+------------------------------------------------------------------------+ +------------------------+----------+------------------------------------------------------------------------+
| scipy | >= ? | Python mathematical library | | scipy | >= ? | Python mathematical library |
+------------------------+----------+------------------------------------------------------------------------+ +------------------------+----------+------------------------------------------------------------------------+

View File

@ -6,7 +6,7 @@ int main() {
array<double, 2> A(2, 2); array<double, 2> A(2, 2);
A() = 3; // declare and init A() = 3; // declare and init
H5::H5File file("store_A.h5", H5F_ACC_TRUNC); // open the file triqs::h5::file file("store_A.h5", H5F_ACC_TRUNC); // open the file
h5_write(file, "A", A); // write the array as 'A' into the file h5_write(file, "A", A); // write the array as 'A' into the file
// array<double,2> B; // read the file into B // array<double,2> B; // read the file into B

View File

@ -25,7 +25,7 @@ int main() {
for (auto &g : Bg1) g = g * i++; for (auto &g : Bg1) g = g * i++;
// a little save in an hdf5 file ? // a little save in an hdf5 file ?
H5::H5File file("test_block_gf.h5", H5F_ACC_TRUNC); triqs::h5::file file("test_block_gf.h5", H5F_ACC_TRUNC);
h5_write(file, "B3", Bg3); h5_write(file, "B3", Bg3);
} }

View File

@ -24,7 +24,7 @@ int main() {
auto gt = g_t_tau_t{{{tmin, tmax, n_re_time}, {beta, Fermion, n_im_time}}, {2, 2, 2}}; auto gt = g_t_tau_t{{{tmin, tmax, n_re_time}, {beta, Fermion, n_im_time}}, {2, 2, 2}};
// a little save in an hdf5 file ? // a little save in an hdf5 file ?
H5::H5File file("test_product_gf.h5", H5F_ACC_TRUNC); triqs::h5::file file("test_product_gf.h5", H5F_ACC_TRUNC);
h5_write(file, "g", g); h5_write(file, "g", g);
} }

View File

@ -5,7 +5,7 @@ int main() {
array<double, 2> A(2, 2); array<double, 2> A(2, 2);
A() = 3; // declare and init A() = 3; // declare and init
H5::H5File file("store_A.h5", H5F_ACC_TRUNC); // open the file triqs::h5::file file("store_A.h5", H5F_ACC_TRUNC); // open the file
h5_write(file, "A", A); // write the array as 'A' into the file h5_write(file, "A", A); // write the array as 'A' into the file
array<double, 2> B; // read the file into B array<double, 2> B; // read the file into B

View File

@ -10,7 +10,7 @@ block_gf_view<imfreq> make_bgf(double a) {
auto B1 = make_block_gf<imfreq>(3, G1); auto B1 = make_block_gf<imfreq>(3, G1);
{ {
H5::H5File file("ess_test_g1.h5", H5F_ACC_TRUNC); h5::file file("ess_test_g1.h5", H5F_ACC_TRUNC);
h5_write(file, "g", B1); h5_write(file, "g", B1);
} }
@ -20,7 +20,7 @@ block_gf_view<imfreq> make_bgf(double a) {
void pass_bgf(block_gf_view<imfreq> g) { void pass_bgf(block_gf_view<imfreq> g) {
{ {
H5::H5File file("ess_test_g2.h5", H5F_ACC_TRUNC); h5::file file("ess_test_g2.h5", H5F_ACC_TRUNC);
h5_write(file, "g", g); h5_write(file, "g", g);
} }
} }
@ -31,7 +31,7 @@ gf_view<imfreq,scalar_valued> make_sgf(double a) {
double beta = 1; double beta = 1;
auto G1 = gf<imfreq, scalar_valued>({beta, Fermion}); auto G1 = gf<imfreq, scalar_valued>({beta, Fermion});
{ {
H5::H5File file("ess_test_g3a.h5", H5F_ACC_TRUNC); h5::file file("ess_test_g3a.h5", H5F_ACC_TRUNC);
h5_write(file, "g", G1); h5_write(file, "g", G1);
} }
return G1; return G1;
@ -40,7 +40,7 @@ gf_view<imfreq,scalar_valued> make_sgf(double a) {
void pass_sgf(gf_view<imfreq,scalar_valued> g) { void pass_sgf(gf_view<imfreq,scalar_valued> g) {
{ {
H5::H5File file("ess_test_g3b.h5", H5F_ACC_TRUNC); h5::file file("ess_test_g3b.h5", H5F_ACC_TRUNC);
h5_write(file, "g", g); h5_write(file, "g", g);
} }
} }

View File

@ -31,7 +31,7 @@ using namespace triqs;
template < class T> template < class T>
void test(std::string filename, T init) { void test(std::string filename, T init) {
H5::H5File file( filename.c_str(), H5F_ACC_TRUNC ); h5::file file( filename.c_str(), H5F_ACC_TRUNC );
h5::group top (file); h5::group top (file);
const size_t N = 12, bufsize = 5, d= 2; const size_t N = 12, bufsize = 5, d= 2;
@ -75,7 +75,7 @@ void test(std::string filename, T init) {
// now we read the file and compare // now we read the file and compare
H5::H5File file2( filename.c_str() ,H5F_ACC_RDONLY ); h5::file file2( filename.c_str() ,H5F_ACC_RDONLY );
h5::group top2(file2); h5::group top2(file2);
h5_read (top2, "A",A_stack_compare); h5_read (top2, "A",A_stack_compare);

View File

@ -40,7 +40,7 @@ int main(int argc, char **argv) {
V1.push_back("de"); V1.push_back("de");
// writing // writing
H5::H5File file( "test_array_string.h5", H5F_ACC_TRUNC ); h5::file file( "test_array_string.h5", H5F_ACC_TRUNC );
h5::group top(file); h5::group top(file);
h5_write(top,"A",A); h5_write(top,"A",A);

View File

@ -40,13 +40,13 @@ int main(int argc, char **argv) {
std::vector <std::complex<double>> vc2; std::vector <std::complex<double>> vc2;
{ {
H5::H5File file1( "test_std_vector.h5", H5F_ACC_TRUNC ); h5::file file1( "test_std_vector.h5", H5F_ACC_TRUNC );
h5::group top(file1); h5::group top(file1);
h5_write(top,"vdouble",v); h5_write(top,"vdouble",v);
h5_write(top,"vcomplex",vc); h5_write(top,"vcomplex",vc);
} }
H5::H5File file2( "test_std_vector.h5", H5F_ACC_RDONLY ); h5::file file2( "test_std_vector.h5", H5F_ACC_RDONLY );
h5::group top2(file2); h5::group top2(file2);
h5_read(top2,"vdouble",v2); h5_read(top2,"vdouble",v2);

View File

@ -66,14 +66,13 @@ int main(int argc, char **argv) {
std::cout<<" C= "<<C<<std::endl; std::cout<<" C= "<<C<<std::endl;
std::cout<<" Arange(0,1),range(1,3) = "<< A(range(),range(1,3))<<std::endl; std::cout<<" Arange(0,1),range(1,3) = "<< A(range(),range(1,3))<<std::endl;
H5::H5File file( "ess.h5", H5F_ACC_TRUNC ); h5::file file( "ess.h5", H5F_ACC_TRUNC );
h5::group top(file); h5::group top(file);
h5_write(top,"A",A); h5_write(top,"A",A);
h5_write(top,"Af",Af); h5_write(top,"Af",Af);
h5_write(top,"C",C); h5_write(top,"C",C);
h5_write(top,"D",D); h5_write(top,"D",D);
h5_write(top,"S",""); h5_write(top,"S","");
// testing scalar // testing scalar
@ -101,6 +100,7 @@ int main(int argc, char **argv) {
//tqa::array<long,1> E; h5_read (top, "A",E); std::cout<< "E = "<< E<<std::endl; //tqa::array<long,1> E; h5_read (top, "A",E); std::cout<< "E = "<< E<<std::endl;
} }
catch(std::exception const& err) { std::cout<<err.what()<<std::endl;}
catch( const char * err) { std::cout<<err<<std::endl;} catch( const char * err) { std::cout<<err<<std::endl;}
return 0; return 0;

View File

@ -1,6 +1,7 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl;
namespace h5 = triqs::h5;
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::arrays; using namespace triqs::arrays;
@ -21,17 +22,17 @@ int main(int argc, char* argv[]) {
bb = aa; bb = aa;
{ {
H5::H5File file("ess_array_gf.h5", H5F_ACC_TRUNC); h5::file file("ess_array_gf.h5", H5F_ACC_TRUNC);
h5_write(file, "Agf", agf); h5_write(file, "Agf", agf);
h5_write(file, "aa", aa); h5_write(file, "aa", aa);
} }
{ {
H5::H5File file("ess_array_gf.h5", H5F_ACC_RDONLY); h5::file file("ess_array_gf.h5", H5F_ACC_RDONLY);
h5_read(file, "Agf", bgf); h5_read(file, "Agf", bgf);
h5_read(file, "aa", bb); h5_read(file, "aa", bb);
} }
{ {
H5::H5File file("ess_array_gf2.h5", H5F_ACC_TRUNC); h5::file file("ess_array_gf2.h5", H5F_ACC_TRUNC);
h5_write(file, "Agf", bgf); h5_write(file, "Agf", bgf);
h5_write(file, "aa", bb); h5_write(file, "aa", bb);
} }

View File

@ -21,12 +21,12 @@ int main() {
// test hdf5 // test hdf5
{ {
H5::H5File file("ess_gf.h5", H5F_ACC_TRUNC); h5::file file("ess_gf.h5", H5F_ACC_TRUNC);
h5_write(file, "B3", B3); h5_write(file, "B3", B3);
} }
{ {
H5::H5File file("ess_gf.h5", H5F_ACC_RDONLY); h5::file file("ess_gf.h5", H5F_ACC_RDONLY);
std::cout << "B4 mesh" << B4.mesh().size() << std::endl; std::cout << "B4 mesh" << B4.mesh().size() << std::endl;
h5_read(file, "B3", B4); h5_read(file, "B3", B4);
std::cout << "B4 mesh" << B4.mesh().size() << std::endl; std::cout << "B4 mesh" << B4.mesh().size() << std::endl;

View File

@ -5,6 +5,7 @@
namespace tql= triqs::clef; namespace tql= triqs::clef;
using namespace triqs::gfs; using namespace triqs::gfs;
namespace h5 = triqs::h5;
int main() { int main() {
@ -84,7 +85,7 @@ try {
std::cout << " curry "<<G_w_wn_curry1[3][8] << std::endl; std::cout << " curry "<<G_w_wn_curry1[3][8] << std::endl;
std::cout << "G_w_wn_sl0_a [3]"<<G_w_wn_sl0_a[3] << std::endl ; std::cout << "G_w_wn_sl0_a [3]"<<G_w_wn_sl0_a[3] << std::endl ;
// test hdf5 // test hdf5
H5::H5File file("gf_re_im_freq_time.h5", H5F_ACC_TRUNC ); h5::file file("gf_re_im_freq_time.h5", H5F_ACC_TRUNC );
h5_write(file, "g_t_tau", G_t_tau); h5_write(file, "g_t_tau", G_t_tau);
h5_write(file, "g_w_wn", G_w_wn); h5_write(file, "g_w_wn", G_w_wn);
h5_write(file, "g_w_tau", G_w_tau); h5_write(file, "g_w_tau", G_w_tau);

View File

@ -9,6 +9,7 @@
#include <triqs/arrays.hpp> #include <triqs/arrays.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
namespace h5 = triqs::h5;
int main() { int main() {

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
#include <triqs/gfs/bz.hpp> #include <triqs/gfs/bz.hpp>
namespace h5 = triqs::h5;
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::clef; using namespace triqs::clef;
using namespace triqs::arrays; using namespace triqs::arrays;
@ -27,7 +28,7 @@ int main() {
G(k_, w_) << 1 / (w_ - eps(k_) - 1 / (w_ + 2)); G(k_, w_) << 1 / (w_ - eps(k_) - 1 / (w_ + 2));
// hdf5 // hdf5
H5::H5File file("ess_g_k_om.h5", H5F_ACC_TRUNC ); h5::file file("ess_g_k_om.h5", H5F_ACC_TRUNC );
h5_write(file, "g", G); h5_write(file, "g", G);

View File

@ -66,7 +66,7 @@ int main() {
//TEST(G_k_tau[{0,0}]); //TEST(G_k_tau[{0,0}]);
// hdf5 // hdf5
//H5::H5File file("ess_g_k_om.h5", H5F_ACC_TRUNC ); //h5::file file("ess_g_k_om.h5", H5F_ACC_TRUNC );
//h5_write(file, "g", G); //h5_write(file, "g", G);

View File

@ -2,6 +2,8 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::arrays; using namespace triqs::arrays;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl;
#include <triqs/gfs/local/functions.hpp> #include <triqs/gfs/local/functions.hpp>
@ -26,7 +28,7 @@ int main() {
vt(tau_) << exp(-a * tau_) / (1 + exp(-beta * a)); vt(tau_) << exp(-a * tau_) / (1 + exp(-beta * a));
// test hdf5 // test hdf5
H5::H5File file("ess_g_notail.h5", H5F_ACC_TRUNC); h5::file file("ess_g_notail.h5", H5F_ACC_TRUNC);
h5_write(file, "g", vt); h5_write(file, "g", vt);
// rebuilding a new gf... // rebuilding a new gf...

View File

@ -23,7 +23,7 @@ int main() {
TEST(n_pos_only); TEST(n_pos_only);
// test hdf5 // test hdf5
//H5::H5File file("gf_scalar.h5", H5F_ACC_TRUNC); //h5::file file("gf_scalar.h5", H5F_ACC_TRUNC);
//h5_write(file, "g", G); //h5_write(file, "g", G);
//h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G)); //h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G));

View File

@ -1,6 +1,7 @@
#define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK #define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
namespace h5 = triqs::h5;
using namespace triqs::arrays; using namespace triqs::arrays;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
double precision=10e-12; double precision=10e-12;
@ -61,7 +62,7 @@ int main() {
if ( std::abs(Git2.on_mesh(N/3)-Git2[N/3]) > precision) TRIQS_RUNTIME_ERROR<< "error in on_mesh()\n"; if ( std::abs(Git2.on_mesh(N/3)-Git2[N/3]) > precision) TRIQS_RUNTIME_ERROR<< "error in on_mesh()\n";
// test hdf5 // test hdf5
H5::H5File file("ess_gfre.h5", H5F_ACC_TRUNC ); h5::file file("ess_gfre.h5", H5F_ACC_TRUNC );
h5_write(file, "gt", Gt); h5_write(file, "gt", Gt);
h5_write(file, "gw", Gw); h5_write(file, "gw", Gw);
h5_write(file, "git", Git); h5_write(file, "git", Git);

View File

@ -2,6 +2,8 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
#include <triqs/gfs/local/functions.hpp> #include <triqs/gfs/local/functions.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
int main() { int main() {
@ -17,7 +19,7 @@ int main() {
TEST(n); TEST(n);
// test hdf5 // test hdf5
H5::H5File file("gf_scalar.h5", H5F_ACC_TRUNC); h5::file file("gf_scalar.h5", H5F_ACC_TRUNC);
h5_write(file, "g", G); h5_write(file, "g", G);
h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G)); h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G));

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::arrays; using namespace triqs::arrays;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
#include <triqs/gfs/local/functions.hpp> #include <triqs/gfs/local/functions.hpp>
@ -118,7 +119,7 @@ int main() {
//auto x = local::impl::gf_impl<triqs::gfs::meshes::imfreq, true>::wrap_infty (G.tail_view()) + 2.0; //auto x = local::impl::gf_impl<triqs::gfs::meshes::imfreq, true>::wrap_infty (G.tail_view()) + 2.0;
// test hdf5 // test hdf5
H5::H5File file("ess_gf.h5", H5F_ACC_TRUNC ); h5::file file("ess_gf.h5", H5F_ACC_TRUNC );
h5_write(file, "g", G); h5_write(file, "g", G);
// //

View File

@ -2,13 +2,14 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::arrays; using namespace triqs::arrays;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
#include <triqs/gfs/local/fourier_matsubara.hpp> #include <triqs/gfs/local/fourier_matsubara.hpp>
int main() { int main() {
double precision=10e-9; double precision=10e-9;
H5::H5File file("test_fourier_matsubara.h5",H5F_ACC_TRUNC); h5::file file("test_fourier_matsubara.h5",H5F_ACC_TRUNC);
triqs::clef::placeholder<0> om_; triqs::clef::placeholder<0> om_;
double beta =1; double beta =1;
int N=10000; int N=10000;

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
using namespace triqs::arrays; using namespace triqs::arrays;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
#include <triqs/gfs/local/fourier_real.hpp> #include <triqs/gfs/local/fourier_real.hpp>
@ -18,7 +19,7 @@ double theta(double x){
int main() { int main() {
double precision=10e-10; double precision=10e-10;
H5::H5File file("fourier_real_time.h5",H5F_ACC_TRUNC); h5::file file("fourier_real_time.h5",H5F_ACC_TRUNC);
std::complex<double> I(0,1); std::complex<double> I(0,1);

View File

@ -5,6 +5,7 @@
using namespace triqs::gfs; using namespace triqs::gfs;
using triqs::clef::placeholder; using triqs::clef::placeholder;
namespace h5 = triqs::h5;
int main() { int main() {
@ -38,19 +39,19 @@ int main() {
//saving //saving
{ {
H5::H5File file("vertex1.h5", H5F_ACC_TRUNC ); h5::file file("vertex1.h5", H5F_ACC_TRUNC );
h5_write(file, "v", vertex); h5_write(file, "v", vertex);
} }
// loading // loading
{ {
H5::H5File file("vertex1.h5", H5F_ACC_RDONLY ); h5::file file("vertex1.h5", H5F_ACC_RDONLY );
h5_read(file, "v", vertex2); h5_read(file, "v", vertex2);
} }
//resaving //resaving
{ {
H5::H5File file("vertex1b.h5", H5F_ACC_TRUNC ); h5::file file("vertex1b.h5", H5F_ACC_TRUNC );
h5_write(file, "v", vertex2); h5_write(file, "v", vertex2);
} }
@ -63,19 +64,19 @@ int main() {
//saving //saving
{ {
H5::H5File file("vertex3.h5", H5F_ACC_TRUNC ); h5::file file("vertex3.h5", H5F_ACC_TRUNC );
h5_write(file, "v", vertex3); h5_write(file, "v", vertex3);
} }
// loading // loading
{ {
H5::H5File file("vertex3.h5", H5F_ACC_RDONLY ); h5::file file("vertex3.h5", H5F_ACC_RDONLY );
h5_read(file, "v", vertex3b); h5_read(file, "v", vertex3b);
} }
//resaving //resaving
{ {
H5::H5File file("vertex3b.h5", H5F_ACC_TRUNC ); h5::file file("vertex3b.h5", H5F_ACC_TRUNC );
h5_write(file, "v", vertex3b); h5_write(file, "v", vertex3b);
} }

View File

@ -32,16 +32,18 @@ int main(int argc, char **argv) {
std::map<std::string, int> m = { {"a",1}, {"b",2} }; std::map<std::string, int> m = { {"a",1}, {"b",2} };
std::map<std::string, std::vector<double>> mv = { {"a",{1.0, 2.0}}, {"b",{2.0, 3.0, 4.0}} }; std::map<std::string, std::vector<double>> mv = { {"a",{1.0, 2.0}}, {"b",{2.0, 3.0, 4.0}} };
H5::H5File file1("test_map.h5", H5F_ACC_TRUNC); {
h5::group top1(file1); h5::file file1("test_map.h5", H5F_ACC_TRUNC);
h5_write(top1, "map_int", m); h5::group top1(file1);
h5_write(top1, "map_vec", mv); h5_write(top1, "map_int", m);
h5_write(top1, "map_vec", mv);
}
// read // read
std::map<std::string, int> mm = { {"c",1} }; std::map<std::string, int> mm = { {"c",1} };
std::map<std::string, std::vector<double>> mmv = { {"c",{1.0}} }; std::map<std::string, std::vector<double>> mmv = { {"c",{1.0}} };
H5::H5File file2("test_map.h5", H5F_ACC_RDONLY); h5::file file2("test_map.h5", H5F_ACC_RDONLY);
h5::group top2(file2); h5::group top2(file2);
h5_read(top2, "map_int", mm); h5_read(top2, "map_int", mm);
h5_read(top2, "map_vec", mmv); h5_read(top2, "map_vec", mmv);

View File

@ -7,6 +7,7 @@
#define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK #define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
#include <triqs/utility/callbacks.hpp> #include <triqs/utility/callbacks.hpp>
#include <triqs/mc_tools/mc_generic.hpp> #include <triqs/mc_tools/mc_generic.hpp>
namespace h5 = triqs::h5;
triqs::arrays::array<std::complex<double>,1> make_array( std::complex<double> c){return {c}; }; triqs::arrays::array<std::complex<double>,1> make_array( std::complex<double> c){return {c}; };
@ -54,7 +55,7 @@ struct compute_histo{
} }
void collect_results(boost::mpi::communicator const &c) { void collect_results(boost::mpi::communicator const &c) {
H/=tot; H/=tot;
H5::H5File file("histo.h5",H5F_ACC_TRUNC); h5::file file("histo.h5",H5F_ACC_TRUNC);
h5_write(file,"H",H); h5_write(file,"H",H);
} }
}; };
@ -81,7 +82,7 @@ int main(int argc, char* argv[]) {
int xmax=floor(4*sqrt(Length_Cycle) ); //max of the position registered in the histogram int xmax=floor(4*sqrt(Length_Cycle) ); //max of the position registered in the histogram
double pl=1.5, pr=1; //non normalized probabilities for proposing a left or right move double pl=1.5, pr=1; //non normalized probabilities for proposing a left or right move
H5::H5File file("params.h5",H5F_ACC_TRUNC); h5::file file("params.h5",H5F_ACC_TRUNC);
h5_write(file,"pr",make_array(pr)); h5_write(file,"pr",make_array(pr));
h5_write(file,"pl",make_array(pl)); h5_write(file,"pl",make_array(pl));
h5_write(file,"xmax",make_array(xmax)); h5_write(file,"xmax",make_array(xmax));

View File

@ -4,6 +4,7 @@
using namespace triqs::params; using namespace triqs::params;
using namespace triqs::arrays; using namespace triqs::arrays;
namespace h5 = triqs::h5;
int main() { int main() {
try { try {
@ -76,20 +77,20 @@ int main() {
// hdf5 // hdf5
{ {
H5::H5File file( "ess.h5", H5F_ACC_TRUNC ); h5::file file( "ess.h5", H5F_ACC_TRUNC );
h5_write( file, "Parameters", P); h5_write( file, "Parameters", P);
} }
{ {
H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); h5::file file( "ess.h5", H5F_ACC_RDONLY );
h5_read( file.openGroup("/"), "Parameters", P_vide); h5_read( file, "Parameters", P_vide);
} }
std::cout << P_vide << std::endl; std::cout << P_vide << std::endl;
{ {
H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); h5::file file( "ess.h5", H5F_ACC_RDONLY );
h5_read( file.openGroup("/"), "Parameters", P); h5_read( file, "Parameters", P);
} }
//std::cout << P << std::endl; //std::cout << P << std::endl;

View File

@ -120,18 +120,18 @@ int main() {
std::cout << P << std::endl; std::cout << P << std::endl;
{ {
H5::H5File file( "ess.h5", H5F_ACC_TRUNC ); h5::file file( "ess.h5", H5F_ACC_TRUNC );
h5_write( file, "Parameters", P); h5_write( file, "Parameters", P);
} }
auto P4 = P; auto P4 = P;
{ {
H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); h5::file file( "ess.h5", H5F_ACC_RDONLY );
h5_read( file.openGroup("/"), "Parameters", P4); h5_read( file, "Parameters", P4);
} }
{ {
H5::H5File file( "ess_relo.h5", H5F_ACC_TRUNC ); h5::file file( "ess_relo.h5", H5F_ACC_TRUNC );
h5_write( file.openGroup("/"), "Parameters", P4); h5_write( file, "Parameters", P4);
} }
std::cout << "P4 after : \n"<< P4<< std::endl ; std::cout << "P4 after : \n"<< P4<< std::endl ;

View File

@ -32,6 +32,7 @@ using triqs::h5::deserialize;
int main() { int main() {
try{
using triqs::arrays::array; using triqs::arrays::array;
auto a = array<double, 1>{1, 2, 3, 4, 5}; auto a = array<double, 1>{1, 2, 3, 4, 5};
@ -54,7 +55,8 @@ int main() {
auto b = deserialize<array<double, 1>>(s1); auto b = deserialize<array<double, 1>>(s1);
std::cout << "a = " << a << " == " << b << std::endl; std::cout << "a = " << a << " == " << b << std::endl;
}
catch(std::exception const & e) { std::cout << e.what()<<std::endl;}
} }
#endif #endif

View File

@ -23,6 +23,7 @@
#include "../array.hpp" #include "../array.hpp"
#include <triqs/h5.hpp> #include <triqs/h5.hpp>
#include "./simple_read_write.hpp" #include "./simple_read_write.hpp"
#include <triqs/h5/base.hpp>
namespace triqs { namespace triqs {
namespace arrays { namespace arrays {
@ -31,9 +32,9 @@ namespace arrays {
namespace h5_impl { namespace h5_impl {
template <typename A> void* __get_array_data_ptr(A& x) { return h5::get_data_ptr(&(x.storage()[0])); } template <typename A> void* __get_array_data_ptr(A& x) { return h5::get_data_ptr(&(x.storage()[0])); }
H5::DataSpace data_space_impl(array_stride_info info, bool is_complex); h5::dataspace data_space_impl(array_stride_info info, bool is_complex);
template <typename ArrayType> H5::DataSpace data_space(ArrayType const& A) { template <typename ArrayType> h5::dataspace data_space(ArrayType const& A) {
if (!A.indexmap().is_contiguous()) TRIQS_RUNTIME_ERROR << " h5 : internal error : array not contiguous"; if (!A.indexmap().is_contiguous()) TRIQS_RUNTIME_ERROR << " h5 : internal error : array not contiguous";
return data_space_impl(array_stride_info{A}, triqs::is_complex<typename ArrayType::value_type>::value); return data_space_impl(array_stride_info{A}, triqs::is_complex<typename ArrayType::value_type>::value);
} }
@ -47,7 +48,7 @@ namespace arrays {
static const bool T_is_complex = triqs::is_complex<T>::value; static const bool T_is_complex = triqs::is_complex<T>::value;
static const unsigned int RANK = dim + 1 + (T_is_complex ? 1 : 0); static const unsigned int RANK = dim + 1 + (T_is_complex ? 1 : 0);
utility::mini_vector<hsize_t, RANK> dims, offset, maxdims, dim_chunk, buffer_dim, zero; utility::mini_vector<hsize_t, RANK> dims, offset, maxdims, dim_chunk, buffer_dim, zero;
H5::DataSet dataset; h5::dataset d_set;
array<T, dim + 1> buffer; array<T, dim + 1> buffer;
public: public:
@ -74,14 +75,11 @@ namespace arrays {
s[i] = buffer_dim[i]; s[i] = buffer_dim[i];
} }
buffer.resize(s); buffer.resize(s);
H5::DataSpace mspace1(RANK, dims.ptr(), maxdims.ptr()); h5::dataspace mspace1 = H5Screate_simple(RANK, dims.ptr(), maxdims.ptr());
H5::DSetCreatPropList cparms; h5::proplist cparms = H5Pcreate(H5P_DATASET_CREATE);
cparms.setChunk(RANK, dim_chunk.ptr()); // Modify dataset creation properties, i.e. enable chunking. auto err = H5Pset_chunk(cparms, RANK, dim_chunk.ptr());
try { d_set = g.create_dataset(name, h5::native_type_from_C(T()), mspace1, cparms);
dataset = g.create_dataset(name, h5::native_type_from_C(typename h5::remove_complex<T>::type()), mspace1, cparms); if (triqs::is_complex<T>::value) h5::write_string_attribute(d_set, "__complex__", "1");
if (triqs::is_complex<T>::value) h5::write_string_attribute(&dataset, "__complex__", "1");
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
} }
/// ///
@ -128,14 +126,19 @@ namespace arrays {
if (step == 0) return; if (step == 0) return;
dims[0] += step; dims[0] += step;
buffer_dim[0] = step; buffer_dim[0] = step;
dataset.extend(dims.ptr());
H5::DataSpace fspace1 = dataset.getSpace(), mspace = h5_impl::data_space(buffer); herr_t err= H5Dset_extent(d_set,dims.ptr()); // resize the data_space
fspace1.selectHyperslab(H5S_SELECT_SET, buffer_dim.ptr(), offset.ptr());
mspace.selectHyperslab(H5S_SELECT_SET, buffer_dim.ptr(), zero.ptr()); h5::dataspace fspace1 = H5Dget_space(d_set);
try { h5::dataspace mspace = h5_impl::data_space(buffer);
dataset.write(h5_impl::__get_array_data_ptr(buffer), h5::data_type_memory<T>(), mspace, fspace1);
} err = H5Sselect_hyperslab(fspace1, H5S_SELECT_SET, offset.ptr(), NULL, buffer_dim.ptr(), NULL);
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; if (err < 0) TRIQS_RUNTIME_ERROR << "Can not set hyperslab";
err = H5Sselect_hyperslab(mspace, H5S_SELECT_SET, zero.ptr(), NULL, buffer_dim.ptr(), NULL);
if (err < 0) TRIQS_RUNTIME_ERROR << "Can not set hyperslab";
err = H5Dwrite(d_set, h5::data_type_memory<T>(), mspace, fspace1, H5P_DEFAULT, h5_impl::__get_array_data_ptr(buffer));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the array_stack buffer";
offset[0] += step; offset[0] += step;
} }
}; };

View File

@ -19,6 +19,7 @@
* *
******************************************************************************/ ******************************************************************************/
#include "./simple_read_write.hpp" #include "./simple_read_write.hpp"
#include "./../../h5/base.hpp"
using dcomplex = std::complex<double>; using dcomplex = std::complex<double>;
namespace triqs { namespace triqs {
@ -26,7 +27,7 @@ namespace arrays {
namespace h5_impl { namespace h5_impl {
// the dataspace corresponding to the array. Contiguous data only... // the dataspace corresponding to the array. Contiguous data only...
H5::DataSpace data_space_impl(array_stride_info info, bool is_complex) { h5::dataspace data_space_impl(array_stride_info info, bool is_complex) {
hsize_t L[info.R], S[info.R]; hsize_t L[info.R], S[info.R];
for (int u = 0; u < info.R; ++u) { for (int u = 0; u < info.R; ++u) {
if (info.strides[u] <= 0) TRIQS_RUNTIME_ERROR << " negative strides not permitted in h5"; if (info.strides[u] <= 0) TRIQS_RUNTIME_ERROR << " negative strides not permitted in h5";
@ -41,13 +42,14 @@ namespace arrays {
template <typename T> void write_array_impl(h5::group g, std::string const& name, const T* start, array_stride_info info) { template <typename T> void write_array_impl(h5::group g, std::string const& name, const T* start, array_stride_info info) {
static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below
bool is_complex = triqs::is_complex<T>::value; bool is_complex = triqs::is_complex<T>::value;
try { h5::dataset ds = g.create_dataset(name, h5::data_type_file<T>(), data_space_impl(info, is_complex));
H5::DataSet ds = g.create_dataset(name, h5::data_type_file<T>(), data_space_impl(info, is_complex));
ds.write(h5::get_data_ptr(start), h5::data_type_memory<T>(), data_space_impl(info, is_complex)); auto err =
// if complex, to be python compatible, we add the __complex__ attribute H5Dwrite(ds, h5::data_type_memory<T>(), data_space_impl(info, is_complex), H5S_ALL, H5P_DEFAULT, h5::get_data_ptr(start));
if (is_complex) h5::write_string_attribute(&ds, "__complex__", "1"); if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the scalar dataset " << name << " in the group" << g.name();
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; // if complex, to be python compatible, we add the __complex__ attribute
if (is_complex) h5::write_string_attribute(ds, "__complex__", "1");
} }
template void write_array_impl<int>(h5::group g, std::string const& name, const int* start, array_stride_info info); template void write_array_impl<int>(h5::group g, std::string const& name, const int* start, array_stride_info info);
@ -55,7 +57,6 @@ namespace arrays {
template void write_array_impl<double>(h5::group g, std::string const& name, const double* start, array_stride_info info); template void write_array_impl<double>(h5::group g, std::string const& name, const double* start, array_stride_info info);
template void write_array_impl<dcomplex>(h5::group g, std::string const& name, const dcomplex* start, array_stride_info info); template void write_array_impl<dcomplex>(h5::group g, std::string const& name, const dcomplex* start, array_stride_info info);
// overload : special treatment for arrays of strings (one dimension only). // overload : special treatment for arrays of strings (one dimension only).
void write_array(h5::group g, std::string const& name, vector_const_view<std::string> V) { void write_array(h5::group g, std::string const& name, vector_const_view<std::string> V) {
std::vector<std::string> tmp(V.size()); std::vector<std::string> tmp(V.size());
@ -71,60 +72,30 @@ namespace arrays {
/// --------------------------- READ --------------------------------------------- /// --------------------------- READ ---------------------------------------------
/* template <typename ArrayType1> void read_array(h5::group g, std::string const& name, ArrayType1&& A, bool C_reorder = true) {
typedef typename std::remove_reference<ArrayType1>::type ArrayType;
static_assert(!std::is_base_of<std::string, typename ArrayType::value_type>::value, " Not implemented"); // 1d is below
try {
H5::DataSet ds = g.open_dataset(name);
H5::DataSpace dataspace = ds.getSpace();
static const unsigned int Rank = ArrayType::rank + (triqs::is_complex<typename ArrayType::value_type>::value ? 1 : 0);
int rank = dataspace.getSimpleExtentNdims();
if (rank != Rank)
TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : the array has rank = " << Rank
<< " while the array stored in the hdf5 file has rank = " << rank;
mini_vector<hsize_t, Rank> dims_out;
dataspace.getSimpleExtentDims(&dims_out[0], NULL);
mini_vector<size_t, ArrayType::rank> d2;
for (size_t u = 0; u < ArrayType::rank; ++u) d2[u] = dims_out[u];
resize_or_check(A, d2);
if (C_reorder) {
read_array(g, name, make_cache(A).view(), false);
//read_array(g, name, cache<ArrayType, typename ArrayType::regular_type>(A).view(), false);
} else
ds.read(__get_array_data_ptr(A), h5::data_type_memory<typename ArrayType::value_type>(), data_space(A), dataspace);
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
}
*/
std::vector<size_t> get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex) { std::vector<size_t> get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex) {
try { h5::dataset ds = g.open_dataset(name);
H5::DataSet ds = g.open_dataset(name); h5::dataspace d_space = H5Dget_space(ds);
H5::DataSpace dataspace = ds.getSpace(); int Rank = R + (is_complex ? 1 : 0);
int Rank = R + (is_complex ? 1 : 0); int rank = H5Sget_simple_extent_ndims(d_space);
int rank = dataspace.getSimpleExtentNdims(); if (rank != Rank)
if (rank != Rank) TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : the array has rank = " << Rank
TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : the array has rank = " << Rank << " while the array stored in the hdf5 file has rank = " << rank;
<< " while the array stored in the hdf5 file has rank = " << rank; std::vector<size_t> d2(R);
std::vector<size_t> d2(R); hsize_t dims_out[rank];
hsize_t dims_out[rank]; H5Sget_simple_extent_dims(d_space, dims_out, NULL);
dataspace.getSimpleExtentDims(&dims_out[0], NULL); for (int u = 0; u < R; ++u) d2[u] = dims_out[u];
for (int u = 0; u < R; ++u) d2[u] = dims_out[u]; return d2;
return d2;
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
} }
template <typename T> void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) { template <typename T> void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) {
static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below
bool is_complex = triqs::is_complex<T>::value; bool is_complex = triqs::is_complex<T>::value;
try { h5::dataset ds = g.open_dataset(name);
H5::DataSet ds = g.open_dataset(name); h5::dataspace d_space = H5Dget_space(ds);
H5::DataSpace dataspace = ds.getSpace();
ds.read(h5::get_data_ptr(start), h5::data_type_memory<T>(), data_space_impl(info, is_complex), dataspace); herr_t err =
} H5Dread(ds, h5::data_type_memory<T>(), data_space_impl(info, is_complex), d_space, H5P_DEFAULT, h5::get_data_ptr(start));
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the scalar dataset " << name << " in the group" << g.name();
} }
template void read_array_impl<int>(h5::group g, std::string const& name, int* start, array_stride_info info); template void read_array_impl<int>(h5::group g, std::string const& name, int* start, array_stride_info info);

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2011-2013 by O. Parcollet * Copyright (C) 2011-2014 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -78,12 +78,8 @@ namespace arrays {
resize_or_check(a, mini_vector<size_t, std::c14::decay_t<A>::rank> (get_array_lengths(a.rank, g, name, triqs::is_complex<typename std::c14::decay_t<A>::value_type>::value))); resize_or_check(a, mini_vector<size_t, std::c14::decay_t<A>::rank> (get_array_lengths(a.rank, g, name, triqs::is_complex<typename std::c14::decay_t<A>::value_type>::value)));
if (C_reorder) { if (C_reorder) {
{ {
// read_array(g, name, make_cache(a).view(), false);
// return ;
auto b = make_cache(a); auto b = make_cache(a);
// auto b = make_cache(a).view();
read_array_impl(g, name, b.view().data_start(), array_stride_info{b.view()}); read_array_impl(g, name, b.view().data_start(), array_stride_info{b.view()});
// read_array_impl(g, name, b.data_start(), array_stride_info{b});
} }
} else } else
read_array_impl(g, name, a.data_start(), array_stride_info{a}); read_array_impl(g, name, a.data_start(), array_stride_info{a});

View File

@ -121,7 +121,7 @@ namespace gfs {
} }
friend void h5_read(h5::group fg, std::string subgroup_name, indices_2 &g) { friend void h5_read(h5::group fg, std::string subgroup_name, indices_2 &g) {
h5::group gr; h5::group gr = fg; // no default construction
try { try {
gr = fg.open_group(subgroup_name); gr = fg.open_group(subgroup_name);
} }

View File

@ -20,20 +20,35 @@
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_H5_FULL_H #ifndef TRIQS_H5_FULL_H
#define TRIQS_H5_FULL_H #define TRIQS_H5_FULL_H
#include "./h5/base_public.hpp"
#include "./h5/file.hpp"
#include "./h5/group.hpp" #include "./h5/group.hpp"
#include "./h5/scalar.hpp" #include "./h5/scalar.hpp"
#include "./h5/string.hpp"
#include "./h5/vector.hpp" #include "./h5/vector.hpp"
#include "./h5/map.hpp" #include "./h5/map.hpp"
#include "./h5/string.hpp"
//#include "./h5/make_h5_read_write.hpp"
// in some old version, the macro is not defined. // traits to detect h5_read/h5_write is overloaded. Unused currently. Kept since
// it can useful and is it not so simple to do...
namespace triqs {
namespace h5 {
template <typename T, typename Enable = void> struct has_h5_read : std::false_type {};
template <typename T>
struct has_h5_read<T, decltype(h5_read(std::declval<h5::group>(), std::string(), *(std::declval<T*>())))> : std::true_type {};
template <typename T, typename Enable = void> struct has_h5_write : std::false_type {};
template <typename T>
struct has_h5_write<T, decltype(h5_write(std::declval<h5::group>(), std::string(), std::declval<const T>()))> : std::true_type {
};
}
}
// in some old version of hdf5 (Ubuntu 12.04 e.g.), the macro is not yet defined.
#ifndef H5_VERSION_GE #ifndef H5_VERSION_GE
#define H5_VERSION_GE(Maj,Min,Rel) \ #define H5_VERSION_GE(Maj, Min, Rel) \
(((H5_VERS_MAJOR==Maj) && (H5_VERS_MINOR==Min) && (H5_VERS_RELEASE>=Rel)) || \ (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE >= Rel)) || \
((H5_VERS_MAJOR==Maj) && (H5_VERS_MINOR>Min)) || \ ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR > Min)) || (H5_VERS_MAJOR > Maj))
(H5_VERS_MAJOR>Maj))
#endif #endif

View File

@ -19,15 +19,15 @@
* *
******************************************************************************/ ******************************************************************************/
#include "./base.hpp" #include "./base.hpp"
#include <hdf5_hl.h>
namespace triqs { namespace triqs {
namespace h5 { namespace h5 {
//------------------------------------------------
// dataspace from lengths and strides. Correct for the complex. strides must be >0 // dataspace from lengths and strides. Correct for the complex. strides must be >0
H5::DataSpace dataspace_from_LS(int R, bool is_complex, hsize_t const *Ltot, hsize_t const *L, hsize_t const *S, dataspace dataspace_from_LS(int R, bool is_complex, hsize_t const *Ltot, hsize_t const *L, hsize_t const *S,
hsize_t const *offset) { hsize_t const *offset) {
int rank = R + (is_complex ? 1 : 0); int rank = R + (is_complex ? 1 : 0);
hsize_t totdimsf[rank], dimsf[rank], stridesf[rank], offsetf[rank]; // dataset dimensions hsize_t totdimsf[rank], dimsf[rank], stridesf[rank], offsetf[rank]; // dataset dimensions
for (size_t u = 0; u < R; ++u) { for (size_t u = 0; u < R; ++u) {
@ -42,54 +42,60 @@ namespace h5 {
totdimsf[rank - 1] = 2; totdimsf[rank - 1] = 2;
stridesf[rank - 1] = 1; stridesf[rank - 1] = 1;
} }
H5::DataSpace ds(rank, totdimsf);
ds.selectHyperslab(H5S_SELECT_SET, dimsf, offsetf, stridesf); dataspace ds = H5Screate_simple(rank, totdimsf, NULL);
if (!ds.is_valid()) TRIQS_RUNTIME_ERROR << "Can not create the dataset";
herr_t err = H5Sselect_hyperslab(ds, H5S_SELECT_SET, offsetf, stridesf, dimsf, NULL);
if (err < 0) TRIQS_RUNTIME_ERROR << "Can not set hyperslab";
return ds; return ds;
} }
/****************** Write string attribute *********************************************/ /****************** Write string attribute *********************************************/
void write_string_attribute(H5::H5Object const *obj, std::string name, std::string value) { void write_string_attribute(hid_t id, std::string name, std::string value) {
H5::DataSpace attr_dataspace = H5::DataSpace(H5S_SCALAR);
// Create new string datatype for attribute datatype strdatatype = H5Tcopy(H5T_C_S1);
H5::StrType strdatatype(H5::PredType::C_S1, value.size()); auto status = H5Tset_size(strdatatype, value.size() + 1);
// Set up write buffer for attribute // auto status = H5Tset_size(strdatatype, H5T_VARIABLE);
// const H5std_string strwritebuf (value); if (status < 0) TRIQS_RUNTIME_ERROR << "Internal error in H5Tset_size";
// Create attribute and write to it
H5::Attribute myatt_in = obj->createAttribute(name.c_str(), strdatatype, attr_dataspace); dataspace space = H5Screate(H5S_SCALAR);
// myatt_in.write(strdatatype, strwritebuf);
myatt_in.write(strdatatype, (void *)(value.c_str())); attribute attr = H5Acreate2(id, name.c_str(), strdatatype, space, H5P_DEFAULT, H5P_DEFAULT);
if (!attr.is_valid()) TRIQS_RUNTIME_ERROR << "Can not create the attribute " << name;
status = H5Awrite(attr, strdatatype, (void *)(value.c_str()));
if (status < 0) TRIQS_RUNTIME_ERROR << "Can not write the attribute " << name;
} }
/****************** Read string attribute *********************************************/ /****************** Read string attribute *********************************************/
/// Return the attribute name of obj, and "" if the attribute does not exist. /// Return the attribute name of obj, and "" if the attribute does not exist.
std::string read_string_attribute(H5::H5Object const *obj, std::string name) { std::string read_string_attribute(hid_t id, std::string name) {
std::string value = "";
H5::Attribute attr; // if the attribute is not present, return 0
if (H5LTfind_attribute(obj->getId(), name.c_str()) == 0) return value; // not present if (H5LTfind_attribute(id, name.c_str()) == 0) return ""; // not present
// can not find how to get the size with hl. Using full interface
// herr_t err2 = H5LTget_attribute_string(gr.getId(), x.c_str(), name.c_str() , &(buf.front()) ) ; attribute attr = H5Aopen(id, name.c_str(), H5P_DEFAULT);
// value.append( &(buf.front()) ); if (!attr.is_valid()) TRIQS_RUNTIME_ERROR << "Can not open the attribute " << name;
try {
attr = obj->openAttribute(name.c_str()); dataspace space = H5Aget_space(attr);
}
catch (H5::AttributeIException) { int rank = H5Sget_simple_extent_ndims(space);
return value; if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0";
}
try { datatype strdatatype = H5Aget_type(attr);
H5::DataSpace dataspace = attr.getSpace();
int rank = dataspace.getSimpleExtentNdims(); std::vector<char> buf(H5Aget_storage_size(attr) + 1, 0x00);
if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0"; auto err = H5Aread(attr, strdatatype, (void *)(&buf[0]));
size_t size = attr.getStorageSize(); if (err < 0) TRIQS_RUNTIME_ERROR << "Can not read the attribute" << name;
H5::StrType strdatatype(H5::PredType::C_S1, size + 1);
std::vector<char> buf(size + 1, 0x00); std::string ret = "";
attr.read(strdatatype, (void *)(&buf[0])); ret.append(&(buf.front()));
value.append(&(buf.front())); return ret;
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
return value;
} }
} }
} }

View File

@ -19,117 +19,89 @@
* *
******************************************************************************/ ******************************************************************************/
#pragma once #pragma once
#include "./base_public.hpp"
#include <triqs/utility/mini_vector.hpp> #include <triqs/utility/mini_vector.hpp>
#include <type_traits>
#include <H5Cpp.h>
#include <triqs/utility/is_complex.hpp> #include <triqs/utility/is_complex.hpp>
#include <type_traits>
#include <hdf5.h>
#include <hdf5_hl.h>
/// This header is only for inclusion in the xxx.cpp files of the h5 lib,
/// not in general code.
namespace triqs { namespace triqs {
namespace h5 {
inline std::string get_triqs_hdf5_data_scheme(bool) { return "bool";} using utility::mini_vector;
inline std::string get_triqs_hdf5_data_scheme(int) { return "int";}
inline std::string get_triqs_hdf5_data_scheme(long) { return "long";}
inline std::string get_triqs_hdf5_data_scheme(long long) { return "long long";}
inline std::string get_triqs_hdf5_data_scheme(unsigned int) { return "int";}
inline std::string get_triqs_hdf5_data_scheme(unsigned long) { return "unsigned long";}
inline std::string get_triqs_hdf5_data_scheme(unsigned long long) { return "unsigned long long";}
inline std::string get_triqs_hdf5_data_scheme(float) { return "float";}
inline std::string get_triqs_hdf5_data_scheme(double) { return "double";}
inline std::string get_triqs_hdf5_data_scheme(long double) { return "long double";}
inline std::string get_triqs_hdf5_data_scheme(std::complex<double>) { return "complex";}
namespace h5 { // conversion of C type to HDF5 native
inline hid_t native_type_from_C(char) { return H5T_NATIVE_CHAR; }
inline hid_t native_type_from_C(signed char) { return H5T_NATIVE_SCHAR; }
inline hid_t native_type_from_C(unsigned char) { return H5T_NATIVE_UCHAR; }
inline hid_t native_type_from_C(short) { return H5T_NATIVE_SHORT; }
inline hid_t native_type_from_C(unsigned short) { return H5T_NATIVE_USHORT; }
inline hid_t native_type_from_C(int) { return H5T_NATIVE_INT; }
inline hid_t native_type_from_C(unsigned) { return H5T_NATIVE_UINT; }
inline hid_t native_type_from_C(long) { return H5T_NATIVE_LONG; }
inline hid_t native_type_from_C(unsigned long) { return H5T_NATIVE_ULONG; }
inline hid_t native_type_from_C(long long) { return H5T_NATIVE_LLONG; }
inline hid_t native_type_from_C(unsigned long long) { return H5T_NATIVE_ULLONG; }
inline hid_t native_type_from_C(float) { return H5T_NATIVE_FLOAT; }
inline hid_t native_type_from_C(double) { return H5T_NATIVE_DOUBLE; }
inline hid_t native_type_from_C(long double) { return H5T_NATIVE_LDOUBLE; }
inline hid_t native_type_from_C(bool) { return H5T_NATIVE_SCHAR; }
inline hid_t native_type_from_C(std::string) { return H5T_C_S1; }
inline hid_t native_type_from_C(std::complex<double>) { return native_type_from_C(double());}
using utility::mini_vector; // conversion of C type to HDF5 native
// We need to discuss which type we use in the file
// NATIVE is only one possibility, like IEEE, etc...
inline hid_t h5_type_from_C(char) { return H5T_NATIVE_CHAR; }
inline hid_t h5_type_from_C(signed char) { return H5T_NATIVE_SCHAR; }
inline hid_t h5_type_from_C(unsigned char) { return H5T_NATIVE_UCHAR; }
inline hid_t h5_type_from_C(short) { return H5T_NATIVE_SHORT; }
inline hid_t h5_type_from_C(unsigned short) { return H5T_NATIVE_USHORT; }
inline hid_t h5_type_from_C(int) { return H5T_NATIVE_INT; }
inline hid_t h5_type_from_C(unsigned) { return H5T_NATIVE_UINT; }
inline hid_t h5_type_from_C(long) { return H5T_NATIVE_LONG; }
inline hid_t h5_type_from_C(unsigned long) { return H5T_NATIVE_ULONG; }
inline hid_t h5_type_from_C(long long) { return H5T_NATIVE_LLONG; }
inline hid_t h5_type_from_C(unsigned long long) { return H5T_NATIVE_ULLONG; }
inline hid_t h5_type_from_C(float) { return H5T_NATIVE_FLOAT; }
inline hid_t h5_type_from_C(double) { return H5T_NATIVE_DOUBLE; }
inline hid_t h5_type_from_C(long double) { return H5T_NATIVE_LDOUBLE; }
inline hid_t h5_type_from_C(bool) { return H5T_NATIVE_SCHAR; }
inline hid_t h5_type_from_C(std::string) { return H5T_C_S1; }
inline hid_t h5_type_from_C(std::complex<double>) { return h5_type_from_C(double());}
// conversion of C type to HDF5 native //------------- compute the data type (removing complex) ----------------------------------
inline H5::PredType native_type_from_C(char) { return H5::PredType::NATIVE_CHAR; }
inline H5::PredType native_type_from_C(signed char) { return H5::PredType::NATIVE_SCHAR; }
inline H5::PredType native_type_from_C(unsigned char) { return H5::PredType::NATIVE_UCHAR; }
inline H5::PredType native_type_from_C(short) { return H5::PredType::NATIVE_SHORT; }
inline H5::PredType native_type_from_C(unsigned short) { return H5::PredType::NATIVE_USHORT; }
inline H5::PredType native_type_from_C(int) { return H5::PredType::NATIVE_INT; }
inline H5::PredType native_type_from_C(unsigned) { return H5::PredType::NATIVE_UINT; }
inline H5::PredType native_type_from_C(long) { return H5::PredType::NATIVE_LONG; }
inline H5::PredType native_type_from_C(unsigned long) { return H5::PredType::NATIVE_ULONG; }
inline H5::PredType native_type_from_C(long long) { return H5::PredType::NATIVE_LLONG; }
inline H5::PredType native_type_from_C(unsigned long long) { return H5::PredType::NATIVE_ULLONG; }
inline H5::PredType native_type_from_C(float) { return H5::PredType::NATIVE_FLOAT; }
inline H5::PredType native_type_from_C(double) { return H5::PredType::NATIVE_DOUBLE; }
inline H5::PredType native_type_from_C(long double) { return H5::PredType::NATIVE_LDOUBLE; }
inline H5::PredType native_type_from_C(bool) { return H5::PredType::NATIVE_SCHAR; }
inline H5::PredType native_type_from_C(std::string) { return H5::PredType::C_S1; }
// conversion of C type to HDF5 native // in memory
// NEED TO CHANGE THIS ? It is not standard... We should fix a standard or have a trait template <typename T> hid_t data_type_memory() { return native_type_from_C(T{});}
inline H5::PredType h5_type_from_C(char) { return H5::PredType::NATIVE_CHAR; }
inline H5::PredType h5_type_from_C(signed char) { return H5::PredType::NATIVE_SCHAR; }
inline H5::PredType h5_type_from_C(unsigned char) { return H5::PredType::NATIVE_UCHAR; }
inline H5::PredType h5_type_from_C(short) { return H5::PredType::NATIVE_SHORT; }
inline H5::PredType h5_type_from_C(unsigned short) { return H5::PredType::NATIVE_USHORT; }
inline H5::PredType h5_type_from_C(int) { return H5::PredType::NATIVE_INT; }
inline H5::PredType h5_type_from_C(unsigned) { return H5::PredType::NATIVE_UINT; }
inline H5::PredType h5_type_from_C(long) { return H5::PredType::NATIVE_LONG; }
inline H5::PredType h5_type_from_C(unsigned long) { return H5::PredType::NATIVE_ULONG; }
inline H5::PredType h5_type_from_C(long long) { return H5::PredType::NATIVE_LLONG; }
inline H5::PredType h5_type_from_C(unsigned long long) { return H5::PredType::NATIVE_ULLONG; }
inline H5::PredType h5_type_from_C(float) { return H5::PredType::NATIVE_FLOAT; }
inline H5::PredType h5_type_from_C(double) { return H5::PredType::NATIVE_DOUBLE; }
inline H5::PredType h5_type_from_C(long double) { return H5::PredType::NATIVE_LDOUBLE; }
inline H5::PredType h5_type_from_C(bool) { return H5::PredType::NATIVE_SCHAR; }
inline H5::PredType h5_type_from_C(std::string) { return H5::PredType::C_S1; }
// If it is complex<T> return T else T // the type of data to put in the file_or_group
template<typename T> struct remove_complex { typedef T type;}; template <typename T> hid_t data_type_file() { return h5_type_from_C(T{});}
template<typename T> struct remove_complex<std::complex<T> > { typedef T type;};
template<typename T> struct remove_complex<std::complex<const T> > { typedef T type;};
template<typename T> struct remove_complex<const T>: remove_complex<T>{};
//------------- compute the data type (removing complex) ---------------------------------- //------------- compute void * pointer to the data ----------------------------------
// 2 cases : complex or not. Complex are reinterpreted according to doc, as N+1 dim double array
template <typename S>
std::enable_if_t<triqs::is_complex<S>::value, std14::conditional_t<std::is_const<S>::value, const void *, void *>>
get_data_ptr(S *p) {
using T = std14::conditional_t<std::is_const<S>::value, const typename S::value_type, typename S::value_type>;
return reinterpret_cast<T *>(p);
}
// in memory template <typename S>
template <typename S> H5::PredType data_type_memory () { return native_type_from_C(typename remove_complex<S>::type()); } std::enable_if_t<!triqs::is_complex<S>::value, std14::conditional_t<std::is_const<S>::value, const void *, void *>>
get_data_ptr(S *p) {
return p;
}
// the type of data to put in the file_or_group // dataspace from lengths and strides. Correct for the complex. strides must be >0
template <typename V> H5::PredType data_type_file () { return h5_type_from_C(typename remove_complex<V>::type());} // used in array and vectors
// implemented in base.cpp
dataspace dataspace_from_LS(int R, bool is_complex, hsize_t const *Ltot, hsize_t const *L, hsize_t const *S,
hsize_t const *offset = NULL);
//------------- compute void * pointer to the data ---------------------------------- }
template <typename S> }
typename std::enable_if< triqs::is_complex<S>::value, typename std::conditional<std::is_const<S>::value, const void *, void *>::type >::type
get_data_ptr (S * p) {
typedef typename std::conditional<std::is_const<S>::value, const typename S::value_type, typename S::value_type>::type T;
return reinterpret_cast<T*>(p);
}
template <typename S >
typename std::enable_if< !triqs::is_complex<S>::value, typename std::conditional<std::is_const<S>::value, const void *, void *>::type >::type
get_data_ptr (S * p) {return p;}
// dataspace from lengths and strides. Correct for the complex. strides must be >0
// used in array and vectors
H5::DataSpace dataspace_from_LS(int R, bool is_complex, hsize_t const *Ltot, hsize_t const *L, hsize_t const *S,
hsize_t const *offset = NULL);
#define TRIQS_ARRAYS_H5_CATCH_EXCEPTION \
catch( triqs::runtime_error const & error) { throw triqs::runtime_error() << error.what();}\
catch( H5::AttributeIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 Attribute error"; }\
catch( H5::DataSetIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 DataSet error"; }\
catch( H5::DataSpaceIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 DataSpace error"; }\
catch( H5::DataTypeIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 DataType error"; }\
catch( H5::FileIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 File error"; }\
catch( H5::GroupIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 Group error"; }\
catch( H5::IdComponentException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 IdComponentException error"; }\
catch( H5::LibraryIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 LibraryIException error"; }\
catch( H5::PropListIException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 PropListIException error"; }\
catch( H5::ReferenceException const & error ) { error.printError(); TRIQS_RUNTIME_ERROR<<"H5 ReferenceException error"; }\
catch(...) { TRIQS_RUNTIME_ERROR<<"H5 unknown error";}
/****************** Read/Write string attribute *********************************************/
void write_string_attribute(H5::H5Object const *obj, std::string name, std::string value);
/// Returns the attribute name of obj, and "" if the attribute does not exist.
std::string read_string_attribute(H5::H5Object const *obj, std::string name);
}}

134
triqs/h5/base_public.hpp Normal file
View File

@ -0,0 +1,134 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2011-2014 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
#include <triqs/utility/mini_vector.hpp>
#include <type_traits>
#include<H5Ipublic.h>
#include<H5Fpublic.h>
#include<H5Gpublic.h>
#include<complex>
namespace triqs {
inline std::string get_triqs_hdf5_data_scheme(bool) { return "bool"; }
inline std::string get_triqs_hdf5_data_scheme(int) { return "int"; }
inline std::string get_triqs_hdf5_data_scheme(long) { return "long"; }
inline std::string get_triqs_hdf5_data_scheme(long long) { return "long long"; }
inline std::string get_triqs_hdf5_data_scheme(unsigned int) { return "int"; }
inline std::string get_triqs_hdf5_data_scheme(unsigned long) { return "unsigned long"; }
inline std::string get_triqs_hdf5_data_scheme(unsigned long long) { return "unsigned long long"; }
inline std::string get_triqs_hdf5_data_scheme(float) { return "float"; }
inline std::string get_triqs_hdf5_data_scheme(double) { return "double"; }
inline std::string get_triqs_hdf5_data_scheme(long double) { return "long double"; }
inline std::string get_triqs_hdf5_data_scheme(std::complex<double>) { return "complex"; }
namespace h5 {
using utility::mini_vector;
//------------- general hdf5 object ------------------
// HDF5 uses a reference counting system, similar to python.
// Same as pyref in python wrapper, its handle the ref. counting of the hdf5 object
// using a RAII pattern.
// We are going to store the id of the various h5 object in such a wrapper
// to provide clean decref, and exception safety.
class h5_object {
// xdecref, xincref manipulate the the ref, but ignore invalid (incl. 0) id.
// like XINC_REF and XDEC_REF in python
static void xdecref(hid_t id) {
if (H5Iis_valid(id)) H5Idec_ref(id);
}
static void xincref(hid_t id) {
if (H5Iis_valid(id)) H5Iinc_ref(id);
}
protected:
hid_t id;
public:
// make an h5_object when the id is now owned (simply inc. the ref).
static h5_object from_borrowed(hid_t id) {
h5_object::xincref(id);
return h5_object(id);
}
// constructor from an owned id (or 0). It will NOT incref, it takes ownership
h5_object(hid_t id = 0) : id(id) {}
h5_object(h5_object const& x) : id(x.id) { xincref(id); } // a new copy, a new ref.
h5_object(h5_object&& x) : id(x.id) { x.id = 0; } // steal the ref.
h5_object& operator=(h5_object const& x) { return operator=(h5_object(x)); } //rewriting with the next overload
h5_object& operator=(h5_object&& x) { //steals the ref, after properly decref its own.
xdecref(id);
id = x.id;
x.id = 0;
return *this;
}
~h5_object() {
// debug : to check the ref counting. Ok in tests.
//if (H5Iis_valid(id)) std::cerr << "closing h5 object id = " << id << " # ref = "<< H5Iget_ref(id) << std::endl;
xdecref(id);
}
void close() { xdecref(id); id=0;} // e.g. to close a file explicitely.
/// cast operator to use it in the C function as its id
operator hid_t() const { return id; }
bool is_valid() const { return H5Iis_valid(id)==1; }
};
//------------- dataset ------------------
using dataset = h5_object;
//------------- datatype ------------------
using datatype = h5_object;
//------------- dataspace ------------------
using dataspace = h5_object;
//------------- proplist ------------------
using proplist = h5_object;
//------------- attribute ------------------
using attribute = h5_object;
/****************** Read/Write string attribute *********************************************/
/// Write an attribute named name, of type string, of value value to the object id
void write_string_attribute(hid_t id, std::string name, std::string value);
/// Returns the attribute name of obj, and "" if the attribute does not exist.
std::string read_string_attribute(hid_t id, std::string name);
}
}

52
triqs/h5/file.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "./file.hpp"
#include "./base.hpp"
namespace triqs {
namespace h5 {
file::file(const char* name, unsigned flags) {
if ((flags == H5F_ACC_RDWR) || (flags == H5F_ACC_RDONLY)) {
id = H5Fopen(name, flags, H5P_DEFAULT);
if (id < 0) TRIQS_RUNTIME_ERROR << "HDF5 : can not open file" << name;
return;
}
if (flags == H5F_ACC_TRUNC) {
id = H5Fcreate(name, flags, H5P_DEFAULT, H5P_DEFAULT);
if (id < 0) TRIQS_RUNTIME_ERROR << "HDF5 : can not create file " << name;
return;
}
if (flags == H5F_ACC_EXCL) {
id = H5Fcreate(name, flags, H5P_DEFAULT, H5P_DEFAULT);
if (id < 0) TRIQS_RUNTIME_ERROR << "HDF5 : can not create file " << name << ". Does it exists ?";
return;
}
TRIQS_RUNTIME_ERROR << "HDF5 file opening : flag not recognized";
}
//---------------------------------------------
file::file (hid_t id_) : h5_object(h5_object(id_)){}
file::file(h5_object obj) : h5_object(std::move(obj)) {
if (!H5Iis_valid(this->id)) TRIQS_RUNTIME_ERROR << "Invalid input in h5::file constructor from id";
if (H5Iget_type(this->id) != H5I_FILE) TRIQS_RUNTIME_ERROR << "h5::file constructor must take the id of a file ";
}
//---------------------------------------------
std::string file::name() const { // same function as for group
char _n[1];
ssize_t size = H5Fget_name(id, _n, 1); // first call, get the size only
std::vector<char> buf(size + 1, 0x00);
H5Fget_name(id, buf.data(), 1); // now get the name
std::string res = "";
res.append(&(buf.front()));
return res;
}
}
}

55
triqs/h5/file.hpp Normal file
View File

@ -0,0 +1,55 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2011-2014 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
#include "./base_public.hpp"
namespace triqs {
namespace h5 {
/**
* \brief A little handler for the file
*/
class file: public h5_object {
public:
/**
* Open the file name.
* Flags can be :
* - H5F_ACC_RDWR
* - H5F_ACC_RDONLY
* - H5F_ACC_TRUNC
* - H5F_ACC_EXCL
*/
file(const char * name, unsigned flags);
/// Cf previous constructor
file(std::string const &name, unsigned flags) : file(name.c_str(), flags) {}
/// Internal : from an hdf5 id.
file (hid_t id);
file(h5_object obj);
/// Name of the file
std::string name() const;
};
}
}

View File

@ -1,66 +1,59 @@
#include "./group.hpp" #include "./group.hpp"
#include <hdf5_hl.h> #include "./base.hpp"
namespace triqs { namespace triqs {
namespace h5 { namespace h5 {
group::group(H5::Group g, H5::Group parent, std::string name_in_parent) group::group(h5::file f) : h5_object() {
: _g(g), _parent(parent), _name_in_parent(name_in_parent) {} id = H5Gopen2(f, "/", H5P_DEFAULT);
if (id < 0) TRIQS_RUNTIME_ERROR << "Can not open the root group / in the file " << f.name();
//group::group(H5::Group g) : _g(g) {}
group::group(H5::H5File f) : _g(f.openGroup("/")) {} // can not fail, right ?
group::group(std::string const &filename, int flag) {
H5::H5File f(filename, H5F_ACC_TRUNC);
*this = group(f);
} }
group::group(hid_t id_, bool is_group) { group::group(h5_object obj) : h5_object(std::move(obj)) {
if (is_group) { if (!H5Iis_valid(this->id)) TRIQS_RUNTIME_ERROR << "Invalid input in group constructor from id";
_g.setId(id_); if (H5Iget_type(this->id) != H5I_GROUP) TRIQS_RUNTIME_ERROR << "Group constructor must take the id of a group or a file ";
} else {
H5::H5File f;
f.setId(id_);
*this = group(f);
}
} }
void group::_write_triqs_hdf5_data_scheme(const char *a) { h5::write_string_attribute(&_g, "TRIQS_HDF5_data_scheme", a); } group::group(hid_t id_) : group(h5_object(id_)){}
std::string group::read_triqs_hdf5_data_scheme() const { return read_string_attribute(&_g, "TRIQS_HDF5_data_scheme"); } void group::_write_triqs_hdf5_data_scheme(const char *a) { h5::write_string_attribute(id, "TRIQS_HDF5_data_scheme", a); }
bool group::has_key(std::string const &key) const { return (H5Lexists(_g.getId(), key.c_str(), H5P_DEFAULT)); } std::string group::read_triqs_hdf5_data_scheme() const { return read_string_attribute(id, "TRIQS_HDF5_data_scheme"); }
std::string group::name() const {
char _n[1];
ssize_t size = H5Iget_name(id, _n, 1); // first call, get the size only
std::vector<char> buf(size + 1, 0x00);
H5Iget_name(id, buf.data(), 1); // now get the name
std::string res = "";
res.append(&(buf.front()));
return res;
}
bool group::has_key(std::string const &key) const { return H5Lexists(id, key.c_str(), H5P_DEFAULT); }
void group::unlink_key_if_exists(std::string const &key) const { void group::unlink_key_if_exists(std::string const &key) const {
if (this->has_key(key)) _g.unlink(key.c_str()); if (!has_key(key)) return;
//auto err = H5Gunlink(id, key.c_str()); // deprecated function
auto err = H5Ldelete(id, key.c_str(),H5P_DEFAULT);
if (err < 0) TRIQS_RUNTIME_ERROR << "Can not unlink object " << key << " in group " << name();
} }
group group::open_group(std::string const &key) const { group group::open_group(std::string const &key) const {
if (!has_key(key)) TRIQS_RUNTIME_ERROR << "no subgroup " << key << " in the group"; if (!has_key(key)) TRIQS_RUNTIME_ERROR << "no subgroup " << key << " in the group";
group res; hid_t sg = H5Gopen2(id, key.c_str(), H5P_DEFAULT);
try { if (sg < 0) TRIQS_RUNTIME_ERROR << "Error in opening the subgroup " << key;
res = group(_g.openGroup(key.c_str()), _g, key); return group(sg);
} // has a parent
catch (H5::GroupIException const &e) {
TRIQS_RUNTIME_ERROR << "Error in opening the subgroup " << key << "\n H5 error message : \n " << e.getCDetailMsg();
}
return res;
} }
/// Open an existing DataSet. Throw it if does not exists /// Open an existing DataSet. Throw it if does not exists
H5::DataSet group::open_dataset(std::string const &key) const { dataset group::open_dataset(std::string const &key) const {
if (!has_key(key)) TRIQS_RUNTIME_ERROR << "no dataset " << key << " in the group"; if (!has_key(key)) TRIQS_RUNTIME_ERROR << "no dataset " << key << " in the group";
H5::DataSet res; dataset ds = H5Dopen2(id, key.c_str(), H5P_DEFAULT);
try { if (!ds.is_valid()) TRIQS_RUNTIME_ERROR << "Can not open dataset " << key << " in the group" << name();
res = _g.openDataSet(key.c_str()); return ds;
}
catch (H5::GroupIException const &e) {
TRIQS_RUNTIME_ERROR << "Error in opening the dataset " << key << "\n H5 error message : \n " << e.getCDetailMsg();
}
return res;
} }
/** /**
* \brief Create a subgroup. * \brief Create a subgroup.
* \param key The name of the subgroup * \param key The name of the subgroup
@ -68,45 +61,44 @@ namespace h5 {
*/ */
group group::create_group(std::string const &key, bool delete_if_exists) const { group group::create_group(std::string const &key, bool delete_if_exists) const {
unlink_key_if_exists(key); unlink_key_if_exists(key);
return group(_g.createGroup(key.c_str()), _g, key); hid_t id_g = H5Gcreate2(id, key.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (id_g < 0) TRIQS_RUNTIME_ERROR << "Can not create the subgroup " << key << " of the group" << name();
return group(id_g);
} }
/** /**
* \brief Create a dataset. * \brief Create a dataset.
* \param key The name of the subgroup * \param key The name of the subgroup
* \param args Other parameters are forwarded to H5::Group
* *
* NB : It unlinks the dataset if it exists. * NB : It unlinks the dataset if it exists.
*/ */
dataset group::create_dataset(std::string const &key, datatype ty, dataspace sp, hid_t pl) const {
H5::DataSet group::create_dataset(std::string const &key, const H5::DataType &data_type, const H5::DataSpace &data_space,
const H5::DSetCreatPropList &create_plist) const {
unlink_key_if_exists(key); unlink_key_if_exists(key);
H5::DataSet res; dataset ds = H5Dcreate2(id, key.c_str(), ty, sp, H5P_DEFAULT, pl, H5P_DEFAULT);
try { if (!ds.is_valid()) TRIQS_RUNTIME_ERROR << "Can not create the dataset " << key << " in the group" << name();
res = _g.createDataSet(key.c_str(), data_type, data_space, create_plist); return ds;
}
catch (H5::GroupIException const &e) {
TRIQS_RUNTIME_ERROR << "Error in creating the dataset " << key << "\n H5 error message : \n " << e.getCDetailMsg();
}
return res;
} }
//----------------------------------------------------------
// Keep as an example of H5LTset_attribute_string
/*
void group::write_string_attribute (std::string const & obj_name, std::string const & attr_name, std::string const & value){ void group::write_string_attribute (std::string const & obj_name, std::string const & attr_name, std::string const & value){
herr_t err = H5LTset_attribute_string(_g.getId(),obj_name.c_str(),attr_name.c_str(), value.c_str() ) ; herr_t err = H5LTset_attribute_string(id, obj_name.c_str(), attr_name.c_str(), value.c_str());
if (err<0) TRIQS_RUNTIME_ERROR << "Error in setting attribute of "<< obj_name<<" named "<< attr_name << " to " << value; if (err<0) TRIQS_RUNTIME_ERROR << "Error in setting attribute of "<< obj_name<<" named "<< attr_name << " to " << value;
} }
*/
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// C callbacks for the next functions using H5Literate
extern "C" { extern "C" {
herr_t get_group_elements_name_ds(hid_t loc_id, const char *name, void *opdata) { herr_t get_group_elements_name_ds(hid_t loc_id, const char *name, const H5L_info_t *info, void *opdata) {
H5O_info_t object_info; H5O_info_t object_info;
herr_t err = H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT); herr_t err = H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT);
if (err < 0) TRIQS_RUNTIME_ERROR << "get_group_elements_name_ds internal"; if (err < 0) TRIQS_RUNTIME_ERROR << "get_group_elements_name_ds internal";
if (object_info.type == H5O_TYPE_DATASET) static_cast<std::vector<std::string> *>(opdata)->push_back(name); if (object_info.type == H5O_TYPE_DATASET) static_cast<std::vector<std::string> *>(opdata)->push_back(name);
return 0; return 0;
} }
herr_t get_group_elements_name_grp(hid_t loc_id, const char *name, void *opdata) { herr_t get_group_elements_name_grp(hid_t loc_id, const char *name, const H5L_info_t *info, void *opdata) {
H5O_info_t object_info; H5O_info_t object_info;
herr_t err = H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT); herr_t err = H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT);
if (err < 0) TRIQS_RUNTIME_ERROR << "get_group_elements_name_grp internal"; if (err < 0) TRIQS_RUNTIME_ERROR << "get_group_elements_name_grp internal";
@ -116,29 +108,19 @@ namespace h5 {
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
std::vector<std::string> group::get_all_subgroup_names(std::string const &key) const { std::vector<std::string> group::get_all_subgroup_names() const {
std::vector<std::string> grp_name; std::vector<std::string> grp_name;
H5::Group F(_g); int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_grp, static_cast<void *>(&grp_name));
F.iterateElems(key.c_str(), NULL, get_group_elements_name_grp, static_cast<void *>(&grp_name)); if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over subgroups of group " << name() << "failed";
return grp_name; return grp_name;
} }
std::vector<std::string> group::get_all_dataset_names(std::string const &key) const { std::vector<std::string> group::get_all_dataset_names() const {
std::vector<std::string> ds_name; std::vector<std::string> ds_name;
H5::Group F(_g); int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_ds, static_cast<void *>(&ds_name));
F.iterateElems(key.c_str(), NULL, get_group_elements_name_ds, static_cast<void *>(&ds_name)); if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over datasets of group " << name() << "failed";
return ds_name; return ds_name;
} }
std::vector<std::string> group::get_all_subgroup_names() const {
if (!has_parent()) TRIQS_RUNTIME_ERROR << "Group hdf5 : parent not found";
return group(_parent).get_all_subgroup_names(_name_in_parent);
}
std::vector<std::string> group::get_all_dataset_names() const {
if (!has_parent()) TRIQS_RUNTIME_ERROR << "Group hdf5 : parent not found";
return group(_parent).get_all_dataset_names(_name_in_parent);
}
} }
} }

View File

@ -19,33 +19,40 @@
* *
******************************************************************************/ ******************************************************************************/
#pragma once #pragma once
#include "./base.hpp" #include "./file.hpp"
namespace triqs { namespace triqs {
namespace h5 { namespace h5 {
// using hid_t = int;
/** /**
* \brief A local derivative of Group. * \brief A local derivative of Group.
* Rational : use ADL for h5_read/h5_write, catch and rethrow exception, add some policy for opening/creating * Rational : use ADL for h5_read/h5_write, catch and rethrow exception, add some policy for opening/creating
*/ */
class group { class group : public h5_object {
// hid_t _g_id, _parent_id; void _write_triqs_hdf5_data_scheme(const char *a); // impl.
H5::Group _g, _parent;
std::string _name_in_parent;
group(H5::Group g, H5::Group parent, std::string name_in_parent);
void _write_triqs_hdf5_data_scheme(const char *a);
public: public:
group() = default; group() = default; // for python converter only
group(group const &) = default;
group(H5::Group g) : _g(g) {}
group(H5::H5File f); /// Takes the "/" group at the top of the file
group(std::string const &filename, int flag);
group(hid_t id_, bool is_group);
bool has_parent() const { return _name_in_parent != ""; } ///
group(group const &) = default;
/// Takes the "/" group at the top of the file
group(h5::file f);
/**
* Takes ownership of the id [expert only]
* id can be :
* - a file : in this case, make a group on /
* - a group : in this case, take the id of the group. DOES NOT take ownership of the ref
*/
group(hid_t id_);
// [expert only]. If not present, the obj is casted to hid_t and there is a ref. leak
group(h5_object obj);
/// Name of the group
std::string name() const;
/// Write the triqs tag of the group if it is an object. /// Write the triqs tag of the group if it is an object.
template <typename T> void write_triqs_hdf5_data_scheme(T const &obj) { template <typename T> void write_triqs_hdf5_data_scheme(T const &obj) {
@ -57,15 +64,15 @@ namespace h5 {
/// ///
bool has_key(std::string const &key) const; bool has_key(std::string const &key) const;
///
///
void unlink_key_if_exists(std::string const &key) const; void unlink_key_if_exists(std::string const &key) const;
/// Open a subgroup. Throw it if does not exists /// Open a subgroup. Throw it if does not exists
group open_group(std::string const &key) const; group open_group(std::string const &key) const;
/// Open an existing DataSet. Throw it if does not exists /// Open an existing DataSet. Throw it if does not exists
H5::DataSet open_dataset(std::string const &key) const; dataset open_dataset(std::string const &key) const;
/** /**
* \brief Create a subgroup. * \brief Create a subgroup.
@ -80,22 +87,13 @@ namespace h5 {
* *
* NB : It unlinks the dataset if it exists. * NB : It unlinks the dataset if it exists.
*/ */
H5::DataSet create_dataset(std::string const &key, const H5::DataType &data_type, const H5::DataSpace &data_space, dataset create_dataset(std::string const &key, datatype ty, dataspace sp, hid_t pl = H5P_DEFAULT) const;
const H5::DSetCreatPropList &create_plist= H5::DSetCreatPropList::DEFAULT) const;
/// Returns all names of subgroup of key in G
std::vector<std::string> get_all_subgroup_names(std::string const &key) const;
/// Returns all names of subgroup of G /// Returns all names of subgroup of G
std::vector<std::string> get_all_subgroup_names() const; std::vector<std::string> get_all_subgroup_names() const;
/// Returns all names of dataset of key in G
std::vector<std::string> get_all_dataset_names(std::string const &key) const;
/// Returns all names of dataset of G /// Returns all names of dataset of G
std::vector<std::string> get_all_dataset_names() const; std::vector<std::string> get_all_dataset_names() const;
void write_string_attribute (std::string const & obj_name, std::string const & attr_name, std::string const & value);
}; };
} }
} }

View File

@ -1,78 +0,0 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2011-2013 by M. Ferrero, O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#ifndef TRIQS_TOOLS_H5_MAKE_READ_WRITE_H
#define TRIQS_TOOLS_H5_MAKE_READ_WRITE_H
#include <triqs/utility/first_include.hpp>
#include <triqs/h5.hpp>
#include <triqs/utility/serialization.hpp>
#include <string>
namespace triqs { namespace h5 {
template<typename T, typename Enable=void> struct has_h5_read : std::false_type {};
template<typename T> struct has_h5_read<T, decltype(h5_read(std::declval<h5::group>(), std::string(), *(std::declval<T*>())))> : std::true_type {};
template<typename T, typename Enable=void> struct has_h5_write : std::false_type {};
template<typename T> struct has_h5_write<T, decltype(h5_write(std::declval<h5::group>(), std::string(), std::declval<const T>()))> : std::true_type {};
typedef std::function<void(h5::group, std::string const &)> h5_rw_lambda_t;
namespace details {
// given a pointer to an object, synthesize h5_read/write function for this object
template<typename T> h5_rw_lambda_t make_h5_write_impl(T * p, std::integral_constant<int,0>) {
return [p](h5::group F, std::string const &Name) {h5_write(F,Name, *p);};
}
template<typename T> h5_rw_lambda_t make_h5_read_impl(T * p, std::integral_constant<int,0>) {
return [p](h5::group F, std::string const &Name) {h5_read(F,Name, *p);};
}
// use boost serialization as a generic case
template<typename T> h5_rw_lambda_t make_h5_read_impl(T * p, std::integral_constant<int,1>) {
return [p](h5::group F, std::string const &Name) { std::string s; h5_read(F,Name, s); *p = triqs::deserialize<T>(s); };
}
template<typename T> h5_rw_lambda_t make_h5_write_impl(const T * p, std::integral_constant<int,1>) {
return
[p](h5::group F, std::string const &Name) {h5_write(F,Name, triqs::serialize(*p));
F.write_string_attribute(Name,"TRIQS_HDF5_data_scheme",get_triqs_hdf5_data_scheme(*p));
};
}
// do_nothing
template<typename T> h5_rw_lambda_t make_h5_read_impl (T * p, std::integral_constant<int,2>) { return h5_rw_lambda_t();}
template<typename T> h5_rw_lambda_t make_h5_write_impl(T * p, std::integral_constant<int,2>) { return h5_rw_lambda_t();}
}//details
// Generate a lambda (h5::group, Name) -> void
// that calls h5_read/write if it exists, and reverts to boost serialization into a string otherwise
template<typename T> h5_rw_lambda_t make_h5_write(T * p) { return details::make_h5_write_impl(p,std::integral_constant<int,has_h5_write<T>::value?0:1>());}
template<typename T> h5_rw_lambda_t make_h5_read (T * p) { return details::make_h5_read_impl (p,std::integral_constant<int,has_h5_read <T>::value?0:1>());}
// Generate a lambda (h5::group, Name) -> void
// that calls h5_read/write if it exists, and does nothing otherwise
template<typename T> h5_rw_lambda_t make_h5_write_or_nothing(T * p) { return details::make_h5_write_impl(p,std::integral_constant<int,has_h5_write<T>::value?0:2>());}
template<typename T> h5_rw_lambda_t make_h5_read_or_nothing (T * p) { return details::make_h5_read_impl (p,std::integral_constant<int,has_h5_read <T>::value?0:2>());}
}}// end namespace
#endif

View File

@ -44,10 +44,10 @@ namespace triqs {
void h5_read (group f, std::string const & name, std::map<std::string,T> & M) { void h5_read (group f, std::string const & name, std::map<std::string,T> & M) {
auto gr = f.open_group(name); auto gr = f.open_group(name);
M.clear(); M.clear();
T value;
for (auto const & x: gr.get_all_dataset_names()) { for (auto const & x: gr.get_all_dataset_names()) {
T value;
h5_read(gr, x, value); h5_read(gr, x, value);
M.emplace(x, value); M.emplace(x, std::move(value));
} }
} }

View File

@ -19,37 +19,48 @@
* *
******************************************************************************/ ******************************************************************************/
#include "./scalar.hpp" #include "./scalar.hpp"
namespace triqs { namespace h5 { #include "./base.hpp"
namespace triqs {
namespace h5 {
namespace { namespace {
// TODO : Fix complex number .... // TODO : Fix complex number ....
// S must be scalar // S must be scalar
template <typename S> template <typename S> void h5_write_impl(group g, std::string const &key, S a) {
void h5_write_impl (group g, std::string const & name, S const & A) {
try { g.unlink_key_if_exists(key);
g.unlink_key_if_exists(name);
H5::DataSet ds = g.create_dataset( name, data_type_file<S>(), H5::DataSpace() ); dataspace space = H5Screate(H5S_SCALAR);
ds.write( (void *)(&A), data_type_memory<S>(), H5::DataSpace() ); auto ds = g.create_dataset(key, data_type_file<S>(), space);
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; auto err = H5Dwrite(ds, data_type_memory<S>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)(&a));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the scalar dataset " << key << " in the group" << g.name();
} }
template <typename S> //-------------------------------------------------------------
void h5_read_impl (group g, std::string const & name, S & A) {
try { template <typename S> void h5_read_impl(group g, std::string const &name, S &A) {
H5::DataSet ds = g.open_dataset(name);
H5::DataSpace dataspace = ds.getSpace(); dataset ds = g.open_dataset(name);
int rank = dataspace.getSimpleExtentNdims(); dataspace d_space = H5Dget_space(ds);
if (rank != 0) TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : expecting a scalar (rank =0)"
<<" while the array stored in the hdf5 file has rank = "<<rank; // check that rank is 0, it is a scalar.
ds.read( (void *)(&A), data_type_memory<S>(), H5::DataSpace() , H5::DataSpace() ); int rank = H5Sget_simple_extent_ndims(d_space);
} if (rank != 0)
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : expecting a scalar (rank =0)"
<< " while the array stored in the hdf5 file has rank = " << rank;
herr_t err = H5Dread(ds, data_type_memory<S>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)(&A));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the scalar dataset " << name << " in the group" << g.name();
} }
} }
// template <> void h5_write_impl(group g, std::string const &key, std::complex<double> a);
// template <> void h5_read_impl(group g, std::string const &key, std::complex<double> &a);
void h5_write(group g, std::string const &name, int const &x) { h5_write_impl(g, name, x); } void h5_write(group g, std::string const &name, int const &x) { h5_write_impl(g, name, x); }
void h5_write(group g, std::string const &name, long const &x) { h5_write_impl(g, name, x); } void h5_write(group g, std::string const &name, long const &x) { h5_write_impl(g, name, x); }
void h5_write(group g, std::string const &name, size_t const &x) { h5_write_impl(g, name, x); } void h5_write(group g, std::string const &name, size_t const &x) { h5_write_impl(g, name, x); }
@ -58,7 +69,6 @@ namespace triqs { namespace h5 {
void h5_write(group g, std::string const &name, double const &x) { h5_write_impl(g, name, x); } void h5_write(group g, std::string const &name, double const &x) { h5_write_impl(g, name, x); }
void h5_write(group g, std::string const &name, std::complex<double> const &x) { h5_write_impl(g, name, x); } void h5_write(group g, std::string const &name, std::complex<double> const &x) { h5_write_impl(g, name, x); }
void h5_read(group g, std::string const &name, int &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, int &x) { h5_read_impl(g, name, x); }
void h5_read(group g, std::string const &name, long &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, long &x) { h5_read_impl(g, name, x); }
void h5_read(group g, std::string const &name, size_t &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, size_t &x) { h5_read_impl(g, name, x); }
@ -66,9 +76,6 @@ namespace triqs { namespace h5 {
void h5_read(group g, std::string const &name, bool &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, bool &x) { h5_read_impl(g, name, x); }
void h5_read(group g, std::string const &name, double &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, double &x) { h5_read_impl(g, name, x); }
void h5_read(group g, std::string const &name, std::complex<double> &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, std::complex<double> &x) { h5_read_impl(g, name, x); }
}
}
}}

View File

@ -20,6 +20,7 @@
******************************************************************************/ ******************************************************************************/
#pragma once #pragma once
#include "./group.hpp" #include "./group.hpp"
#include <complex>
namespace triqs { namespace h5 { namespace triqs { namespace h5 {
// Issue several types are *implicitly* convertible to bool // Issue several types are *implicitly* convertible to bool

View File

@ -19,9 +19,7 @@
* *
******************************************************************************/ ******************************************************************************/
#pragma once #pragma once
//#include <hdf5.h> #include "./base.hpp"
#include <triqs/h5.hpp>
#include <triqs/utility/view_tools.hpp>
//#define CHECK_OR_THROW(Cond, Mess) //#define CHECK_OR_THROW(Cond, Mess)
#define CHECK_OR_THROW(Cond, Mess) \ #define CHECK_OR_THROW(Cond, Mess) \
@ -32,62 +30,52 @@ namespace h5 {
template <typename T> std::string serialize(T const &x) { template <typename T> std::string serialize(T const &x) {
hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); proplist fapl = H5Pcreate(H5P_FILE_ACCESS);
CHECK_OR_THROW((fapl_id >= 0), "creating fapl"); CHECK_OR_THROW((fapl >= 0), "creating fapl");
auto err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), false); auto err = H5Pset_fapl_core(fapl, (size_t)(64 * 1024), false);
CHECK_OR_THROW((err >= 0), "setting core file driver in fapl."); CHECK_OR_THROW((err >= 0), "setting core file driver in fapl.");
hid_t file_id = H5Fcreate("serialization", 0, H5P_DEFAULT, fapl_id); h5::file f = H5Fcreate("serialization", 0, H5P_DEFAULT, fapl);
CHECK_OR_THROW((file_id >= 0), "created core file"); CHECK_OR_THROW((f.is_valid()), "created core file");
auto gr = triqs::h5::group(file_id, false); auto gr = triqs::h5::group(f);
h5_write(gr, "object", x); h5_write(gr, "object", x);
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL); err = H5Fflush(f, H5F_SCOPE_GLOBAL);
CHECK_OR_THROW((err >= 0), "flushed core file."); CHECK_OR_THROW((err >= 0), "flushed core file.");
ssize_t image_len = H5Fget_file_image(file_id, NULL, (size_t)0); ssize_t image_len = H5Fget_file_image(f, NULL, (size_t)0);
CHECK_OR_THROW((image_len > 0), "got image file size"); CHECK_OR_THROW((image_len > 0), "got image file size");
std::string buf(image_len, 0); std::string buf(image_len, 0);
ssize_t bytes_read = H5Fget_file_image(file_id, (void *)&buf[0], (size_t)image_len); ssize_t bytes_read = H5Fget_file_image(f, (void *)&buf[0], (size_t)image_len);
CHECK_OR_THROW(bytes_read == image_len, "wrote file into image buffer"); CHECK_OR_THROW(bytes_read == image_len, "wrote file into image buffer");
err = H5Fclose(file_id);
CHECK_OR_THROW((err >= 0), "closed core file(1).");
err = H5Pclose(fapl_id);
CHECK_OR_THROW((err >= 0), "closed fapl(1).");
return buf; return buf;
} }
// -----------------------------
template <typename T> T deserialize(std::string const &buf) { template <typename T> T deserialize(std::string const &buf) {
T res; T res;
hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); proplist fapl = H5Pcreate(H5P_FILE_ACCESS);
CHECK_OR_THROW((fapl_id >= 0), "creating fapl"); CHECK_OR_THROW((fapl >= 0), "creating fapl");
auto err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), false); auto err = H5Pset_fapl_core(fapl, (size_t)(64 * 1024), false);
CHECK_OR_THROW((err >= 0), "setting core file driver in fapl."); CHECK_OR_THROW((err >= 0), "setting core file driver in fapl.");
err = H5Pset_file_image(fapl_id, (void *)&buf[0], buf.size()); err = H5Pset_file_image(fapl, (void *)&buf[0], buf.size());
CHECK_OR_THROW((err >= 0), "set file image in fapl."); CHECK_OR_THROW((err >= 0), "set file image in fapl.");
hid_t file_id = H5Fopen("serialization", H5F_ACC_RDONLY, fapl_id); h5::file f = H5Fopen("serialization", H5F_ACC_RDONLY, fapl);
CHECK_OR_THROW((file_id >= 0), "opened received file image file"); CHECK_OR_THROW((f.is_valid()), "opened received file image file");
auto gr = triqs::h5::group(file_id, false); auto gr = triqs::h5::group(f);
h5_read(gr, "object", res); h5_read(gr, "object", res);
err = H5Fclose(file_id);
CHECK_OR_THROW((err >= 0), "closed core file(1).");
err = H5Pclose(fapl_id);
CHECK_OR_THROW((err >= 0), "closed fapl(1).");
return res; return res;
} }
} }

View File

@ -19,33 +19,44 @@
* *
******************************************************************************/ ******************************************************************************/
#include "./string.hpp" #include "./string.hpp"
#include "./base.hpp"
namespace triqs { namespace triqs {
namespace h5 { namespace h5 {
void h5_write (group g, std::string const & name, std::string const & value) { void h5_write(group g, std::string const& name, std::string const& value) {
try {
H5::StrType strdatatype(H5::PredType::C_S1, value.size() + 1); // +1 for the 0 terminating char datatype strdatatype = H5Tcopy(H5T_C_S1);
H5::DataSet ds = g.create_dataset(name, strdatatype, H5::DataSpace()); // auto status = H5Tset_size (strdatatype, H5T_VARIABLE);
ds.write((void*)(value.c_str()), strdatatype ); auto status = H5Tset_size(strdatatype, value.size() + 1);
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; dataspace space = H5Screate(H5S_SCALAR);
dataset ds = g.create_dataset(name, strdatatype, space);
auto err = H5Dwrite(ds, strdatatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void*)(value.c_str()));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the string named" << name << " in the group" << g.name();
} }
void h5_read (group g, std::string const & name, std::string & value) { // ------------
try {
H5::DataSet ds = g.open_dataset(name); void h5_read(group g, std::string const& name, std::string& value) {
H5::DataSpace dataspace = ds.getSpace(); dataset ds = g.open_dataset(name);
int rank = dataspace.getSimpleExtentNdims(); h5::dataspace d_space = H5Dget_space(ds);
if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string and got rank !=0"; int rank = H5Sget_simple_extent_ndims(d_space);
size_t size = ds.getStorageSize(); if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string and got rank !=0";
H5::StrType strdatatype(H5::PredType::C_S1, size); size_t size = H5Dget_storage_size(ds);
std::vector<char> buf(size+1, 0x00);
ds.read( (void *)(&buf[0]), strdatatype, H5::DataSpace(), H5::DataSpace() ); datatype strdatatype = H5Tcopy(H5T_C_S1);
value = ""; value.append( &(buf.front()) ); auto status = H5Tset_size(strdatatype, size);
} // auto status = H5Tset_size (strdatatype, H5T_VARIABLE);
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
std::vector<char> buf(size + 1, 0x00);
auto err = H5Dread(ds, strdatatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the string named" << name << " in the group" << g.name();
value = "";
value.append(&(buf.front()));
} }
}
}} }

View File

@ -30,10 +30,9 @@ namespace triqs {
/** /**
* \brief Write a string into an hdf5 file * \brief Write a string into an hdf5 file
* \param f The h5 file or group of type H5::H5File or H5::Group * \param f The h5 file or group
* \param name The name of the hdf5 array in the file/group where the stack will be stored * \param name The name of the hdf5 array in the file/group where the stack will be stored
* \param value The string * \param value The string
* \exception The HDF5 exceptions will be caught and rethrown as TRIQS_RUNTIME_ERROR (with a full stackstrace, cf triqs doc).
*/ */
void h5_write (group g, std::string const & name, std::string const & value); void h5_write (group g, std::string const & name, std::string const & value);
@ -41,10 +40,9 @@ namespace triqs {
/** /**
* \brief Read a string from an hdf5 file * \brief Read a string from an hdf5 file
* \param f The h5 file or group of type H5::H5File or H5::Group * \param f The h5 file or group
* \param name The name of the hdf5 array in the file/group where the stack will be stored * \param name The name of the hdf5 array in the file/group where the stack will be stored
* \param value The string to fill * \param value The string to fill
* \exception The HDF5 exceptions will be caught and rethrown as TRIQS_RUNTIME_ERROR (with a full stackstrace, cf triqs doc).
*/ */
void h5_read (group g, std::string const & name, std::string & value); void h5_read (group g, std::string const & name, std::string & value);

View File

@ -19,102 +19,122 @@
* *
******************************************************************************/ ******************************************************************************/
#include "./vector.hpp" #include "./vector.hpp"
#include "./base.hpp"
namespace triqs { namespace triqs {
namespace h5 { namespace h5 {
void h5_write (group g, std::string const & name, std::vector<std::string> const & V) { void h5_write(group g, std::string const &name, std::vector<std::string> const &V) {
size_t s=0; for (auto & x : V) s = std::max(s,x.size()); size_t s = 0;
try { for (auto &x : V) s = std::max(s, x.size());
H5::DataSet ds;
H5::StrType strdatatype(H5::PredType::C_S1, s);
const size_t n = V.size();
std::vector<char> buf(n*(s+1), 0x00);
size_t i=0; for (auto & x : V) {strcpy( &buf[i*s], x.c_str()); ++i;}
hsize_t L[1], S[1]; datatype strdatatype = H5Tcopy (H5T_C_S1);
L[0] = V.size(); auto status = H5Tset_size (strdatatype, s);
S[0] = 1; //auto status = H5Tset_size (strdatatype, H5T_VARIABLE);
auto d_space = dataspace_from_LS(1,false,L,L,S);
ds = g.create_dataset(name, strdatatype, d_space ); const size_t n = V.size();
ds.write( (void *)(&buf[0]),strdatatype, d_space ); std::vector<char> buf(n * (s + 1), 0x00);
} size_t i = 0;
TRIQS_ARRAYS_H5_CATCH_EXCEPTION; for (auto &x : V) {
} strcpy(&buf[i * s], x.c_str());
++i;
}
void h5_read (group g, std::string const & name, std::vector<std::string> & V) { hsize_t L[1], S[1];
try { L[0] = V.size();
H5::DataSet ds = g.open_dataset(name); S[0] = 1;
H5::DataSpace dataspace = ds.getSpace(); auto d_space = dataspace_from_LS(1, false, L, L, S);
mini_vector<hsize_t,1> dims_out;
int ndims = dataspace.getSimpleExtentDims( &dims_out[0], NULL);
if (ndims !=1) TRIQS_RUNTIME_ERROR << "triqs::h5 : Trying to read 1d array/vector . Rank mismatch : the array stored in the hdf5 file has rank = "<<ndims;
size_t Len = dims_out[0];
V.resize(Len);
size_t size = ds.getStorageSize();
H5::StrType strdatatype(H5::PredType::C_S1, size);
std::vector<char> buf(Len*(size+1), 0x00);
hsize_t L[1], S[1];
L[0] = V.size();
S[0] = 1;
auto d_space = dataspace_from_LS(1,false, L,L,S);
ds.read( (void *)(&buf[0]),strdatatype, d_space );
size_t i=0; for (auto & x : V) { x = ""; x.append(&buf[i*(size)]); ++i;}
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
}
// implementation for vector of double and complex
namespace {
// the dataspace corresponding to the array. Contiguous data only...
template <typename T> H5::DataSpace data_space_for_vector(std::vector<T> const &V) {
hsize_t L[1], S[1];
S[0] = 1;
L[0] = V.size();
return h5::dataspace_from_LS(1, triqs::is_complex<T>::value, L, L, S);
}
template<typename T>
inline void h5_write_vector_impl (group g, std::string const & name, std::vector<T> const & V) {
try {
H5::DataSet ds = g.create_dataset(name, h5::data_type_file<T>(), data_space_for_vector(V) );
ds.write( &V[0], h5::data_type_memory<T>(), data_space_for_vector(V) );
// if complex, to be python compatible, we add the __complex__ attribute
if (triqs::is_complex<T>::value) h5::write_string_attribute(&ds,"__complex__","1");
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
}
template<typename T>
inline void h5_read_impl (group g, std::string const & name, std::vector<T> & V) {
try {
H5::DataSet ds = g.open_dataset(name);
H5::DataSpace dataspace = ds.getSpace();
static const unsigned int Rank = 1 + (triqs::is_complex<T>::value ? 1 : 0);
int rank = dataspace.getSimpleExtentNdims();
if (rank != Rank) TRIQS_RUNTIME_ERROR << "triqs : h5 : read vector. Rank mismatch : the array stored in the hdf5 file has rank = "<<rank;
mini_vector<hsize_t,Rank> dims_out;
dataspace.getSimpleExtentDims( &dims_out[0], NULL);
V.resize(dims_out[0]);
ds.read( &V[0], h5::data_type_memory<T>(), data_space_for_vector(V) , dataspace );
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
}
}// impl namespace
void h5_write (group f, std::string const & name, std::vector<double> const & V) { h5_write_vector_impl(f,name,V);}
void h5_write (group f, std::string const & name, std::vector<std::complex<double>> const & V) { h5_write_vector_impl(f,name,V);}
void h5_read (group f, std::string const & name, std::vector<double> & V) { h5_read_impl(f,name,V);}
void h5_read (group f, std::string const & name, std::vector<std::complex<double>> & V) { h5_read_impl(f,name,V);}
h5::dataset ds = g.create_dataset(name, strdatatype, d_space);
auto err = H5Dwrite(ds, strdatatype, d_space, H5S_ALL, H5P_DEFAULT, &buf[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the vector<string> " << name << " in the group" << g.name();
} }
// ----- read -----
void h5_read(group g, std::string const &name, std::vector<std::string> &V) {
dataset ds = g.open_dataset(name);
h5::dataspace d_space = H5Dget_space(ds);
mini_vector<hsize_t, 1> dims_out;
int ndims = H5Sget_simple_extent_dims(d_space, dims_out.ptr(), NULL);
if (ndims != 1) TRIQS_RUNTIME_ERROR
<< "triqs::h5 : Trying to read 1d array/vector . Rank mismatch : the array stored in the hdf5 file has rank = " << ndims;
size_t Len = dims_out[0];
V.resize(Len);
size_t size = H5Dget_storage_size(ds);
datatype strdatatype = H5Tcopy (H5T_C_S1);
auto status = H5Tset_size (strdatatype, size);
//auto status = H5Tset_size (strdatatype, H5T_VARIABLE);
std::vector<char> buf(Len * (size + 1), 0x00);
hsize_t L[1], S[1];
L[0] = V.size();
S[0] = 1;
auto d_space2 = dataspace_from_LS(1, false, L, L, S);
auto err = H5Dread(ds, strdatatype, d_space2, H5S_ALL, H5P_DEFAULT, &buf[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the vector<string> " << name << " in the group" << g.name();
size_t i = 0;
for (auto &x : V) {
x = "";
x.append(&buf[i * (size)]);
++i;
}
}
// implementation for vector of double and complex
namespace {
// the dataspace corresponding to the array. Contiguous data only...
template <typename T> dataspace data_space_for_vector(std::vector<T> const &V) {
hsize_t L[1], S[1];
S[0] = 1;
L[0] = V.size();
return h5::dataspace_from_LS(1, triqs::is_complex<T>::value, L, L, S);
}
//------------------------------------
template <typename T> inline void h5_write_vector_impl(group g, std::string const &name, std::vector<T> const &V) {
dataset ds = g.create_dataset(name, h5::data_type_file<T>(), data_space_for_vector(V));
auto err = H5Dwrite(ds, h5::data_type_memory<T>(), data_space_for_vector(V), H5S_ALL, H5P_DEFAULT, &V[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the vector<....> " << name << " in the group" << g.name();
// if complex, to be python compatible, we add the __complex__ attribute
if (triqs::is_complex<T>::value) h5::write_string_attribute(ds, "__complex__", "1");
}
//------------------------------------
template <typename T> inline void h5_read_impl(group g, std::string const &name, std::vector<T> &V) {
dataset ds = g.open_dataset(name);
h5::dataspace d_space = H5Dget_space(ds);
static const unsigned int Rank = 1 + (triqs::is_complex<T>::value ? 1 : 0);
int rank = H5Sget_simple_extent_ndims(d_space);
if (rank != Rank)
TRIQS_RUNTIME_ERROR << "triqs : h5 : read vector. Rank mismatch : the array stored in the hdf5 file has rank = " << rank;
hsize_t dims_out[Rank];
H5Sget_simple_extent_dims(d_space, dims_out, NULL);
V.resize(dims_out[0]);
auto err = H5Dread(ds, h5::data_type_memory<T>(), data_space_for_vector(V), d_space, H5P_DEFAULT, &V[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the vector<...> " << name << " in the group" << g.name();
}
} // impl namespace
void h5_write(group f, std::string const &name, std::vector<double> const &V) { h5_write_vector_impl(f, name, V); }
void h5_write(group f, std::string const &name, std::vector<std::complex<double>> const &V) { h5_write_vector_impl(f, name, V); }
void h5_read(group f, std::string const &name, std::vector<double> &V) { h5_read_impl(f, name, V); }
void h5_read(group f, std::string const &name, std::vector<std::complex<double>> &V) { h5_read_impl(f, name, V); }
}
} }

View File

@ -22,6 +22,7 @@
#include "./group.hpp" #include "./group.hpp"
#include "./string.hpp" #include "./string.hpp"
#include <vector> #include <vector>
#include <complex>
namespace triqs { namespace triqs {

View File

@ -215,10 +215,27 @@ template <> struct py_converter<triqs::h5::group> {
static pyref group_type; static pyref group_type;
//-------
static triqs::h5::group py2c (PyObject * ob) { static triqs::h5::group py2c (PyObject * ob) {
int id = PyInt_AsLong(borrowed(ob).attr("id").attr("id")); int id = PyInt_AsLong(borrowed(ob).attr("id").attr("id"));
int cmp = PyObject_RichCompareBool((PyObject *)ob->ob_type, group_type, Py_EQ); // id can be a file or a group. If it is a file, we open its root group '/'
return triqs::h5::group (id, (cmp==1)); if (H5Iget_type(id) == H5I_FILE) {
id = H5Gopen2(id, "/", H5P_DEFAULT);
if (id < 0) TRIQS_RUNTIME_ERROR << "Internal error : Can not open the root group / in the file !"; // should never happen
}
else { // must be a group, because check in convertible
H5Iinc_ref(id); // we did not have ownership of the id
}
return triqs::h5::group (id);
}
//-------
#define RAISE(MESS) \
{ \
if (raise_exception) PyErr_SetString(PyExc_TypeError, MESS); \
return false; \
} }
static bool is_convertible(PyObject *ob, bool raise_exception) { static bool is_convertible(PyObject *ob, bool raise_exception) {
@ -227,22 +244,17 @@ template <> struct py_converter<triqs::h5::group> {
if (PyErr_Occurred()) TRIQS_RUNTIME_ERROR << "Can not load h5py module and find the group in it"; if (PyErr_Occurred()) TRIQS_RUNTIME_ERROR << "Can not load h5py module and find the group in it";
} }
int cmp = PyObject_RichCompareBool((PyObject *)ob->ob_type, group_type, Py_EQ); int cmp = PyObject_RichCompareBool((PyObject *)ob->ob_type, group_type, Py_EQ);
if (cmp<0) { if (cmp < 0) RAISE("hd5 : internal : comparison to group type has failed !!");
if (raise_exception) {
PyErr_SetString(PyExc_TypeError, "hd5 : internal : comparison to group type has failed !!");
}
return false;
}
pyref id_py = borrowed(ob).attr("id").attr("id"); pyref id_py = borrowed(ob).attr("id").attr("id");
if ((!id_py) ||(!PyInt_Check((PyObject*)id_py))) { if ((!id_py) || (!PyInt_Check((PyObject *)id_py))) RAISE("hd5 : INTERNAL : group id.id is not an int !!");
if (raise_exception) { int id = PyInt_AsLong(borrowed(ob).attr("id").attr("id"));
PyErr_SetString(PyExc_TypeError, "hd5 : INTERNAL : group id.id is not an int !!"); if (!H5Iis_valid(id)) RAISE("Internal error : invalid id from h5py !");
} if (!((H5Iget_type(id) == H5I_FILE) || (H5Iget_type(id) == H5I_GROUP)))
return false; RAISE("h5py object is neither an hdf5 group or an hdf5 file");
}
return true; return true;
} }
}; };
#undef RAISE
// --- vector --- // --- vector ---

View File

@ -68,8 +68,7 @@ class crash_logger {
names.push_back(name); names.push_back(name);
guards.emplace_back([&obj,this, name](){ guards.emplace_back([&obj,this, name](){
using triqs::h5::h5_write; // to have the proper overload for scalar type !! using triqs::h5::h5_write; // to have the proper overload for scalar type !!
try { h5_write( h5::group(H5::H5File(this->filename_.c_str(),H5F_ACC_RDWR)), name, obj); } try { h5_write( h5::group(h5::file(this->filename_.c_str(),H5F_ACC_RDWR)), name, obj); }
catch(H5::Exception const & e) { std::cerr << "An hdf5 exception has occurred in crash_logger : I can not recover : error is " <<std::endl ; e.printError();}
catch(...) { std::cerr << "An exception has occurred in crash_logger for an object of type " << typeid_name(obj) << " named " << name<< std::endl ; } catch(...) { std::cerr << "An exception has occurred in crash_logger for an object of type " << typeid_name(obj) << " named " << name<< std::endl ; }
}); //end lambda }); //end lambda
return *this; return *this;
@ -81,7 +80,7 @@ class crash_logger {
std::cerr << "crash_logger : I am destroyed without being dismissed. Dumping the objects : "; std::cerr << "crash_logger : I am destroyed without being dismissed. Dumping the objects : ";
for (auto & x : names) std::cerr<< "\""<< x <<"\" "; for (auto & x : names) std::cerr<< "\""<< x <<"\" ";
std::cerr<< std::endl; std::cerr<< std::endl;
H5::H5File(this->filename_.c_str(),H5F_ACC_TRUNC); // create the file h5::file(this->filename_.c_str(), H5F_ACC_TRUNC); // create the file
} }
} }
catch(...) {} // just in case ... destructor can not throw catch(...) {} // just in case ... destructor can not throw