1+ /*
2+ * Copyright (c) 2018-2021 Steven Varga, Toronto,ON Canada
3+ * Author: Varga, Steven <steven@vargaconsulting.ca>
4+ */
5+ #include < initializer_list>
6+
7+
8+ #ifndef H5CPP_RALL_HPP
9+ #define H5CPP_RALL_HPP
10+
11+ namespace h5 {
12+ template <class ... args_t >
13+ reference_t reference (const h5::fd_t & fd, const std::string& dataset_path, args_t &&... args) {
14+ using tcount = typename arg::tpos<const h5::count_t &,const args_t &...>;
15+ using toffset = typename arg::tpos<const h5::offset_t &, const args_t &...>;
16+ using tstride = typename arg::tpos<const h5::stride_t &, const args_t &...>;
17+ using tblock = typename arg::tpos<const h5::block_t &, const args_t &...>;
18+ auto tuple = std::forward_as_tuple (args...);
19+
20+ if constexpr (toffset::present) { // region reference
21+
22+ h5::ds_t ds = h5::open (fd, dataset_path);
23+ h5::sp_t sp{H5Dget_space (ds)};
24+ int rank = h5::get_simple_extent_ndims (sp);
25+ herr_t err = 0 ;
26+
27+ h5::count_t count = std::get<tcount::value>( tuple ); // we make a copy of it
28+ const h5::block_t & block = arg::get ( h5::default_block, args...);
29+ const h5::offset_t & offset = arg::get ( h5::default_offset, args...);
30+ const h5::stride_t & stride = arg::get ( h5::default_stride, args...);
31+ if constexpr ( tblock::present ){ // we have to normalise `count` such that `size[i] = count[i] * block[i]` holds
32+ for (hsize_t i=0 ; i < rank; i++) count[i] /= block[i];
33+ err = H5Sselect_hyperslab (sp, H5S_SELECT_SET, *offset, *stride, *count, *block);
34+ } else { // we have to convert h5::count_t{..} to h5::block{..} and initiate a single block transfer
35+ h5::block_t block_ = static_cast <h5::block_t >(count);
36+ block_.rank = rank;
37+ err = H5Sselect_hyperslab (sp, H5S_SELECT_SET, *offset, *stride, *h5::default_count, *block_);
38+ }
39+ H5CPP_CHECK_NZ (err, h5::error::io::dataset::misc, h5::error::msg::select_hyperslab);
40+ reference_t ref;
41+ err = H5Rcreate (&ref.value , fd, dataset_path.data (), H5R_DATASET_REGION, sp);
42+ H5CPP_CHECK_NZ (err, h5::error::io::dataset::misc, " couldn't create reference to dataset..." );
43+ return ref;
44+ } else { // TODO: object reference
45+ static_assert ( !tcount::present && !tstride::present && !tblock::present
46+ ," count | stride | block are not allowed without h5::offset present.." );
47+ static_assert ( !toffset::present, " object reference is not yet impleneted" );
48+ }
49+ }
50+ }
51+ /* TODO: needs be matched with function below
52+ template<class T, class... args_t>
53+ inline void read(const h5::ds_t& ds, h5::reference_t& reference, T& object, args_t&&... args){
54+ using element_t = typename impl::decay<T>::type;
55+ element_t* ptr = impl::data(object);
56+ h5::count_t size = impl::size(object);
57+
58+ h5::ds_t ds_ = H5Rdereference2(ds, H5P_DEFAULT, H5R_DATASET_REGION, &reference);
59+ h5::sp_t file_space = H5Rget_region(ds_, H5R_DATASET_REGION, &reference);
60+
61+ h5::sp_t mem_space = h5::create_simple( size );
62+ h5::dt_t<element_t> mem_type;
63+ h5::select_all( mem_space );
64+ h5::select_all( file_space );
65+
66+ H5CPP_CHECK_NZ(
67+ H5Dread(ds_, mem_type, mem_space, file_space, dxpl, ptr ),
68+ h5::error::io::dataset::read, h5::error::msg::read_dataset);
69+ }
70+ */
71+ namespace h5 ::exp {
72+ template <class T , class ... args_t >
73+ inline T read (const h5::ds_t & ds, h5::reference_t & reference, args_t &&... args){
74+ using element_t = typename impl::decay<T>::type;
75+
76+ h5::ds_t ds_ = H5Rdereference2 (ds, H5P_DEFAULT, H5R_DATASET_REGION, &reference);
77+ h5::sp_t file_space = H5Rget_region (ds_, H5R_DATASET_REGION, &reference);
78+
79+ h5::dt_t <element_t > mem_type;
80+ h5::count_t start, stop, block;
81+ start.rank = stop.rank = block.rank = H5Sget_simple_extent_ndims (file_space);
82+ H5Sget_select_bounds (file_space, *start, *stop);
83+ for (auto i=0 ; i < block.rank ; i++)
84+ block[i] = stop[i] - start[i]+1 ;
85+ T object = impl::get<T>::ctor (block);
86+ H5Sselect_hyperslab (file_space, H5S_SELECT_SET,
87+ *start, nullptr , *h5::default_count, *block);
88+ element_t *ptr = impl::data (object);
89+ h5::sp_t mem_space = h5::create_simple (block);
90+ h5::select_all (mem_space);
91+
92+ H5CPP_CHECK_NZ (
93+ H5Dread (ds_, mem_type, mem_space, file_space, dxpl, ptr ),
94+ h5::error::io::dataset::read, h5::error::msg::read_dataset);
95+ return object;
96+
97+ }
98+
99+ template <class T , class ... args_t >
100+ inline h5::ds_t write ( const h5::ds_t & ds, h5::reference_t & reference,
101+ const T* ptr, args_t &&... args ) try {
102+ h5::dt_t <T> mem_type;
103+
104+ const h5::dxpl_t & dxpl = arg::get (h5::default_dxpl, args...);
105+ h5::ds_t ds_ = H5Rdereference2 (ds, H5P_DEFAULT, H5R_DATASET_REGION, &reference);
106+ h5::sp_t file_space = H5Rget_region (ds_, H5R_DATASET_REGION, &reference);
107+ h5::count_t start, stop, block;
108+
109+ start.rank = stop.rank = block.rank = H5Sget_simple_extent_ndims (file_space);
110+ H5Sget_select_bounds (file_space, *start, *stop);
111+ for (auto i=0 ; i < block.rank ; i++)
112+ block[i] = stop[i] - start[i]+1 ;
113+ H5Sselect_hyperslab (file_space, H5S_SELECT_SET,
114+ *start, nullptr , *h5::default_count, *block);
115+
116+ h5::sp_t mem_space = h5::create_simple (block);
117+ h5::select_all (mem_space);
118+
119+ H5CPP_CHECK_NZ (
120+ H5Dwrite (ds_, mem_type, mem_space, file_space, dxpl, ptr),
121+ h5::error::io::dataset::write, h5::error::msg::write_dataset);
122+ return ds;
123+ } catch ( const std::exception& err ){
124+ throw h5::error::io::dataset::write ( err.what () );
125+ }
126+
127+
128+ }
129+ #endif
0 commit comments