 |
Cerata
A library to generate structural hardware designs
|
15 #include "cerata/flattype.h"
25 #include "cerata/utils.h"
26 #include "cerata/type.h"
27 #include "cerata/node.h"
28 #include "cerata/expression.h"
33 std::stringstream ret;
35 ret << root.
str + sep;
49 FlatType::FlatType(
Type *t, std::vector<NamePart> prefix,
const std::string &name,
bool invert)
50 : type_(t), reverse_(invert) {
65 const std::optional<FlatType> &parent,
67 for (
const auto &f :
record->fields()) {
68 Flatten(list, f->type().get(), parent, f->name(), invert != f->reversed(), f->sep());
74 const std::optional<FlatType> &parent,
75 const std::string &name,
88 list->push_back(result);
98 std::vector<FlatType> result;
99 Flatten(&result, type, {},
"",
false);
103 std::string
ToString(std::vector<FlatType> flat_type_list) {
104 std::stringstream ret;
105 for (
size_t i = 0; i < flat_type_list.size(); i++) {
106 const auto &ft = flat_type_list[i];
107 auto name = ft.name(ft.nesting_level_ == 0 ?
NamePart(
"(root)") :
NamePart());
108 ret << std::setw(3) << std::right << i <<
" :"
109 << std::setw(32) << std::left
110 << std::string(
static_cast<int64_t
>(2 * ft.nesting_level_),
' ') + name <<
" | "
111 << std::setw(16) << std::left << ft.type_->name() <<
" | "
112 << std::setw(3) << std::right << ft.nesting_level_ <<
" | ";
113 if (ft.type_->width()) {
114 ret << std::setw(3) << std::right << (*ft.type_->width())->
ToString() <<
" | ";
116 ret << std::setw(3) << std::right << 0 <<
" | ";
118 ret << std::setw(8) << std::left << ft.type_->ToString(
true) << std::endl;
124 for (
const auto &ft : flat_types_list) {
125 if (ft.type_ == type) {
133 for (
size_t i = 0; i < flat_types_list.size(); i++) {
134 if (flat_types_list[i].type_ == type) {
138 return static_cast<int64_t
>(-1);
142 :
Named(a->name() +
"_to_" + b->name()),
149 for (
size_t i = 0; i <
fa_.size(); i++) {
156 auto ret = std::make_shared<TypeMapper>(
a,
b);
161 auto ret = std::make_shared<TypeMapper>(
a,
b);
163 for (
size_t i = 0; i < ret->flat_a().size(); i++) {
176 constexpr
int w = 20;
177 std::stringstream ret;
178 ret <<
"TypeMapper (a) " <<
a()->
ToString(
true,
true) +
" => (b) " +
b()->
ToString(
true,
true) +
"\n";
179 ret <<
" Meta: " + ::cerata::ToString(
meta) +
"\n";
180 ret << std::setw(w) <<
" " <<
" | ";
182 for (
const auto &x :
fb_) {
183 ret << std::setw(w) << x.name() <<
" | ";
186 ret << std::setw(w) <<
" " <<
" | ";
187 for (
const auto &x :
fb_) {
188 ret << std::setw(w) << x.type_->ToString() <<
" | ";
193 for (
size_t i = 0; i <
fb_.size() + 1; i++) { ret << std::string(w,
'-') <<
" | "; }
196 for (
size_t y = 0; y <
fa_.size(); y++) {
197 ret << std::setw(w) <<
fa_[y].name() <<
" | ";
198 for (
size_t x = 0; x <
fb_.size(); x++) {
199 ret << std::setw(w) <<
" " <<
" | ";
202 ret << std::setw(w) <<
fa_[y].type_->ToString() <<
" | ";
203 for (
size_t x = 0; x <
fb_.size(); x++) {
205 ret << std::setw(w) << val <<
" | ";
209 for (
size_t i = 0; i <
fb_.size() + 1; i++) { ret << std::string(w,
'-') <<
" | "; }
222 return ((
a_ ==
a) && (
b_ ==
b));
226 auto result = std::make_shared<TypeMapper>(
b_,
a_);
228 result->meta = this->
meta;
233 std::vector<MappingPair> pairs;
235 for (
size_t ia = 0; ia <
fa_.size(); ia++) {
237 if (maps_a.size() == 1) {
238 auto ib = maps_a.front().first;
240 if (maps_b.size() == 1) {
242 mp.
a.emplace_back(ia, 0,
fa_[ia]);
243 mp.
b.emplace_back(ib, 0,
fb_[ib]);
250 for (
size_t ia = 0; ia <
fa_.size(); ia++) {
252 if (maps.size() > 1) {
254 mp.
a.emplace_back(ia, 0,
fa_[ia]);
255 for (
const auto &m : maps) {
256 mp.
b.emplace_back(m.first, m.second,
fb_[m.first]);
263 for (
size_t ib = 0; ib <
fb_.size(); ib++) {
265 if (maps.size() > 1) {
267 mp.
b.emplace_back(ib, 0,
fb_[ib]);
268 for (
const auto &m : maps) {
269 mp.
a.emplace_back(m.first, m.second,
fa_[m.first]);
278 return std::make_shared<TypeMapper>(
a,
a);
285 std::shared_ptr<TypeMapper>
TypeMapper::Make(
const std::shared_ptr<Type> &a,
const std::shared_ptr<Type> &b) {
286 return Make(
a.get(),
b.get());
290 std::stringstream ret;
291 ret <<
"MappingPair: " << std::endl;
292 for (
size_t i = 0; i < std::max(
a.size(),
b.size()); i++) {
294 ret <<
" idx: " << std::setw(3) <<
index_a(i);
295 ret <<
" off: " << std::setw(3) <<
offset_a(i);
299 ret << std::setw(74) <<
" ";
303 ret <<
" idx: " << std::setw(3) <<
index_b(i);
304 ret <<
" off: " << std::setw(3) <<
offset_b(i);
308 ret << std::setw(74) <<
" ";
313 ret <<
" w: " << std::setw(74) <<
width_a()->ToString();
315 ret <<
" w: " << std::setw(74) <<
width_b()->ToString();
320 std::shared_ptr<Node>
MappingPair::width_a(
const std::optional<std::shared_ptr<Node>> &no_width_increment)
const {
321 std::shared_ptr<Node> result =
intl(0);
322 for (int64_t i = 0; i <
num_a(); i++) {
325 result = result + fw.value();
326 }
else if (no_width_increment) {
327 result = result + *no_width_increment;
333 std::shared_ptr<Node>
MappingPair::width_b(
const std::optional<std::shared_ptr<Node>> &no_width_increment)
const {
334 std::shared_ptr<Node> result =
intl(0);
335 for (int64_t i = 0; i <
num_b(); i++) {
338 result = result + fw.value();
339 }
else if (no_width_increment) {
340 result = result + *no_width_increment;
bool sep
Whether we should insert a separator after this part.
static std::shared_ptr< TypeMapper > Make(Type *a)
Construct a new TypeMapper from some type to itself, and return a smart pointer to it.
std::shared_ptr< Node > width_b(const OptionalNode &no_width_increment={}) const
Return the total width of the types on side B.
std::vector< std::pair< int64_t, T > > mapping_row(int64_t y)
Obtain non-zero element indices and value from row y, sorted by value.
std::vector< FlatType > fa_
The list of flattened types on the "a"-side.
Type * b_
Type of the "b"-side.
FlatType flat_type_a(int64_t i) const
Return the i-th FlatType on the "a"-side in the mapping matrix.
std::string ToString() const
Return a human-readable string of this TypeMapper.
Type * type_
A pointer to the original type.
virtual bool IsEqual(const Type &other) const
Determine if this Type is exactly equal to an other Type.
A Record type containing zero or more fields.
A structure to dynamically define type mappings between flattened types.
std::shared_ptr< TypeMapper > Inverse() const
Return a new TypeMapper that is the inverse of this TypeMapper.
MappingMatrix & SetNext(int64_t y, int64_t x)
Set the next (existing maximum + 1) value in a matrix at some position.
std::vector< FlatType > flat_b() const
Return the list of flattened types on the "b"-side.
Contains every Cerata class, function, etc...
std::shared_ptr< Node > width_a(const OptionalNode &no_width_increment={}) const
Return the total width of the types on side A.
MappingMatrix Transpose() const
Transpose the matrix.
Convenience struct to generate names in parts.
ID id() const
Return the Type ID.
bool CanConvert(const Type *a, const Type *b) const
Return true if this TypeMapper can map type a to type b.
std::vector< MappingPair > GetUniqueMappingPairs()
Get a list of unique mapping pairs.
std::string ToString(Expression::Op operation)
Human-readable expression operator.
std::string ToString(bool show_meta=false, bool show_mappers=false) const
Return the Type ID as a human-readable string.
Type * a() const
Return the type on the "a"-side.
std::vector< NamePart > name_parts_
Name parts of this flattened type.
std::vector< std::pair< int64_t, T > > mapping_column(int64_t x)
Obtain non-zero element indices and value from column x, sorted by value.
int64_t IndexOfFlatType(const std::vector< FlatType > &flat_types_list, const Type *type)
Return the index of some Type in a list of FlatTypes.
bool operator<(const FlatType &a, const FlatType &b)
Compares two FlatTypes first by name, then by nesting level. Useful for sorting.
bool ContainsFlatType(const std::vector< FlatType > &flat_types_list, const Type *type)
Return true if some Type is contained in a list of FlatTypes, false otherwise.
static std::shared_ptr< TypeMapper > MakeImplicit(Type *a, Type *b)
Construct a new TypeMapper from some type to another type, and automatically determine the type mappi...
std::shared_ptr< Literal > intl(int64_t i)
Obtain a shared pointer to an integer literal from the default node pool.
bool reverse_
Whether to invert this flattened type if it would be on a terminator node.
int64_t num_b() const
Return the number of FlatTypes on the "b"-side.
void FlattenRecord(std::vector< FlatType > *list, const Record *record, const std::optional< FlatType > &parent, bool invert)
Flatten a Record.
index index_b(int64_t i) const
Return the index of the i-th FlatType on the "b"-side in the mapping matrix.
TypeMapper(Type *a, Type *b)
TypeMapper constructor. Constructs an empty type mapping.
FlatType flat_type_b(int64_t i) const
Return the i-th FlatType on the "b"-side in the mapping matrix.
Convenience structure for anything that is named. Names are case-sensitive.
virtual std::optional< Node * > width() const
Return the width of the type, if it is synthesizable.
std::string name(const NamePart &root=NamePart(), const std::string &sep="_") const
Return the name of this flattened type, constructed from the name parts.
index index_a(int64_t i) const
Return the index of the i-th FlatType on the "a"-side in the mapping matrix.
Type * b() const
Return the type on the "b"-side.
offset offset_b(int64_t i) const
Return the offset of the i-th FlatType on the "b"-side in the mapping matrix.
std::shared_ptr< Record > record(const std::string &name, const std::vector< std::shared_ptr< Field >> &fields)
Create a new Record type, and return a shared pointer to it.
std::unordered_map< std::string, std::string > meta
KV storage for metadata of tools or specific backend implementations.
std::string str
The string of this name part.
A structure representing a mapping pair for a type mapping.
void Flatten(std::vector< FlatType > *list, Type *type, const std::optional< FlatType > &parent, const std::string &name, bool invert, bool sep)
Flatten any Type.
MappingMatrix< int64_t > map_matrix()
Return the mapping matrix of this TypeMapper.
TypeMapper & Add(int64_t a, int64_t b)
Add a mapping between two FlatTypes to the mapper.
A matrix used for TypeMapper.
std::vector< IOF > a
Flattype and its index in a mapping matrix on the "a"-side.
void SetMappingMatrix(MappingMatrix< int64_t > map_matrix)
Set the mapping matrix of this TypeMapper.
std::vector< FlatType > flat_a() const
Return the list of flattened types on the "a"-side.
Type * a_
Type of the "a"-side.
std::vector< FlatType > fb_
The list of flattened types on the "b"-side.
MappingMatrix< int64_t > matrix_
The mapping matrix.
int nesting_level_
Nesting level in a type hierarchy.
std::vector< IOF > b
Flattype and its index in a mapping matrix on the "b"-side.
offset offset_a(int64_t i) const
Return the offset of the i-th FlatType on the "a"-side in the mapping matrix.
int64_t num_a() const
Return the number of FlatTypes on the "a"-side.
std::string ToString() const
Generate a human-readable version of this MappingPair.