add capnp for unique blocks and add write bin function
This commit is contained in:
parent
faa222f2c1
commit
5174b7a336
|
@ -1,4 +1,4 @@
|
|||
`rr_graph_uxsdcxx.capnp` is generated via uxsdcxx and is checked in to
|
||||
`unique_blocks_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.
|
||||
|
||||
|
|
|
@ -11,19 +11,28 @@ using Cxx = import "/capnp/c++.capnp";
|
|||
$Cxx.namespace("uniqueblockcap");
|
||||
|
||||
enum BlockType {
|
||||
cbx @0;
|
||||
cby @1;
|
||||
sb @2;
|
||||
cbx @0;
|
||||
cby @1;
|
||||
sb @2;
|
||||
}
|
||||
|
||||
struct BlockInfo {
|
||||
type @0: BlockType;
|
||||
x @1: Int32;
|
||||
y @2: Int32;
|
||||
type @0: BlockType;
|
||||
x @1: Int32;
|
||||
y @2: Int32;
|
||||
}
|
||||
|
||||
|
||||
struct InstanceInfo {
|
||||
x @0 :Int32;
|
||||
y @1 :Int32;
|
||||
x @0: Int32;
|
||||
y @1: Int32;
|
||||
}
|
||||
|
||||
|
||||
struct UniqueBlockPacked {
|
||||
blockInfo @0: BlockInfo;
|
||||
instanceList @1: List(InstanceInfo);
|
||||
}
|
||||
|
||||
struct UniqueBlockCompactInfo {
|
||||
atomInfo @0: List(UniqueBlockPacked);
|
||||
}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
//
|
||||
// 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
|
|
@ -1,141 +0,0 @@
|
|||
#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_ */
|
|
@ -44,7 +44,9 @@ target_link_libraries(libopenfpga
|
|||
libnamemanager
|
||||
libtileconfig
|
||||
libpugixml
|
||||
libvpr)
|
||||
libvpr
|
||||
libopenfpgacapnproto
|
||||
)
|
||||
|
||||
#Create the test executable
|
||||
add_executable(openfpga ${EXEC_SOURCE})
|
||||
|
|
|
@ -154,4 +154,10 @@ int read_xml_unique_blocks(DeviceRRGSB& device_rr_gsb, const char* file_name,
|
|||
archfpga_throw(file_name, e.line(), "%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
int read_bin_unique_blocks(DeviceRRGSB& device_rr_gsb, const char* file_name,
|
||||
bool verbose_output) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openfpga
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
/* Headers from libarchfpga */
|
||||
#include "arch_error.h"
|
||||
#include "device_rr_gsb_utils.h"
|
||||
|
||||
#include "unique_blocks_uxsdcxx.capnp.h"
|
||||
/********************************************************************
|
||||
* This file includes the top-level functions of this library
|
||||
* which includes:
|
||||
|
@ -35,5 +35,8 @@ void report_unique_module_status_read(const DeviceRRGSB& device_rr_gsb,
|
|||
|
||||
int read_xml_unique_blocks(DeviceRRGSB& device_rr_gsb, const char* file_name,
|
||||
bool verbose_output);
|
||||
|
||||
int read_bin_unique_blocks(DeviceRRGSB& device_rr_gsb, const char* file_name,
|
||||
bool verbose_output);
|
||||
} // namespace openfpga
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
|
||||
#include <capnp/message.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
/* Headers from pugi XML library */
|
||||
#include "pugixml.hpp"
|
||||
#include "pugixml_util.hpp"
|
||||
|
||||
#include "serdes_utils.h"
|
||||
/* Headers from vtr util library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
@ -17,6 +18,7 @@
|
|||
#include "openfpga_digest.h"
|
||||
#include "read_xml_util.h"
|
||||
#include "rr_gsb.h"
|
||||
#include "unique_blocks_uxsdcxx.capnp.h"
|
||||
#include "write_xml_unique_blocks.h"
|
||||
#include "write_xml_utils.h"
|
||||
|
||||
|
@ -187,4 +189,66 @@ int write_xml_unique_blocks(const DeviceRRGSB& device_rr_gsb, const char* fname,
|
|||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
// int write_bin_atom_block(std::fstream& fp,
|
||||
// const std::vector<vtr::Point<size_t>>& instance_map,
|
||||
// const vtr::Point<size_t>& unique_block_coord,
|
||||
// std::string type,
|
||||
// ucap::RrGraph::Builder &root) {
|
||||
|
||||
// root.init
|
||||
// write_xml_attribute(fp, "type", type.c_str());
|
||||
// write_xml_attribute(fp, "x", unique_block_coord.x());
|
||||
// write_xml_attribute(fp, "y", unique_block_coord.y());
|
||||
|
||||
// for (const auto& instance_info : instance_map) {
|
||||
// if (instance_info.x() == unique_block_coord.x() &&
|
||||
// instance_info.y() == unique_block_coord.y()) {
|
||||
// ;
|
||||
// } else {
|
||||
// openfpga::write_tab_to_file(fp, 2);
|
||||
// fp << "<instance";
|
||||
// write_xml_attribute(fp, "x", instance_info.x());
|
||||
// write_xml_attribute(fp, "y", instance_info.y());
|
||||
// }
|
||||
// }
|
||||
// return openfpga::CMD_EXEC_SUCCESS;
|
||||
// }
|
||||
|
||||
int write_bin_unique_blocks(const DeviceRRGSB& device_rr_gsb, const char* fname,
|
||||
bool verbose_output) {
|
||||
::capnp::MallocMessageBuilder builder;
|
||||
auto unique_blocks =
|
||||
builder.initRoot<uniqueblockcap::UniqueBlockCompactInfo>();
|
||||
void* context;
|
||||
int num_unique_blocks = device_rr_gsb.get_num_sb_unique_module() +
|
||||
device_rr_gsb.get_num_cb_unique_module(CHANX) +
|
||||
device_rr_gsb.get_num_cb_unique_module(CHANY);
|
||||
unique_blocks.initAtomInfo(num_unique_blocks);
|
||||
for (size_t id = 0; id < device_rr_gsb.get_num_sb_unique_module(); ++id) {
|
||||
const auto unique_block_coord = device_rr_gsb.get_sb_unique_block_coord(id);
|
||||
const std::vector<vtr::Point<size_t>> instance_map =
|
||||
device_rr_gsb.get_sb_unique_block_instance_coord(unique_block_coord);
|
||||
|
||||
auto unique_block = unique_blocks[id];
|
||||
auto block_info = unique_block.initBlockInfo();
|
||||
block_info.setX(unique_block_coord.x());
|
||||
block_info.setY(unique_block_coord.y());
|
||||
block_info.setType(SB);
|
||||
auto instance_list = unique_block.initInstanceList(instance_map.size());
|
||||
for (size_t instance_id = 0 ; instance_id < instance_map; instance_id ++){
|
||||
if (instance_map[instance_id].x() == unique_block_coord.x() &&
|
||||
instance_map[instance_id].y() == unique_block_coord.y()) {
|
||||
;
|
||||
} else {
|
||||
auto instance = instance_list[instance_id];
|
||||
instance.setX(instance_map[instance_id].x());
|
||||
instance.setY(instance_map[instance_id].y());
|
||||
}
|
||||
}
|
||||
}
|
||||
writeMessageToFile(fname, &builder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openfpga
|
||||
|
|
|
@ -33,5 +33,7 @@ void report_unique_module_status_write(
|
|||
bool verbose_output); /*report status of written info*/
|
||||
int write_xml_unique_blocks(const DeviceRRGSB& device_rr_gsb, const char* fname,
|
||||
bool verbose_output);
|
||||
int write_bin_unique_blocks(const DeviceRRGSB& device_rr_gsb, const char* fname,
|
||||
bool verbose_output);
|
||||
} // namespace openfpga
|
||||
#endif
|
||||
|
|
|
@ -500,6 +500,10 @@ int read_unique_blocks_template(T& openfpga_ctx, const Command& cmd,
|
|||
return read_xml_unique_blocks(openfpga_ctx.mutable_device_rr_gsb(),
|
||||
file_name.c_str(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
} else if (file_type == "bin") {
|
||||
return read_bin_unique_blocks(openfpga_ctx.mutable_device_rr_gsb(),
|
||||
file_name.c_str(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
} else {
|
||||
VTR_LOG_ERROR("file type %s not supported", file_type.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
|
@ -528,6 +532,10 @@ int write_unique_blocks_template(T& openfpga_ctx, const Command& cmd,
|
|||
return write_xml_unique_blocks(openfpga_ctx.device_rr_gsb(),
|
||||
file_name.c_str(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
} else if (file_type == "bin") {
|
||||
return write_bin_unique_blocks(openfpga_ctx.mutable_device_rr_gsb(),
|
||||
file_name.c_str(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
} else {
|
||||
VTR_LOG_ERROR("file type %s not supported", file_type.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
|
|
Loading…
Reference in New Issue