20namespace ddc::detail {
22NpyByteOrder get_byte_order(std::size_t
const itemsize)
noexcept
25 return NpyByteOrder::not_applicable;
28 if (std::endian::native == std::endian::little) {
29 return NpyByteOrder::little_endian;
32 if (std::endian::native == std::endian::big) {
33 return NpyByteOrder::big_endian;
36 return NpyByteOrder::not_applicable;
39void write_le(std::ostream& os, std::uint16_t
const value_u16)
41 constexpr unsigned int mask = 0xFFU;
43 unsigned int const value_u = value_u16;
45 std::array<
char, 2> bytes;
46 bytes[0] = value_u & mask;
47 bytes[1] = (value_u >> 8U) & mask;
49 os.write(bytes.data(),
sizeof(value_u16));
52std::string NpyDtype::str()
const
54 return std::string(1,
static_cast<
char>(byte_order)) +
static_cast<
char>(kind)
55 + std::to_string(itemsize);
59void save_npy(std::ostream& os, NpyArrayView
const& view)
62 std::string shape_str =
"(";
63 for (std::size_t
const ext : view.shape) {
64 shape_str += std::to_string(ext);
69 std::string
const header_dict
70 = std::string(
"{'descr': '") + view.dtype.str() +
"', 'fortran_order': "
71 + (view.fortran_order ?
"True" :
"False") +
", 'shape': " + shape_str +
", }";
74 std::size_t
const non_padded_header_len = header_dict.size() + 1;
76 std::size_t
const alignment = 16;
77 std::size_t
const remainder = (6 + 1 + 1 + 2 + non_padded_header_len) % alignment;
78 std::size_t
const padding = (alignment - remainder) % alignment;
79 if (!std::in_range<std::uint16_t>(non_padded_header_len + padding)) {
80 throw std::runtime_error(
"save_npy: header too large for npy v1.0.");
82 auto const header_len =
static_cast<std::uint16_t>(non_padded_header_len + padding);
85 os.write(
"\x93NUMPY", 6);
91 write_le(os, header_len);
93 os.write(header_dict.data(), header_dict.size());
94 os.write(
" ", padding);
98 std::size_t
const n_elems
99 = std::accumulate(view.shape.begin(), view.shape.end(), 1ULL, std::multiplies<> {});
100 os.write(
reinterpret_cast<
char const*>(view.data), n_elems * view.dtype.itemsize);
103void save_npy(std::filesystem::path
const& filename, NpyArrayView
const& view)
105 std::ofstream file(filename, std::ios::binary);
106 file.exceptions(std::ios::failbit | std::ios::badbit);
108 save_npy(file, view);
The top-level namespace of DDC.