create capnp folder
This commit is contained in:
parent
4af766930b
commit
faa222f2c1
|
@ -10,3 +10,4 @@ add_subdirectory(libpcf)
|
||||||
add_subdirectory(libbusgroup)
|
add_subdirectory(libbusgroup)
|
||||||
add_subdirectory(libnamemanager)
|
add_subdirectory(libnamemanager)
|
||||||
add_subdirectory(libtileconfig)
|
add_subdirectory(libtileconfig)
|
||||||
|
add_subdirectory(libopenfpgacapnproto)
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
if(NOT MSCV)
|
||||||
|
# These flags generate noisy but non-bug warnings when using lib kj,
|
||||||
|
# supress them.
|
||||||
|
set(WARN_FLAGS_TO_DISABLE
|
||||||
|
-Wno-undef
|
||||||
|
-Wno-non-virtual-dtor
|
||||||
|
)
|
||||||
|
foreach(flag ${WARN_FLAGS_TO_DISABLE})
|
||||||
|
CHECK_CXX_COMPILER_FLAG(${flag} CXX_COMPILER_SUPPORTS_${flag})
|
||||||
|
if(CXX_COMPILER_SUPPORTS_${flag})
|
||||||
|
#Flag supported, so enable it
|
||||||
|
add_compile_options(${flag})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create generated headers from capnp schema files
|
||||||
|
#
|
||||||
|
# Each schema used should appear here.
|
||||||
|
set(CAPNP_DEFS
|
||||||
|
gen/unique_blocks_uxsdcxx.capnp
|
||||||
|
)
|
||||||
|
|
||||||
|
capnp_generate_cpp(CAPNP_SRCS CAPNP_HDRS
|
||||||
|
${CAPNP_DEFS}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
set(IC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../vtr-verilog-to-routing/libs/EXTERNAL/libinterchange/interchange)
|
||||||
|
set(CAPNPC_SRC_PREFIX ${IC_DIR})
|
||||||
|
|
||||||
|
find_program(WGET wget REQUIRED)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
|
||||||
|
# Add Java schema
|
||||||
|
set(JAVA_SCHEMA ${CMAKE_CURRENT_BINARY_DIR}/../../vtr-verilog-to-routing/libs/libvtrcapnproto/schema/capnp/java.capnp)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${JAVA_SCHEMA}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../../vtr-verilog-to-routing/libs/libvtrcapnproto/schema/capnp/
|
||||||
|
COMMAND ${WGET}
|
||||||
|
https://raw.githubusercontent.com/capnproto/capnproto-java/master/compiler/src/main/schema/capnp/java.capnp
|
||||||
|
-O ${JAVA_SCHEMA}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
set(CAPNPC_IMPORT_DIRS)
|
||||||
|
list(APPEND CAPNPC_IMPORT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/../../vtr-verilog-to-routing/libs/libvtrcapnproto/schema)
|
||||||
|
|
||||||
|
set(IC_PROTOS)
|
||||||
|
set(IC_SRCS)
|
||||||
|
set(IC_HDRS)
|
||||||
|
foreach(PROTO ${IC_PROTOS})
|
||||||
|
capnp_generate_cpp(
|
||||||
|
IC_SRC
|
||||||
|
IC_HDR
|
||||||
|
${IC_DIR}/${PROTO}
|
||||||
|
)
|
||||||
|
list(APPEND IC_SRCS ${IC_SRC})
|
||||||
|
list(APPEND IC_HDRS ${IC_HDR})
|
||||||
|
list(APPEND CAPNP_DEFS ${IC_DIR}/${PROTO})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
|
||||||
|
install(FILES ${CAPNP_DEFS} DESTINATION ${CMAKE_INSTALL_DATADIR}/openfpga)
|
||||||
|
|
||||||
|
add_library(libopenfpgacapnproto STATIC
|
||||||
|
${CAPNP_SRCS}
|
||||||
|
${IC_SRCS}
|
||||||
|
mmap_file.h
|
||||||
|
mmap_file.cpp
|
||||||
|
serdes_utils.h
|
||||||
|
serdes_utils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_dependencies(libopenfpgacapnproto
|
||||||
|
get_java_capnp_schema)
|
||||||
|
|
||||||
|
|
||||||
|
target_include_directories(libopenfpgacapnproto PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/gen
|
||||||
|
)
|
||||||
|
target_link_libraries(libopenfpgacapnproto
|
||||||
|
libopenfpgautil
|
||||||
|
CapnProto::capnp
|
||||||
|
)
|
|
@ -0,0 +1,84 @@
|
||||||
|
Capnproto usage in VTR
|
||||||
|
======================
|
||||||
|
|
||||||
|
Capnproto is a data serialization framework designed for portabliity and speed.
|
||||||
|
In VPR, capnproto is used to provide binary formats for internal data
|
||||||
|
structures that can be computed once, and used many times. Specific examples:
|
||||||
|
- rrgraph
|
||||||
|
- Router lookahead data
|
||||||
|
- Place matrix delay estimates
|
||||||
|
|
||||||
|
What is capnproto?
|
||||||
|
==================
|
||||||
|
|
||||||
|
capnproto can be broken down into 3 parts:
|
||||||
|
- A schema language
|
||||||
|
- A code generator
|
||||||
|
- A library
|
||||||
|
|
||||||
|
The schema language is used to define messages. Each message must have an
|
||||||
|
explcit capnproto schema, which are stored in files suffixed with ".capnp".
|
||||||
|
The capnproto documentation for how to write these schema files can be found
|
||||||
|
here: https://capnproto.org/language.html
|
||||||
|
|
||||||
|
The schema by itself is not especially useful. In order to read and write
|
||||||
|
messages defined by the schema in a target language (e.g. C++), a code
|
||||||
|
generation step is required. Capnproto provides a cmake function for this
|
||||||
|
purpose, `capnp_generate_cpp`. This generates C++ source and header files.
|
||||||
|
These source and header files combined with the capnproto C++ library, enables
|
||||||
|
C++ code to read and write the messages matching a particular schema. The C++
|
||||||
|
library API can be found here: https://capnproto.org/cxx.html
|
||||||
|
|
||||||
|
Contents of libvtrcapnproto
|
||||||
|
===========================
|
||||||
|
|
||||||
|
libvtrcapnproto should contain two elements:
|
||||||
|
- Utilities for working capnproto messages in VTR
|
||||||
|
- Generate source and header files of all capnproto messages used in VTR
|
||||||
|
|
||||||
|
I/O Utilities
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Capnproto does not provide IO support, instead it works from arrays (or file
|
||||||
|
descriptors). To avoid re-writing this code, libvtrcapnproto provides two
|
||||||
|
utilities that should be used whenever reading or writing capnproto message to
|
||||||
|
disk:
|
||||||
|
- `serdes_utils.h` provides the writeMessageToFile function - Writes a
|
||||||
|
capnproto message to disk.
|
||||||
|
- `mmap_file.h` provides MmapFile object - Maps a capnproto message from the
|
||||||
|
disk as a flat array.
|
||||||
|
|
||||||
|
NdMatrix Utilities
|
||||||
|
------------------
|
||||||
|
|
||||||
|
A common datatype which appears in many data structures that VPR might want to
|
||||||
|
serialize is the generic type `vtr::NdMatrix`. `ndmatrix_serdes.h` provides
|
||||||
|
generic functions ToNdMatrix and FromNdMatrix, which can be used to generically
|
||||||
|
convert between the provideid capnproto message `Matrix` and `vtr::NdMatrix`.
|
||||||
|
|
||||||
|
Capnproto schemas
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
libvtrcapnproto should contain all capnproto schema definitions used within
|
||||||
|
VTR. To add a new schema:
|
||||||
|
1. Add the schema to git in `libs/libvtrcapnproto/`
|
||||||
|
2. Add the schema file name to `capnp_generate_cpp` invocation in
|
||||||
|
`libs/libvtrcapnproto/CMakeLists.txt`.
|
||||||
|
|
||||||
|
The schema will be available in the header file `schema filename>.h`. The
|
||||||
|
actual header file will appear in the CMake build directory
|
||||||
|
`libs/libvtrcapnproto` after `libvtrcapnproto` has been rebuilt.
|
||||||
|
|
||||||
|
Writing capnproto binary files to text
|
||||||
|
======================================
|
||||||
|
|
||||||
|
The `capnp` tool (found in the CMake build directiory
|
||||||
|
`libs/EXTERNAL/capnproto/c++/src/capnp`) can be used to convert from a binary
|
||||||
|
capnp message to a textual form.
|
||||||
|
|
||||||
|
Example converting VprOverrideDelayModel from binary to text:
|
||||||
|
|
||||||
|
```
|
||||||
|
capnp convert binary:text place_delay_model.capnp VprOverrideDelayModel \
|
||||||
|
< place_delay.bin > place_delay.txt
|
||||||
|
```
|
|
@ -0,0 +1,4 @@
|
||||||
|
`rr_graph_uxsdcxx.capnp` is generated via uxsdcxx and is checked in to
|
||||||
|
avoid requiring python3 and the uxsdcxx depedencies to build VPR.
|
||||||
|
|
||||||
|
See `vpr/src/route/gen/SCHEMA_GENERATOR.md` for details.
|
|
@ -0,0 +1,29 @@
|
||||||
|
# This file is generated by uxsdcap 0.1.0.
|
||||||
|
# https://github.com/duck2/uxsdcxx
|
||||||
|
# Modify only if your build process doesn't involve regenerating this file.
|
||||||
|
#
|
||||||
|
# Cmdline: /home/talaeikh/uxsdcxx/uxsdcap.py /home/talaeikh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
|
||||||
|
# Input file: /home/talaeikh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
|
||||||
|
# md5sum of input file: 9c14a0ddd3c6bc1e690ca6abf467bae6
|
||||||
|
|
||||||
|
@0xa136dddfdd48783b;
|
||||||
|
using Cxx = import "/capnp/c++.capnp";
|
||||||
|
$Cxx.namespace("uniqueblockcap");
|
||||||
|
|
||||||
|
enum BlockType {
|
||||||
|
cbx @0;
|
||||||
|
cby @1;
|
||||||
|
sb @2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BlockInfo {
|
||||||
|
type @0: BlockType;
|
||||||
|
x @1: Int32;
|
||||||
|
y @2: Int32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct InstanceInfo {
|
||||||
|
x @0 :Int32;
|
||||||
|
y @1 :Int32;
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
//
|
||||||
|
// Created by amin on 1/17/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VTR_INTRA_CLUSTER_SERDES_H
|
||||||
|
#define VTR_INTRA_CLUSTER_SERDES_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "vtr_ndmatrix.h"
|
||||||
|
#include "vpr_error.h"
|
||||||
|
#include "matrix.capnp.h"
|
||||||
|
#include "map_lookahead.capnp.h"
|
||||||
|
#include "vpr_types.h"
|
||||||
|
#include "router_lookahead_map_utils.h"
|
||||||
|
|
||||||
|
template<typename CapElemType, typename ElemType>
|
||||||
|
void toVector(std::vector<ElemType>& vec_out,
|
||||||
|
const typename capnp::List<CapElemType>::Reader& m_in,
|
||||||
|
const std::function<void(std::vector<ElemType>&,
|
||||||
|
int,
|
||||||
|
const ElemType&)>& copy_fun) {
|
||||||
|
int size = m_in.size();
|
||||||
|
vec_out.resize(size);
|
||||||
|
for(int idx = 0; idx < size; idx++) {
|
||||||
|
copy_fun(vec_out, idx, m_in[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CapKeyType, typename CapValType, typename KeyType, typename CostType>
|
||||||
|
void toUnorderedMap(
|
||||||
|
std::unordered_map<KeyType, CostType>& map_in,
|
||||||
|
const int begin_flat_idx,
|
||||||
|
const int end_flat_idx,
|
||||||
|
const typename capnp::List<CapKeyType>::Reader& m_out_key,
|
||||||
|
const typename capnp::List<CapValType>::Reader& m_out_val,
|
||||||
|
const std::function<void(std::unordered_map<KeyType, CostType>&,
|
||||||
|
const KeyType&,
|
||||||
|
const typename CapValType::Reader&)>& copy_fun) {
|
||||||
|
|
||||||
|
for(int flat_idx = begin_flat_idx; flat_idx < end_flat_idx; flat_idx++) {
|
||||||
|
copy_fun(map_in, m_out_key[flat_idx], m_out_val[flat_idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CapElemType, typename ElemType>
|
||||||
|
void fromVector(typename capnp::List<CapElemType>::Builder& m_out,
|
||||||
|
const std::vector<ElemType>& vec_in,
|
||||||
|
const std::function<void(typename capnp::List<CapElemType>::Builder&,
|
||||||
|
int,
|
||||||
|
const ElemType&)>& copy_fun) {
|
||||||
|
|
||||||
|
for(int idx = 0; idx < (int)vec_in.size(); idx++) {
|
||||||
|
copy_fun(m_out, idx, vec_in[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CapKeyType, typename CapValType, typename KeyType, typename CostType>
|
||||||
|
void FromUnorderedMap(
|
||||||
|
typename capnp::List<CapKeyType>::Builder& m_out_key,
|
||||||
|
typename capnp::List<CapValType>::Builder& m_out_val,
|
||||||
|
const KeyType out_offset,
|
||||||
|
const std::unordered_map<KeyType, CostType>& map_in,
|
||||||
|
const std::function<void(typename capnp::List<CapKeyType>::Builder&,
|
||||||
|
typename capnp::List<CapValType>::Builder&,
|
||||||
|
int,
|
||||||
|
const KeyType&,
|
||||||
|
const CostType&)>& copy_fun) {
|
||||||
|
|
||||||
|
int flat_idx = out_offset;
|
||||||
|
for (const auto& entry : map_in) {
|
||||||
|
copy_fun(m_out_key, m_out_val, flat_idx, entry.first, entry.second);
|
||||||
|
flat_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //VTR_INTRA_CLUSTER_SERDES_H
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "mmap_file.h"
|
||||||
|
#include "vtr_error.h"
|
||||||
|
#include "vtr_util.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "kj/filesystem.h"
|
||||||
|
|
||||||
|
MmapFile::MmapFile(const std::string& file)
|
||||||
|
: size_(0) {
|
||||||
|
try {
|
||||||
|
auto fs = kj::newDiskFilesystem();
|
||||||
|
auto path = fs->getCurrentPath().evalNative(file);
|
||||||
|
|
||||||
|
const auto& dir = fs->getRoot();
|
||||||
|
auto stat = dir.lstat(path);
|
||||||
|
auto f = dir.openFile(path);
|
||||||
|
size_ = stat.size;
|
||||||
|
data_ = f->mmap(0, stat.size);
|
||||||
|
} catch (kj::Exception& e) {
|
||||||
|
throw vtr::VtrError(e.getDescription().cStr(), e.getFile(), e.getLine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const kj::ArrayPtr<const ::capnp::word> MmapFile::getData() const {
|
||||||
|
if ((size_ % sizeof(::capnp::word)) != 0) {
|
||||||
|
throw vtr::VtrError(
|
||||||
|
vtr::string_fmt("size_ %d is not a multiple of capnp::word", size_),
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kj::arrayPtr(reinterpret_cast<const ::capnp::word*>(data_.begin()),
|
||||||
|
size_ / sizeof(::capnp::word));
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef MMAP_FILE_H_
|
||||||
|
#define MMAP_FILE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "capnp/message.h"
|
||||||
|
#include "kj/array.h"
|
||||||
|
|
||||||
|
// Platform independent mmap, useful for reading large capnp's.
|
||||||
|
class MmapFile {
|
||||||
|
public:
|
||||||
|
explicit MmapFile(const std::string& file);
|
||||||
|
const kj::ArrayPtr<const ::capnp::word> getData() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t size_;
|
||||||
|
kj::Array<const kj::byte> data_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MMAP_FILE_H_ */
|
|
@ -0,0 +1,141 @@
|
||||||
|
#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_ */
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "serdes_utils.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "vtr_error.h"
|
||||||
|
#include "kj/filesystem.h"
|
||||||
|
|
||||||
|
void writeMessageToFile(const std::string& file, ::capnp::MessageBuilder* builder) {
|
||||||
|
try {
|
||||||
|
auto fs = kj::newDiskFilesystem();
|
||||||
|
auto path = fs->getCurrentPath().evalNative(file);
|
||||||
|
|
||||||
|
const auto& dir = fs->getRoot();
|
||||||
|
auto f = dir.openFile(path, kj::WriteMode::CREATE | kj::WriteMode::MODIFY);
|
||||||
|
f->truncate(0);
|
||||||
|
auto f_app = kj::newFileAppender(std::move(f));
|
||||||
|
capnp::writeMessage(*f_app, *builder);
|
||||||
|
} catch (kj::Exception& e) {
|
||||||
|
throw vtr::VtrError(e.getDescription().cStr(), e.getFile(), e.getLine());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef SERDES_UTILS_H_
|
||||||
|
#define SERDES_UTILS_H_
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include "capnp/serialize.h"
|
||||||
|
|
||||||
|
// Platform indepedent way to file message to a file on disk.
|
||||||
|
void writeMessageToFile(const std::string& file,
|
||||||
|
::capnp::MessageBuilder* builder);
|
||||||
|
|
||||||
|
inline ::capnp::ReaderOptions default_large_capnp_opts() {
|
||||||
|
::capnp::ReaderOptions opts = ::capnp::ReaderOptions();
|
||||||
|
|
||||||
|
/* Remove traversal limit */
|
||||||
|
opts.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SERDES_UTILS_H_ */
|
Loading…
Reference in New Issue