mirror of
https://github.com/triqs/dft_tools
synced 2024-12-25 05:43:40 +01:00
hdf5 : clean up
- For users : only change is : H5::H5File in apps. to be replaced by triqs::h5::file, same API. - using only the C API because : - it is cleaner, better documented, more examples. - it is the native hdf5 interface. - simplify the installation e.g. on mac. Indeed, hdf5 is usually installed without C++ interface, which is optional. E.g. EPD et al., brew by default. Also the infamous mpi+ hdf5_cpp bug, for which we have no clean solution. - clean the notion of parent of a group. Not needed, better iterate function in C LT API. - modified doc : no need for C++ bindings any more. - modified cmake to avoid requiring CPP bindings.
This commit is contained in:
parent
36a60ce529
commit
4af1afbdaf
@ -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})
|
||||
|
@ -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
|
||||
---------------
|
||||
|
@ -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 |
|
||||
+------------------------+----------+------------------------------------------------------------------------+
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <triqs/arrays.hpp>
|
||||
|
||||
using namespace triqs::gfs;
|
||||
namespace h5 = triqs::h5;
|
||||
|
||||
int main() {
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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...
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
||||
//
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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 ;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
29
triqs/h5.hpp
29
triqs/h5.hpp
@ -20,20 +20,35 @@
|
||||
******************************************************************************/
|
||||
#ifndef TRIQS_H5_FULL_H
|
||||
#define TRIQS_H5_FULL_H
|
||||
#include "./h5/base_public.hpp"
|
||||
#include "./h5/file.hpp"
|
||||
#include "./h5/group.hpp"
|
||||
#include "./h5/scalar.hpp"
|
||||
#include "./h5/string.hpp"
|
||||
#include "./h5/vector.hpp"
|
||||
#include "./h5/map.hpp"
|
||||
#include "./h5/string.hpp"
|
||||
//#include "./h5/make_h5_read_write.hpp"
|
||||
|
||||
// in some old version, the macro is not defined.
|
||||
// traits to detect h5_read/h5_write is overloaded. Unused currently. Kept since
|
||||
// it can useful and is it not so simple to do...
|
||||
namespace triqs {
|
||||
namespace h5 {
|
||||
template <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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
134
triqs/h5/base_public.hpp
Normal 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
52
triqs/h5/file.cpp
Normal 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
55
triqs/h5/file.hpp
Normal 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;
|
||||
};
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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); }
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
@ -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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user