CIRCT 21.0.0git
Loading...
Searching...
No Matches
MSFTModule.cpp
Go to the documentation of this file.
1//===- MSFTModule.cpp - MSFT API nanobind module --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "CIRCTModules.h"
10
13
14#include "mlir/Bindings/Python/NanobindAdaptors.h"
15#include "mlir/CAPI/IR.h"
16#include "mlir/CAPI/Support.h"
17
18#include "NanobindUtils.h"
19namespace nb = nanobind;
20
21// using namespace circt;
22// using namespace circt::msft;
23using namespace mlir::python::nanobind_adaptors;
24
25static nb::handle getPhysLocationAttr(MlirAttribute attr) {
26 return nb::module_::import_("circt.dialects.msft")
27 .attr("PhysLocationAttr")(attr)
28 .release();
29}
30
32public:
33 PrimitiveDB(MlirContext ctxt) { db = circtMSFTCreatePrimitiveDB(ctxt); }
35 bool addPrimitive(MlirAttribute locAndPrim) {
36 return mlirLogicalResultIsSuccess(
38 }
39 bool isValidLocation(MlirAttribute loc) {
41 }
42
44};
45
47public:
48 PlacementDB(MlirModule top, PrimitiveDB *seed) {
49 db = circtMSFTCreatePlacementDB(top, seed ? seed->db
50 : CirctMSFTPrimitiveDB{nullptr});
51 }
53 MlirOperation place(MlirOperation instOp, MlirAttribute loc,
54 std::string subpath, MlirLocation srcLoc) {
55 auto cSubpath = mlirStringRefCreate(subpath.c_str(), subpath.size());
56 return circtMSFTPlacementDBPlace(db, instOp, loc, cSubpath, srcLoc);
57 }
58 void removePlacement(MlirOperation locOp) {
60 }
61 bool movePlacement(MlirOperation locOp, MlirAttribute newLoc) {
62 return mlirLogicalResultIsSuccess(
64 }
65 MlirOperation getInstanceAt(MlirAttribute loc) {
67 }
68 nb::handle getNearestFreeInColumn(PrimitiveType prim, uint64_t column,
69 uint64_t nearestToY) {
70 auto cPrim = static_cast<CirctMSFTPrimitiveType>(prim);
71 MlirAttribute nearest = circtMSFTPlacementDBGetNearestFreeInColumn(
72 db, cPrim, column, nearestToY);
73 if (!nearest.ptr)
74 return nb::none();
75 return getPhysLocationAttr(nearest);
76 }
78 nb::callable pycb,
79 std::tuple<nb::object, nb::object, nb::object, nb::object> bounds,
80 nb::object prim, nb::object walkOrder) {
81
82 auto handleNone = [](nb::object o) {
83 return o.is_none() ? -1 : nb::cast<int64_t>(o);
84 };
85 int64_t cBounds[4] = {
86 handleNone(std::get<0>(bounds)), handleNone(std::get<1>(bounds)),
87 handleNone(std::get<2>(bounds)), handleNone(std::get<3>(bounds))};
89 if (prim.is_none())
90 cPrim = -1;
91 else
92 cPrim = nb::cast<CirctMSFTPrimitiveType>(prim);
93
94 CirctMSFTWalkOrder cWalkOrder;
95 if (!walkOrder.is_none())
96 cWalkOrder = nb::cast<CirctMSFTWalkOrder>(walkOrder);
97 else
100
102 db,
103 [](MlirAttribute loc, MlirOperation locOp, void *userData) {
104 nb::gil_scoped_acquire gil;
105 nb::callable pycb = *((nb::callable *)(userData));
106 pycb(loc, locOp);
107 },
108 cBounds, cPrim, cWalkOrder, &pycb);
109 }
110
111private:
113};
114
116public:
117 /// Get item at the specified position, translating a nullptr to None.
118 static std::optional<MlirAttribute> getItem(MlirAttribute locVec,
119 intptr_t pos) {
120 MlirAttribute loc = circtMSFTLocationVectorAttrGetElement(locVec, pos);
121 if (loc.ptr == nullptr)
122 return std::nullopt;
123 return loc;
124 }
125
126 PyLocationVecIterator(MlirAttribute attr) : attr(attr) {}
128
129 std::optional<MlirAttribute> dunderNext() {
131 throw nb::stop_iteration();
132 }
133 return getItem(attr, nextIndex++);
134 }
135
136 static void bind(nb::module_ &m) {
137 nb::class_<PyLocationVecIterator>(m, "LocationVectorAttrIterator")
138 .def("__iter__", &PyLocationVecIterator::dunderIter)
139 .def("__next__", &PyLocationVecIterator::dunderNext);
140 }
141
142private:
143 MlirAttribute attr;
144 intptr_t nextIndex = 0;
145};
146
147/// Populate the msft python module.
150
151 m.doc() = "MSFT dialect Python native extension";
152
153 m.def("replaceAllUsesWith", &circtMSFTReplaceAllUsesWith);
154
155 nb::enum_<PrimitiveType>(m, "PrimitiveType")
156 .value("M20K", PrimitiveType::M20K)
157 .value("DSP", PrimitiveType::DSP)
158 .value("FF", PrimitiveType::FF)
159 .export_values();
160
161 nb::enum_<CirctMSFTDirection>(m, "Direction")
162 .value("NONE", CirctMSFTDirection::NONE)
163 .value("ASC", CirctMSFTDirection::ASC)
164 .value("DESC", CirctMSFTDirection::DESC)
165 .export_values();
166
167 mlir_attribute_subclass(m, "PhysLocationAttr",
169 .def_classmethod(
170 "get",
171 [](nb::object cls, PrimitiveType devType, uint64_t x, uint64_t y,
172 uint64_t num, MlirContext ctxt) {
173 return cls(circtMSFTPhysLocationAttrGet(ctxt, (uint64_t)devType, x,
174 y, num));
175 },
176 "Create a physical location attribute", nb::arg(),
177 nb::arg("dev_type"), nb::arg("x"), nb::arg("y"), nb::arg("num"),
178 nb::arg("ctxt") = nb::none())
179 .def_property_readonly(
180 "devtype",
181 [](MlirAttribute self) {
182 return (PrimitiveType)circtMSFTPhysLocationAttrGetPrimitiveType(
183 self);
184 })
185 .def_property_readonly("x",
186 [](MlirAttribute self) {
188 })
189 .def_property_readonly("y",
190 [](MlirAttribute self) {
192 })
193 .def_property_readonly("num", [](MlirAttribute self) {
195 });
196
197 mlir_attribute_subclass(m, "PhysicalBoundsAttr",
199 .def_classmethod(
200 "get",
201 [](nb::object cls, uint64_t xMin, uint64_t xMax, uint64_t yMin,
202 uint64_t yMax, MlirContext ctxt) {
203 auto physicalBounds =
204 circtMSFTPhysicalBoundsAttrGet(ctxt, xMin, xMax, yMin, yMax);
205 return cls(physicalBounds);
206 },
207 "Create a PhysicalBounds attribute", nb::arg("cls"), nb::arg("xMin"),
208 nb::arg("xMax"), nb::arg("yMin"), nb::arg("yMax"),
209 nb::arg("context") = nb::none());
210
211 mlir_attribute_subclass(m, "LocationVectorAttr",
213 .def_classmethod(
214 "get",
215 [](nb::object cls, MlirType type, std::vector<nb::handle> pylocs,
216 MlirContext ctxt) {
217 // Get a LocationVector being sensitive to None in the list of
218 // locations.
219 SmallVector<MlirAttribute> locs;
220 for (auto attrHandle : pylocs)
221 if (attrHandle.is_none())
222 locs.push_back({nullptr});
223 else
224 locs.push_back(mlirPythonCapsuleToAttribute(
225 mlirApiObjectToCapsule(attrHandle).ptr()));
226 return cls(circtMSFTLocationVectorAttrGet(ctxt, type, locs.size(),
227 locs.data()));
228 },
229 "Create a LocationVector attribute", nb::arg("cls"), nb::arg("type"),
230 nb::arg("locs"), nb::arg("context") = nb::none())
231 .def("reg_type", &circtMSFTLocationVectorAttrGetType)
233 .def("__getitem__", &PyLocationVecIterator::getItem,
234 "Get the location at the specified position", nb::arg("pos"))
235 .def("__iter__",
236 [](MlirAttribute arr) { return PyLocationVecIterator(arr); });
238
239 nb::class_<PrimitiveDB>(m, "PrimitiveDB")
240 .def(nb::init<MlirContext>(), nb::arg("ctxt") = nb::none())
241 .def("add_primitive", &PrimitiveDB::addPrimitive,
242 "Inform the DB about a new placement.", nb::arg("loc_and_prim"))
243 .def("is_valid_location", &PrimitiveDB::isValidLocation,
244 "Query the DB as to whether or not a primitive exists.",
245 nb::arg("loc"));
246
247 nb::class_<PlacementDB>(m, "PlacementDB")
248 .def(nb::init<MlirModule, PrimitiveDB *>(), nb::arg("top"),
249 nb::arg("seed") = nullptr)
250 .def("place", &PlacementDB::place, "Place a dynamic instance.",
251 nb::arg("dyn_inst"), nb::arg("location"), nb::arg("subpath"),
252 nb::arg("src_location") = nb::none())
253 .def("remove_placement", &PlacementDB::removePlacement,
254 "Remove a placement.", nb::arg("location"))
255 .def("move_placement", &PlacementDB::movePlacement,
256 "Move a placement to another location.", nb::arg("old_location"),
257 nb::arg("new_location"))
258 .def("get_nearest_free_in_column", &PlacementDB::getNearestFreeInColumn,
259 "Find the nearest free primitive location in column.",
260 nb::arg("prim_type"), nb::arg("column"), nb::arg("nearest_to_y"))
261 .def("get_instance_at", &PlacementDB::getInstanceAt,
262 "Get the instance at location. Returns None if nothing exists "
263 "there. Otherwise, returns (path, subpath, op) of the instance "
264 "there.")
265 .def("walk_placements", &PlacementDB::walkPlacements,
266 "Walk the placements, with possible bounds. Bounds are (xmin, xmax, "
267 "ymin, ymax) with 'None' being unbounded.",
268 nb::arg("callback"),
269 nb::arg("bounds") =
270 std::make_tuple(nb::none(), nb::none(), nb::none(), nb::none()),
271 nb::arg("prim_type") = nb::none(),
272 nb::arg("walk_order") = nb::none());
273
274 nb::class_<CirctMSFTWalkOrder>(m, "WalkOrder")
275 .def(nb::init<CirctMSFTDirection, CirctMSFTDirection>(),
276 nb::arg("columns") = CirctMSFTDirection::NONE,
277 nb::arg("rows") = CirctMSFTDirection::NONE);
278}
static nb::handle getPhysLocationAttr(MlirAttribute attr)
MLIR_CAPI_EXPORTED uint64_t circtMSFTPhysLocationAttrGetNum(MlirAttribute)
Definition MSFT.cpp:197
MLIR_CAPI_EXPORTED MlirType circtMSFTLocationVectorAttrGetType(MlirAttribute)
Definition MSFT.cpp:227
MLIR_CAPI_EXPORTED CirctMSFTPlacementDB circtMSFTCreatePlacementDB(MlirModule top, CirctMSFTPrimitiveDB seed)
Definition MSFT.cpp:70
MLIR_CAPI_EXPORTED CirctMSFTPrimitiveType circtMSFTPhysLocationAttrGetPrimitiveType(MlirAttribute)
Definition MSFT.cpp:186
MLIR_CAPI_EXPORTED void circtMSFTDeletePlacementDB(CirctMSFTPlacementDB self)
Definition MSFT.cpp:76
MLIR_CAPI_EXPORTED bool circtMSFTAttributeIsAPhysicalBoundsAttr(MlirAttribute)
Definition MSFT.cpp:201
int32_t CirctMSFTPrimitiveType
Definition MSFT.h:24
MLIR_CAPI_EXPORTED bool circtMSFTAttributeIsALocationVectorAttribute(MlirAttribute)
Definition MSFT.cpp:212
MLIR_CAPI_EXPORTED MlirAttribute circtMSFTPlacementDBGetNearestFreeInColumn(CirctMSFTPlacementDB, CirctMSFTPrimitiveType prim, uint64_t column, uint64_t nearestToY)
Definition MSFT.cpp:121
MLIR_CAPI_EXPORTED MlirAttribute circtMSFTLocationVectorAttrGet(MlirContext, MlirType type, intptr_t numElements, MlirAttribute const *elements)
Definition MSFT.cpp:215
MLIR_CAPI_EXPORTED intptr_t circtMSFTLocationVectorAttrGetNumElements(MlirAttribute)
Definition MSFT.cpp:230
MLIR_CAPI_EXPORTED MlirLogicalResult circtMSFTPlacementDBMovePlacement(CirctMSFTPlacementDB, MlirOperation locOp, MlirAttribute newLoc)
Definition MSFT.cpp:104
MLIR_CAPI_EXPORTED MlirAttribute circtMSFTLocationVectorAttrGetElement(MlirAttribute attr, intptr_t pos)
Definition MSFT.cpp:233
MLIR_CAPI_EXPORTED void circtMSFTPlacementDBRemovePlacement(CirctMSFTPlacementDB, MlirOperation locOp)
Definition MSFT.cpp:94
MLIR_CAPI_EXPORTED bool circtMSFTPrimitiveDBIsValidLocation(CirctMSFTPrimitiveDB, MlirAttribute locAndPrim)
Definition MSFT.cpp:58
MLIR_CAPI_EXPORTED MlirOperation circtMSFTPlacementDBGetInstanceAt(CirctMSFTPlacementDB, MlirAttribute loc)
Definition MSFT.cpp:117
MLIR_CAPI_EXPORTED CirctMSFTPrimitiveDB circtMSFTCreatePrimitiveDB(MlirContext)
Definition MSFT.cpp:47
MLIR_CAPI_EXPORTED void circtMSFTDeletePrimitiveDB(CirctMSFTPrimitiveDB self)
Definition MSFT.cpp:50
MLIR_CAPI_EXPORTED uint64_t circtMSFTPhysLocationAttrGetX(MlirAttribute)
Definition MSFT.cpp:191
MLIR_CAPI_EXPORTED void circtMSFTPlacementDBWalkPlacements(CirctMSFTPlacementDB, CirctMSFTPlacementCallback, int64_t bounds[4], CirctMSFTPrimitiveType primTypeFilter, CirctMSFTWalkOrder walkOrder, void *userData)
Walk all the placements within 'bounds' ([xmin, xmax, ymin, ymax], inclusive on all sides),...
Definition MSFT.cpp:131
MLIR_CAPI_EXPORTED MlirAttribute circtMSFTPhysicalBoundsAttrGet(MlirContext, uint64_t, uint64_t, uint64_t, uint64_t)
Definition MSFT.cpp:205
@ ASC
Definition MSFT.h:87
@ DESC
Definition MSFT.h:87
@ NONE
Definition MSFT.h:87
MLIR_CAPI_EXPORTED bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute)
Definition MSFT.cpp:173
MLIR_CAPI_EXPORTED MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext, CirctMSFTPrimitiveType, uint64_t x, uint64_t y, uint64_t num)
Definition MSFT.cpp:176
MLIR_CAPI_EXPORTED MlirOperation circtMSFTPlacementDBPlace(CirctMSFTPlacementDB, MlirOperation inst, MlirAttribute loc, MlirStringRef subpath, MlirLocation srcLoc)
Definition MSFT.cpp:80
MLIR_CAPI_EXPORTED MlirLogicalResult circtMSFTPrimitiveDBAddPrimitive(CirctMSFTPrimitiveDB, MlirAttribute locAndPrim)
Definition MSFT.cpp:53
MLIR_CAPI_EXPORTED void mlirMSFTRegisterPasses(void)
Definition MSFT.cpp:32
MLIR_CAPI_EXPORTED uint64_t circtMSFTPhysLocationAttrGetY(MlirAttribute)
Definition MSFT.cpp:194
MLIR_CAPI_EXPORTED void circtMSFTReplaceAllUsesWith(MlirValue value, MlirValue newValue)
Definition MSFT.cpp:37
MlirOperation getInstanceAt(MlirAttribute loc)
MlirOperation place(MlirOperation instOp, MlirAttribute loc, std::string subpath, MlirLocation srcLoc)
CirctMSFTPlacementDB db
bool movePlacement(MlirOperation locOp, MlirAttribute newLoc)
PlacementDB(MlirModule top, PrimitiveDB *seed)
void walkPlacements(nb::callable pycb, std::tuple< nb::object, nb::object, nb::object, nb::object > bounds, nb::object prim, nb::object walkOrder)
void removePlacement(MlirOperation locOp)
nb::handle getNearestFreeInColumn(PrimitiveType prim, uint64_t column, uint64_t nearestToY)
bool isValidLocation(MlirAttribute loc)
PrimitiveDB(MlirContext ctxt)
bool addPrimitive(MlirAttribute locAndPrim)
CirctMSFTPrimitiveDB db
PyLocationVecIterator(MlirAttribute attr)
PyLocationVecIterator & dunderIter()
static void bind(nb::module_ &m)
static std::optional< MlirAttribute > getItem(MlirAttribute locVec, intptr_t pos)
Get item at the specified position, translating a nullptr to None.
std::optional< MlirAttribute > dunderNext()
void populateDialectMSFTSubmodule(nanobind::module_ &m)