CIRCT  20.0.0git
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 
11 #include "circt-c/Dialect/MSFT.h"
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>
22 namespace py = pybind11;
23 
24 // using namespace circt;
25 // using namespace circt::msft;
26 using namespace mlir::python::adaptors;
27 
28 static py::handle getPhysLocationAttr(MlirAttribute attr) {
29  return py::module::import("circt.dialects.msft")
30  .attr("PhysLocationAttr")(attr)
31  .release();
32 }
33 
34 class PrimitiveDB {
35 public:
38  bool addPrimitive(MlirAttribute locAndPrim) {
39  return mlirLogicalResultIsSuccess(
40  circtMSFTPrimitiveDBAddPrimitive(db, locAndPrim));
41  }
42  bool isValidLocation(MlirAttribute loc) {
44  }
45 
47 };
48 
49 class PlacementDB {
50 public:
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(
66  circtMSFTPlacementDBMovePlacement(db, locOp, newLoc));
67  }
68  MlirOperation getInstanceAt(MlirAttribute loc) {
69  return circtMSFTPlacementDBGetInstanceAt(db, 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 
113 private:
115 };
116 
118 public:
119  /// Get item at the specified position, translating a nullptr to None.
120  static py::handle getItem(MlirAttribute locVec, intptr_t pos) {
121  MlirAttribute loc = circtMSFTLocationVectorAttrGetElement(locVec, pos);
122  if (loc.ptr == nullptr)
123  return py::none();
124  return py::detail::type_caster<MlirAttribute>().cast(
125  loc, py::return_value_policy::automatic, py::handle());
126  }
127 
128  PyLocationVecIterator(MlirAttribute attr) : attr(attr) {}
129  PyLocationVecIterator &dunderIter() { return *this; }
130 
131  py::handle dunderNext() {
132  if (nextIndex >= circtMSFTLocationVectorAttrGetNumElements(attr)) {
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 
145 private:
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) {
190  return circtMSFTPhysLocationAttrGetX(self);
191  })
192  .def_property_readonly("y",
193  [](MlirAttribute self) {
194  return circtMSFTPhysLocationAttrGetY(self);
195  })
196  .def_property_readonly("num", [](MlirAttribute self) {
197  return circtMSFTPhysLocationAttrGetNum(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)
Definition: MSFTModule.cpp:28
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)
Definition: MSFTModule.cpp:79
MlirOperation getInstanceAt(MlirAttribute loc)
Definition: MSFTModule.cpp:68
MlirOperation place(MlirOperation instOp, MlirAttribute loc, std::string subpath, MlirLocation srcLoc)
Definition: MSFTModule.cpp:56
CirctMSFTPlacementDB db
Definition: MSFTModule.cpp:114
bool movePlacement(MlirOperation locOp, MlirAttribute newLoc)
Definition: MSFTModule.cpp:64
PlacementDB(MlirModule top, PrimitiveDB *seed)
Definition: MSFTModule.cpp:51
py::handle getNearestFreeInColumn(CirctMSFTPrimitiveType prim, uint64_t column, uint64_t nearestToY)
Definition: MSFTModule.cpp:71
void removePlacement(MlirOperation locOp)
Definition: MSFTModule.cpp:61
bool isValidLocation(MlirAttribute loc)
Definition: MSFTModule.cpp:42
PrimitiveDB(MlirContext ctxt)
Definition: MSFTModule.cpp:36
bool addPrimitive(MlirAttribute locAndPrim)
Definition: MSFTModule.cpp:38
CirctMSFTPrimitiveDB db
Definition: MSFTModule.cpp:46
PyLocationVecIterator(MlirAttribute attr)
Definition: MSFTModule.cpp:128
static void bind(py::module &m)
Definition: MSFTModule.cpp:138
py::handle dunderNext()
Definition: MSFTModule.cpp:131
PyLocationVecIterator & dunderIter()
Definition: MSFTModule.cpp:129
static py::handle getItem(MlirAttribute locVec, intptr_t pos)
Get item at the specified position, translating a nullptr to None.
Definition: MSFTModule.cpp:120
MlirAttribute attr
Definition: MSFTModule.cpp:146
void populateDialectMSFTSubmodule(pybind11::module &m)