diff --git a/CMakeLists.txt b/CMakeLists.txt index 11da2841..adaedb5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,9 +230,9 @@ link_libraries(${TRIQS_LIBRARY_LAPACK}) 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... 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") - find_package(HDF5 REQUIRED C CXX HL ) + find_package(HDF5 REQUIRED C HL) endif(${CMAKE_VERSION} VERSION_LESS "2.8.6") if(NOT HDF5_FOUND) 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 ? 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_INCLUDE_HDF5 ${HDF5_INCLUDE_DIR}) set(TRIQS_CXX_DEFINITIONS ${TRIQS_CXX_DEFINITIONS} ${HDF5_DEFINITIONS}) diff --git a/doc/installation/osx_lion.rst b/doc/installation/osx_lion.rst index a478859b..4de078c7 100644 --- a/doc/installation/osx_lion.rst +++ b/doc/installation/osx_lion.rst @@ -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 : 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. As a result, the installation instructions may work on one day, and suddenly stop to work 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 install cmake brew install gfortran - brew install --enable-cxx hdf5 + brew install hdf5 brew install gsl brew install fftw brew install open-mpi brew install zmq brew install python - #brew formula has been repaired, since boost installation of mpi.python is a complete mess - #which needs to be fixed manually (except in Debian/Ubuntu where it is correct). + #brew formula has been repaired ### 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 @@ -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 mpi4py pip install matplotlib - pip install breathe pip install sphinxcontrib-doxylink pip install tornado 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 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 --------------- diff --git a/doc/installation/requirements.rst b/doc/installation/requirements.rst index 4eaafc0c..8966920d 100644 --- a/doc/installation/requirements.rst +++ b/doc/installation/requirements.rst @@ -51,9 +51,9 @@ Libraries +------------------------+----------+------------------------------------------------------------------------+ | 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 | +------------------------+----------+------------------------------------------------------------------------+ diff --git a/doc/reference/c++/arrays/h5_rw_0.cpp b/doc/reference/c++/arrays/h5_rw_0.cpp index 47474fa4..04a68488 100644 --- a/doc/reference/c++/arrays/h5_rw_0.cpp +++ b/doc/reference/c++/arrays/h5_rw_0.cpp @@ -6,7 +6,7 @@ int main() { array A(2, 2); 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 // array B; // read the file into B diff --git a/doc/reference/c++/gf/gf_block_0.cpp b/doc/reference/c++/gf/gf_block_0.cpp index fba9d935..71360925 100644 --- a/doc/reference/c++/gf/gf_block_0.cpp +++ b/doc/reference/c++/gf/gf_block_0.cpp @@ -25,7 +25,7 @@ int main() { for (auto &g : Bg1) g = g * i++; // 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); } diff --git a/doc/reference/c++/gf/gf_product_0.cpp b/doc/reference/c++/gf/gf_product_0.cpp index 402c6c21..39245aff 100644 --- a/doc/reference/c++/gf/gf_product_0.cpp +++ b/doc/reference/c++/gf/gf_product_0.cpp @@ -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}}; // 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); } diff --git a/doc/tutorials/c++/array_tutorial_2.cpp b/doc/tutorials/c++/array_tutorial_2.cpp index 618cd480..46511846 100644 --- a/doc/tutorials/c++/array_tutorial_2.cpp +++ b/doc/tutorials/c++/array_tutorial_2.cpp @@ -5,7 +5,7 @@ int main() { array A(2, 2); 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 array B; // read the file into B diff --git a/pytriqs/wrap_generator/wrapper.mako.cpp b/pytriqs/wrap_generator/wrapper.mako.cpp index 105bafdf..670f681e 100644 --- a/pytriqs/wrap_generator/wrapper.mako.cpp +++ b/pytriqs/wrap_generator/wrapper.mako.cpp @@ -23,7 +23,7 @@ ${module._preamble} //--------------------- a dict of python function used in the module but not exposed to user (cf init function) ---------------- -%if len(module.python_functions) + len(module.hidden_python_functions) > 0 : +%if len(module.python_functions) + len(module.hidden_python_functions) > 0 : static PyObject * _module_hidden_python_function = NULL; %endif @@ -63,7 +63,7 @@ static PyObject * ${c.py_type}__get_member_${m.py_name} (PyObject *self, void *c %if not m.read_only: static int ${c.py_type}__set_member_${m.py_name} (PyObject *self, PyObject *value, void *closure); %endif -%endfor +%endfor //--------------------- all properties ----------------------------- @@ -72,7 +72,7 @@ static PyObject * ${c.py_type}__get_prop_${p.name} (PyObject *self, void *closur %if p.setter : static int ${c.py_type}__set_prop_${p.name} (PyObject *self, PyObject *value, void *closure); %endif -%endfor +%endfor //--------------------- [] ----------------------------- @@ -81,7 +81,7 @@ static Py_ssize_t ${c.py_type}___len__(PyObject *self); %endif %if "__getitem__impl" in c.methods : -static PyObject* ${c.py_type}___getitem__(PyObject *self, PyObject *key); +static PyObject* ${c.py_type}___getitem__(PyObject *self, PyObject *key); %endif %if "__setitem__impl" in c.methods : @@ -161,7 +161,7 @@ static PyObject* ${c.py_type}_new(PyTypeObject *type, PyObject *args, PyObject * ##// self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views ##//%endif } - catch (std::exception const & e) { + catch (std::exception const & e) { std::cout << e.what()< struct py_converter<${c.c_type}> { @@ -383,14 +383,14 @@ template <> struct py_converter<${c.c_type}> { } return (PyObject *)self; } - + static ${c.c_type} & py2c(PyObject * ob){ auto *_c = ((${c.py_type} *)ob)->_c; if (_c == NULL) TRIQS_RUNTIME_ERROR << "Severe internal error : _c is null in py2c for type ${c.c_type} !"; return *_c; } - - static bool is_convertible(PyObject *ob, bool raise_exception){ + + static bool is_convertible(PyObject *ob, bool raise_exception){ if (PyObject_TypeCheck(ob, & ${c.py_type}Type)) { if (((${c.py_type} *)ob)->_c != NULL) return true; if (raise_exception) PyErr_SetString(PyExc_TypeError, "Severe internal error : Python object of ${c.py_type} has a _c NULL pointer !!"); @@ -402,7 +402,7 @@ template <> struct py_converter<${c.c_type}> { }; // TO BE MOVED IN GENERAL HPP -%if c.implement_regular_type_converter : +%if c.implement_regular_type_converter : // ${c.py_type} is wrapping a view, we are also implementing the converter of the associated regular type template<> struct py_converter<${c.regular_type}> { using regular_type = ${c.regular_type}; @@ -426,7 +426,7 @@ template <> struct py_converter<${c.c_type}> { %for en in module.enums : -namespace triqs { namespace py_tools { +namespace triqs { namespace py_tools { template <> struct py_converter<${en.c_name}> { static PyObject * c2py(${en.c_name} x) { @@ -475,7 +475,7 @@ template <> struct py_converter<${en.c_name}> { template static int converter_for_parser_non_wrapped_type(PyObject * ob, T * p) { if (!convertible_from_python(ob,true)) return 0; - *p = convert_from_python(ob); + *p = convert_from_python(ob); return 1; } template @@ -535,10 +535,10 @@ template %if t in module._wrapped_types : ${t}* ${n} = NULL; // ${t} is a wrapped type %elif is_type_a_view(t): - ${t} ${n} = typename ${t}::regular_type{}; // ${t} is a view, but not wrapped - %else: + ${t} ${n} = typename ${t}::regular_type{}; // ${t} is a view, but not wrapped + %else: ${t} ${n} ${'=%s'%d if d else ''}; // ${t} is a regular type - %endif + %endif %endfor static char *kwlist[] = {${",".join([ '"%s"'%n for t,n,d in overload.args] + ["NULL"])}}; static const char * format = "${overload._parsing_format()}"; @@ -653,7 +653,7 @@ static PyObject* ${c.py_type}_${f_name} (PyObject *self, PyObject *args, PyObjec PyObject * ret = PyObject_Call(py_fnt, args2,keywds); return ret; } - %else : + %else : // The methods with inline code in the module static PyObject* ${c.py_type}_${f_name} (PyObject *self, PyObject *args, PyObject *keywds) { pyref args2 = PySequence_Concat(PyTuple_Pack(1,self),args); @@ -692,7 +692,7 @@ static int ${c.py_type}__set_member_${m.py_name} (PyObject *self, PyObject *valu static PyObject * ${c.py_type}__get_prop_${p.name} (PyObject *self, void *closure) { %if isinstance(p.getter, str): - // pure python call + // pure python call static pyref py_fnt = pyref::module("${p.getter.rsplit('.',1)[0]}").attr("${p.getter.rsplit('.',1)[1]}"); return py_fnt(self).new_ref(); %else: @@ -1047,11 +1047,11 @@ init${module.name}(void) if (c_api_object != NULL) PyModule_AddObject(m, "_exported_wrapper_convert_fnt", c_api_object); %endif - %if len(module.python_functions) + len(module.hidden_python_functions) > 0 : - + %if len(module.python_functions) + len(module.hidden_python_functions) > 0 : + PyObject* main_module = PyImport_AddModule("__main__"); //borrowed PyObject* global_dict = PyModule_GetDict(main_module); //borrowed - + // load and compile the module function defined in pure python %for f in module.python_functions.values() : if (!PyRun_String( _module_python_function_code_${f.name},Py_file_input, global_dict, PyModule_GetDict(m) )) return; @@ -1061,7 +1061,7 @@ init${module.name}(void) _module_hidden_python_function = PyModule_New("hidden_functions"); // if we wish to still see the functions... PyModule_AddObject(m, "__hidden_fnt", _module_hidden_python_function); - + PyObject * d = PyModule_GetDict(_module_hidden_python_function); //borrowed %for f in module.hidden_python_functions.values() : if (!PyRun_String( _module_hidden_python_function_code_${f.name}, Py_file_input, global_dict ,d)) return; diff --git a/test/pytriqs/wrap_test/g.hpp b/test/pytriqs/wrap_test/g.hpp index 5e933e23..54cdf5cf 100644 --- a/test/pytriqs/wrap_test/g.hpp +++ b/test/pytriqs/wrap_test/g.hpp @@ -10,7 +10,7 @@ block_gf_view make_bgf(double a) { auto B1 = make_block_gf(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); } @@ -20,7 +20,7 @@ block_gf_view make_bgf(double a) { void pass_bgf(block_gf_view 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); } } @@ -31,7 +31,7 @@ gf_view make_sgf(double a) { double beta = 1; auto G1 = gf({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); } return G1; @@ -40,7 +40,7 @@ gf_view make_sgf(double a) { void pass_sgf(gf_view 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); } } diff --git a/test/triqs/arrays/h5_stack.cpp b/test/triqs/arrays/h5_stack.cpp index 8feb77c3..796dc93f 100644 --- a/test/triqs/arrays/h5_stack.cpp +++ b/test/triqs/arrays/h5_stack.cpp @@ -31,7 +31,7 @@ using namespace triqs; template < class T> 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); 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 - H5::H5File file2( filename.c_str() ,H5F_ACC_RDONLY ); + h5::file file2( filename.c_str() ,H5F_ACC_RDONLY ); h5::group top2(file2); h5_read (top2, "A",A_stack_compare); diff --git a/test/triqs/arrays/h5_string_arrays.cpp b/test/triqs/arrays/h5_string_arrays.cpp index 1a32a4a4..8f7e08a5 100644 --- a/test/triqs/arrays/h5_string_arrays.cpp +++ b/test/triqs/arrays/h5_string_arrays.cpp @@ -40,7 +40,7 @@ int main(int argc, char **argv) { V1.push_back("de"); // 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_write(top,"A",A); diff --git a/test/triqs/arrays/h5_vector_array.cpp b/test/triqs/arrays/h5_vector_array.cpp index 2ad20de2..ac165e6f 100644 --- a/test/triqs/arrays/h5_vector_array.cpp +++ b/test/triqs/arrays/h5_vector_array.cpp @@ -40,13 +40,13 @@ int main(int argc, char **argv) { std::vector > 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_write(top,"vdouble",v); 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_read(top2,"vdouble",v2); diff --git a/test/triqs/arrays/hdf5.cpp b/test/triqs/arrays/hdf5.cpp index ceda54d1..3ae6e6b7 100644 --- a/test/triqs/arrays/hdf5.cpp +++ b/test/triqs/arrays/hdf5.cpp @@ -66,14 +66,13 @@ int main(int argc, char **argv) { std::cout<<" C= "< E; h5_read (top, "A",E); std::cout<< "E = "<< E< #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::arrays; @@ -21,17 +22,17 @@ int main(int argc, char* argv[]) { 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, "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, "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, "aa", bb); } diff --git a/test/triqs/gfs/block.cpp b/test/triqs/gfs/block.cpp index e56074d4..ca71b3d8 100644 --- a/test/triqs/gfs/block.cpp +++ b/test/triqs/gfs/block.cpp @@ -21,12 +21,12 @@ int main() { // 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::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; h5_read(file, "B3", B4); std::cout << "B4 mesh" << B4.mesh().size() << std::endl; diff --git a/test/triqs/gfs/curry1.cpp b/test/triqs/gfs/curry1.cpp index da937a15..5afde624 100644 --- a/test/triqs/gfs/curry1.cpp +++ b/test/triqs/gfs/curry1.cpp @@ -5,6 +5,7 @@ namespace tql= triqs::clef; using namespace triqs::gfs; +namespace h5 = triqs::h5; int main() { @@ -84,7 +85,7 @@ try { std::cout << " curry "< using namespace triqs::gfs; +namespace h5 = triqs::h5; int main() { diff --git a/test/triqs/gfs/g_k_om.cpp b/test/triqs/gfs/g_k_om.cpp index 146ea6d0..de207437 100644 --- a/test/triqs/gfs/g_k_om.cpp +++ b/test/triqs/gfs/g_k_om.cpp @@ -2,6 +2,7 @@ #include #include +namespace h5 = triqs::h5; using namespace triqs::gfs; using namespace triqs::clef; using namespace triqs::arrays; @@ -27,7 +28,7 @@ int main() { G(k_, w_) << 1 / (w_ - eps(k_) - 1 / (w_ + 2)); // 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); diff --git a/test/triqs/gfs/g_k_om2.cpp b/test/triqs/gfs/g_k_om2.cpp index 66d27001..f02b112c 100644 --- a/test/triqs/gfs/g_k_om2.cpp +++ b/test/triqs/gfs/g_k_om2.cpp @@ -66,7 +66,7 @@ int main() { //TEST(G_k_tau[{0,0}]); // 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); diff --git a/test/triqs/gfs/gf_notail.cpp b/test/triqs/gfs/gf_notail.cpp index d1480890..f2c796df 100644 --- a/test/triqs/gfs/gf_notail.cpp +++ b/test/triqs/gfs/gf_notail.cpp @@ -2,6 +2,8 @@ #include using namespace triqs::gfs; using namespace triqs::arrays; +namespace h5 = triqs::h5; + #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl; #include @@ -26,7 +28,7 @@ int main() { vt(tau_) << exp(-a * tau_) / (1 + exp(-beta * a)); // 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); // rebuilding a new gf... diff --git a/test/triqs/gfs/gf_positive_and_negative_matsubara.cpp b/test/triqs/gfs/gf_positive_and_negative_matsubara.cpp index 1f6c1c63..146da93b 100644 --- a/test/triqs/gfs/gf_positive_and_negative_matsubara.cpp +++ b/test/triqs/gfs/gf_positive_and_negative_matsubara.cpp @@ -23,7 +23,7 @@ int main() { TEST(n_pos_only); // 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, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G)); diff --git a/test/triqs/gfs/gf_retw.cpp b/test/triqs/gfs/gf_retw.cpp index 87c4267d..31f5832e 100644 --- a/test/triqs/gfs/gf_retw.cpp +++ b/test/triqs/gfs/gf_retw.cpp @@ -1,6 +1,7 @@ #define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK #include using namespace triqs::gfs; +namespace h5 = triqs::h5; using namespace triqs::arrays; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < precision) TRIQS_RUNTIME_ERROR<< "error in on_mesh()\n"; // 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, "gw", Gw); h5_write(file, "git", Git); diff --git a/test/triqs/gfs/gf_scalar.cpp b/test/triqs/gfs/gf_scalar.cpp index b523ee9e..92063764 100644 --- a/test/triqs/gfs/gf_scalar.cpp +++ b/test/triqs/gfs/gf_scalar.cpp @@ -2,6 +2,8 @@ #include #include using namespace triqs::gfs; +namespace h5 = triqs::h5; + #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < using namespace triqs::gfs; using namespace triqs::arrays; +namespace h5 = triqs::h5; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < @@ -118,7 +119,7 @@ int main() { //auto x = local::impl::gf_impl::wrap_infty (G.tail_view()) + 2.0; // 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); // diff --git a/test/triqs/gfs/test_fourier_matsubara.cpp b/test/triqs/gfs/test_fourier_matsubara.cpp index 24a22d8e..5d28f08f 100644 --- a/test/triqs/gfs/test_fourier_matsubara.cpp +++ b/test/triqs/gfs/test_fourier_matsubara.cpp @@ -2,13 +2,14 @@ #include using namespace triqs::gfs; using namespace triqs::arrays; +namespace h5 = triqs::h5; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < int main() { 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_; double beta =1; int N=10000; diff --git a/test/triqs/gfs/test_fourier_real_time.cpp b/test/triqs/gfs/test_fourier_real_time.cpp index 3580ca84..d22fdcb9 100644 --- a/test/triqs/gfs/test_fourier_real_time.cpp +++ b/test/triqs/gfs/test_fourier_real_time.cpp @@ -2,6 +2,7 @@ #include using namespace triqs::gfs; using namespace triqs::arrays; +namespace h5 = triqs::h5; #define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < @@ -18,7 +19,7 @@ double theta(double x){ int main() { 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 I(0,1); diff --git a/test/triqs/gfs/vertex.cpp b/test/triqs/gfs/vertex.cpp index 09a7c991..8c6c3639 100644 --- a/test/triqs/gfs/vertex.cpp +++ b/test/triqs/gfs/vertex.cpp @@ -5,6 +5,7 @@ using namespace triqs::gfs; using triqs::clef::placeholder; +namespace h5 = triqs::h5; int main() { @@ -38,19 +39,19 @@ int main() { //saving { - H5::H5File file("vertex1.h5", H5F_ACC_TRUNC ); + h5::file file("vertex1.h5", H5F_ACC_TRUNC ); h5_write(file, "v", vertex); } // loading { - H5::H5File file("vertex1.h5", H5F_ACC_RDONLY ); + h5::file file("vertex1.h5", H5F_ACC_RDONLY ); h5_read(file, "v", vertex2); } //resaving { - H5::H5File file("vertex1b.h5", H5F_ACC_TRUNC ); + h5::file file("vertex1b.h5", H5F_ACC_TRUNC ); h5_write(file, "v", vertex2); } @@ -63,19 +64,19 @@ int main() { //saving { - H5::H5File file("vertex3.h5", H5F_ACC_TRUNC ); + h5::file file("vertex3.h5", H5F_ACC_TRUNC ); h5_write(file, "v", vertex3); } // loading { - H5::H5File file("vertex3.h5", H5F_ACC_RDONLY ); + h5::file file("vertex3.h5", H5F_ACC_RDONLY ); h5_read(file, "v", vertex3b); } //resaving { - H5::H5File file("vertex3b.h5", H5F_ACC_TRUNC ); + h5::file file("vertex3b.h5", H5F_ACC_TRUNC ); h5_write(file, "v", vertex3b); } diff --git a/test/triqs/h5/map_h5.cpp b/test/triqs/h5/map_h5.cpp index 11f5e8ae..ede001ba 100644 --- a/test/triqs/h5/map_h5.cpp +++ b/test/triqs/h5/map_h5.cpp @@ -26,22 +26,24 @@ namespace h5 = triqs::h5; int main(int argc, char **argv) { - try { + try { // write std::map m = { {"a",1}, {"b",2} }; std::map> 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_write(top1, "map_int", m); - h5_write(top1, "map_vec", mv); + { + h5::file file1("test_map.h5", H5F_ACC_TRUNC); + h5::group top1(file1); + h5_write(top1, "map_int", m); + h5_write(top1, "map_vec", mv); + } // read std::map mm = { {"c",1} }; std::map> 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_read(top2, "map_int", mm); h5_read(top2, "map_vec", mmv); diff --git a/test/triqs/mc_tools/different_moves_mc.cpp b/test/triqs/mc_tools/different_moves_mc.cpp index ae06fb51..ade953e4 100644 --- a/test/triqs/mc_tools/different_moves_mc.cpp +++ b/test/triqs/mc_tools/different_moves_mc.cpp @@ -7,6 +7,7 @@ #define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK #include #include +namespace h5 = triqs::h5; triqs::arrays::array,1> make_array( std::complex c){return {c}; }; @@ -54,7 +55,7 @@ struct compute_histo{ } void collect_results(boost::mpi::communicator const &c) { H/=tot; - H5::H5File file("histo.h5",H5F_ACC_TRUNC); + h5::file file("histo.h5",H5F_ACC_TRUNC); 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 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,"pl",make_array(pl)); h5_write(file,"xmax",make_array(xmax)); diff --git a/test/triqs/parameters/default.cpp b/test/triqs/parameters/default.cpp index dbfa340e..ceaf6e0c 100644 --- a/test/triqs/parameters/default.cpp +++ b/test/triqs/parameters/default.cpp @@ -4,6 +4,7 @@ using namespace triqs::params; using namespace triqs::arrays; +namespace h5 = triqs::h5; int main() { try { @@ -76,20 +77,20 @@ int main() { // hdf5 { - H5::H5File file( "ess.h5", H5F_ACC_TRUNC ); + h5::file file( "ess.h5", H5F_ACC_TRUNC ); h5_write( file, "Parameters", P); } { - H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); - h5_read( file.openGroup("/"), "Parameters", P_vide); + h5::file file( "ess.h5", H5F_ACC_RDONLY ); + h5_read( file, "Parameters", P_vide); } std::cout << P_vide << std::endl; { - H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); - h5_read( file.openGroup("/"), "Parameters", P); + h5::file file( "ess.h5", H5F_ACC_RDONLY ); + h5_read( file, "Parameters", P); } //std::cout << P << std::endl; diff --git a/test/triqs/parameters/param.cpp b/test/triqs/parameters/param.cpp index ad3c3e99..a9e5cd6f 100644 --- a/test/triqs/parameters/param.cpp +++ b/test/triqs/parameters/param.cpp @@ -120,18 +120,18 @@ int main() { 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); } auto P4 = P; { - H5::H5File file( "ess.h5", H5F_ACC_RDONLY ); - h5_read( file.openGroup("/"), "Parameters", P4); + h5::file file( "ess.h5", H5F_ACC_RDONLY ); + h5_read( file, "Parameters", P4); } { - H5::H5File file( "ess_relo.h5", H5F_ACC_TRUNC ); - h5_write( file.openGroup("/"), "Parameters", P4); + h5::file file( "ess_relo.h5", H5F_ACC_TRUNC ); + h5_write( file, "Parameters", P4); } std::cout << "P4 after : \n"<< P4<< std::endl ; diff --git a/test/triqs/utility/h5_seria.cpp b/test/triqs/utility/h5_seria.cpp index c8b9b3e1..ab7f5a2c 100644 --- a/test/triqs/utility/h5_seria.cpp +++ b/test/triqs/utility/h5_seria.cpp @@ -32,6 +32,7 @@ using triqs::h5::deserialize; int main() { + try{ using triqs::arrays::array; auto a = array{1, 2, 3, 4, 5}; @@ -54,7 +55,8 @@ int main() { auto b = deserialize>(s1); std::cout << "a = " << a << " == " << b << std::endl; - + } + catch(std::exception const & e) { std::cout << e.what()< #include "./simple_read_write.hpp" +#include namespace triqs { namespace arrays { // to be cleaned - namespace h5_impl { + namespace h5_impl { template 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 H5::DataSpace data_space(ArrayType const& A) { + template h5::dataspace data_space(ArrayType const& A) { 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::value); } } - + /// The implementation class template class array_stack_impl { static const size_t dim = R; @@ -47,7 +48,7 @@ namespace arrays { static const bool T_is_complex = triqs::is_complex::value; static const unsigned int RANK = dim + 1 + (T_is_complex ? 1 : 0); utility::mini_vector dims, offset, maxdims, dim_chunk, buffer_dim, zero; - H5::DataSet dataset; + h5::dataset d_set; array buffer; public: @@ -74,14 +75,11 @@ namespace arrays { s[i] = buffer_dim[i]; } buffer.resize(s); - H5::DataSpace mspace1(RANK, dims.ptr(), maxdims.ptr()); - H5::DSetCreatPropList cparms; - cparms.setChunk(RANK, dim_chunk.ptr()); // Modify dataset creation properties, i.e. enable chunking. - try { - dataset = g.create_dataset(name, h5::native_type_from_C(typename h5::remove_complex::type()), mspace1, cparms); - if (triqs::is_complex::value) h5::write_string_attribute(&dataset, "__complex__", "1"); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + h5::dataspace mspace1 = H5Screate_simple(RANK, dims.ptr(), maxdims.ptr()); + h5::proplist cparms = H5Pcreate(H5P_DATASET_CREATE); + auto err = H5Pset_chunk(cparms, RANK, dim_chunk.ptr()); + d_set = g.create_dataset(name, h5::native_type_from_C(T()), mspace1, cparms); + if (triqs::is_complex::value) h5::write_string_attribute(d_set, "__complex__", "1"); } /// @@ -128,27 +126,32 @@ namespace arrays { if (step == 0) return; dims[0] += step; buffer_dim[0] = step; - dataset.extend(dims.ptr()); - H5::DataSpace fspace1 = dataset.getSpace(), mspace = h5_impl::data_space(buffer); - fspace1.selectHyperslab(H5S_SELECT_SET, buffer_dim.ptr(), offset.ptr()); - mspace.selectHyperslab(H5S_SELECT_SET, buffer_dim.ptr(), zero.ptr()); - try { - dataset.write(h5_impl::__get_array_data_ptr(buffer), h5::data_type_memory(), mspace, fspace1); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + + herr_t err= H5Dset_extent(d_set,dims.ptr()); // resize the data_space + + h5::dataspace fspace1 = H5Dget_space(d_set); + h5::dataspace mspace = h5_impl::data_space(buffer); + + err = H5Sselect_hyperslab(fspace1, H5S_SELECT_SET, offset.ptr(), NULL, buffer_dim.ptr(), NULL); + 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(), 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; } }; // ------------------------- User classes ------------------------------ - + // The simple case, 1d template class array_stack : public array_stack_impl { static_assert((is_scalar::value), "Only available for a scalar type"); public: /** - * \brief Constructor - * \param g The h5 group + * \brief Constructor + * \param g The h5 group * \param name The name of the hdf5 array in the file/group where the stack will be stored * \param bufsize The size of the buffer * \exception The HDF5 exceptions will be caught and rethrown as TRIQS_RUNTIME_ERROR (with stackstrace, cf doc). @@ -162,7 +165,7 @@ namespace arrays { public: /** * \brief Constructor - * \param g The h5 group + * \param g The h5 group * \param name The name of the hdf5 array in the file/group where the stack will be stored * \param base_element_shape The shape of the base array of the stack. * \param bufsize The size of the buffer diff --git a/triqs/arrays/h5/simple_read_write.cpp b/triqs/arrays/h5/simple_read_write.cpp index 91b75fff..a8c22d3e 100644 --- a/triqs/arrays/h5/simple_read_write.cpp +++ b/triqs/arrays/h5/simple_read_write.cpp @@ -19,6 +19,7 @@ * ******************************************************************************/ #include "./simple_read_write.hpp" +#include "./../../h5/base.hpp" using dcomplex = std::complex; namespace triqs { @@ -26,7 +27,7 @@ namespace arrays { namespace h5_impl { // 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]; for (int u = 0; u < info.R; ++u) { if (info.strides[u] <= 0) TRIQS_RUNTIME_ERROR << " negative strides not permitted in h5"; @@ -37,17 +38,18 @@ namespace arrays { } /// --------------------------- WRITE --------------------------------------------- - + template void write_array_impl(h5::group g, std::string const& name, const T* start, array_stride_info info) { static_assert(!std::is_base_of::value, " Not implemented"); // 1d is below bool is_complex = triqs::is_complex::value; - try { - H5::DataSet ds = g.create_dataset(name, h5::data_type_file(), data_space_impl(info, is_complex)); - ds.write(h5::get_data_ptr(start), h5::data_type_memory(), data_space_impl(info, is_complex)); - // if complex, to be python compatible, we add the __complex__ attribute - if (is_complex) h5::write_string_attribute(&ds, "__complex__", "1"); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + h5::dataset ds = g.create_dataset(name, h5::data_type_file(), data_space_impl(info, is_complex)); + + auto err = + H5Dwrite(ds, h5::data_type_memory(), data_space_impl(info, is_complex), H5S_ALL, H5P_DEFAULT, h5::get_data_ptr(start)); + if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the scalar dataset " << name << " in the group" << g.name(); + + // 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(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(h5::group g, std::string const& name, const double* start, array_stride_info info); template void write_array_impl(h5::group g, std::string const& name, const dcomplex* start, array_stride_info info); - // overload : special treatment for arrays of strings (one dimension only). void write_array(h5::group g, std::string const& name, vector_const_view V) { std::vector tmp(V.size()); @@ -70,61 +71,31 @@ namespace arrays { } /// --------------------------- READ --------------------------------------------- - - -/* template void read_array(h5::group g, std::string const& name, ArrayType1&& A, bool C_reorder = true) { - typedef typename std::remove_reference::type ArrayType; - static_assert(!std::is_base_of::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::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 dims_out; - dataspace.getSimpleExtentDims(&dims_out[0], NULL); - mini_vector 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(A).view(), false); - } else - ds.read(__get_array_data_ptr(A), h5::data_type_memory(), data_space(A), dataspace); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } -*/ - - std::vector get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex) { - try { - H5::DataSet ds = g.open_dataset(name); - H5::DataSpace dataspace = ds.getSpace(); - int Rank = R + (is_complex ? 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; - std::vector d2(R); - hsize_t dims_out[rank]; - dataspace.getSimpleExtentDims(&dims_out[0], NULL); - for (int u = 0; u < R; ++u) d2[u] = dims_out[u]; - return d2; - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + + std::vector get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex) { + h5::dataset ds = g.open_dataset(name); + h5::dataspace d_space = H5Dget_space(ds); + int Rank = R + (is_complex ? 1 : 0); + int rank = H5Sget_simple_extent_ndims(d_space); + 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; + std::vector d2(R); + hsize_t dims_out[rank]; + H5Sget_simple_extent_dims(d_space, dims_out, NULL); + for (int u = 0; u < R; ++u) d2[u] = dims_out[u]; + return d2; } - template void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) { + template void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) { static_assert(!std::is_base_of::value, " Not implemented"); // 1d is below bool is_complex = triqs::is_complex::value; - try { - H5::DataSet ds = g.open_dataset(name); - H5::DataSpace dataspace = ds.getSpace(); - ds.read(h5::get_data_ptr(start), h5::data_type_memory(), data_space_impl(info, is_complex), dataspace); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + h5::dataset ds = g.open_dataset(name); + h5::dataspace d_space = H5Dget_space(ds); + + herr_t err = + H5Dread(ds, h5::data_type_memory(), data_space_impl(info, is_complex), d_space, H5P_DEFAULT, h5::get_data_ptr(start)); + if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the scalar dataset " << name << " in the group" << g.name(); } template void read_array_impl(h5::group g, std::string const& name, int* start, array_stride_info info); diff --git a/triqs/arrays/h5/simple_read_write.hpp b/triqs/arrays/h5/simple_read_write.hpp index dbd53393..2a31e5df 100644 --- a/triqs/arrays/h5/simple_read_write.hpp +++ b/triqs/arrays/h5/simple_read_write.hpp @@ -2,7 +2,7 @@ * * 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 * terms of the GNU General Public License as published by the Free Software @@ -69,7 +69,7 @@ namespace arrays { void write_array(h5::group g, std::string const& name, array_const_view V); /*********************************** READ array ****************************************************************/ - + std::vector get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex); template void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info); @@ -78,12 +78,8 @@ namespace arrays { resize_or_check(a, mini_vector::rank> (get_array_lengths(a.rank, g, name, triqs::is_complex::value_type>::value))); if (C_reorder) { { - // read_array(g, name, make_cache(a).view(), false); - // return ; 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.data_start(), array_stride_info{b}); } } else read_array_impl(g, name, a.data_start(), array_stride_info{a}); @@ -104,7 +100,7 @@ namespace arrays { typename A::value_type>()))> : std::integral_constant::value || std::is_base_of::value> {}; - // get_triqs_hdf5_data_scheme + // get_triqs_hdf5_data_scheme template TYPE_ENABLE_IFC(std::string, is_amv_value_or_view_class::value) get_triqs_hdf5_data_scheme(ArrayType const&) { using triqs::get_triqs_hdf5_data_scheme; // for the basic types, not found by ADL diff --git a/triqs/gfs/tools.hpp b/triqs/gfs/tools.hpp index 8b845ea5..b25415fe 100644 --- a/triqs/gfs/tools.hpp +++ b/triqs/gfs/tools.hpp @@ -121,7 +121,7 @@ namespace gfs { } 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 { gr = fg.open_group(subgroup_name); } diff --git a/triqs/h5.hpp b/triqs/h5.hpp index 7b8ef728..75e06005 100644 --- a/triqs/h5.hpp +++ b/triqs/h5.hpp @@ -20,20 +20,35 @@ ******************************************************************************/ #ifndef TRIQS_H5_FULL_H #define TRIQS_H5_FULL_H +#include "./h5/base_public.hpp" +#include "./h5/file.hpp" #include "./h5/group.hpp" #include "./h5/scalar.hpp" +#include "./h5/string.hpp" #include "./h5/vector.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 struct has_h5_read : std::false_type {}; + template + struct has_h5_read(), std::string(), *(std::declval())))> : std::true_type {}; + + template struct has_h5_write : std::false_type {}; + template + struct has_h5_write(), std::string(), std::declval()))> : std::true_type { + }; +} +} + +// in some old version of hdf5 (Ubuntu 12.04 e.g.), the macro is not yet defined. #ifndef H5_VERSION_GE -#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_MAJOR>Maj)) +#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_MAJOR > Maj)) #endif diff --git a/triqs/h5/base.cpp b/triqs/h5/base.cpp index dda485b3..088ff3ba 100644 --- a/triqs/h5/base.cpp +++ b/triqs/h5/base.cpp @@ -19,15 +19,15 @@ * ******************************************************************************/ #include "./base.hpp" -#include namespace triqs { - namespace h5 { + //------------------------------------------------ + // 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, - hsize_t const *offset) { + 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) { int rank = R + (is_complex ? 1 : 0); hsize_t totdimsf[rank], dimsf[rank], stridesf[rank], offsetf[rank]; // dataset dimensions for (size_t u = 0; u < R; ++u) { @@ -42,54 +42,60 @@ namespace h5 { totdimsf[rank - 1] = 2; 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; } /****************** Write string attribute *********************************************/ - void write_string_attribute(H5::H5Object const *obj, std::string name, std::string value) { - H5::DataSpace attr_dataspace = H5::DataSpace(H5S_SCALAR); - // Create new string datatype for attribute - H5::StrType strdatatype(H5::PredType::C_S1, value.size()); - // Set up write buffer for attribute - // const H5std_string strwritebuf (value); - // Create attribute and write to it - H5::Attribute myatt_in = obj->createAttribute(name.c_str(), strdatatype, attr_dataspace); - // myatt_in.write(strdatatype, strwritebuf); - myatt_in.write(strdatatype, (void *)(value.c_str())); + void write_string_attribute(hid_t id, std::string name, std::string value) { + + datatype strdatatype = H5Tcopy(H5T_C_S1); + auto status = H5Tset_size(strdatatype, value.size() + 1); + // auto status = H5Tset_size(strdatatype, H5T_VARIABLE); + if (status < 0) TRIQS_RUNTIME_ERROR << "Internal error in H5Tset_size"; + + dataspace space = H5Screate(H5S_SCALAR); + + 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 *********************************************/ /// 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 value = ""; - H5::Attribute attr; - if (H5LTfind_attribute(obj->getId(), name.c_str()) == 0) return value; // 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()) ) ; - // value.append( &(buf.front()) ); - try { - attr = obj->openAttribute(name.c_str()); - } - catch (H5::AttributeIException) { - return value; - } - try { - H5::DataSpace dataspace = attr.getSpace(); - int rank = dataspace.getSimpleExtentNdims(); - if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0"; - size_t size = attr.getStorageSize(); - H5::StrType strdatatype(H5::PredType::C_S1, size + 1); - std::vector buf(size + 1, 0x00); - attr.read(strdatatype, (void *)(&buf[0])); - value.append(&(buf.front())); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - return value; + std::string read_string_attribute(hid_t id, std::string name) { + + // if the attribute is not present, return 0 + if (H5LTfind_attribute(id, name.c_str()) == 0) return ""; // not present + + attribute attr = H5Aopen(id, name.c_str(), H5P_DEFAULT); + if (!attr.is_valid()) TRIQS_RUNTIME_ERROR << "Can not open the attribute " << name; + + dataspace space = H5Aget_space(attr); + + int rank = H5Sget_simple_extent_ndims(space); + if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0"; + + datatype strdatatype = H5Aget_type(attr); + + std::vector buf(H5Aget_storage_size(attr) + 1, 0x00); + auto err = H5Aread(attr, strdatatype, (void *)(&buf[0])); + if (err < 0) TRIQS_RUNTIME_ERROR << "Can not read the attribute" << name; + + std::string ret = ""; + ret.append(&(buf.front())); + return ret; } } } diff --git a/triqs/h5/base.hpp b/triqs/h5/base.hpp index 3c12ae1d..c66268f4 100644 --- a/triqs/h5/base.hpp +++ b/triqs/h5/base.hpp @@ -19,117 +19,89 @@ * ******************************************************************************/ #pragma once +#include "./base_public.hpp" #include -#include -#include #include +#include +#include +#include +/// 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";} - 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) { return "complex";} + using utility::mini_vector; - 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) { 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) { return h5_type_from_C(double());} - // conversion of C type to HDF5 native - 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; } + //------------- compute the data type (removing complex) ---------------------------------- - // conversion of C type to HDF5 native - // NEED TO CHANGE THIS ? It is not standard... We should fix a standard or have a trait - 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; } + // in memory + template hid_t data_type_memory() { return native_type_from_C(T{});} - // If it is complex return T else T - template struct remove_complex { typedef T type;}; - template struct remove_complex > { typedef T type;}; - template struct remove_complex > { typedef T type;}; - template struct remove_complex: remove_complex{}; + // the type of data to put in the file_or_group + template hid_t data_type_file() { return h5_type_from_C(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 + std::enable_if_t::value, std14::conditional_t::value, const void *, void *>> + get_data_ptr(S *p) { + using T = std14::conditional_t::value, const typename S::value_type, typename S::value_type>; + return reinterpret_cast(p); + } - // in memory - template H5::PredType data_type_memory () { return native_type_from_C(typename remove_complex::type()); } + template + std::enable_if_t::value, std14::conditional_t::value, const void *, void *>> + get_data_ptr(S *p) { + return p; + } - // the type of data to put in the file_or_group - template H5::PredType data_type_file () { return h5_type_from_C(typename remove_complex::type());} + // dataspace from lengths and strides. Correct for the complex. strides must be >0 + // 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 std::enable_if< triqs::is_complex::value, typename std::conditional::value, const void *, void *>::type >::type - get_data_ptr (S * p) { - typedef typename std::conditional::value, const typename S::value_type, typename S::value_type>::type T; - return reinterpret_cast(p); - } - - template - typename std::enable_if< !triqs::is_complex::value, typename std::conditional::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); - - }} +} +} diff --git a/triqs/h5/base_public.hpp b/triqs/h5/base_public.hpp new file mode 100644 index 00000000..7506ea90 --- /dev/null +++ b/triqs/h5/base_public.hpp @@ -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 . + * + ******************************************************************************/ +#pragma once +#include +#include +#include +#include +#include +#include + +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) { 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); +} +} + diff --git a/triqs/h5/file.cpp b/triqs/h5/file.cpp new file mode 100644 index 00000000..155dcf2d --- /dev/null +++ b/triqs/h5/file.cpp @@ -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 buf(size + 1, 0x00); + H5Fget_name(id, buf.data(), 1); // now get the name + std::string res = ""; + res.append(&(buf.front())); + return res; + } +} +} + diff --git a/triqs/h5/file.hpp b/triqs/h5/file.hpp new file mode 100644 index 00000000..f0a88b1f --- /dev/null +++ b/triqs/h5/file.hpp @@ -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 . + * + ******************************************************************************/ +#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; + }; +} +} diff --git a/triqs/h5/group.cpp b/triqs/h5/group.cpp index 93ba624b..24404ca0 100644 --- a/triqs/h5/group.cpp +++ b/triqs/h5/group.cpp @@ -1,66 +1,59 @@ #include "./group.hpp" -#include +#include "./base.hpp" namespace triqs { namespace h5 { - group::group(H5::Group g, H5::Group parent, std::string name_in_parent) - : _g(g), _parent(parent), _name_in_parent(name_in_parent) {} - - //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(h5::file f) : h5_object() { + id = H5Gopen2(f, "/", H5P_DEFAULT); + if (id < 0) TRIQS_RUNTIME_ERROR << "Can not open the root group / in the file " << f.name(); } - group::group(hid_t id_, bool is_group) { - if (is_group) { - _g.setId(id_); - } else { - H5::H5File f; - f.setId(id_); - *this = group(f); - } + group::group(h5_object obj) : h5_object(std::move(obj)) { + if (!H5Iis_valid(this->id)) TRIQS_RUNTIME_ERROR << "Invalid input in group constructor from id"; + if (H5Iget_type(this->id) != H5I_GROUP) TRIQS_RUNTIME_ERROR << "Group constructor must take the id of a group or a file "; } - 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 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 { - 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 { if (!has_key(key)) TRIQS_RUNTIME_ERROR << "no subgroup " << key << " in the group"; - group res; - try { - res = group(_g.openGroup(key.c_str()), _g, key); - } // 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; + hid_t sg = H5Gopen2(id, key.c_str(), H5P_DEFAULT); + if (sg < 0) TRIQS_RUNTIME_ERROR << "Error in opening the subgroup " << key; + return group(sg); } - /// 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"; - H5::DataSet res; - try { - res = _g.openDataSet(key.c_str()); - } - catch (H5::GroupIException const &e) { - TRIQS_RUNTIME_ERROR << "Error in opening the dataset " << key << "\n H5 error message : \n " << e.getCDetailMsg(); - } - return res; + dataset ds = H5Dopen2(id, key.c_str(), H5P_DEFAULT); + if (!ds.is_valid()) TRIQS_RUNTIME_ERROR << "Can not open dataset " << key << " in the group" << name(); + return ds; } + /** * \brief Create a 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 { 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. * \param key The name of the subgroup - * \param args Other parameters are forwarded to H5::Group * * NB : It unlinks the dataset if it exists. */ - - 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 { + dataset group::create_dataset(std::string const &key, datatype ty, dataspace sp, hid_t pl) const { unlink_key_if_exists(key); - H5::DataSet res; - try { - res = _g.createDataSet(key.c_str(), data_type, data_space, create_plist); - } - catch (H5::GroupIException const &e) { - TRIQS_RUNTIME_ERROR << "Error in creating the dataset " << key << "\n H5 error message : \n " << e.getCDetailMsg(); - } - return res; + dataset ds = H5Dcreate2(id, key.c_str(), ty, sp, H5P_DEFAULT, pl, H5P_DEFAULT); + if (!ds.is_valid()) TRIQS_RUNTIME_ERROR << "Can not create the dataset " << key << " in the group" << name(); + return ds; } + //---------------------------------------------------------- + // 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){ - 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; } - +*/ //----------------------------------------------------------------------- + // C callbacks for the next functions using H5Literate 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; 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 (object_info.type == H5O_TYPE_DATASET) static_cast *>(opdata)->push_back(name); 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; 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"; @@ -116,29 +108,19 @@ namespace h5 { } //----------------------------------------------------------------------- - std::vector group::get_all_subgroup_names(std::string const &key) const { + std::vector group::get_all_subgroup_names() const { std::vector grp_name; - H5::Group F(_g); - F.iterateElems(key.c_str(), NULL, get_group_elements_name_grp, static_cast(&grp_name)); + int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_grp, static_cast(&grp_name)); + if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over subgroups of group " << name() << "failed"; return grp_name; } - std::vector group::get_all_dataset_names(std::string const &key) const { + std::vector group::get_all_dataset_names() const { std::vector ds_name; - H5::Group F(_g); - F.iterateElems(key.c_str(), NULL, get_group_elements_name_ds, static_cast(&ds_name)); + int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_ds, static_cast(&ds_name)); + if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over datasets of group " << name() << "failed"; return ds_name; } - - std::vector 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 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); - } } } diff --git a/triqs/h5/group.hpp b/triqs/h5/group.hpp index 95c5cb5d..575996a3 100644 --- a/triqs/h5/group.hpp +++ b/triqs/h5/group.hpp @@ -19,33 +19,40 @@ * ******************************************************************************/ #pragma once -#include "./base.hpp" +#include "./file.hpp" namespace triqs { namespace h5 { - // using hid_t = int; - /** * \brief A local derivative of Group. * Rational : use ADL for h5_read/h5_write, catch and rethrow exception, add some policy for opening/creating */ - class group { - // hid_t _g_id, _parent_id; - 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); + class group : public h5_object { + void _write_triqs_hdf5_data_scheme(const char *a); // impl. public: - group() = default; - 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); + group() = default; // for python converter only - 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. template void write_triqs_hdf5_data_scheme(T const &obj) { @@ -57,15 +64,15 @@ namespace h5 { /// bool has_key(std::string const &key) const; - /// + /// void unlink_key_if_exists(std::string const &key) const; /// Open a subgroup. Throw it if does not exists group open_group(std::string const &key) const; /// 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. @@ -73,29 +80,20 @@ namespace h5 { * \param delete_if_exists Unlink the group if it exists */ group create_group(std::string const &key, bool delete_if_exists = true) const; - + /** * \brief Create a dataset. * \param key The name of the subgroup * * 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, - const H5::DSetCreatPropList &create_plist= H5::DSetCreatPropList::DEFAULT) const; - - /// Returns all names of subgroup of key in G - std::vector get_all_subgroup_names(std::string const &key) const; + dataset create_dataset(std::string const &key, datatype ty, dataspace sp, hid_t pl = H5P_DEFAULT) const; /// Returns all names of subgroup of G std::vector get_all_subgroup_names() const; - /// Returns all names of dataset of key in G - std::vector get_all_dataset_names(std::string const &key) const; - /// Returns all names of dataset of G std::vector get_all_dataset_names() const; - - void write_string_attribute (std::string const & obj_name, std::string const & attr_name, std::string const & value); }; } } diff --git a/triqs/h5/make_h5_read_write.hpp b/triqs/h5/make_h5_read_write.hpp deleted file mode 100644 index ac2e54da..00000000 --- a/triqs/h5/make_h5_read_write.hpp +++ /dev/null @@ -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 . - * - ******************************************************************************/ -#ifndef TRIQS_TOOLS_H5_MAKE_READ_WRITE_H -#define TRIQS_TOOLS_H5_MAKE_READ_WRITE_H -#include -#include -#include -#include - -namespace triqs { namespace h5 { - - template struct has_h5_read : std::false_type {}; - template struct has_h5_read(), std::string(), *(std::declval())))> : std::true_type {}; - - template struct has_h5_write : std::false_type {}; - template struct has_h5_write(), std::string(), std::declval()))> : std::true_type {}; - - typedef std::function h5_rw_lambda_t; - - namespace details { - // given a pointer to an object, synthesize h5_read/write function for this object - template h5_rw_lambda_t make_h5_write_impl(T * p, std::integral_constant) { - return [p](h5::group F, std::string const &Name) {h5_write(F,Name, *p);}; - } - template h5_rw_lambda_t make_h5_read_impl(T * p, std::integral_constant) { - return [p](h5::group F, std::string const &Name) {h5_read(F,Name, *p);}; - } - - // use boost serialization as a generic case - template h5_rw_lambda_t make_h5_read_impl(T * p, std::integral_constant) { - return [p](h5::group F, std::string const &Name) { std::string s; h5_read(F,Name, s); *p = triqs::deserialize(s); }; - } - template h5_rw_lambda_t make_h5_write_impl(const T * p, std::integral_constant) { - 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 h5_rw_lambda_t make_h5_read_impl (T * p, std::integral_constant) { return h5_rw_lambda_t();} - template h5_rw_lambda_t make_h5_write_impl(T * p, std::integral_constant) { 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 h5_rw_lambda_t make_h5_write(T * p) { return details::make_h5_write_impl(p,std::integral_constant::value?0:1>());} - template h5_rw_lambda_t make_h5_read (T * p) { return details::make_h5_read_impl (p,std::integral_constant::value?0:1>());} - - // Generate a lambda (h5::group, Name) -> void - // that calls h5_read/write if it exists, and does nothing otherwise - template h5_rw_lambda_t make_h5_write_or_nothing(T * p) { return details::make_h5_write_impl(p,std::integral_constant::value?0:2>());} - template h5_rw_lambda_t make_h5_read_or_nothing (T * p) { return details::make_h5_read_impl (p,std::integral_constant::value?0:2>());} - -}}// end namespace -#endif - - - diff --git a/triqs/h5/map.hpp b/triqs/h5/map.hpp index 318d2f80..2e65e3d2 100644 --- a/triqs/h5/map.hpp +++ b/triqs/h5/map.hpp @@ -44,10 +44,10 @@ namespace triqs { void h5_read (group f, std::string const & name, std::map & M) { auto gr = f.open_group(name); M.clear(); - T value; for (auto const & x: gr.get_all_dataset_names()) { + T value; h5_read(gr, x, value); - M.emplace(x, value); + M.emplace(x, std::move(value)); } } diff --git a/triqs/h5/scalar.cpp b/triqs/h5/scalar.cpp index 736153be..85d61c4e 100644 --- a/triqs/h5/scalar.cpp +++ b/triqs/h5/scalar.cpp @@ -19,37 +19,48 @@ * ******************************************************************************/ #include "./scalar.hpp" -namespace triqs { namespace h5 { +#include "./base.hpp" + +namespace triqs { +namespace h5 { namespace { - // TODO : Fix complex number .... - - // S must be scalar - template - void h5_write_impl (group g, std::string const & name, S const & A) { - try { - g.unlink_key_if_exists(name); - H5::DataSet ds = g.create_dataset( name, data_type_file(), H5::DataSpace() ); - ds.write( (void *)(&A), data_type_memory(), H5::DataSpace() ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + // TODO : Fix complex number .... + + // S must be scalar + template void h5_write_impl(group g, std::string const &key, S a) { + + g.unlink_key_if_exists(key); + + dataspace space = H5Screate(H5S_SCALAR); + auto ds = g.create_dataset(key, data_type_file(), space); + + auto err = H5Dwrite(ds, data_type_memory(), 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 - void h5_read_impl (group g, std::string const & name, S & A) { - try { - H5::DataSet ds = g.open_dataset(name); - H5::DataSpace dataspace = ds.getSpace(); - int rank = dataspace.getSimpleExtentNdims(); - 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 = "<(), H5::DataSpace() , H5::DataSpace() ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + //------------------------------------------------------------- + + template void h5_read_impl(group g, std::string const &name, S &A) { + + dataset ds = g.open_dataset(name); + dataspace d_space = H5Dget_space(ds); + + // check that rank is 0, it is a scalar. + int rank = H5Sget_simple_extent_ndims(d_space); + 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; + + herr_t err = H5Dread(ds, data_type_memory(), 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 a); +// template <> void h5_read_impl(group g, std::string const &key, std::complex &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, 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); } @@ -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, std::complex 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, 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); } @@ -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, double &x) { h5_read_impl(g, name, x); } void h5_read(group g, std::string const &name, std::complex &x) { h5_read_impl(g, name, x); } - - -}} - - +} +} diff --git a/triqs/h5/scalar.hpp b/triqs/h5/scalar.hpp index 1b4c7bf6..506be9c9 100644 --- a/triqs/h5/scalar.hpp +++ b/triqs/h5/scalar.hpp @@ -20,14 +20,15 @@ ******************************************************************************/ #pragma once #include "./group.hpp" +#include namespace triqs { namespace h5 { - // Issue several types are *implicitly* convertible to bool - // it could be confusing. Better to use int in hdf5 files. + // Issue several types are *implicitly* convertible to bool + // it could be confusing. Better to use int in hdf5 files. void h5_write(group g, std::string const &name, int const &x); void h5_write(group g, std::string const &name, long const &x); void h5_write(group g, std::string const &name, size_t const &x); - void h5_write(group g, std::string const &name, bool const &x); + void h5_write(group g, std::string const &name, bool const &x); void h5_write(group g, std::string const &name, char const &x); void h5_write(group g, std::string const &name, double const &x); void h5_write(group g, std::string const &name, std::complex const &x); diff --git a/triqs/h5/serialization.hpp b/triqs/h5/serialization.hpp index 30f265d9..968147b4 100644 --- a/triqs/h5/serialization.hpp +++ b/triqs/h5/serialization.hpp @@ -19,9 +19,7 @@ * ******************************************************************************/ #pragma once -//#include -#include -#include +#include "./base.hpp" //#define CHECK_OR_THROW(Cond, Mess) #define CHECK_OR_THROW(Cond, Mess) \ @@ -32,62 +30,52 @@ namespace h5 { template std::string serialize(T const &x) { - hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); - CHECK_OR_THROW((fapl_id >= 0), "creating fapl"); + proplist fapl = H5Pcreate(H5P_FILE_ACCESS); + 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."); - hid_t file_id = H5Fcreate("serialization", 0, H5P_DEFAULT, fapl_id); - CHECK_OR_THROW((file_id >= 0), "created core file"); + h5::file f = H5Fcreate("serialization", 0, H5P_DEFAULT, fapl); + 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); - err = H5Fflush(file_id, H5F_SCOPE_GLOBAL); + err = H5Fflush(f, H5F_SCOPE_GLOBAL); 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"); 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"); - 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; } + // ----------------------------- + template T deserialize(std::string const &buf) { T res; - hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); - CHECK_OR_THROW((fapl_id >= 0), "creating fapl"); + proplist fapl = H5Pcreate(H5P_FILE_ACCESS); + 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."); - 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."); - hid_t file_id = H5Fopen("serialization", H5F_ACC_RDONLY, fapl_id); - CHECK_OR_THROW((file_id >= 0), "opened received file image file"); + h5::file f = H5Fopen("serialization", H5F_ACC_RDONLY, fapl); + 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); - 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; } } diff --git a/triqs/h5/string.cpp b/triqs/h5/string.cpp index 1a0908f0..8daa76c2 100644 --- a/triqs/h5/string.cpp +++ b/triqs/h5/string.cpp @@ -19,33 +19,44 @@ * ******************************************************************************/ #include "./string.hpp" -namespace triqs { - - namespace h5 { +#include "./base.hpp" +namespace triqs { - 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 - H5::DataSet ds = g.create_dataset(name, strdatatype, H5::DataSpace()); - ds.write((void*)(value.c_str()), strdatatype ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; +namespace h5 { + + void h5_write(group g, std::string const& name, std::string const& value) { + + datatype strdatatype = H5Tcopy(H5T_C_S1); + // auto status = H5Tset_size (strdatatype, H5T_VARIABLE); + auto status = H5Tset_size(strdatatype, value.size() + 1); + + 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); - H5::DataSpace dataspace = ds.getSpace(); - int rank = dataspace.getSimpleExtentNdims(); - if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string and got rank !=0"; - size_t size = ds.getStorageSize(); - H5::StrType strdatatype(H5::PredType::C_S1, size); - std::vector buf(size+1, 0x00); - ds.read( (void *)(&buf[0]), strdatatype, H5::DataSpace(), H5::DataSpace() ); - value = ""; value.append( &(buf.front()) ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; + // ------------ + + void h5_read(group g, std::string const& name, std::string& value) { + dataset ds = g.open_dataset(name); + h5::dataspace d_space = H5Dget_space(ds); + int rank = H5Sget_simple_extent_ndims(d_space); + if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string and got rank !=0"; + 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 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())); } - -}} +} +} diff --git a/triqs/h5/string.hpp b/triqs/h5/string.hpp index 10007349..8dd29dcf 100644 --- a/triqs/h5/string.hpp +++ b/triqs/h5/string.hpp @@ -22,18 +22,17 @@ #include "./group.hpp" #include -namespace triqs { - +namespace triqs { + inline std::string get_triqs_hdf5_data_scheme(std::string const & ) { return "string";} - + namespace h5 { /** * \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 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); @@ -41,14 +40,13 @@ namespace triqs { /** * \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 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); inline void h5_read (group g, std::string const & name, char * s) = delete; - + }} diff --git a/triqs/h5/vector.cpp b/triqs/h5/vector.cpp index 0a34979b..94c21628 100644 --- a/triqs/h5/vector.cpp +++ b/triqs/h5/vector.cpp @@ -19,102 +19,122 @@ * ******************************************************************************/ #include "./vector.hpp" +#include "./base.hpp" namespace triqs { - namespace h5 { +namespace h5 { - void h5_write (group g, std::string const & name, std::vector const & V) { - size_t s=0; for (auto & x : V) s = std::max(s,x.size()); - try { - H5::DataSet ds; - H5::StrType strdatatype(H5::PredType::C_S1, s); - const size_t n = V.size(); - std::vector buf(n*(s+1), 0x00); - size_t i=0; for (auto & x : V) {strcpy( &buf[i*s], x.c_str()); ++i;} + void h5_write(group g, std::string const &name, std::vector const &V) { + size_t s = 0; + for (auto &x : V) s = std::max(s, x.size()); - hsize_t L[1], S[1]; - L[0] = V.size(); - S[0] = 1; - auto d_space = dataspace_from_LS(1,false,L,L,S); + datatype strdatatype = H5Tcopy (H5T_C_S1); + auto status = H5Tset_size (strdatatype, s); + //auto status = H5Tset_size (strdatatype, H5T_VARIABLE); - ds = g.create_dataset(name, strdatatype, d_space ); - ds.write( (void *)(&buf[0]),strdatatype, d_space ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } + const size_t n = V.size(); + std::vector buf(n * (s + 1), 0x00); + size_t i = 0; + for (auto &x : V) { + strcpy(&buf[i * s], x.c_str()); + ++i; + } - void h5_read (group g, std::string const & name, std::vector & V) { - try { - H5::DataSet ds = g.open_dataset(name); - H5::DataSpace dataspace = ds.getSpace(); - mini_vector 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 = "< 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 H5::DataSpace data_space_for_vector(std::vector const &V) { - hsize_t L[1], S[1]; - S[0] = 1; - L[0] = V.size(); - return h5::dataspace_from_LS(1, triqs::is_complex::value, L, L, S); - } - - template - inline void h5_write_vector_impl (group g, std::string const & name, std::vector const & V) { - try { - H5::DataSet ds = g.create_dataset(name, h5::data_type_file(), data_space_for_vector(V) ); - ds.write( &V[0], h5::data_type_memory(), data_space_for_vector(V) ); - // if complex, to be python compatible, we add the __complex__ attribute - if (triqs::is_complex::value) h5::write_string_attribute(&ds,"__complex__","1"); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } - - template - inline void h5_read_impl (group g, std::string const & name, std::vector & V) { - try { - H5::DataSet ds = g.open_dataset(name); - H5::DataSpace dataspace = ds.getSpace(); - static const unsigned int Rank = 1 + (triqs::is_complex::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 = "< dims_out; - dataspace.getSimpleExtentDims( &dims_out[0], NULL); - V.resize(dims_out[0]); - ds.read( &V[0], h5::data_type_memory(), data_space_for_vector(V) , dataspace ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } - }// impl namespace - - - void h5_write (group f, std::string const & name, std::vector const & V) { h5_write_vector_impl(f,name,V);} - void h5_write (group f, std::string const & name, std::vector> const & V) { h5_write_vector_impl(f,name,V);} - void h5_read (group f, std::string const & name, std::vector & V) { h5_read_impl(f,name,V);} - void h5_read (group f, std::string const & name, std::vector> & V) { h5_read_impl(f,name,V);} + hsize_t L[1], S[1]; + L[0] = V.size(); + S[0] = 1; + auto d_space = dataspace_from_LS(1, false, L, L, S); + 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 " << name << " in the group" << g.name(); } -} + + // ----- read ----- + void h5_read(group g, std::string const &name, std::vector &V) { + dataset ds = g.open_dataset(name); + h5::dataspace d_space = H5Dget_space(ds); + + mini_vector 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 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 " << 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 dataspace data_space_for_vector(std::vector const &V) { + hsize_t L[1], S[1]; + S[0] = 1; + L[0] = V.size(); + return h5::dataspace_from_LS(1, triqs::is_complex::value, L, L, S); + } + + //------------------------------------ + + template inline void h5_write_vector_impl(group g, std::string const &name, std::vector const &V) { + + dataset ds = g.create_dataset(name, h5::data_type_file(), data_space_for_vector(V)); + + auto err = H5Dwrite(ds, h5::data_type_memory(), 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::value) h5::write_string_attribute(ds, "__complex__", "1"); + } + + //------------------------------------ + + template inline void h5_read_impl(group g, std::string const &name, std::vector &V) { + + dataset ds = g.open_dataset(name); + h5::dataspace d_space = H5Dget_space(ds); + + static const unsigned int Rank = 1 + (triqs::is_complex::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(), 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 const &V) { h5_write_vector_impl(f, name, V); } + void h5_write(group f, std::string const &name, std::vector> const &V) { h5_write_vector_impl(f, name, V); } + void h5_read(group f, std::string const &name, std::vector &V) { h5_read_impl(f, name, V); } + void h5_read(group f, std::string const &name, std::vector> &V) { h5_read_impl(f, name, V); } +} +} + diff --git a/triqs/h5/vector.hpp b/triqs/h5/vector.hpp index 224ab1c3..e1759fc7 100644 --- a/triqs/h5/vector.hpp +++ b/triqs/h5/vector.hpp @@ -22,6 +22,7 @@ #include "./group.hpp" #include "./string.hpp" #include +#include namespace triqs { @@ -37,13 +38,13 @@ namespace triqs { void h5_write (group f, std::string const & name, std::vector const & V); void h5_read (group f, std::string const & name, std::vector & V); - void h5_write (group f, std::string const & name, std::vector const & V); + void h5_write (group f, std::string const & name, std::vector const & V); void h5_write (group f, std::string const & name, std::vector> const & V); void h5_read (group f, std::string const & name, std::vector & V); void h5_read (group f, std::string const & name, std::vector> & V); } -} +} diff --git a/triqs/python_tools/wrapper_tools.hpp b/triqs/python_tools/wrapper_tools.hpp index f1eeffab..e199e02c 100644 --- a/triqs/python_tools/wrapper_tools.hpp +++ b/triqs/python_tools/wrapper_tools.hpp @@ -25,14 +25,14 @@ return RET; }\ catch(...) { PyErr_SetString(PyExc_RuntimeError,"Unknown error " MESS ); return RET; }\ -namespace triqs { namespace py_tools { +namespace triqs { namespace py_tools { //--------------------- py_converters ----------------------------- // default version for a wrapped type. To be specialized later. // py2c behaviour is undefined is is_convertible return false template struct py_converter; - //{ + //{ // static PyObject * c2py(T const & x); // static T & py2c(PyObject * ob); // static bool is_convertible(PyObject * ob, bool raise_exception); @@ -84,7 +84,7 @@ template static int converter_for_parser(PyObject *ob, T *p) { } public: template reductor & operator&(T &x) { elem.push_back(convert_to_python(x)); return *this;} - template + template PyObject * apply_to(T & x) { x.serialize(*this,0); return as_tuple();} }; @@ -104,7 +104,7 @@ template static int converter_for_parser(PyObject *ob, T *p) { // no protection for convertion ! template struct py_converter_from_reductor { template static PyObject *c2py(U && x) { return reductor{}.apply_to(x); } - static T py2c(PyObject *ob) { + static T py2c(PyObject *ob) { T res; auto r = reconstructor{ob}; res.serialize(r, 0); @@ -114,17 +114,17 @@ template static int converter_for_parser(PyObject *ob, T *p) { }; // ----------------------------------- -// basic types +// basic types // ----------------------------------- -// PyObject * +// PyObject * template <> struct py_converter { static PyObject *c2py(PyObject *ob) { return ob; } static PyObject *py2c(PyObject *ob) { return ob; } static bool is_convertible(PyObject *ob, bool raise_exception) { return true;} }; -// --- bool +// --- bool template <> struct py_converter { static PyObject *c2py(bool b) { if (b) @@ -185,7 +185,7 @@ template <> struct py_converter> { } }; -// --- string +// --- string template <> struct py_converter { static PyObject *c2py(std::string const &x) { return PyString_FromString(x.c_str()); } @@ -210,39 +210,51 @@ template <> struct py_converter { // --- h5 group of h5py into a triqs::h5 group template <> struct py_converter { - + static PyObject *c2py(std::string const &x) =delete; - + static pyref group_type; + //------- + static triqs::h5::group py2c (PyObject * ob) { int id = PyInt_AsLong(borrowed(ob).attr("id").attr("id")); - int cmp = PyObject_RichCompareBool((PyObject *)ob->ob_type, group_type, Py_EQ); - return triqs::h5::group (id, (cmp==1)); + // id can be a file or a group. If it is a file, we open its root group '/' + 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) { - if (group_type.is_null()) { + if (group_type.is_null()) { group_type = pyref::module("h5py").attr("highlevel").attr("Group"); 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); - if (cmp<0) { - if (raise_exception) { - PyErr_SetString(PyExc_TypeError, "hd5 : internal : comparison to group type has failed !!"); - } - return false; - } + if (cmp < 0) RAISE("hd5 : internal : comparison to group type has failed !!"); pyref id_py = borrowed(ob).attr("id").attr("id"); - if ((!id_py) ||(!PyInt_Check((PyObject*)id_py))) { - if (raise_exception) { - PyErr_SetString(PyExc_TypeError, "hd5 : INTERNAL : group id.id is not an int !!"); - } - return false; - } - return true; + if ((!id_py) || (!PyInt_Check((PyObject *)id_py))) RAISE("hd5 : INTERNAL : group id.id is not an int !!"); + int id = PyInt_AsLong(borrowed(ob).attr("id").attr("id")); + if (!H5Iis_valid(id)) RAISE("Internal error : invalid id from h5py !"); + if (!((H5Iget_type(id) == H5I_FILE) || (H5Iget_type(id) == H5I_GROUP))) + RAISE("h5py object is neither an hdf5 group or an hdf5 file"); + return true; } -}; + }; +#undef RAISE // --- vector --- @@ -265,7 +277,7 @@ template struct py_converter> { for (int i = 0; i < len; i++) if (!py_converter::is_convertible(PySequence_Fast_GET_ITEM((PyObject*)seq, i),raise_exception)) goto _false; //borrowed ref return true; } - _false: + _false: if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Can not convert to std::vector");} return false; } @@ -337,7 +349,7 @@ template struct py_converter> { if (!py_converter::is_convertible(PySequence_Fast_GET_ITEM((PyObject*)seq, 1),raise_exception)) goto _false; //borrowed ref return true; } - _false: + _false: if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Can not convert to std::pair");} return false; } @@ -420,7 +432,7 @@ template <> struct py_converter { } static triqs::arrays::range py2c(PyObject *ob) { if (PyInt_Check(ob)) { - int i = PyInt_AsLong(ob); + int i = PyInt_AsLong(ob); return {i,i+1,1}; } int len = 4; // no clue what this len is ?? @@ -440,7 +452,7 @@ template <> struct py_converter { template<> struct py_converter { static PyObject *c2py(triqs::gfs::nothing g) { Py_RETURN_NONE;} - static bool is_convertible(PyObject *ob, bool raise_exception) { + static bool is_convertible(PyObject *ob, bool raise_exception) { if (ob ==Py_None) return true; if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Can not convert to triqs::gfs::nothing : can only convert None");} return false; @@ -462,7 +474,7 @@ template struct py_converter vg; + std::vector vg; vg.reserve(g.data().size()); for (auto const & x : g.data()) vg.push_back(x); pyref v_gf = convert_to_python(vg); @@ -544,7 +556,7 @@ template struct py_converter> static_assert(sizeof...(T) < 5, "More than 5 variables not implemented"); typedef struct { - PyObject_HEAD + PyObject_HEAD std::function *_c; } std_function; @@ -552,7 +564,7 @@ template struct py_converter> std_function *self; self = (std_function *)type->tp_alloc(type, 0); if (self != NULL) { - self->_c = new std::function{}; + self->_c = new std::function{}; } return (PyObject *)self; } @@ -570,7 +582,7 @@ template struct py_converter> static PyObject *_call_and_treat_return(nop, std_function *pyf, TU const &tu, index_seq) { return py_converter::c2py(pyf->_c->operator()(std::get(tu)...)); } - template + template static PyObject *_call_and_treat_return(nop, std_function *pyf, TU const &tu, index_seq) { pyf->_c->operator()(std::get(tu)...); Py_RETURN_NONE; @@ -591,7 +603,7 @@ template struct py_converter> // the call function object ... // TODO : ADD THE REF AND POINTERS in x ?? static PyObject *std_function_call(PyObject *self, PyObject *args, PyObject *kwds) { - arg_tuple_t x; + arg_tuple_t x; if (!_parse(_int_max(), args, x)) return NULL; try { return _call_and_treat_return(nop(), (std_function *)self, x, make_index_seq()); @@ -654,14 +666,14 @@ template struct py_converter> std_function *self; static PyTypeObject Type; static bool ready = false; - ensure_type_ready(Type, ready); + ensure_type_ready(Type, ready); self = (std_function *)Type.tp_alloc(&Type, 0); if (self != NULL) { self->_c = new std::function{ std::forward(x) }; } return (PyObject *)self; } - + static bool is_convertible(PyObject *ob, bool raise_exception) { if (PyCallable_Check(ob)) return true; if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Can not convert to std::function a non callable object");} @@ -672,11 +684,11 @@ template struct py_converter> static PyTypeObject Type; static bool ready = false; ensure_type_ready(Type, ready); - // If we convert a wrapped std::function, just extract it. + // If we convert a wrapped std::function, just extract it. if (PyObject_TypeCheck(ob, &Type)) { return *(((std_function *)ob)->_c);} // otherwise, we build a new std::function around the python function pyref py_fnt = borrowed(ob); - auto l = [py_fnt](T... x) mutable -> R { // py_fnt is a pyref, it will keep the ref and manage the ref counting... + auto l = [py_fnt](T... x) mutable -> R { // py_fnt is a pyref, it will keep the ref and manage the ref counting... pyref ret = PyObject_CallFunctionObjArgs(py_fnt, (PyObject*)pyref(convert_to_python(x))...,NULL); return py_converter::py2c(ret); }; diff --git a/triqs/utility/crash_logger.hpp b/triqs/utility/crash_logger.hpp index 7d96f6ed..8053da02 100644 --- a/triqs/utility/crash_logger.hpp +++ b/triqs/utility/crash_logger.hpp @@ -68,8 +68,7 @@ class crash_logger { names.push_back(name); guards.emplace_back([&obj,this, name](){ 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); } - catch(H5::Exception const & e) { std::cerr << "An hdf5 exception has occurred in crash_logger : I can not recover : error is " <filename_.c_str(),H5F_ACC_RDWR)), name, obj); } catch(...) { std::cerr << "An exception has occurred in crash_logger for an object of type " << typeid_name(obj) << " named " << name<< std::endl ; } }); //end lambda return *this; @@ -81,7 +80,7 @@ class crash_logger { std::cerr << "crash_logger : I am destroyed without being dismissed. Dumping the objects : "; for (auto & x : names) std::cerr<< "\""<< x <<"\" "; 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