Skip to content

Vpr constraints fixes #1602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vpr/src/base/ShowSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void ShowSetup(const t_vpr_setup& vpr_setup) {
VTR_LOG("Circuit placement file: %s\n", vpr_setup.FileNameOpts.PlaceFile.c_str());
VTR_LOG("Circuit routing file: %s\n", vpr_setup.FileNameOpts.RouteFile.c_str());
VTR_LOG("Circuit SDC file: %s\n", vpr_setup.Timing.SDCFile.c_str());
VTR_LOG("Vpr Constraints file: %s\n", vpr_setup.FileNameOpts.read_vpr_constraints_file.c_str());
VTR_LOG("Vpr floorplanning constraints file: %s\n", vpr_setup.FileNameOpts.read_vpr_constraints_file.c_str());
VTR_LOG("\n");

VTR_LOG("Packer: %s\n", (vpr_setup.PackerOpts.doPacking ? "ENABLED" : "DISABLED"));
Expand Down
3 changes: 2 additions & 1 deletion vpr/src/base/constraints_load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void print_region(FILE* fp, Region region) {

void print_partition(FILE* fp, Partition part) {
std::string name = part.get_name();
fprintf(fp, "\npartition_name: %s\n", name.c_str());
fprintf(fp, "partition_name: %s\n", name.c_str());

PartitionRegion pr = part.get_part_region();

Expand Down Expand Up @@ -51,6 +51,7 @@ void print_constraints(FILE* fp, VprConstraints constraints, int num_parts) {

temp_part = constraints.get_partition(part_id);

fprintf(fp, "\npartition_id: %zu\n", size_t(part_id));
print_partition(fp, temp_part);

atoms = constraints.get_part_atoms(part_id);
Expand Down
17 changes: 8 additions & 9 deletions vpr/src/base/gen/vpr_constraints_uxsdcxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* https://github.com/duck2/uxsdcxx
* Modify only if your build process doesn't involve regenerating this file.
*
* Cmdline: uxsdcxx.py ../vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
* Input file: /home/khalid88/Documents/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
* md5sum of input file: 3e1f2692931484aa45dce794ba723aa9
* Cmdline: uxsdcxx.py vpr_constraints.xsd
* Input file: /home/khalid88/Documents/uxsdcxx/vpr_constraints.xsd
* md5sum of input file: 6b6011a6e6446347b234da82e517422e
*/

#include <functional>
Expand Down Expand Up @@ -521,12 +521,11 @@ inline void load_add_region(const pugi::xml_node& root, T& out, Context& context
noreturn_report(report_error, "Unexpected child element in <add_region>.");
}

constexpr int NUM_T_PARTITION_STATES = 3;
constexpr int NUM_T_PARTITION_STATES = 2;
constexpr const int NUM_T_PARTITION_INPUTS = 2;
constexpr int gstate_t_partition[NUM_T_PARTITION_STATES][NUM_T_PARTITION_INPUTS] = {
{-1, 0},
{1, 0},
{1, -1},
{0, 0},
{0, 0},
};
template<class T, typename Context>
inline void load_partition(const pugi::xml_node& root, T& out, Context& context, const std::function<void(const char*)>* report_error, ptrdiff_t* offset_debug) {
Expand All @@ -552,7 +551,7 @@ inline void load_partition(const pugi::xml_node& root, T& out, Context& context,
size_t add_atom_count = 0;
size_t add_region_count = 0;
{
int next, state = 2;
int next, state = 1;
for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
*offset_debug = node.offset_debug();
gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
Expand All @@ -575,7 +574,7 @@ inline void load_partition(const pugi::xml_node& root, T& out, Context& context,
out.preallocate_partition_add_atom(context, add_atom_count);
out.preallocate_partition_add_region(context, add_region_count);
}
int next, state = 2;
int next, state = 1;
for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
*offset_debug = node.offset_debug();
gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
Expand Down
12 changes: 7 additions & 5 deletions vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* https://github.com/duck2/uxsdcxx
* Modify only if your build process doesn't involve regenerating this file.
*
* Cmdline: uxsdcxx.py ../vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
* Input file: /home/khalid88/Documents/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
* md5sum of input file: 3e1f2692931484aa45dce794ba723aa9
* Cmdline: uxsdcxx.py vpr_constraints.xsd
* Input file: /home/khalid88/Documents/uxsdcxx/vpr_constraints.xsd
* md5sum of input file: 6b6011a6e6446347b234da82e517422e
*/

#include <functional>
Expand Down Expand Up @@ -68,8 +68,10 @@ class VprConstraintsBase {
/** Generated for complex type "partition":
* <xs:complexType name="partition">
* <xs:sequence>
* <xs:element maxOccurs="unbounded" name="add_atom" type="add_atom" />
* <xs:element maxOccurs="unbounded" name="add_region" type="add_region" />
* <xs:choice maxOccurs="unbounded">
* <xs:element name="add_atom" type="add_atom" />
* <xs:element name="add_region" type="add_region" />
* </xs:choice>
* </xs:sequence>
* <xs:attribute name="name" type="xs:string" use="required" />
* </xs:complexType>
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.read_vpr_constraints_file, "--read_vpr_constraints")
.help("Reads the constraints data from the constraints file.")
.help("Reads the floorplanning constraints from the specified XML file.")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.read_router_lookahead, "--read_router_lookahead")
Expand Down
6 changes: 4 additions & 2 deletions vpr/src/base/vpr_constraints.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@
the add_region elements. -->
<xs:complexType name="partition">
<xs:sequence>
<xs:element name="add_atom" type="add_atom" maxOccurs="unbounded"/>
<xs:element name="add_region" type="add_region" maxOccurs="unbounded"/>
<xs:choice maxOccurs="unbounded">
<xs:element name="add_atom" type="add_atom"/>
<xs:element name="add_region" type="add_region"/>
</xs:choice>
</xs:sequence>

<xs:attribute name="name" type="xs:string" use="required"/>
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/vpr_constraints_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void load_vpr_constraints_file(const char* read_vpr_constraints_name) {
} else {
VTR_LOG_WARN(
"VPR constraints file '%s' may be in incorrect format. "
"Expecting .xml format\n",
"Expecting .xml format. Not reading file.\n",
read_vpr_constraints_name);
}

Expand Down
4 changes: 3 additions & 1 deletion vpr/src/base/vpr_constraints_reader.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* Defines the function used to load a vpr constraints file written in xml format into vpr*/
/* Defines the function used to load a vpr constraints file written in XML format into vpr
* The functions loads up the VprConstraints, Partition, Region, and PartitionRegion data structures
* according to the data provided in the XML file*/

#ifndef VPR_CONSTRAINTS_READER_H_
#define VPR_CONSTRAINTS_READER_H_
Expand Down
87 changes: 84 additions & 3 deletions vpr/src/base/vpr_constraints_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,44 @@

#include "vpr_constraints_uxsdcxx_interface.h"

/**
* @file
* @brief The reading of vpr floorplanning constraints is now done via uxsdcxx and the 'vpr_constraints.xsd' file.
* The interface between the generated code and VPR is provided by VprConstraintsBase, which is in the
* file 'vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h'.
* This file implements the virtual functions from VprConstraintsBase.
*
* Overview
* ========
* 'vpr_constraints.xsd' is an XML schema that specifies the desired format for a VPR constraints file.
* If this schema is changed, the following files must be regenerated: 'vpr/src/base/gen/vpr_constraints_uxsdcxx.h' and
* 'vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h'.
*
* Instructions to Update the Files
* ================================
*
* 1. Clone https://github.com/duck2/uxsdcxx/
* 2. Run 'python3 -mpip install --user -r requirements.txt'
* 3. Run 'python3 uxsdcxx.py vpr/src/base/vpr_constraints.xsd'
* 4. Copy 'vpr_constraints_uxsdcxx.h' and 'vpr_constraints_uxsdcxx_interface.h' to vpr/src/base/gen
* 5. Run 'make format'
* 6. Update 'vpr/src/base/vpr_constraints_serializer.h' (this file) by adding or changing functions as needed.
* If the schema has changed, the compiler will complain that virtual functions are missing if they are
* not implemented here.
*
* Functions in this file
* ======================
*
* This file implements all the functions that are necessary for the load/read interface of uxsdcxx. These are start_load, finish_load,
* error_encountered, and any function starting with 'set', 'add', 'preallocate' or 'finish'. Some of the load functions (ex. finish_load and
* the preallocate functions) have been stubbed out because the load could be successfully completed without implementing them.
*
* The functions related to the write interface have also been stubbed out because writing vpr_constraints XML files is not needed at this time.
* These functions can be implemented to make the write interface if needed.
*
* For more detail on how the load and write interfaces work with uxsdcxx, refer to 'vpr/src/route/SCHEMA_GENERATOR.md'
*/

struct VprConstraintsContextTypes : public uxsd::DefaultVprConstraintsContextTypes {
using AddAtomReadContext = void*;
using AddRegionReadContext = void*;
Expand Down Expand Up @@ -58,9 +96,38 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
virtual inline void set_add_atom_name_pattern(const char* name_pattern, void*& /*ctx*/) final {
auto& atom_ctx = g_vpr_ctx.atom();
std::string atom_name = name_pattern;

auto atom_name_regex = std::regex(atom_name);

atoms_.clear();

atom_id_ = atom_ctx.nlist.find_block(name_pattern);

if (atom_id_ == AtomBlockId::INVALID()) {
/* The constraints file may either provide a specific atom name or a regex.
* If the a valid atom ID is found for the atom name, then a specific atom name
* must have been read in from the file. The if condition checks for this case.
* The else statement checks for atoms that may match a regex.
* This code may get slow if many regexes are given in the file.
*/
if (atom_id_ != AtomBlockId::INVALID()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might have a specific name, might have a regex, this code could get slow if you have a lot of wildcards

atoms_.push_back(atom_id_);
} else {
/*If the atom name returns an invalid ID, it might be a regular expression, so loop through the atoms blocks
* and see if any block names match atom_name_regex.
*/
for (auto block_id : atom_ctx.nlist.blocks()) {
auto block_name = atom_ctx.nlist.block_name(block_id);

if (std::regex_search(block_name, atom_name_regex)) {
atoms_.push_back(block_id);
}
}
}

/*If the atoms_ vector is empty by this point, no atoms were found that matched the name,
* so the name is invalid.
*/
if (atoms_.empty()) {
VTR_LOG_WARN("Atom %s was not found, skipping atom.\n", name_pattern);
}
}
Expand Down Expand Up @@ -128,8 +195,8 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
virtual inline void finish_partition_add_atom(void*& /*ctx*/) final {
PartitionId part_id(num_partitions_);

if (atom_id_ != AtomBlockId::INVALID()) {
constraints_.add_constrained_atom(atom_id_, part_id);
for (unsigned int i = 0; i < atoms_.size(); i++) {
constraints_.add_constrained_atom(atoms_[i], part_id);
}
}

Expand Down Expand Up @@ -211,6 +278,11 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr

virtual inline void set_vpr_constraints_tool_name(const char* /*tool_name*/, void*& /*ctx*/) final {}

virtual inline void set_vpr_constraints_constraints_comment(const char* /*constraints_comment*/, void*& /*ctx*/) final {}

virtual inline const char* get_vpr_constraints_constraints_comment(void*& /*ctx*/) final {
return temp_.c_str();
}
virtual inline void* init_vpr_constraints_partition_list(void*& /*ctx*/) final {
return nullptr;
}
Expand All @@ -227,13 +299,22 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr

//temp data for loads
const std::function<void(const char*)>* report_error_;

//temp data structures to be loaded during file reading
Region loaded_region;
Partition loaded_partition;
PartitionRegion loaded_part_region;
VprConstraints constraints_;

//temp string used when a method must return a const char*
std::string temp_;

//used to count the number of partitions read in from the file
int num_partitions_ = 0;

//used when reading in atom names and regular expressions for atoms
AtomBlockId atom_id_;
std::vector<AtomBlockId> atoms_;
};

#endif /* VPR_CONSTRAINTS_SERIALIZER_H_ */