[MSFT] [DeviceDB] Add bindings to walk functions (#1942)

This commit is contained in:
John Demme 2021-10-06 21:46:15 -07:00 committed by GitHub
parent dfba36df9f
commit 07c2778fa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 47 deletions

View File

@ -33,6 +33,47 @@ MLIR_CAPI_EXPORTED MlirLogicalResult mlirMSFTExportTcl(MlirOperation,
MlirStringCallback,
void *userData);
//===----------------------------------------------------------------------===//
// MSFT Attributes.
//===----------------------------------------------------------------------===//
/// Add a physical location attribute with the given entity name, device type, x
/// and y coordinates, and number.
MLIR_CAPI_EXPORTED void mlirMSFTAddPhysLocationAttr(MlirOperation op,
const char *entityName,
PrimitiveType type, long x,
long y, long num);
bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute);
MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext, CirctMSFTPrimitiveType,
uint64_t x, uint64_t y,
uint64_t num);
CirctMSFTPrimitiveType circtMSFTPhysLocationAttrGetPrimitiveType(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetX(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetY(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetNum(MlirAttribute);
bool circtMSFTAttributeIsARootedInstancePathAttribute(MlirAttribute);
MlirAttribute circtMSFTRootedInstancePathAttrGet(MlirContext,
MlirAttribute rootSym,
MlirAttribute *pathStringAttrs,
size_t num);
typedef struct {
MlirAttribute instance;
MlirAttribute attr;
} CirctMSFTSwitchInstanceCase;
bool circtMSFTAttributeIsASwitchInstanceAttribute(MlirAttribute);
MlirAttribute circtMSFTSwitchInstanceAttrGet(
MlirContext, CirctMSFTSwitchInstanceCase *listOfCases, size_t numCases);
size_t circtMSFTSwitchInstanceAttrGetNumCases(MlirAttribute);
void circtMSFTSwitchInstanceAttrGetCases(MlirAttribute,
CirctMSFTSwitchInstanceCase *dstArray,
size_t space);
MlirOperation circtMSFTGetInstance(MlirOperation root, MlirAttribute path);
//===----------------------------------------------------------------------===//
// PrimitiveDB.
//===----------------------------------------------------------------------===//
@ -77,46 +118,13 @@ MlirAttribute circtMSFTPlacementDBGetNearestFreeInColumn(
CirctMSFTPlacementDB, CirctMSFTPrimitiveType prim, uint64_t column,
uint64_t nearestToY);
//===----------------------------------------------------------------------===//
// MSFT Attributes.
//===----------------------------------------------------------------------===//
/// Add a physical location attribute with the given entity name, device type, x
/// and y coordinates, and number.
MLIR_CAPI_EXPORTED void mlirMSFTAddPhysLocationAttr(MlirOperation op,
const char *entityName,
PrimitiveType type, long x,
long y, long num);
bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute);
MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext, CirctMSFTPrimitiveType,
uint64_t x, uint64_t y,
uint64_t num);
CirctMSFTPrimitiveType circtMSFTPhysLocationAttrGetPrimitiveType(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetX(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetY(MlirAttribute);
uint64_t circtMSFTPhysLocationAttrGetNum(MlirAttribute);
bool circtMSFTAttributeIsARootedInstancePathAttribute(MlirAttribute);
MlirAttribute circtMSFTRootedInstancePathAttrGet(MlirContext,
MlirAttribute rootSym,
MlirAttribute *pathStringAttrs,
size_t num);
typedef struct {
MlirAttribute instance;
MlirAttribute attr;
} CirctMSFTSwitchInstanceCase;
bool circtMSFTAttributeIsASwitchInstanceAttribute(MlirAttribute);
MlirAttribute circtMSFTSwitchInstanceAttrGet(
MlirContext, CirctMSFTSwitchInstanceCase *listOfCases, size_t numCases);
size_t circtMSFTSwitchInstanceAttrGetNumCases(MlirAttribute);
void circtMSFTSwitchInstanceAttrGetCases(MlirAttribute,
CirctMSFTSwitchInstanceCase *dstArray,
size_t space);
MlirOperation circtMSFTGetInstance(MlirOperation root, MlirAttribute path);
typedef void (*CirctMSFTPlacementCallback)(MlirAttribute loc,
CirctMSFTPlacedInstance,
void *userData);
/// Walk all the placements. Set 'colNo' to -1 to walk all of the columns.
void circtMSFTPlacementDBWalkPlacements(CirctMSFTPlacementDB, int64_t colNo,
CirctMSFTPlacementCallback,
void *userData);
#ifdef __cplusplus
}

View File

@ -51,6 +51,8 @@ with ir.Context() as ctx, ir.Location.unknown():
ir.Attribute.parse("@top"),
[ir.StringAttr.get("inst1"),
ir.StringAttr.get("ext1")])
print(path)
# CHECK-NEXT: #msft<"@top[\22inst1\22,\22ext1\22]">
# CHECK-NEXT: #msft.switch.inst<@top["inst1","ext1"]=#msft.physloc<M20K, 2, 6, 1>>
instSwitch = msft.SwitchInstanceAttr.get([(path, physAttr)])
print(instSwitch)
@ -58,7 +60,7 @@ with ir.Context() as ctx, ir.Location.unknown():
resolved_inst = msft.get_instance(top.operation,
ir.Attribute.parse("@inst1::@ext1"))
assert (resolved_inst == ext_inst.operation)
resolved_inst.attributes["loc:subpath"] = instSwitch
resolved_inst.attributes["loc:foo_subpath"] = instSwitch
not_found_inst = msft.get_instance(top.operation,
ir.Attribute.parse("@inst_none::@ext1"))
@ -72,12 +74,12 @@ with ir.Context() as ctx, ir.Location.unknown():
db = msft.PlacementDB(top.operation)
assert db.get_instance_at(physAttr) is None
place_rc = db.add_placement(physAttr, path, "subpath", resolved_inst)
place_rc = db.add_placement(physAttr, path, "foo_subpath", resolved_inst)
assert place_rc
located_inst = db.get_instance_at(physAttr)
assert located_inst is not None
assert located_inst[0] == path
assert located_inst[1] == "subpath"
assert located_inst[1] == "foo_subpath"
assert located_inst[2] == resolved_inst
num_failed = db.add_design_placements()
@ -88,7 +90,7 @@ with ir.Context() as ctx, ir.Location.unknown():
print("=== tcl ===")
# CHECK: proc top_config { parent } {
# CHECK: set_location_assignment M20K_X2_Y6_N1 -to $parent|inst1|ext1|ext1|subpath
# CHECK: set_location_assignment M20K_X2_Y6_N1 -to $parent|inst1|ext1|ext1|foo_subpath
msft.export_tcl(top.operation, sys.stdout)
devdb = msft.PrimitiveDB()
@ -102,13 +104,40 @@ with ir.Context() as ctx, ir.Location.unknown():
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)
rc = seeded_pdb.add_placement(physAttr, path, "foo_subpath", resolved_inst)
assert rc
print(seeded_pdb.get_nearest_free_in_column(msft.M20K, 2, 4))
# CHECK: #msft.physloc<M20K, 2, 50, 1>
def print_placement(loc, placement):
if placement:
path = msft.RootedInstancePathAttr(placement[0])
print(f"{loc}, {path}")
else:
print(f"{loc}")
print("=== Placements:")
seeded_pdb.walk_placements(print_placement)
# CHECK-LABEL: === Placements:
# CHECK: #msft.physloc<M20K, 2, 6, 1>, #msft<"@top[\22inst1\22,\22ext1\22]">
# CHECK: #msft.physloc<M20K, 2, 50, 1>
print("=== Placements (col 2):")
seeded_pdb.walk_placements(print_placement, column_num=2)
# CHECK-LABEL: === Placements (col 2):
# CHECK: #msft.physloc<M20K, 2, 6, 1>, #msft<"@top[\22inst1\22,\22ext1\22]">
# CHECK: #msft.physloc<M20K, 2, 50, 1>
print("=== Placements (col 6):")
seeded_pdb.walk_placements(print_placement, column_num=6)
# CHECK-LABEL: === Placements (col 6):
print("=== Errors:", file=sys.stderr)
# ERR-LABEL: === Errors:
bad_loc = msft.PhysLocationAttr.get(msft.M20K, x=7, y=99, num=1)
rc = seeded_pdb.add_placement(bad_loc, path, "subpath", resolved_inst)
rc = seeded_pdb.add_placement(bad_loc, path, "foo_subpath", resolved_inst)
assert not rc
# ERR: error: 'hw.instance' op Could not apply placement. Invalid location

View File

@ -71,6 +71,21 @@ public:
return py::none();
return py::cast(nearest);
}
void walkPlacements(py::function pycb, int64_t colNo = -1) {
circtMSFTPlacementDBWalkPlacements(
db, colNo,
[](MlirAttribute loc, CirctMSFTPlacedInstance p, void *userData) {
std::string subpath(p.subpath, p.subpathLength);
py::gil_scoped_acquire gil;
py::function pycb = *((py::function *)(userData));
if (!p.op.ptr) {
pycb(loc, py::none());
} else {
pycb(loc, std::make_tuple(p.path, subpath, p.op));
}
},
&pycb);
}
private:
CirctMSFTPlacementDB db;
@ -191,5 +206,8 @@ void circt::python::populateDialectMSFTSubmodule(py::module &m) {
.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 "
"there.");
"there.")
.def("walk_placements", &PlacementDB::walkPlacements,
"Walk the placements.", py::arg("callback"),
py::arg("column_num") = -1);
}

View File

@ -111,6 +111,22 @@ MlirAttribute circtMSFTPlacementDBGetNearestFreeInColumn(
db->getNearestFreeInColumn((PrimitiveType)prim, column, nearestToY));
}
void circtMSFTPlacementDBWalkPlacements(CirctMSFTPlacementDB cdb, int64_t colNo,
CirctMSFTPlacementCallback ccb,
void *userData) {
PlacementDB *db = unwrap(cdb);
auto cb = [ccb, userData](PhysLocationAttr loc,
PlacementDB::PlacedInstance p) {
CirctMSFTPlacedInstance cPlacement = {wrap(p.path), p.subpath.data(),
p.subpath.size(), wrap(p.op)};
ccb(wrap(loc), cPlacement, userData);
};
if (colNo >= 0)
db->walkColumnPlacements(colNo, cb);
else
db->walkPlacements(cb);
}
//===----------------------------------------------------------------------===//
// MSFT Attributes.
//===----------------------------------------------------------------------===//