-
Notifications
You must be signed in to change notification settings - Fork 415
Created draft of new constraints class header file #1535
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
Changes from 12 commits
42492c7
31b826e
cbaf198
29d9bf5
85f1c10
131eca9
4c93f5f
92f267b
ff1c22d
ff95d41
c3ace92
37ad863
687105b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include "partition.h" | ||
#include <algorithm> | ||
#include <vector> | ||
|
||
const std::string Partition::get_name() { | ||
return name; | ||
} | ||
|
||
void Partition::set_name(std::string _part_name) { | ||
name = _part_name; | ||
} | ||
|
||
const PartitionRegion Partition::get_part_region() { | ||
return part_region; | ||
} | ||
|
||
void Partition::set_part_region(PartitionRegion pr) { | ||
part_region = pr; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef PARTITION_H | ||
#define PARTITION_H | ||
|
||
#include "vtr_strong_id.h" | ||
#include "region.h" | ||
#include "atom_netlist_fwd.h" | ||
#include "partition_region.h" | ||
/** | ||
* @file | ||
* @brief This file defines the data for a partition: a grouping of atoms that are constrained to a portion of an FPGA. | ||
* | ||
* A partition defines the atoms that are assigned to it, and the locations in which they can be placed. | ||
* The locations are a union of rectangles in x, y, sub_tile space. | ||
* Common cases include a single rectangle or a single x, y, sub_tile (specific location). More complex partitions | ||
* with L, T or other shapes can be created with a union of multiple rectangles. | ||
*/ | ||
|
||
/// @brief Type tag for PartitionId | ||
struct partition_id_tag; | ||
|
||
/// @brief A unique identifier for a partition | ||
typedef vtr::StrongId<partition_id_tag> PartitionId; | ||
|
||
class Partition { | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public: | ||
vaughnbetz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const std::string get_name(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put a brief comment for doxygen on top of these functions too. |
||
|
||
void set_name(std::string _part_name); | ||
|
||
/** | ||
* @brief Set the PartitionRegion (union of rectangular regions) for this partition | ||
* | ||
* @param pr The PartitionRegion belonging to the partition | ||
*/ | ||
void set_part_region(PartitionRegion pr); | ||
|
||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* @brief Get the PartitionRegion (union of rectangular regions) for this partition | ||
*/ | ||
const PartitionRegion get_part_region(); | ||
|
||
private: | ||
std::string name; ///< name of the partition, name will be unique across partitions | ||
PartitionRegion part_region; ///< the union of regions that the partition can be placed in | ||
}; | ||
|
||
#endif /* PARTITION_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#include "partition_region.h" | ||
|
||
PartitionRegion PartitionRegion::get_intersection(PartitionRegion part_region) { | ||
/**for N regions in part_region and M in the calling object you can get anywhere from | ||
* 0 to M*N regions in the resulting vector. Only intersection regions with non-zero area rectangles and | ||
* equivalent subtiles are put in the resulting vector | ||
* Rectangles are not merged even if it would be possible | ||
*/ | ||
PartitionRegion pr; | ||
Region intersect_region; | ||
bool regions_intersect; | ||
for (unsigned int i = 0; i < partition_region.size(); i++) { | ||
for (unsigned int j = 0; j < part_region.partition_region.size(); j++) { | ||
regions_intersect = partition_region[i].do_regions_intersect(part_region.partition_region[j]); | ||
if (regions_intersect) { | ||
intersect_region = partition_region[i].regions_intersection(part_region.partition_region[j]); | ||
pr.partition_region.push_back(intersect_region); | ||
} | ||
} | ||
} | ||
|
||
return pr; | ||
} | ||
|
||
void PartitionRegion::add_to_part_region(Region region) { | ||
partition_region.push_back(region); | ||
} | ||
|
||
std::vector<Region> PartitionRegion::get_partition_region() { | ||
return partition_region; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef PARTITION_REGIONS_H | ||
#define PARTITION_REGIONS_H | ||
|
||
#include "region.h" | ||
#include "atom_netlist_fwd.h" | ||
|
||
/** | ||
* @file | ||
* @brief This file defines the PartitionRegions class. The PartitionRegions class is used to store the union | ||
* of regions that a partition can be placed in. | ||
*/ | ||
|
||
class PartitionRegion { | ||
public: | ||
/** | ||
* @brief Return the intersection of two PartitionRegions | ||
* | ||
* @param part_region The PartitionRegion that the calling object will be intersected with | ||
*/ | ||
PartitionRegion get_intersection(PartitionRegion part_region); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets follow Keith's suggestion and be more like Rect. |
||
|
||
/** | ||
* @brief Add a region to the union of regions belonging to the partition | ||
* | ||
* @param region The region to be added to the calling object | ||
*/ | ||
void add_to_part_region(Region region); | ||
|
||
/** | ||
* @brief Return the union of regions | ||
*/ | ||
std::vector<Region> get_partition_region(); | ||
|
||
private: | ||
std::vector<Region> partition_region; ///< union of rectangular regions that a partition can be placed in | ||
}; | ||
|
||
#endif /* PARTITION_REGIONS_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "region.h" | ||
|
||
/// @brief sentinel value for indicating that a subtile has not been specified | ||
constexpr int NO_SUBTILE = -1; | ||
|
||
Region::Region() { | ||
sub_tile = NO_SUBTILE; | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
//default rect for a region is (-1, -1, -1, -1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Explain why (invalid, to help catch uninitialized use). |
||
region_bounds.set_xmin(-1); | ||
region_bounds.set_ymin(-1); | ||
region_bounds.set_xmax(-1); | ||
region_bounds.set_ymax(-1); | ||
} | ||
|
||
vtr::Rect<int> Region::get_region_rect() { | ||
return region_bounds; | ||
} | ||
|
||
void Region::set_region_rect(int _xmin, int _ymin, int _xmax, int _ymax) { | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
region_bounds.set_xmin(_xmin); | ||
region_bounds.set_xmax(_xmax); | ||
region_bounds.set_ymin(_ymin); | ||
region_bounds.set_ymax(_ymax); | ||
} | ||
|
||
int Region::get_sub_tile() { | ||
return sub_tile; | ||
} | ||
|
||
void Region::set_sub_tile(int _sub_tile) { | ||
sub_tile = _sub_tile; | ||
} | ||
|
||
bool Region::do_regions_intersect(Region region) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to intersect, should probably make this |
||
bool intersect = true; | ||
|
||
vtr::Rect<int> region_rect = region.get_region_rect(); | ||
vtr::Rect<int> intersect_rect; | ||
|
||
intersect_rect = intersection(region_bounds, region_rect); | ||
|
||
/** | ||
* if the intersection rectangle is empty or the subtile of the two regions does not match, | ||
* the regions do not intersect | ||
*/ | ||
if (intersect_rect.empty() || sub_tile != region.get_sub_tile()) { | ||
return intersect = false; | ||
} | ||
|
||
return intersect; | ||
} | ||
|
||
Region Region::regions_intersection(Region region) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to intersection, and make it a global function at the bottom of the header file (outside class): |
||
Region intersect; | ||
|
||
/** | ||
* If the subtiles of the two regions don't match, there is no intersection. | ||
* If they do match, the intersection function if used to get the overlap of the two regions' rectangles. | ||
* If there is no overlap, an empty rectangle will be returned. | ||
*/ | ||
if (sub_tile == region.get_sub_tile()) { | ||
intersect.set_sub_tile(sub_tile); | ||
vtr::Rect<int> region_rect = region.get_region_rect(); | ||
vtr::Rect<int> intersect_rect; | ||
|
||
intersect_rect = intersection(region_bounds, region_rect); | ||
|
||
intersect.set_region_rect(intersect_rect.xmin(), intersect_rect.ymin(), intersect_rect.xmax(), intersect_rect.ymax()); | ||
} | ||
|
||
return intersect; | ||
} | ||
|
||
bool Region::locked() { | ||
bool locked = false; | ||
|
||
if (region_bounds.xmin() != region_bounds.xmax()) { | ||
return locked; | ||
} | ||
|
||
if (region_bounds.ymin() != region_bounds.ymax()) { | ||
return locked; | ||
} | ||
|
||
if (sub_tile == NO_SUBTILE) { | ||
return locked; | ||
} | ||
|
||
return locked = true; | ||
} | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
bool Region::empty() { | ||
return region_bounds.empty(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#ifndef REGION_H | ||
#define REGION_H | ||
|
||
#include <vtr_geometry.h> | ||
|
||
/** | ||
* @file | ||
* @brief This file defines the Region class. The Region class stores the data for each constraint region. | ||
* | ||
* This includes the x and y bounds of the region rectangle and its sub_tile. To lock a block down to a specific location, | ||
* when defining the region specify xmin = xmax, ymin = ymax, and specify a subtile value. | ||
* | ||
*/ | ||
|
||
class Region { | ||
public: | ||
Region(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add @brief on these methods too so they show up in Doxygen (then build Doxygen to the vtr docs and make sure it shows up). |
||
|
||
vtr::Rect<int> get_region_rect(); | ||
|
||
void set_region_rect(int _xmin, int _ymin, int _xmax, int _ymax); | ||
|
||
int get_sub_tile(); | ||
|
||
void set_sub_tile(int _sub_tile); | ||
|
||
/** | ||
* @brief Return whether the region is empty, based on whether the region rectangle is empty | ||
*/ | ||
bool empty(); | ||
|
||
/** | ||
* @brief Returns whether two regions intersect | ||
* | ||
* Intersection is the area of overlap between the rectangles of two regions, | ||
* given that both regions have matching subtile values, or no subtiles assigned to them | ||
* The overlap is inclusive of the x and y boundaries of the rectangles | ||
* | ||
* @param region The region to intersect with the calling object | ||
*/ | ||
bool do_regions_intersect(Region region); | ||
|
||
/** | ||
* @brief Returns the coordinates of intersection of two regions | ||
* | ||
* @param region The region to intersect with the calling object | ||
*/ | ||
Region regions_intersection(Region region); | ||
|
||
/** | ||
* @brief Checks whether a block is locked down to a specific x, y, subtile location | ||
*/ | ||
bool locked(); | ||
|
||
private: | ||
//may need to include zmin, zmax for future use in 3D FPGA designs | ||
vtr::Rect<int> region_bounds; ///< xmin, ymin, xmax, ymax inclusive | ||
int sub_tile; ///< users will optionally select a subtile | ||
}; | ||
|
||
#endif /* REGION_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "vpr_constraints.h" | ||
|
||
void VprConstraints::add_constrained_atom(const AtomBlockId blk_id, const PartitionId part_id) { | ||
constrained_atoms.insert({blk_id, part_id}); | ||
|
||
auto got = constrained_atoms.find(blk_id); | ||
|
||
if (got == constrained_atoms.end()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each atom can be in only one partition; if it's already in a partition it will be switched to the new partition instead. |
||
constrained_atoms.insert({blk_id, part_id}); | ||
} else { | ||
got->second = part_id; | ||
} | ||
} | ||
|
||
PartitionId VprConstraints::get_atom_partition(AtomBlockId blk_id) { | ||
PartitionId part_id; | ||
|
||
auto got = constrained_atoms.find(blk_id); | ||
|
||
if (got == constrained_atoms.end()) { | ||
return part_id = PartitionId::INVALID(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // Not in a partition, i.e. unconstrained. |
||
} else { | ||
return got->second; | ||
} | ||
} | ||
|
||
void VprConstraints::add_partition(Partition part) { | ||
partitions.push_back(part); | ||
} | ||
|
||
Partition VprConstraints::get_partition(PartitionId part_id) { | ||
return partitions[part_id]; | ||
} | ||
|
||
std::vector<AtomBlockId> VprConstraints::get_part_atoms(PartitionId part_id) { | ||
std::vector<AtomBlockId> part_atoms; | ||
|
||
for (auto& it : constrained_atoms) { | ||
if (it.second == part_id) { | ||
part_atoms.push_back(it.first); | ||
} | ||
} | ||
|
||
return part_atoms; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.