mirror of https://github.com/llvm/circt.git
[MSFT] [DeviceDB] Find nearest free location in column (#1937)
Find the nearest primitive in a column to the desired row. Said primitive should be of a given primitive type, and be unoccupied.
This commit is contained in:
parent
9909253abf
commit
d488343996
|
@ -24,6 +24,9 @@ MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(MSFT, msft);
|
|||
|
||||
MLIR_CAPI_EXPORTED void mlirMSFTRegisterPasses();
|
||||
|
||||
// Values represented in `MSFT.td`.
|
||||
typedef uint32_t CirctMSFTPrimitiveType;
|
||||
|
||||
/// Emits tcl for the specified module using the provided callback and user
|
||||
/// data
|
||||
MLIR_CAPI_EXPORTED MlirLogicalResult mlirMSFTExportTcl(MlirOperation,
|
||||
|
@ -70,6 +73,9 @@ circtMSFTPlacementDBAddPlacement(CirctMSFTPlacementDB, MlirAttribute loc,
|
|||
bool circtMSFTPlacementDBTryGetInstanceAt(CirctMSFTPlacementDB,
|
||||
MlirAttribute loc,
|
||||
CirctMSFTPlacedInstance *out);
|
||||
MlirAttribute circtMSFTPlacementDBGetNearestFreeInColumn(
|
||||
CirctMSFTPlacementDB, CirctMSFTPrimitiveType prim, uint64_t column,
|
||||
uint64_t nearestToY);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MSFT Attributes.
|
||||
|
@ -82,9 +88,6 @@ MLIR_CAPI_EXPORTED void mlirMSFTAddPhysLocationAttr(MlirOperation op,
|
|||
PrimitiveType type, long x,
|
||||
long y, long num);
|
||||
|
||||
// Values represented in `MSFT.td`.
|
||||
typedef uint32_t CirctMSFTPrimitiveType;
|
||||
|
||||
bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute);
|
||||
MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext, CirctMSFTPrimitiveType,
|
||||
uint64_t x, uint64_t y,
|
||||
|
|
|
@ -60,9 +60,19 @@ public:
|
|||
/// Lookup the instance at a particular location.
|
||||
Optional<PlacedInstance> getInstanceAt(PhysLocationAttr);
|
||||
|
||||
/// Find the nearest unoccupied primitive location to 'nearestToY' in
|
||||
/// 'column'.
|
||||
PhysLocationAttr getNearestFreeInColumn(PrimitiveType prim, uint64_t column,
|
||||
uint64_t nearestToY);
|
||||
|
||||
/// Walk the placement information in some sort of reasonable order.
|
||||
void walkPlacements(function_ref<void(PhysLocationAttr, PlacedInstance)>);
|
||||
|
||||
/// Walk the column placements in some sort of reasonable order.
|
||||
void
|
||||
walkColumnPlacements(uint64_t column,
|
||||
function_ref<void(PhysLocationAttr, PlacedInstance)>);
|
||||
|
||||
private:
|
||||
MLIRContext *ctxt;
|
||||
Operation *top;
|
||||
|
|
|
@ -94,12 +94,20 @@ with ir.Context() as ctx, ir.Location.unknown():
|
|||
devdb = msft.DeviceDB()
|
||||
assert not devdb.is_valid_location(physAttr)
|
||||
devdb.add_primitive(physAttr)
|
||||
devdb.add_primitive(msft.PhysLocationAttr.get(msft.M20K, x=2, y=50, num=1))
|
||||
assert devdb.is_valid_location(physAttr)
|
||||
|
||||
seeded_pdb = msft.PlacementDB(top.operation, devdb)
|
||||
|
||||
print(seeded_pdb.get_nearest_free_in_column(msft.M20K, 2, 4))
|
||||
# CHECK: #msft.physloc<M20K, 2, 6, 1>
|
||||
|
||||
rc = seeded_pdb.add_placement(physAttr, path, "subpath", resolved_inst)
|
||||
assert rc
|
||||
|
||||
print(seeded_pdb.get_nearest_free_in_column(msft.M20K, 2, 4))
|
||||
# CHECK: #msft.physloc<M20K, 2, 50, 1>
|
||||
|
||||
bad_loc = msft.PhysLocationAttr.get(msft.M20K, x=7, y=99, num=1)
|
||||
rc = seeded_pdb.add_placement(bad_loc, path, "subpath", resolved_inst)
|
||||
assert not rc
|
||||
|
|
|
@ -63,6 +63,14 @@ public:
|
|||
std::string subpath(inst.subpath, inst.subpathLength);
|
||||
return (py::tuple)py::cast(std::make_tuple(inst.path, subpath, inst.op));
|
||||
}
|
||||
py::object getNearestFreeInColumn(CirctMSFTPrimitiveType prim,
|
||||
uint64_t column, uint64_t nearestToY) {
|
||||
MlirAttribute nearest = circtMSFTPlacementDBGetNearestFreeInColumn(
|
||||
db, prim, column, nearestToY);
|
||||
if (!nearest.ptr)
|
||||
return py::none();
|
||||
return py::cast(nearest);
|
||||
}
|
||||
|
||||
private:
|
||||
CirctMSFTPlacementDB db;
|
||||
|
@ -179,6 +187,9 @@ void circt::python::populateDialectMSFTSubmodule(py::module &m) {
|
|||
.def("add_placement", &PlacementDB::addPlacement,
|
||||
"Inform the DB about a new placement.", py::arg("location"),
|
||||
py::arg("path"), py::arg("subpath"), py::arg("op"))
|
||||
.def("get_nearest_free_in_column", &PlacementDB::getNearestFreeInColumn,
|
||||
"Find the nearest free primitive location in column.",
|
||||
py::arg("prim_type"), py::arg("column"), py::arg("nearest_to_y"))
|
||||
.def("get_instance_at", &PlacementDB::getInstanceAt,
|
||||
"Get the instance at location. Returns None if nothing exists "
|
||||
"there. Otherwise, returns (path, subpath, op) of the instance "
|
||||
|
|
|
@ -102,6 +102,14 @@ bool circtMSFTPlacementDBTryGetInstanceAt(CirctMSFTPlacementDB self,
|
|||
return true;
|
||||
}
|
||||
|
||||
MlirAttribute circtMSFTPlacementDBGetNearestFreeInColumn(
|
||||
CirctMSFTPlacementDB cdb, CirctMSFTPrimitiveType prim, uint64_t column,
|
||||
uint64_t nearestToY) {
|
||||
auto db = unwrap(cdb);
|
||||
return wrap(
|
||||
db->getNearestFreeInColumn((PrimitiveType)prim, column, nearestToY));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MSFT Attributes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -112,6 +112,27 @@ PlacementDB::getInstanceAt(PhysLocationAttr loc) {
|
|||
return instF->getSecond();
|
||||
}
|
||||
|
||||
PhysLocationAttr PlacementDB::getNearestFreeInColumn(PrimitiveType prim,
|
||||
uint64_t columnNum,
|
||||
uint64_t nearestToY) {
|
||||
// Simplest possible algorithm.
|
||||
PhysLocationAttr nearest = {};
|
||||
walkColumnPlacements(columnNum, [&nearest, columnNum](PhysLocationAttr loc,
|
||||
PlacedInstance inst) {
|
||||
if (inst.op)
|
||||
return;
|
||||
if (!nearest) {
|
||||
nearest = loc;
|
||||
return;
|
||||
}
|
||||
int64_t curDist = std::abs((int64_t)columnNum - (int64_t)nearest.getY());
|
||||
int64_t replDist = std::abs((int64_t)columnNum - (int64_t)loc.getY());
|
||||
if (replDist < curDist)
|
||||
nearest = loc;
|
||||
});
|
||||
return nearest;
|
||||
}
|
||||
|
||||
Optional<PlacementDB::PlacedInstance *>
|
||||
PlacementDB::getLeaf(PhysLocationAttr loc) {
|
||||
PrimitiveType primType = loc.getPrimitiveType().getValue();
|
||||
|
@ -119,11 +140,10 @@ PlacementDB::getLeaf(PhysLocationAttr loc) {
|
|||
DimNumMap &nums = placements[loc.getX()][loc.getY()];
|
||||
if (!seeded)
|
||||
return &nums[loc.getNum()][primType];
|
||||
|
||||
auto primitivesF = nums.find(loc.getNum());
|
||||
if (primitivesF == nums.end())
|
||||
if (!nums.count(loc.getNum()))
|
||||
return {};
|
||||
auto primitives = primitivesF->second;
|
||||
|
||||
DimDevType &primitives = nums[loc.getNum()];
|
||||
if (primitives.count(primType) == 0)
|
||||
return {};
|
||||
return &primitives[primType];
|
||||
|
@ -136,30 +156,41 @@ void PlacementDB::walkPlacements(
|
|||
for (auto colF = placements.begin(), colE = placements.end(); colF != colE;
|
||||
++colF) {
|
||||
size_t x = colF->getFirst();
|
||||
DimYMap yMap = colF->getSecond();
|
||||
walkColumnPlacements(x, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Y loop.
|
||||
for (auto rowF = yMap.begin(), rowE = yMap.end(); rowF != rowE; ++rowF) {
|
||||
size_t y = rowF->getFirst();
|
||||
DimNumMap numMap = rowF->getSecond();
|
||||
/// Walk the column placements in some sort of reasonable order.
|
||||
void PlacementDB::walkColumnPlacements(
|
||||
uint64_t columnNum,
|
||||
function_ref<void(PhysLocationAttr, PlacedInstance)> callback) {
|
||||
|
||||
// Num loop.
|
||||
for (auto numF = numMap.begin(), numE = numMap.end(); numF != numE;
|
||||
++numF) {
|
||||
size_t num = numF->getFirst();
|
||||
DimDevType devMap = numF->getSecond();
|
||||
auto colF = placements.find(columnNum);
|
||||
if (colF == placements.end())
|
||||
return;
|
||||
DimYMap yMap = colF->getSecond();
|
||||
|
||||
// DevType loop.
|
||||
for (auto devF = devMap.begin(), devE = devMap.end(); devF != devE;
|
||||
++devF) {
|
||||
PrimitiveType devtype = devF->getFirst();
|
||||
PlacedInstance inst = devF->getSecond();
|
||||
// Y loop.
|
||||
for (auto rowF = yMap.begin(), rowE = yMap.end(); rowF != rowE; ++rowF) {
|
||||
size_t y = rowF->getFirst();
|
||||
DimNumMap numMap = rowF->getSecond();
|
||||
|
||||
// Marshall and run the callback.
|
||||
PhysLocationAttr loc = PhysLocationAttr::get(
|
||||
ctxt, PrimitiveTypeAttr::get(ctxt, devtype), x, y, num);
|
||||
callback(loc, inst);
|
||||
}
|
||||
// Num loop.
|
||||
for (auto numF = numMap.begin(), numE = numMap.end(); numF != numE;
|
||||
++numF) {
|
||||
size_t num = numF->getFirst();
|
||||
DimDevType devMap = numF->getSecond();
|
||||
|
||||
// DevType loop.
|
||||
for (auto devF = devMap.begin(), devE = devMap.end(); devF != devE;
|
||||
++devF) {
|
||||
PrimitiveType devtype = devF->getFirst();
|
||||
PlacedInstance inst = devF->getSecond();
|
||||
|
||||
// Marshall and run the callback.
|
||||
PhysLocationAttr loc = PhysLocationAttr::get(
|
||||
ctxt, PrimitiveTypeAttr::get(ctxt, devtype), columnNum, y, num);
|
||||
callback(loc, inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue