add capnp for unique blocks and add write bin function

This commit is contained in:
Lin 2024-09-26 17:39:52 +08:00
parent faa222f2c1
commit 5174b7a336
10 changed files with 109 additions and 238 deletions

View File

@ -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.

View File

@ -22,8 +22,17 @@ struct BlockInfo {
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);
}

View File

@ -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

View File

@ -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_ */

View File

@ -44,7 +44,9 @@ target_link_libraries(libopenfpga
libnamemanager
libtileconfig
libpugixml
libvpr)
libvpr
libopenfpgacapnproto
)
#Create the test executable
add_executable(openfpga ${EXEC_SOURCE})

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;