Skip to content

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

Merged
merged 13 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
47 changes: 47 additions & 0 deletions vpr/src/base/partition.h
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 "partition_regions.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.
*/

//Type tag for PartitionId
struct partition_id_tag;

//A unique identifier for a partition
typedef vtr::StrongId<partition_id_tag> PartitionId;

class Partition {
public:
PartitionId get_partition_id();
void set_partiton_id(PartitionId _part_id);

std::string get_name();
void set_name(std::string _part_name);

//append to the atom_blocks vector
void add_to_atom_blocks(AtomBlockId id);

//check if a given atom is in the partition
bool is_atom_in_part(AtomBlockId id);

std::vector<AtomBlockId> get_partition_atoms();

PartitionRegions get_partition_regions();

private:
PartitionId id;
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 this too - unique id for this partition

std::string name; //name of the partition
Copy link
Contributor Author

Choose a reason for hiding this comment

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

name will be unique across partitions

std::vector<AtomBlockId> atom_blocks; //atoms that belong to this partition
PartitionRegions part_regions; //the union of regions that the partition can be placed in
};

#endif /* PARTITION_H */
37 changes: 37 additions & 0 deletions vpr/src/base/partition_regions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef PARTITION_REGIONS_H
#define PARTITION_REGIONS_H

/**
* @file
* @brief This file defines the PartitionRegions class. The PartitionRegions class is used to store the union
* of regions that a particular partition can be placed in.
*/

class PartitionRegions {
public:
/**
* Returns the intersection of two PartitionRegions vectors that are passed to it.
*/
PartitionRegions get_intersection(PartitionRegions region);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Consider making this a static method that consumes two arguments?


/**
* A test for intersection
* For example, test if the PartitionRegions of an atom intersect with PartitionRegions of a cluster.
*/
bool intersects(PartitionRegions region);

/**
* Takes Atom Id and PartitonRegions vector and returns the intersection of the atom's PartitionRegions
* and the net PartitionRegions of the cluster (if any exists)
*/
PartitionRegions get_intersection(const AtomBlockId& id, PartitionRegions part_regions);

void add_to_part_regions(Region region);

std::vector<Region> get_partition_regions();

private:
std::vector<Region> partition_regions; //vector of regions that a partition can be placed in
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure a vector of Region is the right data structure here. I feel like you want a spatial tree, e.g. :

You probably want to prototype a couple different data structures balancing simplicity of implementation, data size overhead, etc.

At a minimum, I believe that PartitionRegion needs a t_bb that encompasses the vector of regions to provide a quick no if the query it outside any of the supplied regions.

Copy link
Contributor

Choose a reason for hiding this comment

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

Common case is that the regions are simple (0 or 1 rectangle will be the dominant cases). T-shaped and L-shaped will be possible but relatively rare. So I think a k-d tree etc. is overkill and will be slower and more complex for the common case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Given your statement, should we consider a dynamic dispatch approach here? Where the simple 0/1 case is implemented without the vector at all, and the more complicated case gets a more complicated object?

Copy link
Contributor

Choose a reason for hiding this comment

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

We could. I'd leave it simple for now though, and based on future need we can update if we hit cpu bottlenecks, memory footprint etc. The class interface should hide all that from the callers, so re-coding would be limited.

};

#endif /* PARTITION_REGIONS_H */
31 changes: 31 additions & 0 deletions vpr/src/base/region.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef REGION_H
#define REGION_H

#include "globals.h"

/**
* @file
* @brief This file defines the Region class. The Region class stores the data for each constraint region.
* This includes the bounds of the region rectangle and the sub_tile bounds. To lock a block down to a specific location,
* when defining the region specify xmin = xmax, ymin = ymax, sub_tile_min = sub_tile_max
*
*/

class Region {
public:
vtr::Rect get_region_rect();
void set_region_rect(int _xmin, int _xmax, int _ymin, int _ymax);

int get_sub_tile_min();
int get_sub_tile_max();

void set_sub_tile_min(int _sub_tile_min);
void set_sub_tile_max(int _sub_tile_max);

private:
//may need to include zmin, zmax for future use in 3D FPGA designs
vtr::Rect<int> region_bounds; //xmin, xmax, ymin, ymax inclusive
int sub_tile_min, sub_tile_max; //inclusive bounds
};

#endif /* REGION_H */
46 changes: 46 additions & 0 deletions vpr/src/base/vpr_constraints.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef VPR_CONSTRAINTS_H
#define VPR_CONSTRAINTS_H

#include "vtr_vector.h"
#include "vpr_utils.h"
#include "partition.h"
#include "partition_regions.h"

/**
* @file
* @brief This file defines the VprConstraints class used to store and read out data related to user-specified
* block and region constraints for the packing and placement stages.
*
* Overview
* ========
* This class contains functions that read in and store information from a constraints XML file.
* The XML file provides a partition list, with the names/ids of the partitions, and each atom in the partition.
* It also specifies which regions the partitions should be placed in.
*
*/

class VprConstraints {
public:
void add_constrained_atom(const AtomBlockId blk_id, const PartitionId partition);

//Method to find which partition an atom belongs to
PartitionId get_atom_partition(AtomBlockId);

void add_partition(const PartitionId id, const std::string part_name, std::vector<AtomBlockId> atom_blocks, PartitionRegions part_region);

vtr::vector<PartitionId, Partition> get_partitions();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should return the partition that corresponds to a certain ID, not the whole vector.
Then you need to think about how you quickly get that partition from a partitionID that is passed in. If the index in the vector is the partition id, then you can simply look it up. But then you need to delete the partition_id you are storing or make sure it matches the index. Safer to delete it, and compute partition_id using nicer C++ pointer arithmetic (done in some rr_graph functions now); web search should find it.


private:
/**
* Store constraints information of each constrained atom.
* Store ID of the partition the atom belongs to.
*/
std::unordered_map<AtomBlockId, PartitionId> constrained_atoms;

/**
* Store partitions in a vector
*/
vtr::vector<PartitionId, Partition> partitions;
};

#endif /* VPR_CONSTRAINTS_H */