CIRCT 20.0.0git
Loading...
Searching...
No Matches
MSFTModule.cpp
Go to the documentation of this file.
1//===- MSFTModule.cpp - MSFT API pybind 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/PybindAdaptors.h"
15#include "mlir/CAPI/IR.h"
16#include "mlir/CAPI/Support.h"
17
18#include "PybindUtils.h"
19#include <pybind11/functional.h>
20#include <pybind11/pybind11.h>
21#include <pybind11/stl.h>
22namespace py = pybind11;
23
24// using namespace circt;
25// using namespace circt::msft;
26using namespace mlir::python::adaptors;
27
28static py::handle getPhysLocationAttr(MlirAttribute attr) {
29 return py::module::import("circt.dialects.msft")
30 .attr("PhysLocationAttr")(attr)
31 .release();
32}
33
35public:
36 PrimitiveDB(MlirContext ctxt) { db = circtMSFTCreatePrimitiveDB(ctxt); }
38 bool addPrimitive(MlirAttribute locAndPrim) {
39 return mlirLogicalResultIsSuccess(
41 }
42 bool isValidLocation(MlirAttribute loc) {
44 }
45
47};
48
50public:
51 PlacementDB(MlirModule top, PrimitiveDB *seed) {
52 db = circtMSFTCreatePlacementDB(top, seed ? seed->db
53 : CirctMSFTPrimitiveDB{nullptr});
54 }
56 MlirOperation place(MlirOperation instOp, MlirAttribute loc,
57 std::string subpath, MlirLocation srcLoc) {
58 auto cSubpath = mlirStringRefCreate(subpath.c_str(), subpath.size());
59 return circtMSFTPlacementDBPlace(db, instOp, loc, cSubpath, srcLoc);
60 }
61 void removePlacement(MlirOperation locOp) {
63 }
64 bool movePlacement(MlirOperation locOp, MlirAttribute newLoc) {
65 return mlirLogicalResultIsSuccess(
67 }
68 MlirOperation getInstanceAt(MlirAttribute loc) {
70 }
72 uint64_t column, uint64_t nearestToY) {
73 MlirAttribute nearest = circtMSFTPlacementDBGetNearestFreeInColumn(
74 db, prim, column, nearestToY);
75 if (!nearest.ptr)
76 return py::none();
77 return getPhysLocationAttr(nearest);
78 }
80 py::function pycb,
81 std::tuple<py::object, py::object, py::object, py::object> bounds,
82 py::object prim, py::object walkOrder) {
83
84 auto handleNone = [](py::object o) {
85 return o.is_none() ? -1 : o.cast<int64_t>();
86 };
87 int64_t cBounds[4] = {
88 handleNone(std::get<0>(bounds)), handleNone(std::get<1>(bounds)),
89 handleNone(std::get<2>(bounds)), handleNone(std::get<3>(bounds))};
91 if (prim.is_none())
92 cPrim = -1;
93 else
94 cPrim = prim.cast<CirctMSFTPrimitiveType>();
95
96 CirctMSFTWalkOrder cWalkOrder;
97 if (!walkOrder.is_none())
98 cWalkOrder = walkOrder.cast<CirctMSFTWalkOrder>();
99 else
102
104 db,
105 [](MlirAttribute loc, MlirOperation locOp, void *userData) {
106 py::gil_scoped_acquire gil;
107 py::function pycb = *((py::function *)(userData));
108 pycb(loc, locOp);
109 },
110 cBounds, cPrim, cWalkOrder, &pycb);
111 }
112
113private:
115};
116
118public:
119 /// Get item at the specified position, translating a nullptr to None.
120 static std::optional<MlirAttribute> getItem(MlirAttribute locVec,
121 intptr_t pos) {
122 MlirAttribute loc = circtMSFTLocationVectorAttrGetElement(locVec, pos);
123 if (loc.ptr == nullptr)
124 return std::nullopt;
125 return loc;
126 }
127
128 PyLocationVecIterator(MlirAttribute attr) : attr(attr) {}
130
131 std::optional<MlirAttribute> dunderNext() {
133 throw py::stop_iteration();
134 }
135 return getItem(attr, nextIndex++);
136 }
137
138 static void bind(py::module &m) {
139 py::class_<PyLocationVecIterator>(m, "LocationVectorAttrIterator",
140 py::module_local())
141 .def("__iter__", &PyLocationVecIterator::dunderIter)
142 .def("__next__", &PyLocationVecIterator::dunderNext);
143 }
144
145private:
146 MlirAttribute attr;
147 intptr_t nextIndex = 0;
148};
149
150/// Populate the msft python module.
153
154 m.doc() = "MSFT dialect Python native extension";
155
156 m.def("replaceAllUsesWith", &circtMSFTReplaceAllUsesWith);
157
158 py::enum_<PrimitiveType>(m, "PrimitiveType")
159 .value("M20K", PrimitiveType::M20K)
160 .value("DSP", PrimitiveType::DSP)
161 .value("FF", PrimitiveType::FF)
162 .export_values();
163
164 py::enum_<CirctMSFTDirection>(m, "Direction")
165 .value("NONE", CirctMSFTDirection::NONE)
166 .value("ASC", CirctMSFTDirection::ASC)
167 .value("DESC", CirctMSFTDirection::DESC)
168 .export_values();
169
170 mlir_attribute_subclass(m, "PhysLocationAttr",
172 .def_classmethod(
173 "get",
174 [](py::object cls, PrimitiveType devType, uint64_t x, uint64_t y,
175 uint64_t num, MlirContext ctxt) {
176 return cls(circtMSFTPhysLocationAttrGet(ctxt, (uint64_t)devType, x,
177 y, num));
178 },
179 "Create a physical location attribute", py::arg(),
180 py::arg("dev_type"), py::arg("x"), py::arg("y"), py::arg("num"),
181 py::arg("ctxt") = py::none())
182 .def_property_readonly(
183 "devtype",
184 [](MlirAttribute self) {
185 return (PrimitiveType)circtMSFTPhysLocationAttrGetPrimitiveType(
186 self);
187 })
188 .def_property_readonly("x",
189 [](MlirAttribute self) {
191 })
192 .def_property_readonly("y",
193 [](MlirAttribute self) {
195 })
196 .def_property_readonly("num", [](MlirAttribute self) {
198 });
199
200 mlir_attribute_subclass(m, "PhysicalBoundsAttr",
202 .def_classmethod(
203 "get",
204 [](py::object cls, uint64_t xMin, uint64_t xMax, uint64_t yMin,
205 uint64_t yMax, MlirContext ctxt) {
206 auto physicalBounds =
207 circtMSFTPhysicalBoundsAttrGet(ctxt, xMin, xMax, yMin, yMax);
208 return cls(physicalBounds);
209 },
210 "Create a PhysicalBounds attribute", py::arg("cls"), py::arg("xMin"),
211 py::arg("xMax"), py::arg("yMin"), py::arg("yMax"),
212 py::arg("context") = py::none());
213
214 mlir_attribute_subclass(m, "LocationVectorAttr",
216 .def_classmethod(
217 "get",
218 [](py::object cls, MlirType type, std::vector<py::handle> pylocs,
219 MlirContext ctxt) {
220 // Get a LocationVector being sensitive to None in the list of
221 // locations.
222 SmallVector<MlirAttribute> locs;
223 for (auto attrHandle : pylocs)
224 if (attrHandle.is_none())
225 locs.push_back({nullptr});
226 else
227 locs.push_back(mlirPythonCapsuleToAttribute(
228 mlirApiObjectToCapsule(attrHandle).ptr()));
229 return cls(circtMSFTLocationVectorAttrGet(ctxt, type, locs.size(),
230 locs.data()));
231 },
232 "Create a LocationVector attribute", py::arg("cls"), py::arg("type"),
233 py::arg("locs"), py::arg("context") = py::none())
234 .def("reg_type", &circtMSFTLocationVectorAttrGetType)
236 .def("__getitem__", &PyLocationVecIterator::getItem,
237 "Get the location at the specified position", py::arg("pos"))
238 .def("__iter__",
239 [](MlirAttribute arr) { return PyLocationVecIterator(arr); });
241
242 py::class_<PrimitiveDB>(m, "PrimitiveDB")
243 .def(py::init<MlirContext>(), py::arg("ctxt") = py::none())
244 .def("add_primitive", &PrimitiveDB::addPrimitive,
245 "Inform the DB about a new placement.", py::arg("loc_and_prim"))
246 .def("is_valid_location", &PrimitiveDB::isValidLocation,
247 "Query the DB as to whether or not a primitive exists.",
248 py::arg("loc"));
249
250 py::class_<PlacementDB>(m, "PlacementDB")
251 .def(py::init<MlirModule, PrimitiveDB *>(), py::arg("top"),
252 py::arg("seed") = nullptr)
253 .def("place", &PlacementDB::place, "Place a dynamic instance.",
254 py::arg("dyn_inst"), py::arg("location"), py::arg("subpath"),
255 py::arg("src_location") = py::none())
256 .def("remove_placement", &PlacementDB::removePlacement,
257 "Remove a placement.", py::arg("location"))
258 .def("move_placement", &PlacementDB::movePlacement,
259 "Move a placement to another location.", py::arg("old_location"),
260 py::arg("new_location"))
261 .def("get_nearest_free_in_column", &PlacementDB::getNearestFreeInColumn,
262 "Find the nearest free primitive location in column.",
263 py::arg("prim_type"), py::arg("column"), py::arg("nearest_to_y"))
264 .def("get_instance_at", &PlacementDB::getInstanceAt,
265 "Get the instance at location. Returns None if nothing exists "
266 "there. Otherwise, returns (path, subpath, op) of the instance "
267 "there.")
268 .def("walk_placements", &PlacementDB::walkPlacements,
269 "Walk the placements, with possible bounds. Bounds are (xmin, xmax, "
270 "ymin, ymax) with 'None' being unbounded.",
271 py::arg("callback"),
272 py::arg("bounds") =
273 std::make_tuple(py::none(), py::none(), py::none(), py::none()),
274 py::arg("prim_type") = py::none(),
275 py::arg("walk_order") = py::none());
276
277 py::class_<CirctMSFTWalkOrder>(m, "WalkOrder")
278 .def(py::init<CirctMSFTDirection, CirctMSFTDirection>(),
279 py::arg("columns") = CirctMSFTDirection::NONE,
280 py::arg("rows") = CirctMSFTDirection::NONE);
281}
static py::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
void walkPlacements(py::function pycb, std::tuple< py::object, py::object, py::object, py::object > bounds, py::object prim, py::object walkOrder)
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)
py::handle getNearestFreeInColumn(CirctMSFTPrimitiveType prim, uint64_t column, uint64_t nearestToY)
void removePlacement(MlirOperation locOp)
bool isValidLocation(MlirAttribute loc)
PrimitiveDB(MlirContext ctxt)
bool addPrimitive(MlirAttribute locAndPrim)
CirctMSFTPrimitiveDB db
PyLocationVecIterator(MlirAttribute attr)
static void bind(py::module &m)
PyLocationVecIterator & dunderIter()
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(pybind11::module &m)