1 #ifndef DIY_IO_NMPY_HPP
2 #define DIY_IO_NMPY_HPP
8 #include "../serialization.hpp"
21 unsigned word_size()
const {
return word_size_; }
23 unsigned read_header()
27 size_t offset = parse_npy_header(shape, fortran);
29 throw std::runtime_error(
"diy::io::NumPy cannot read data in fortran order");
30 BOV::set_offset(offset);
31 BOV::set_shape(shape);
38 template<
class T,
class S>
39 void write_header(
const S& shape);
42 inline size_t parse_npy_header(BOV::Shape& shape,
bool& fortran_order);
47 std::ostringstream oss;
58 inline char big_endian();
60 char map_numpy_type();
71 parse_npy_header(BOV::Shape& shape,
bool& fortran_order)
74 file().read_at_all(0, buffer, 256);
75 std::string header(buffer, buffer + 256);
76 size_t nl = header.find(
'\n');
77 if (nl == std::string::npos)
78 throw std::runtime_error(
"parse_npy_header: failed to read the header");
79 header = header.substr(11, nl - 11 + 1);
80 size_t header_size = nl + 1;
85 loc1 = header.find(
"fortran_order")+16;
86 fortran_order = (header.substr(loc1,4) ==
"True" ?
true :
false);
90 loc1 = header.find(
"(");
91 loc2 = header.find(
")");
92 std::string str_shape = header.substr(loc1+1,loc2-loc1-1);
93 if(str_shape[str_shape.size()-1] ==
',') ndims = 1;
94 else ndims = std::count(str_shape.begin(),str_shape.end(),
',')+1;
96 for(
unsigned int i = 0;i < ndims;i++) {
97 loc1 = str_shape.find(
",");
98 shape[i] = atoi(str_shape.substr(0,loc1).c_str());
99 str_shape = str_shape.substr(loc1+1);
105 loc1 = header.find(
"descr")+9;
112 std::string str_ws = header.substr(loc1+2);
113 loc2 = str_ws.find(
"'");
114 word_size_ = atoi(str_ws.substr(0,loc2).c_str());
122 write_header(
int dim,
const DiscreteBounds& bounds)
124 std::vector<int> shape;
125 for (
int i = 0; i < dim; ++i)
126 shape.push_back(bounds.max[i] - bounds.min[i] + 1);
128 write_header< T, std::vector<int> >(shape);
132 template<
class T,
class S>
135 write_header(
const S& shape)
137 BOV::set_shape(shape);
140 save(dict,
"{'descr': '");
142 diy::save(dict, detail::map_numpy_type<T>());
143 convert_and_save(dict,
sizeof(T));
144 save(dict,
"', 'fortran_order': False, 'shape': (");
145 convert_and_save(dict, shape[0]);
146 for (
int i = 1; i < (int) shape.size(); i++)
149 convert_and_save(dict, shape[i]);
151 if(shape.size() == 1)
save(dict,
",");
154 int remainder = 16 - (10 + dict.position) % 16;
155 for (
int i = 0; i < remainder - 1; ++i)
161 save(header,
"NUMPY");
164 diy::save(header, (
unsigned short) dict.position);
165 header.
save_binary(&dict.buffer[0], dict.buffer.size());
167 BOV::set_offset(header.position);
169 if (file().comm().rank() == 0)
170 file().write_at(0, &header.buffer[0], header.buffer.size());
174 diy::io::detail::big_endian()
176 unsigned char x[] = {1,0};
178 short y = *
static_cast<short*
>(x_void);
179 return y == 1 ?
'<' :
'>';
188 template<>
inline char map_numpy_type<float>() {
return 'f'; }
189 template<>
inline char map_numpy_type<double>() {
return 'f'; }
190 template<>
inline char map_numpy_type<long double>() {
return 'f'; }
192 template<>
inline char map_numpy_type<int>() {
return 'i'; }
193 template<>
inline char map_numpy_type<char>() {
return 'i'; }
194 template<>
inline char map_numpy_type<short>() {
return 'i'; }
195 template<>
inline char map_numpy_type<long>() {
return 'i'; }
196 template<>
inline char map_numpy_type<long long>() {
return 'i'; }
198 template<>
inline char map_numpy_type<unsigned int>() {
return 'u'; }
199 template<>
inline char map_numpy_type<unsigned char>() {
return 'u'; }
200 template<>
inline char map_numpy_type<unsigned short>() {
return 'u'; }
201 template<>
inline char map_numpy_type<unsigned long>() {
return 'u'; }
202 template<>
inline char map_numpy_type<unsigned long long>() {
return 'u'; }
204 template<>
inline char map_numpy_type<bool>() {
return 'b'; }
206 template<>
inline char map_numpy_type< std::complex<float> >() {
return 'c'; }
207 template<>
inline char map_numpy_type< std::complex<double> >() {
return 'c'; }
208 template<>
inline char map_numpy_type< std::complex<long double> >() {
return 'c'; }
virtual void save_binary(const char *x, size_t count)=0
copy count bytes from x into the buffer
void save(BinaryBuffer &bb, const T &x)
Saves x to bb by calling diy::Serialization<T>::save(bb,x).
Definition: serialization.hpp:102
Wraps MPI file IO.
Definition: io.hpp:16
Definition: serialization.hpp:26
virtual void save_binary(const char *x, size_t count) override
copy count bytes from x into the buffer
Definition: serialization.hpp:413
A serialization buffer.
Definition: serialization.hpp:19