Loading...
Searching...
No Matches
cnpy.C
Go to the documentation of this file.
1//Copyright (C) 2011 Carl Rogers
2//Released under MIT License
3//license available in LICENSE file, or at http://www.opensource.org/licenses/mit-license.php
4
5#include "ITHACAstream.H"
6#include <complex>
7#include <cstdlib>
8#include <algorithm>
9#include <cstring>
10#include <iomanip>
11
12#pragma GCC diagnostic push
13#pragma GCC diagnostic ignored "-Wold-style-cast"
14
16{
17 int x = 1;
18 return (((char*)&x)[0]) ? '<' : '>';
19}
20
21char cnpy::map_type(const std::type_info& t)
22{
23 if (t == typeid(float) )
24 {
25 return 'f';
26 }
27
28 if (t == typeid(double) )
29 {
30 return 'f';
31 }
32
33 if (t == typeid(long double) )
34 {
35 return 'f';
36 }
37
38 if (t == typeid(int) )
39 {
40 return 'i';
41 }
42
43 if (t == typeid(char) )
44 {
45 return 'i';
46 }
47
48 if (t == typeid(short) )
49 {
50 return 'i';
51 }
52
53 if (t == typeid(long) )
54 {
55 return 'i';
56 }
57
58 if (t == typeid(long long) )
59 {
60 return 'i';
61 }
62
63 if (t == typeid(unsigned char) )
64 {
65 return 'u';
66 }
67
68 if (t == typeid(unsigned short) )
69 {
70 return 'u';
71 }
72
73 if (t == typeid(unsigned long) )
74 {
75 return 'u';
76 }
77
78 if (t == typeid(unsigned long long) )
79 {
80 return 'u';
81 }
82
83 if (t == typeid(unsigned int) )
84 {
85 return 'u';
86 }
87
88 if (t == typeid(bool) )
89 {
90 return 'b';
91 }
92
93 if (t == typeid(std::complex<float>) )
94 {
95 return 'c';
96 }
97
98 if (t == typeid(std::complex<double>) )
99 {
100 return 'c';
101 }
102
103 if (t == typeid(std::complex<long double>) )
104 {
105 return 'c';
106 }
107 else
108 {
109 return '?';
110 }
111}
112
113template<> std::vector<char>& cnpy::operator+=(std::vector<char>& lhs,
114 const std::string rhs)
115{
116 lhs.insert(lhs.end(), rhs.begin(), rhs.end());
117 return lhs;
118}
119
120template<> std::vector<char>& cnpy::operator+=(std::vector<char>& lhs,
121 const char* rhs)
122{
123 //write in little endian
124 size_t len = strlen(rhs);
125 lhs.reserve(len);
126
127 for (size_t byte = 0; byte < len; byte++)
128 {
129 lhs.push_back(rhs[byte]);
130 }
131
132 return lhs;
133}
134
135void cnpy::parse_npy_header(unsigned char* buffer, size_t& word_size,
136 std::vector<size_t>& shape, bool& fortran_order, std::string& number_type)
137{
138 //std::string magic_string(buffer,6);
139 uint8_t major_version = *reinterpret_cast<uint8_t*>(buffer + 6);
140 uint8_t minor_version = *reinterpret_cast<uint8_t*>(buffer + 7);
141 uint16_t header_len = *reinterpret_cast<uint16_t*>(buffer + 8);
142 std::string header(reinterpret_cast<char*>(buffer + 9), header_len);
143 size_t loc1, loc2;
144 //fortran order
145 loc1 = header.find("fortran_order") + 16;
146 fortran_order = (header.substr(loc1, 4) == "True" ? true : false);
147 //shape
148 loc1 = header.find("(");
149 loc2 = header.find(")");
150 std::regex num_regex("[0-9][0-9]*");
151 std::smatch sm;
152 shape.clear();
153 std::string str_shape = header.substr(loc1 + 1, loc2 - loc1 - 1);
154
155 while (std::regex_search(str_shape, sm, num_regex))
156 {
157 shape.push_back(std::stoi(sm[0].str()));
158 str_shape = sm.suffix().str();
159 }
160
161 //endian, word size, data type
162 //byte order code | stands for not applicable.
163 //not sure when this applies except for byte array
164 loc1 = header.find("descr") + 9;
165 bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
166 assert(littleEndian);
167 //char type = header[loc1+1];
168 //assert(type == map_type(T));
169 number_type = header.substr(loc1 + 1, 2);
170 std::string str_ws = header.substr(loc1 + 2);
171 loc2 = str_ws.find("'");
172 word_size = atoi(str_ws.substr(0, loc2).c_str());
173}
174
175void cnpy::parse_npy_header(FILE* fp, size_t& word_size,
176 std::vector<size_t>& shape, bool& fortran_order, std::string& number_type)
177{
178 char buffer[256];
179 size_t res = fread(buffer, sizeof(char), 11, fp);
180
181 if (res != 11)
182 {
183 throw std::runtime_error("parse_npy_header: failed fread");
184 }
185
186 std::string header = fgets(buffer, 256, fp);
187 assert(header[header.size() - 1] == '\n');
188 size_t loc1, loc2;
189 //fortran order
190 loc1 = header.find("fortran_order");
191
192 if (loc1 == std::string::npos)
193 {
194 throw std::runtime_error("parse_npy_header: failed to find header keyword: 'fortran_order'");
195 }
196
197 loc1 += 16;
198 fortran_order = (header.substr(loc1, 4) == "True" ? true : false);
199 //shape
200 loc1 = header.find("(");
201 loc2 = header.find(")");
202
203 if (loc1 == std::string::npos || loc2 == std::string::npos)
204 {
205 throw std::runtime_error("parse_npy_header: failed to find header keyword: '(' or ')'");
206 }
207
208 std::regex num_regex("[0-9][0-9]*");
209 std::smatch sm;
210 shape.clear();
211 std::string str_shape = header.substr(loc1 + 1, loc2 - loc1 - 1);
212
213 while (std::regex_search(str_shape, sm, num_regex))
214 {
215 shape.push_back(std::stoi(sm[0].str()));
216 str_shape = sm.suffix().str();
217 }
218
219 //endian, word size, data type
220 //byte order code | stands for not applicable.
221 //not sure when this applies except for byte array
222 loc1 = header.find("descr");
223
224 if (loc1 == std::string::npos)
225 {
226 throw std::runtime_error("parse_npy_header: failed to find header keyword: 'descr'");
227 }
228
229 loc1 += 9;
230 bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
231 assert(littleEndian);
232 //char type = header[loc1+1];
233 //assert(type == map_type(T));
234 std::string str_ws = header.substr(loc1 + 2);
235 number_type = header.substr(loc1 + 1, 2);
236 loc2 = str_ws.find("'");
237 word_size = atoi(str_ws.substr(0, loc2).c_str());
238}
239
240void cnpy::parse_zip_footer(FILE* fp, uint16_t& nrecs,
241 size_t& global_header_size, size_t& global_header_offset)
242{
243 std::vector<char> footer(22);
244 fseek(fp, -22, SEEK_END);
245 size_t res = fread(&footer[0], sizeof(char), 22, fp);
246
247 if (res != 22)
248 {
249 throw std::runtime_error("parse_zip_footer: failed fread");
250 }
251
252 uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
253 disk_no = *(uint16_t*) &footer[4];
254 disk_start = *(uint16_t*) &footer[6];
255 nrecs_on_disk = *(uint16_t*) &footer[8];
256 nrecs = *(uint16_t*) &footer[10];
257 global_header_size = *(uint32_t*) &footer[12];
258 global_header_offset = *(uint32_t*) &footer[16];
259 comment_len = *(uint16_t*) &footer[20];
260 assert(disk_no == 0);
261 assert(disk_start == 0);
262 assert(nrecs_on_disk == nrecs);
263 assert(comment_len == 0);
264}
265
267{
268 std::vector<size_t> shape;
269 size_t word_size;
270 bool fortran_order;
271 std::string number_type;
272 cnpy::parse_npy_header(fp, word_size, shape, fortran_order, number_type);
273 cnpy::NpyArray arr(shape, word_size, fortran_order, number_type);
274 size_t nread = fread(arr.data<char>(), 1, arr.num_bytes(), fp);
275
276 if (nread != arr.num_bytes())
277 {
278 throw std::runtime_error("load_the_npy_file: failed fread");
279 }
280
281 return arr;
282}
283
285{
286 FILE* fp = fopen(fname.c_str(), "rb");
287 return load_the_npy_file(fp);
288}
289
290cnpy::NpyArray load_the_npz_array(FILE* fp, uint32_t compr_bytes,
291 uint32_t uncompr_bytes)
292{
293 std::vector<unsigned char> buffer_compr(compr_bytes);
294 std::vector<unsigned char> buffer_uncompr(uncompr_bytes);
295 size_t nread = fread(&buffer_compr[0], 1, compr_bytes, fp);
296
297 if (nread != compr_bytes)
298 {
299 throw std::runtime_error("load_the_npy_file: failed fread");
300 }
301
302 int err;
303 z_stream d_stream;
304 d_stream.zalloc = Z_NULL;
305 d_stream.zfree = Z_NULL;
306 d_stream.opaque = Z_NULL;
307 d_stream.avail_in = 0;
308 d_stream.next_in = Z_NULL;
309 err = inflateInit2(&d_stream, -MAX_WBITS);
310 d_stream.avail_in = compr_bytes;
311 d_stream.next_in = &buffer_compr[0];
312 d_stream.avail_out = uncompr_bytes;
313 d_stream.next_out = &buffer_uncompr[0];
314 err = inflate(&d_stream, Z_FINISH);
315 err = inflateEnd(&d_stream);
316 std::vector<size_t> shape;
317 size_t word_size;
318 bool fortran_order;
319 std::string number_type;
320 cnpy::parse_npy_header(&buffer_uncompr[0], word_size, shape, fortran_order,
321 number_type);
322 cnpy::NpyArray array(shape, word_size, fortran_order, number_type);
323 size_t offset = uncompr_bytes - array.num_bytes();
324 memcpy(array.data<unsigned char>(), &buffer_uncompr[0] + offset,
325 array.num_bytes());
326 return array;
327}
328
329cnpy::npz_t cnpy::npz_load(std::string fname)
330{
331 FILE* fp = fopen(fname.c_str(), "rb");
332
333 if (!fp)
334 {
335 throw std::runtime_error("npz_load: Error! Unable to open file " + fname + "!");
336 }
337
338 cnpy::npz_t arrays;
339
340 while (1)
341 {
342 std::vector<char> local_header(30);
343 size_t headerres = fread(&local_header[0], sizeof(char), 30, fp);
344
345 if (headerres != 30)
346 {
347 throw std::runtime_error("npz_load: failed fread");
348 }
349
350 //if we've reached the global header, stop reading
351 if (local_header[2] != 0x03 || local_header[3] != 0x04)
352 {
353 break;
354 }
355
356 //read in the variable name
357 uint16_t name_len = *(uint16_t*) &local_header[26];
358 std::string varname(name_len, ' ');
359 size_t vname_res = fread(&varname[0], sizeof(char), name_len, fp);
360
361 if (vname_res != name_len)
362 {
363 throw std::runtime_error("npz_load: failed fread");
364 }
365
366 //erase the lagging .npy
367 varname.erase(varname.end() - 4, varname.end());
368 //read in the extra field
369 uint16_t extra_field_len = *(uint16_t*) &local_header[28];
370
371 if (extra_field_len > 0)
372 {
373 std::vector<char> buff(extra_field_len);
374 size_t efield_res = fread(&buff[0], sizeof(char), extra_field_len, fp);
375
376 if (efield_res != extra_field_len)
377 {
378 throw std::runtime_error("npz_load: failed fread");
379 }
380 }
381
382 uint16_t compr_method = *reinterpret_cast<uint16_t*>(&local_header[0] + 8);
383 uint32_t compr_bytes = *reinterpret_cast<uint32_t*>(&local_header[0] + 18);
384 uint32_t uncompr_bytes = *reinterpret_cast<uint32_t*>(&local_header[0] + 22);
385
386 if (compr_method == 0)
387 {
388 arrays[varname] = load_the_npy_file(fp);
389 }
390 else
391 {
392 arrays[varname] = load_the_npz_array(fp, compr_bytes, uncompr_bytes);
393 }
394 }
395
396 fclose(fp);
397 return arrays;
398}
399
400cnpy::NpyArray cnpy::npz_load(std::string fname, std::string varname)
401{
402 FILE* fp = fopen(fname.c_str(), "rb");
403
404 if (!fp)
405 {
406 throw std::runtime_error("npz_load: Unable to open file " + fname);
407 }
408
409 while (1)
410 {
411 std::vector<char> local_header(30);
412 size_t header_res = fread(&local_header[0], sizeof(char), 30, fp);
413
414 if (header_res != 30)
415 {
416 throw std::runtime_error("npz_load: failed fread");
417 }
418
419 //if we've reached the global header, stop reading
420 if (local_header[2] != 0x03 || local_header[3] != 0x04)
421 {
422 break;
423 }
424
425 //read in the variable name
426 uint16_t name_len = *(uint16_t*) &local_header[26];
427 std::string vname(name_len, ' ');
428 size_t vname_res = fread(&vname[0], sizeof(char), name_len, fp);
429
430 if (vname_res != name_len)
431 {
432 throw std::runtime_error("npz_load: failed fread");
433 }
434
435 vname.erase(vname.end() - 4, vname.end()); //erase the lagging .npy
436 //read in the extra field
437 uint16_t extra_field_len = *(uint16_t*) &local_header[28];
438 fseek(fp, extra_field_len, SEEK_CUR); //skip past the extra field
439 uint16_t compr_method = *reinterpret_cast<uint16_t*>(&local_header[0] + 8);
440 uint32_t compr_bytes = *reinterpret_cast<uint32_t*>(&local_header[0] + 18);
441 uint32_t uncompr_bytes = *reinterpret_cast<uint32_t*>(&local_header[0] + 22);
442
443 if (vname == varname)
444 {
445 NpyArray array = (compr_method == 0) ? load_the_npy_file(
446 fp) : load_the_npz_array(fp, compr_bytes, uncompr_bytes);
447 fclose(fp);
448 return array;
449 }
450 else
451 {
452 //skip past the data
453 uint32_t size = *(uint32_t*) &local_header[22];
454 fseek(fp, size, SEEK_CUR);
455 }
456 }
457
458 fclose(fp);
459 //if we get here, we haven't found the variable in the file
460 throw std::runtime_error("npz_load: Variable name " + varname + " not found in "
461 + fname);
462}
463
465{
466 FILE* fp = fopen(fname.c_str(), "rb");
467
468 if (!fp)
469 {
470 throw std::runtime_error("npy_load: Unable to open file " + fname);
471 }
472
473 NpyArray arr = load_the_npy_file(fp);
474 fclose(fp);
475 return arr;
476}
477
478template<class typeNumber, int dim>
479void cnpy::save(const Eigen::Matrix<typeNumber, Eigen::Dynamic, dim>&
480 mat, const std::string fname)
481{
482 std::vector<typeNumber> matvec(mat.rows() * mat.cols());
483 std::vector<size_t> shape = {(unsigned int) mat.rows(), (unsigned int)mat.cols()};
484
485 for (int i = 0; i < mat.rows(); ++i)
486 {
487 for (int j = 0; j < mat.cols(); ++j)
488 {
489 matvec[i * mat.cols() + j] = mat(i, j);
490 }
491 }
492
493 npy_save(fname, matvec.data(), shape);
494}
495
496template<class typeNumber>
497void cnpy::save(const Eigen::Tensor<typeNumber, 3>&
498 tens, const std::string fname)
499{
500 typename Eigen::Tensor<typeNumber, 3>::Dimensions dim = tens.dimensions();
501 int tot = 1;
502
503 for (int k = 0; k < dim.size(); k++)
504 {
505 tot *= dim[k];
506 }
507
508 std::vector<typeNumber> matvec(tot);
509 std::vector<size_t> shape = {(unsigned int) dim[0], (unsigned int) dim[1], (unsigned int) dim[2]};
510
511 for (int i = 0; i < dim[0]; ++i)
512 {
513 for (int j = 0; j < dim[1]; ++j)
514 {
515 for (int k = 0; k < dim[2]; ++k)
516 {
517 matvec[i * dim[2]*dim[1] + j * dim[2] + k] = tens(i, j, k);
518 }
519 }
520 }
521
522 npy_save(fname, matvec.data(), shape);
523}
524
525template<class typeNumber, int dim>
526Eigen::Matrix<typeNumber, Eigen::Dynamic, dim> cnpy::load(
527 Eigen::Matrix<typeNumber, Eigen::Dynamic, dim>& mat,
528 const std::string fname, std::string order)
529{
530 M_Assert(order == "rowMajor" ||
531 order == "colMajor", "Order can be only rowMajor or colMajor");
532 NpyArray arr = npy_load(fname);
533 assert(arr.shape.size() == 2);
534 mat.resize(arr.shape[0], arr.shape[1]);
535 std::vector<typeNumber> data = arr.as_vec<typeNumber>();
536
537 if (order == "rowMajor")
538 {
539 for (size_t i = 0; i < arr.shape[0]; ++i)
540 {
541 for (size_t j = 0; j < arr.shape[1]; ++j)
542 {
543 mat(i, j) = data[arr.shape[1] * i + j];
544 }
545 }
546 }
547 else if (order == "colMajor")
548 {
549 for (size_t i = 0; i < arr.shape[0]; ++i)
550 {
551 for (size_t j = 0; j < arr.shape[1]; ++j)
552 {
553 data[arr.shape[0] * j + i];
554 }
555 }
556 }
557
558 // delete[] arr.data;
559 return mat;
560}
561
562template<typename typeNumber>
563Eigen::Tensor<typeNumber, 3> cnpy::load(Eigen::Tensor<typeNumber, 3>& tens,
564 const std::string fname, std::string order)
565{
566 M_Assert(order == "rowMajor" ||
567 order == "colMajor", "Order can be only rowMajor or colMajor");
568 NpyArray arr = npy_load(fname);
569 assert(arr.shape.size() == 3);
570 tens.resize(static_cast<long>(arr.shape[0]), static_cast<long>(arr.shape[1]),
571 static_cast<long>(arr.shape[2]));
572 std::vector<typeNumber> data = arr.as_vec<typeNumber>();
573
574 if (order == "rowMajor")
575 {
576 for (size_t i = 0; i < arr.shape[0]; ++i)
577 {
578 for (size_t j = 0; j < arr.shape[1]; ++j)
579 {
580 for (size_t k = 0; k < arr.shape[2]; ++k)
581 {
582 tens(i, j, k) = data[arr.shape[1] * arr.shape[2] * i + j *
583 arr.shape[2] + k];
584 }
585 }
586 }
587 }
588 else if (order == "colMajor")
589 {
590 for (size_t i = 0; i < arr.shape[0]; ++i)
591 {
592 for (size_t j = 0; j < arr.shape[1]; ++j)
593 {
594 for (size_t k = 0; k < arr.shape[2]; ++k)
595 {
596 tens(i, j, k) = (typeNumber) data[arr.shape[0] * arr.shape[1] * k + j *
597 arr.shape[0] + i];
598 }
599 }
600 }
601 }
602
603 // delete[] arr.data;
604 return tens;
605}
606
607template<typename T>
608Eigen::SparseMatrix<T> cnpy::load(Eigen::SparseMatrix<T>& smatrix,
609 const std::string fname)
610{
611 auto d1 = cnpy::npz_load(fname, "data");
612 auto d2 = cnpy::npz_load(fname, "indices");
613 auto d3 = cnpy::npz_load(fname, "indptr");
614 auto d4 = cnpy::npz_load(fname, "shape");
615 std::vector<T> data = d1.as_vec<T>();
616 int32_t* indices = reinterpret_cast<int32_t*>(d2.data<int32_t>());
617 int32_t* indptr = reinterpret_cast<int32_t*>(d3.data<int32_t>());
618 int* shape = reinterpret_cast<int*>(d4.data<int>());
619 int rows, cols;
620 M_Assert(d4.shape[0] == 2, "Method works only with 2-D matrices");
621 rows = (int) shape[0];
622 cols = (int) d3.shape[0] - 1;
623 int nel = d1.shape[0];
624 smatrix.resize(rows, cols);
625 smatrix.reserve(nel);
626 typedef Eigen::Triplet<T> Trip;
627 std::vector<Trip> tripletList;
628
629 for (int i = 0; i < cols; ++i)
630 {
631 for (int j = indptr[i]; j < indptr[i + 1]; j++)
632 {
633 tripletList.push_back(Trip(indices[j], i, (T) data[j]));
634 }
635 }
636
637 smatrix.setFromTriplets(tripletList.begin(), tripletList.end());
638 return smatrix;
639}
640
641template<typename T>
642void cnpy::save(const Eigen::SparseMatrix<T>& mat, const std::string fname)
643{
644 std::vector<size_t> shape1 = std::vector<size_t> {(unsigned long) (mat.nonZeros())};
645 std::vector<size_t> shape2 = std::vector<size_t> {(unsigned long) (mat.outerSize() + 1)};
646 std::vector<size_t> shape3 = std::vector<size_t> {2};
647 std::vector<size_t> shape4 = std::vector<size_t> {256};
648 cnpy::npz_save(fname, "data", mat.valuePtr(), shape1, "w");
649 cnpy::npz_save(fname, "indices", mat.innerIndexPtr(), shape1, "a");
650 cnpy::npz_save(fname, "indptr", mat.outerIndexPtr(), shape2, "a");
651 int64_t t1 = mat.rows();
652 int64_t t2 = mat.cols();
653 int64_t* shape = new int64_t[2];
654 shape[0] = mat.rows();
655 shape[1] = mat.cols();
656 cnpy::npz_save(fname, "shape", shape, shape3, "a");
657 char myVar2 = 'abc';
658 cnpy::npz_save(fname, "format", &myVar2, shape4, "a");
659}
660
661template void cnpy::save(const Eigen::MatrixXi& mat, const std::string fname);
662template Eigen::MatrixXi cnpy::load(Eigen::MatrixXi& mat,
663 const std::string fname, std::string order);
664template void cnpy::save(const Eigen::MatrixXd& mat, const std::string fname);
665template Eigen::MatrixXd cnpy::load(Eigen::MatrixXd& mat,
666 const std::string fname, std::string order);
667template void cnpy::save(const Eigen::MatrixXf& mat, const std::string fname);
668template Eigen::MatrixXf cnpy::load(Eigen::MatrixXf& mat,
669 const std::string fname, std::string order);
670template void cnpy::save(const Eigen::MatrixXcd& mat, const std::string fname);
671template Eigen::MatrixXcd cnpy::load(Eigen::MatrixXcd& mat,
672 const std::string fname, std::string order);
673template void cnpy::save(const Eigen::VectorXi& mat, const std::string fname);
674template Eigen::VectorXi cnpy::load(Eigen::VectorXi& mat,
675 const std::string fname, std::string order);
676template void cnpy::save(const Eigen::VectorXd& mat, const std::string fname);
677template Eigen::VectorXd cnpy::load(Eigen::VectorXd& mat,
678 const std::string fname, std::string order);
679template void cnpy::save(const Eigen::VectorXf& mat, const std::string fname);
680template Eigen::VectorXf cnpy::load(Eigen::VectorXf& mat,
681 const std::string fname, std::string order);
682template void cnpy::save(const Eigen::VectorXcd& mat, const std::string fname);
683template Eigen::VectorXcd cnpy::load(Eigen::VectorXcd& mat,
684 const std::string fname, std::string order);
685template void cnpy::save(const Eigen::SparseMatrix<double>& mat,
686 const std::string fname);
687template Eigen::SparseMatrix<double> cnpy::load(Eigen::SparseMatrix<double>&
688 smatrix, const std::string fname);
689
690template void cnpy::save(const Eigen::Tensor<int, 3>& mat,
691 const std::string fname);
692template Eigen::Tensor<int, 3> cnpy::load(Eigen::Tensor<int, 3>& tens,
693 const std::string fname, std::string order);
694template void cnpy::save(const Eigen::Tensor<double, 3>& mat,
695 const std::string fname);
696template Eigen::Tensor<double, 3> cnpy::load(Eigen::Tensor<double, 3>& tens,
697 const std::string fname, std::string order);
698template void cnpy::save(const Eigen::Tensor<float, 3>& mat,
699 const std::string fname);
700template Eigen::Tensor<float, 3> cnpy::load(Eigen::Tensor<float, 3>& tens,
701 const std::string fname, std::string order);
702template void cnpy::save(const Eigen::Tensor<std::complex<double>, 3>& mat,
703 const std::string fname);
704template Eigen::Tensor<std::complex<double>, 3> cnpy::load(
705 Eigen::Tensor<std::complex<double>, 3>& tens,
706 const std::string fname, std::string order);
707#pragma GCC diagnostic pop
#define M_Assert(Expr, Msg)
Header file of the ITHACAstream class, it contains the implementation of several methods for input ou...
cnpy::NpyArray load_the_npz_array(FILE *fp, uint32_t compr_bytes, uint32_t uncompr_bytes)
Definition cnpy.C:290
volScalarField & T
Definition createT.H:46
void parse_zip_footer(FILE *fp, uint16_t &nrecs, size_t &global_header_size, size_t &global_header_offset)
Definition cnpy.C:240
void save(const Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
std::map< std::string, NpyArray > npz_t
Definition cnpy.H:163
cnpy::NpyArray load_the_npy_file(FILE *fp)
Definition cnpy.C:266
char map_type(const std::type_info &t)
Definition cnpy.C:21
Eigen::Matrix< T, -1, dim > load(Eigen::Matrix< T, -1, dim > &mat, const std::string fname, std::string order="rowMajor")
char BigEndianTest()
Definition cnpy.C:15
npz_t npz_load(std::string fname)
Definition cnpy.C:329
void npy_save(std::string fname, const T *data, const std::vector< size_t > shape, std::string mode="w")
Definition cnpy.H:198
NpyArray npy_load(std::string fname)
Definition cnpy.C:464
void npz_save(std::string zipname, std::string fname, const T *data, const std::vector< size_t > &shape, std::string mode="w")
Definition cnpy.H:262
void parse_npy_header(FILE *fp, size_t &word_size, std::vector< size_t > &shape, bool &fortran_order, std::string &number_type)
Definition cnpy.C:175
std::vector< char > & operator+=(std::vector< char > &lhs, const T rhs)
Definition cnpy.H:179
label i
Definition pEqn.H:46
T * data()
Definition cnpy.H:52
size_t num_bytes() const
Definition cnpy.H:150