Skip to content

Instantly share code, notes, and snippets.

@bshillingford
Created April 14, 2017 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bshillingford/fff3298e93cbee07c71d674f210f89fe to your computer and use it in GitHub Desktop.
Save bshillingford/fff3298e93cbee07c71d674f210f89fe to your computer and use it in GitHub Desktop.
C++ numpy format deserializer
#ifndef _READNP_H_
#define _READNP_H_
// Simple header-only library for loading serialized numpy arrays.
// Only for testing.
#include <algorithm>
#include <cassert>
#include <fstream>
#include <regex>
#include <string>
#include <vector>
template<typename T>
inline void readnp(std::string fn, std::vector<T>& data, std::vector<uint64_t>& shape) {
static_assert(std::is_same<T, float>::value
|| std::is_same<T, int>::value, "unsupported type");
static std::string signature = "\x93NUMPY";
std::ifstream f(fn);
std::string line;
std::getline(f, line, '\n');
//std::cout << "line: " << line << std::endl;
// many filetypes are handled by np.load, so check it's the right kind:
assert(std::equal(signature.begin(), signature.end(), line.begin()));
// double check types:
if (std::is_same<T, float>::value) { // float == <f4
assert(std::regex_search(line, std::regex(R"('descr':\s*'<f4')")));
} else if (std::is_same<T, int>::value) { // int == <i4
assert(std::regex_search(line, std::regex(R"('descr':\s*'<i4')")));
}
assert(std::regex_search(line, std::regex(R"('fortran_order':\s*False)")));
// get shape:
std::smatch mat;
assert(std::regex_search(line, mat, std::regex(R"('shape':\s*\(([\d, ]+)\))")));
std::string shape_str = mat.str(1);
//std::cout << "shape = " << shape_str << std::endl;
assert(shape.empty());
std::smatch num_match;
std::regex num_re("\\d+");
uint64_t nelem = 1;
while(std::regex_search(shape_str, num_match, num_re)) {
uint64_t dim = std::stol(num_match.str(0));
//std::cout << "dim: " << dim << std::endl;
shape.push_back(dim);
nelem *= dim;
shape_str = num_match.suffix();
}
// populate data:
data.resize(nelem);
f.read(reinterpret_cast<char*>(&data[0]), sizeof(T) * nelem);
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment