#ifndef NDMATRIX_SERDES_H_ #define NDMATRIX_SERDES_H_ // Provide generic functions for serializing vtr::NdMatrix to and from Cap'n // proto Matrix. // // Functions: // ToNdMatrix - Converts Matrix capnproto message to vtr::NdMatrix // FromNdMatrix - Converts vtr::NdMatrix to Matrix capnproto // // Example: // // Schema: // // using Matrix = import "matrix.capnp"; // // // struct Test { // struct Vec2 { // x @0 :Float32; // y @1 :Float32; // } // vectors @0 :Matrix.Matrix(Vec2) // } // // C++: // // struct Vec2 { // float x; // float y; // }; // // static void ToVec2(Vec2 *out, const Test::Vec2::Reader& in) { // out->x = in.getX(); // out->y = in.getY(); // } // // static void FromVec2(Test::Vec2::Builder* out, const Vec2 &in) { // out->setX(in.x); // out->setY(in.y); // } // // void example(std::string file) { // vtr::NdMatrix mat_in({3, 3, 3}, {2, 3}); // // ::capnp::MallocMessageBuilder builder; // auto test = builder.initRoot(); // auto vectors = test.getVectors(); // // FromNdMatrix<3, Test::Vec2, Vec2>(&vectors, mat_in, FromVec2); // writeMessageToFile(file, &builder); // // MmapFile f(file); // ::capnp::FlatArrayMessageReader reader(f.getData()); // auto test = reader.getRoot(); // // vtr::NdMatrix mat_out; // ToNdMatrix<3, Test::Vec2, Vec2>(&mat_out, test.getVectors(), FromVec2); // } #include #include "vtr_ndmatrix.h" #include "vpr_error.h" #include "matrix.capnp.h" // Generic function to convert from Matrix capnproto message to vtr::NdMatrix. // // Template arguments: // N = Number of matrix dimensions, must be fixed. // CapType = Source capnproto message type that is a single element the // Matrix capnproto message. // CType = Target C++ type that is a single element of vtr::NdMatrix. // // Arguments: // m_out = Target vtr::NdMatrix. // m_in = Source capnproto message reader. // copy_fun = Function to convert from CapType to CType. template void ToNdMatrix( vtr::NdMatrix* m_out, const typename Matrix::Reader& m_in, const std::function& copy_fun) { const auto& dims = m_in.getDims(); if (N != dims.size()) { VPR_THROW(VPR_ERROR_OTHER, "Wrong dimension of template N = %zu, m_in.getDims() = %zu", N, dims.size()); } std::array dim_sizes; size_t required_elements = 1; for (size_t i = 0; i < N; ++i) { dim_sizes[i] = dims[i]; required_elements *= dims[i]; } m_out->resize(dim_sizes); const auto& data = m_in.getData(); if (data.size() != required_elements) { VPR_THROW(VPR_ERROR_OTHER, "Wrong number of elements, expected %zu, actual %zu", required_elements, data.size()); } for (size_t i = 0; i < required_elements; ++i) { copy_fun(&m_out->get(i), data[i].getValue()); } } // Generic function to convert from vtr::NdMatrix to Matrix capnproto message. // // Template arguments: // N = Number of matrix dimensions, must be fixed. // CapType = Target capnproto message type that is a single element the // Matrix capnproto message. // CType = Source C++ type that is a single element of vtr::NdMatrix. // // Arguments: // m_out = Target capnproto message builder. // m_in = Source vtr::NdMatrix. // copy_fun = Function to convert from CType to CapType. // template void FromNdMatrix( typename Matrix::Builder* m_out, const vtr::NdMatrix& m_in, const std::function& copy_fun) { size_t elements = 1; auto dims = m_out->initDims(N); for (size_t i = 0; i < N; ++i) { dims.set(i, m_in.dim_size(i)); elements *= dims[i]; } auto data = m_out->initData(elements); for (size_t i = 0; i < elements; ++i) { auto elem = data[i].getValue(); copy_fun(&elem, m_in.get(i)); } } #endif /* NDMATRIX_SERDES_H_ */