OpenFPGA/libs/libvtrcapnproto/ndmatrix_serdes.h

142 lines
4.1 KiB
C
Raw Normal View History

#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<Vec2, 3> mat_in({3, 3, 3}, {2, 3});
//
// ::capnp::MallocMessageBuilder builder;
// auto test = builder.initRoot<Test>();
// 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<Test>();
//
// vtr::NdMatrix<Vec2, 3> mat_out;
// ToNdMatrix<3, Test::Vec2, Vec2>(&mat_out, test.getVectors(), FromVec2);
// }
#include <functional>
#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<size_t N, typename CapType, typename CType>
void ToNdMatrix(
vtr::NdMatrix<CType, N>* m_out,
const typename Matrix<CapType>::Reader& m_in,
const std::function<void(CType*, const typename CapType::Reader&)>& 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<size_t, N> 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<size_t N, typename CapType, typename CType>
void FromNdMatrix(
typename Matrix<CapType>::Builder* m_out,
const vtr::NdMatrix<CType, N>& m_in,
const std::function<void(typename CapType::Builder*, const CType&)>& 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_ */