25 NpyArray(
const std::vector<size_t>& _shape,
size_t _word_size,
bool _fortran_order) :
38 return reinterpret_cast<T*
>(&(*data_holder)[0]);
43 return reinterpret_cast<T*
>(&(*data_holder)[0]);
48 const T*
p = data<T>();
63 using npz_t = std::map<std::string, NpyArray>;
75 template<
typename T> std::vector<char>&
operator+=(std::vector<char>& lhs,
const T rhs) {
85 template<> std::vector<char>&
operator+=(std::vector<char>& lhs,
const char* rhs);
90 std::vector<size_t> true_data_shape;
92 if(mode ==
"a") fp = fopen(fname.c_str(),
"r+b");
100 throw std::runtime_error(
"npy_save: unexpected fortran order");
103 if(word_size !=
sizeof(
T)) {
104 std::cerr<<
"libnpy error: "<<fname<<
" has word size "<<word_size<<
" but npy_save appending data sized "<<
sizeof(
T)<<
"\n";
105 if( word_size !=
sizeof(
T) ) {
106 throw std::runtime_error(
"npy_save: illegal word size");
109 if(true_data_shape.size() != shape.size()) {
110 std::cerr<<
"libnpy error: npy_save attempting to append misdimensioned data to "<<fname<<
"\n";
111 throw std::runtime_error(
"npy_save: misdimensioned data");
115 for(
size_t i = 1; i < shape.size(); i++) {
116 if(shape[i] != true_data_shape[i]) {
117 std::cerr<<
"libnpy error: npy_save attempting to append misshaped data to "<<fname<<
"\n";
118 throw std::runtime_error(
"npy_save: misdimensioned data");
121 true_data_shape[0] += shape[0];
124 fp = fopen(fname.c_str(),
"wb");
125 true_data_shape =
shape;
128 std::vector<char> header = create_npy_header<T>(true_data_shape);
129 size_t nels = std::accumulate(shape.begin(),shape.end(),1,std::multiplies<size_t>());
131 fseek(fp,0,SEEK_SET);
132 fwrite(&header[0],
sizeof(
char),header.size(),
fp);
133 fseek(fp,0,SEEK_END);
134 fwrite(data,
sizeof(
T),nels,fp);
146 size_t global_header_offset = 0;
147 std::vector<char> global_header;
149 if(mode ==
"a") fp = fopen(zipname.c_str(),
"r+b");
156 size_t global_header_size;
158 fseek(fp,global_header_offset,SEEK_SET);
159 global_header.resize(global_header_size);
160 size_t res = fread(&global_header[0],
sizeof(
char),global_header_size,fp);
161 if(res != global_header_size){
162 throw std::runtime_error(
"npz_save: header read error while adding to existing zip");
164 fseek(fp,global_header_offset,SEEK_SET);
167 fp = fopen(zipname.c_str(),
"wb");
170 std::vector<char> npy_header = create_npy_header<T>(
shape);
172 size_t nels = std::accumulate(shape.begin(),shape.end(),1,std::multiplies<size_t>());
173 size_t nbytes = nels*
sizeof(
T) + npy_header.size();
177 crc = crc32(crc,(
uint8_t*)data,nels*
sizeof(
T));
180 std::vector<char> local_header;
181 local_header +=
"PK";
191 local_header += (
uint16_t) fname.size();
193 local_header +=
fname;
196 global_header +=
"PK";
199 global_header.insert(global_header.end(),local_header.begin()+4,local_header.begin()+30);
204 global_header += (
uint32_t) global_header_offset;
205 global_header +=
fname;
208 std::vector<char> footer;
215 footer += (
uint32_t) global_header.size();
216 footer += (
uint32_t) (global_header_offset + nbytes + local_header.size());
220 fwrite(&local_header[0],
sizeof(
char),local_header.size(),
fp);
221 fwrite(&npy_header[0],
sizeof(
char),npy_header.size(),
fp);
222 fwrite(data,
sizeof(
T),nels,fp);
223 fwrite(&global_header[0],
sizeof(
char),global_header.size(),
fp);
224 fwrite(&footer[0],
sizeof(
char),footer.size(),
fp);
229 std::vector<size_t>
shape;
230 shape.push_back(data.size());
231 npy_save(fname, &data[0], shape, mode);
235 std::vector<size_t>
shape;
236 shape.push_back(data.size());
237 npz_save(zipname, fname, &data[0], shape, mode);
242 std::vector<char> dict;
243 dict +=
"{'descr': '";
247 dict +=
"', 'fortran_order': False, 'shape': (";
249 for(
size_t i = 1;i < shape.size();i++) {
253 if(shape.size() == 1) dict +=
",";
256 int remainder = 16 - (10 + dict.size()) % 16;
257 dict.insert(dict.end(),remainder,
' ');
260 std::vector<char> header;
261 header += (char) 0x93;
263 header += (char) 0x01;
264 header += (char) 0x00;
266 header.insert(header.end(),dict.begin(),dict.end());
void npz_save(std::string zipname, std::string fname, const T *data, const std::vector< size_t > &shape, std::string mode="w")
char map_type(const std::type_info &t)
void parse_zip_footer(FILE *fp, uint16_t &nrecs, size_t &global_header_size, size_t &global_header_offset)
npz_t npz_load(std::string fname)
NpyArray npy_load(std::string fname)
void npy_save(std::string fname, const T *data, const std::vector< size_t > shape, std::string mode="w")
std::map< std::string, NpyArray > npz_t
std::vector< T > as_vec() const
NpyArray(const std::vector< size_t > &_shape, size_t _word_size, bool _fortran_order)
std::vector< size_t > shape
std::vector< char > create_npy_header(const std::vector< size_t > &shape)
void parse_npy_header(FILE *fp, size_t &word_size, std::vector< size_t > &shape, bool &fortran_order)
byte_as<> byte
Type of data size stored in bytes, in long long precision.
std::vector< char > & operator+=(std::vector< char > &lhs, const T rhs)
std::shared_ptr< std::vector< char > > data_holder
std::string to_string(ModuleType const mt)