3
0
mirror of https://github.com/triqs/dft_tools synced 2024-10-31 19:23:45 +01:00

hdf5 : clean up

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

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

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

View File

@ -230,9 +230,9 @@ link_libraries(${TRIQS_LIBRARY_LAPACK})
message( STATUS "-------- HDF5 detection -------------")
# 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})

View File

@ -29,7 +29,7 @@ in the way scientific librairies are installed.
(e.g. currently the default version of mpi and hdf5 installed by brew are in conflict :
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
---------------

View File

@ -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 |
+------------------------+----------+------------------------------------------------------------------------+

View File

@ -6,7 +6,7 @@ int main() {
array<double, 2> 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<double,2> B; // read the file into B

View File

@ -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);
}

View File

@ -24,7 +24,7 @@ int main() {
auto gt = g_t_tau_t{{{tmin, tmax, n_re_time}, {beta, Fermion, n_im_time}}, {2, 2, 2}};
// 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);
}

View File

@ -5,7 +5,7 @@ int main() {
array<double, 2> 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<double, 2> B; // read the file into B

View File

@ -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()<<std::endl;
PyErr_SetString(PyExc_RuntimeError, "Default constructor of class ${c.py_type} is throwing an exception !");
return NULL;
@ -241,7 +241,7 @@ PyObject* ${c.py_type}___iter__(PyObject *self);
//--------------------- Register as_number -----------------------------
%if c.number_protocol :
%if c.number_protocol :
static PyNumberMethods ${c.py_type}_as_number = {
%for op_name in ["add", "subtract", "multiply", "divide", "remainder", "divmod", "power", "negative", "positive", "absolute", "nonzero", "invert", "lshift", "rshift", "and", "xor", "or", "coerce", "int", "long", "float", "oct", "hex", "inplace_add", "inplace_subtract", "inplace_multiply", "inplace_divide", "inplace_remainder", "inplace_power", "inplace_lshift", "inplace_rshift", "inplace_and", "inplace_xor", "inplace_or", "floor_divide ", "true_divide ", "inplace_floor_divide ", "inplace_true_divide ", "index "] :
@ -371,7 +371,7 @@ static PyTypeObject ${c.py_type}Type = {
//--------------------- converters for the class c -----------------------------
namespace triqs { namespace py_tools {
namespace triqs { namespace py_tools {
template <> 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<typename T>
static int converter_for_parser_non_wrapped_type(PyObject * ob, T * p) {
if (!convertible_from_python<T>(ob,true)) return 0;
*p = convert_from_python<T>(ob);
*p = convert_from_python<T>(ob);
return 1;
}
template<typename T>
@ -535,10 +535,10 @@ template<typename T>
%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;

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -40,13 +40,13 @@ int main(int argc, char **argv) {
std::vector <std::complex<double>> vc2;
{
H5::H5File file1( "test_std_vector.h5", H5F_ACC_TRUNC );
h5::file file1( "test_std_vector.h5", H5F_ACC_TRUNC );
h5::group top(file1);
h5_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);

View File

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

View File

@ -1,6 +1,7 @@
#include <triqs/gfs.hpp>
#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);
}

View File

@ -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;

View File

@ -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 "<<G_w_wn_curry1[3][8] << std::endl;
std::cout << "G_w_wn_sl0_a [3]"<<G_w_wn_sl0_a[3] << std::endl ;
// test hdf5
H5::H5File file("gf_re_im_freq_time.h5", H5F_ACC_TRUNC );
h5::file file("gf_re_im_freq_time.h5", H5F_ACC_TRUNC );
h5_write(file, "g_t_tau", G_t_tau);
h5_write(file, "g_w_wn", G_w_wn);
h5_write(file, "g_w_tau", G_w_tau);

View File

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

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp>
#include <triqs/gfs/bz.hpp>
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);

View File

@ -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);

View File

@ -2,6 +2,8 @@
#include <triqs/gfs.hpp>
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 <triqs/gfs/local/functions.hpp>
@ -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...

View File

@ -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));

View File

@ -1,6 +1,7 @@
#define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
#include <triqs/gfs.hpp>
using namespace triqs::gfs;
namespace h5 = triqs::h5;
using namespace triqs::arrays;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
double precision=10e-12;
@ -61,7 +62,7 @@ int main() {
if ( std::abs(Git2.on_mesh(N/3)-Git2[N/3]) > precision) TRIQS_RUNTIME_ERROR<< "error in on_mesh()\n";
// 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);

View File

@ -2,6 +2,8 @@
#include <triqs/gfs.hpp>
#include <triqs/gfs/local/functions.hpp>
using namespace triqs::gfs;
namespace h5 = triqs::h5;
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
int main() {
@ -17,7 +19,7 @@ int main() {
TEST(n);
// 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));

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp>
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 <triqs/gfs/local/functions.hpp>
@ -118,7 +119,7 @@ int main() {
//auto x = local::impl::gf_impl<triqs::gfs::meshes::imfreq, true>::wrap_infty (G.tail_view()) + 2.0;
// 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);
//

View File

@ -2,13 +2,14 @@
#include <triqs/gfs.hpp>
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 <triqs/gfs/local/fourier_matsubara.hpp>
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;

View File

@ -2,6 +2,7 @@
#include <triqs/gfs.hpp>
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 <triqs/gfs/local/fourier_real.hpp>
@ -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<double> I(0,1);

View File

@ -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);
}

View File

@ -26,22 +26,24 @@ namespace h5 = triqs::h5;
int main(int argc, char **argv) {
try {
try {
// write
std::map<std::string, int> m = { {"a",1}, {"b",2} };
std::map<std::string, std::vector<double>> mv = { {"a",{1.0, 2.0}}, {"b",{2.0, 3.0, 4.0}} };
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<std::string, int> mm = { {"c",1} };
std::map<std::string, std::vector<double>> mmv = { {"c",{1.0}} };
H5::H5File file2("test_map.h5", H5F_ACC_RDONLY);
h5::file file2("test_map.h5", H5F_ACC_RDONLY);
h5::group top2(file2);
h5_read(top2, "map_int", mm);
h5_read(top2, "map_vec", mmv);

View File

@ -7,6 +7,7 @@
#define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
#include <triqs/utility/callbacks.hpp>
#include <triqs/mc_tools/mc_generic.hpp>
namespace h5 = triqs::h5;
triqs::arrays::array<std::complex<double>,1> make_array( std::complex<double> c){return {c}; };
@ -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));

View File

@ -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;

View File

@ -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 ;

View File

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

View File

@ -23,22 +23,23 @@
#include "../array.hpp"
#include <triqs/h5.hpp>
#include "./simple_read_write.hpp"
#include <triqs/h5/base.hpp>
namespace triqs {
namespace arrays {
// to be cleaned
namespace h5_impl {
namespace h5_impl {
template <typename A> void* __get_array_data_ptr(A& x) { return h5::get_data_ptr(&(x.storage()[0])); }
H5::DataSpace data_space_impl(array_stride_info info, bool is_complex);
h5::dataspace data_space_impl(array_stride_info info, bool is_complex);
template <typename ArrayType> H5::DataSpace data_space(ArrayType const& A) {
template <typename ArrayType> h5::dataspace data_space(ArrayType const& A) {
if (!A.indexmap().is_contiguous()) TRIQS_RUNTIME_ERROR << " h5 : internal error : array not contiguous";
return data_space_impl(array_stride_info{A}, triqs::is_complex<typename ArrayType::value_type>::value);
}
}
/// The implementation class
template <typename T, int R> 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<T>::value;
static const unsigned int RANK = dim + 1 + (T_is_complex ? 1 : 0);
utility::mini_vector<hsize_t, RANK> dims, offset, maxdims, dim_chunk, buffer_dim, zero;
H5::DataSet dataset;
h5::dataset d_set;
array<T, dim + 1> 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<T>::type()), mspace1, cparms);
if (triqs::is_complex<T>::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<T>::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<T>(), 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<T>(), mspace, fspace1, H5P_DEFAULT, h5_impl::__get_array_data_ptr(buffer));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the array_stack buffer";
offset[0] += step;
}
};
// ------------------------- User classes ------------------------------
// The simple case, 1d
template <typename T> class array_stack : public array_stack_impl<T, 0> {
static_assert((is_scalar<T>::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

View File

@ -19,6 +19,7 @@
*
******************************************************************************/
#include "./simple_read_write.hpp"
#include "./../../h5/base.hpp"
using dcomplex = std::complex<double>;
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 <typename T> void write_array_impl(h5::group g, std::string const& name, const T* start, array_stride_info info) {
static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below
bool is_complex = triqs::is_complex<T>::value;
try {
H5::DataSet ds = g.create_dataset(name, h5::data_type_file<T>(), data_space_impl(info, is_complex));
ds.write(h5::get_data_ptr(start), h5::data_type_memory<T>(), 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<T>(), data_space_impl(info, is_complex));
auto err =
H5Dwrite(ds, h5::data_type_memory<T>(), 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<int>(h5::group g, std::string const& name, const int* start, array_stride_info info);
@ -55,7 +57,6 @@ namespace arrays {
template void write_array_impl<double>(h5::group g, std::string const& name, const double* start, array_stride_info info);
template void write_array_impl<dcomplex>(h5::group g, std::string const& name, const dcomplex* start, array_stride_info info);
// overload : special treatment for arrays of strings (one dimension only).
void write_array(h5::group g, std::string const& name, vector_const_view<std::string> V) {
std::vector<std::string> tmp(V.size());
@ -70,61 +71,31 @@ namespace arrays {
}
/// --------------------------- READ ---------------------------------------------
/* template <typename ArrayType1> void read_array(h5::group g, std::string const& name, ArrayType1&& A, bool C_reorder = true) {
typedef typename std::remove_reference<ArrayType1>::type ArrayType;
static_assert(!std::is_base_of<std::string, typename ArrayType::value_type>::value, " Not implemented"); // 1d is below
try {
H5::DataSet ds = g.open_dataset(name);
H5::DataSpace dataspace = ds.getSpace();
static const unsigned int Rank = ArrayType::rank + (triqs::is_complex<typename ArrayType::value_type>::value ? 1 : 0);
int rank = dataspace.getSimpleExtentNdims();
if (rank != Rank)
TRIQS_RUNTIME_ERROR << "triqs::array::h5::read. Rank mismatch : the array has rank = " << Rank
<< " while the array stored in the hdf5 file has rank = " << rank;
mini_vector<hsize_t, Rank> dims_out;
dataspace.getSimpleExtentDims(&dims_out[0], NULL);
mini_vector<size_t, ArrayType::rank> d2;
for (size_t u = 0; u < ArrayType::rank; ++u) d2[u] = dims_out[u];
resize_or_check(A, d2);
if (C_reorder) {
read_array(g, name, make_cache(A).view(), false);
//read_array(g, name, cache<ArrayType, typename ArrayType::regular_type>(A).view(), false);
} else
ds.read(__get_array_data_ptr(A), h5::data_type_memory<typename ArrayType::value_type>(), data_space(A), dataspace);
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
}
*/
std::vector<size_t> get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex) {
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<size_t> 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<size_t> 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<size_t> 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 <typename T> void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) {
template <typename T> void read_array_impl(h5::group g, std::string const& name, T* start, array_stride_info info) {
static_assert(!std::is_base_of<std::string, T>::value, " Not implemented"); // 1d is below
bool is_complex = triqs::is_complex<T>::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<T>(), 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<T>(), 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<int>(h5::group g, std::string const& name, int* start, array_stride_info info);

View File

@ -2,7 +2,7 @@
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* 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<std::string, 1> V);
/*********************************** READ array ****************************************************************/
std::vector<size_t> get_array_lengths(int R, h5::group g, std::string const& name, bool is_complex);
template <typename T> 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<size_t, std::c14::decay_t<A>::rank> (get_array_lengths(a.rank, g, name, triqs::is_complex<typename std::c14::decay_t<A>::value_type>::value)));
if (C_reorder) {
{
// 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<bool, is_scalar<typename A::value_type>::value ||
std::is_base_of<std::string,
typename A::value_type>::value> {};
// get_triqs_hdf5_data_scheme
// get_triqs_hdf5_data_scheme
template <typename ArrayType>
TYPE_ENABLE_IFC(std::string, is_amv_value_or_view_class<ArrayType>::value) get_triqs_hdf5_data_scheme(ArrayType const&) {
using triqs::get_triqs_hdf5_data_scheme; // for the basic types, not found by ADL

View File

@ -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);
}

View File

@ -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 <typename T, typename Enable = void> struct has_h5_read : std::false_type {};
template <typename T>
struct has_h5_read<T, decltype(h5_read(std::declval<h5::group>(), std::string(), *(std::declval<T*>())))> : std::true_type {};
template <typename T, typename Enable = void> struct has_h5_write : std::false_type {};
template <typename T>
struct has_h5_write<T, decltype(h5_write(std::declval<h5::group>(), std::string(), std::declval<const T>()))> : std::true_type {
};
}
}
// in some old version of hdf5 (Ubuntu 12.04 e.g.), the macro is not yet defined.
#ifndef H5_VERSION_GE
#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

View File

@ -19,15 +19,15 @@
*
******************************************************************************/
#include "./base.hpp"
#include <hdf5_hl.h>
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<char> 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<char> 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;
}
}
}

View File

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

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

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

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

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

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

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

View File

@ -1,66 +1,59 @@
#include "./group.hpp"
#include <hdf5_hl.h>
#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<char> buf(size + 1, 0x00);
H5Iget_name(id, buf.data(), 1); // now get the name
std::string res = "";
res.append(&(buf.front()));
return res;
}
bool group::has_key(std::string const &key) const { return H5Lexists(id, key.c_str(), H5P_DEFAULT); }
void group::unlink_key_if_exists(std::string const &key) const {
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<std::vector<std::string> *>(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<std::string> group::get_all_subgroup_names(std::string const &key) const {
std::vector<std::string> group::get_all_subgroup_names() const {
std::vector<std::string> grp_name;
H5::Group F(_g);
F.iterateElems(key.c_str(), NULL, get_group_elements_name_grp, static_cast<void *>(&grp_name));
int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_grp, static_cast<void *>(&grp_name));
if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over subgroups of group " << name() << "failed";
return grp_name;
}
std::vector<std::string> group::get_all_dataset_names(std::string const &key) const {
std::vector<std::string> group::get_all_dataset_names() const {
std::vector<std::string> ds_name;
H5::Group F(_g);
F.iterateElems(key.c_str(), NULL, get_group_elements_name_ds, static_cast<void *>(&ds_name));
int r = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, get_group_elements_name_ds, static_cast<void *>(&ds_name));
if (r != 0) TRIQS_RUNTIME_ERROR << "Iteration over datasets of group " << name() << "failed";
return ds_name;
}
std::vector<std::string> group::get_all_subgroup_names() const {
if (!has_parent()) TRIQS_RUNTIME_ERROR << "Group hdf5 : parent not found";
return group(_parent).get_all_subgroup_names(_name_in_parent);
}
std::vector<std::string> group::get_all_dataset_names() const {
if (!has_parent()) TRIQS_RUNTIME_ERROR << "Group hdf5 : parent not found";
return group(_parent).get_all_dataset_names(_name_in_parent);
}
}
}

View File

@ -19,33 +19,40 @@
*
******************************************************************************/
#pragma once
#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 <typename T> void write_triqs_hdf5_data_scheme(T const &obj) {
@ -57,15 +64,15 @@ namespace h5 {
///
bool has_key(std::string const &key) const;
///
///
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<std::string> 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<std::string> get_all_subgroup_names() const;
/// Returns all names of dataset of key in G
std::vector<std::string> get_all_dataset_names(std::string const &key) const;
/// Returns all names of dataset of G
std::vector<std::string> get_all_dataset_names() const;
void write_string_attribute (std::string const & obj_name, std::string const & attr_name, std::string const & value);
};
}
}

View File

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

View File

@ -44,10 +44,10 @@ namespace triqs {
void h5_read (group f, std::string const & name, std::map<std::string,T> & M) {
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));
}
}

View File

@ -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 <typename S>
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<S>(), H5::DataSpace() );
ds.write( (void *)(&A), data_type_memory<S>(), H5::DataSpace() );
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
// TODO : Fix complex number ....
// S must be scalar
template <typename S> 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<S>(), space);
auto err = H5Dwrite(ds, data_type_memory<S>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)(&a));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error writing the scalar dataset " << key << " in the group" << g.name();
}
template <typename S>
void h5_read_impl (group g, std::string const & name, S & A) {
try {
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 = "<<rank;
ds.read( (void *)(&A), data_type_memory<S>(), H5::DataSpace() , H5::DataSpace() );
}
TRIQS_ARRAYS_H5_CATCH_EXCEPTION;
//-------------------------------------------------------------
template <typename S> 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<S>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)(&A));
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the scalar dataset " << name << " in the group" << g.name();
}
}
// template <> void h5_write_impl(group g, std::string const &key, std::complex<double> a);
// template <> void h5_read_impl(group g, std::string const &key, std::complex<double> &a);
void h5_write(group g, std::string const &name, int const &x) { h5_write_impl(g, name, x); }
void h5_write(group g, std::string const &name, 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<double> const &x) { h5_write_impl(g, name, x); }
void h5_read(group g, std::string const &name, int &x) { h5_read_impl(g, name, x); }
void h5_read(group g, std::string const &name, 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<double> &x) { h5_read_impl(g, name, x); }
}}
}
}

View File

@ -20,14 +20,15 @@
******************************************************************************/
#pragma once
#include "./group.hpp"
#include <complex>
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<double> const &x);

View File

@ -19,9 +19,7 @@
*
******************************************************************************/
#pragma once
//#include <hdf5.h>
#include <triqs/h5.hpp>
#include <triqs/utility/view_tools.hpp>
#include "./base.hpp"
//#define CHECK_OR_THROW(Cond, Mess)
#define CHECK_OR_THROW(Cond, Mess) \
@ -32,62 +30,52 @@ namespace h5 {
template <typename T> std::string serialize(T const &x) {
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 <typename T> 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;
}
}

View File

@ -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<char> 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<char> buf(size + 1, 0x00);
auto err = H5Dread(ds, strdatatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf[0]);
if (err < 0) TRIQS_RUNTIME_ERROR << "Error reading the string named" << name << " in the group" << g.name();
value = "";
value.append(&(buf.front()));
}
}}
}
}

View File

@ -22,18 +22,17 @@
#include "./group.hpp"
#include <cstring>
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;
}}

View File

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

View File

@ -22,6 +22,7 @@
#include "./group.hpp"
#include "./string.hpp"
#include <vector>
#include <complex>
namespace triqs {
@ -37,13 +38,13 @@ namespace triqs {
void h5_write (group f, std::string const & name, std::vector<std::string> const & V);
void h5_read (group f, std::string const & name, std::vector<std::string> & V);
void h5_write (group f, std::string const & name, std::vector<double> const & V);
void h5_write (group f, std::string const & name, std::vector<double> const & V);
void h5_write (group f, std::string const & name, std::vector<std::complex<double>> const & V);
void h5_read (group f, std::string const & name, std::vector<double> & V);
void h5_read (group f, std::string const & name, std::vector<std::complex<double>> & V);
}
}
}

View File

@ -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<typename T> 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 <typename T> static int converter_for_parser(PyObject *ob, T *p) {
}
public:
template <typename T> reductor & operator&(T &x) { elem.push_back(convert_to_python(x)); return *this;}
template<typename T>
template<typename T>
PyObject * apply_to(T & x) { x.serialize(*this,0); return as_tuple();}
};
@ -104,7 +104,7 @@ template <typename T> static int converter_for_parser(PyObject *ob, T *p) {
// no protection for convertion !
template <typename T> struct py_converter_from_reductor {
template<typename U> 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 <typename T> static int converter_for_parser(PyObject *ob, T *p) {
};
// -----------------------------------
// basic types
// basic types
// -----------------------------------
// PyObject *
// PyObject *
template <> struct py_converter<PyObject *> {
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<bool> {
static PyObject *c2py(bool b) {
if (b)
@ -185,7 +185,7 @@ template <> struct py_converter<std::complex<double>> {
}
};
// --- string
// --- string
template <> struct py_converter<std::string> {
static PyObject *c2py(std::string const &x) { return PyString_FromString(x.c_str()); }
@ -210,39 +210,51 @@ template <> struct py_converter<const char *> {
// --- h5 group of h5py into a triqs::h5 group
template <> struct py_converter<triqs::h5::group> {
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 <typename T> struct py_converter<std::vector<T>> {
for (int i = 0; i < len; i++) if (!py_converter<T>::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 <typename T1, typename T2> struct py_converter<std::pair<T1,T2>> {
if (!py_converter<T2>::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<triqs::arrays::range> {
}
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<triqs::arrays::range> {
template<> struct py_converter<triqs::gfs::nothing> {
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 <typename... T> struct py_converter<triqs::gfs::gf_view<triqs::gfs::blo
static PyObject *c2py(c_type g) {
// rm the view_proxy
std::vector<gf_view_type> vg;
std::vector<gf_view_type> 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 <typename R, typename... T> struct py_converter<std::function<R(T...)>>
static_assert(sizeof...(T) < 5, "More than 5 variables not implemented");
typedef struct {
PyObject_HEAD
PyObject_HEAD
std::function<R(T...)> *_c;
} std_function;
@ -552,7 +564,7 @@ template <typename R, typename... T> struct py_converter<std::function<R(T...)>>
std_function *self;
self = (std_function *)type->tp_alloc(type, 0);
if (self != NULL) {
self->_c = new std::function<R(T...)>{};
self->_c = new std::function<R(T...)>{};
}
return (PyObject *)self;
}
@ -570,7 +582,7 @@ template <typename R, typename... T> struct py_converter<std::function<R(T...)>>
static PyObject *_call_and_treat_return(nop<RR>, std_function *pyf, TU const &tu, index_seq<Is...>) {
return py_converter<RR>::c2py(pyf->_c->operator()(std::get<Is>(tu)...));
}
template <typename TU, int... Is>
template <typename TU, int... Is>
static PyObject *_call_and_treat_return(nop<void>, std_function *pyf, TU const &tu, index_seq<Is...>) {
pyf->_c->operator()(std::get<Is>(tu)...);
Py_RETURN_NONE;
@ -591,7 +603,7 @@ template <typename R, typename... T> struct py_converter<std::function<R(T...)>>
// 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<R>(), (std_function *)self, x, make_index_seq<sizeof...(T)>());
@ -654,14 +666,14 @@ template <typename R, typename... T> struct py_converter<std::function<R(T...)>>
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<R(T...)>{ std::forward<U>(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 <typename R, typename... T> struct py_converter<std::function<R(T...)>>
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<R>::py2c(ret);
};

View File

@ -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 " <<std::endl ; e.printError();}
try { h5_write( h5::group(h5::file(this->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