CIRCT  20.0.0git
OMModule.cpp
Go to the documentation of this file.
1 //===- OMModule.cpp - OM 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 #include "circt-c/Dialect/HW.h"
11 #include "circt-c/Dialect/OM.h"
12 #include "mlir-c/BuiltinAttributes.h"
13 #include "mlir-c/BuiltinTypes.h"
14 #include "mlir-c/IR.h"
15 #include "mlir/Bindings/Python/PybindAdaptors.h"
16 #include <pybind11/pybind11.h>
17 #include <pybind11/stl.h>
18 namespace py = pybind11;
19 
20 using namespace mlir;
21 using namespace mlir::python;
22 using namespace mlir::python::adaptors;
23 
24 namespace {
25 
26 struct List;
27 struct Object;
28 struct Tuple;
29 struct Map;
30 struct BasePath;
31 struct Path;
32 
33 /// These are the Python types that are represented by the different primitive
34 /// OMEvaluatorValues as Attributes.
35 using PythonPrimitive = std::variant<py::int_, py::float_, py::str, py::bool_,
36  py::tuple, py::list, py::dict>;
37 
38 /// None is used to by pybind when default initializing a PythonValue. The
39 /// order of types in the variant matters here, and we want pybind to try
40 /// casting to the Python classes defined in this file first, before
41 /// MlirAttribute and the upstream MLIR type casters. If the MlirAttribute
42 /// is tried first, then we can hit an assert inside the MLIR codebase.
43 struct None {};
44 using PythonValue = std::variant<None, Object, List, Tuple, Map, BasePath, Path,
45  PythonPrimitive>;
46 
47 /// Map an opaque OMEvaluatorValue into a python value.
48 PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result);
49 OMEvaluatorValue pythonValueToOMEvaluatorValue(PythonValue result,
50  MlirContext ctx);
51 static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr);
52 static MlirAttribute omPythonValueToPrimitive(PythonPrimitive value,
53  MlirContext ctx);
54 
55 /// Provides a List class by simply wrapping the OMObject CAPI.
56 struct List {
57  // Instantiate a List with a reference to the underlying OMEvaluatorValue.
58  List(OMEvaluatorValue value) : value(value) {}
59 
60  /// Return the number of elements.
61  intptr_t getNumElements() { return omEvaluatorListGetNumElements(value); }
62 
63  PythonValue getElement(intptr_t i);
64  OMEvaluatorValue getValue() const { return value; }
65 
66 private:
67  // The underlying CAPI value.
68  OMEvaluatorValue value;
69 };
70 
71 struct Tuple {
72  // Instantiate a Tuple with a reference to the underlying OMEvaluatorValue.
73  Tuple(OMEvaluatorValue value) : value(value) {}
74 
75  /// Return the number of elements.
76  intptr_t getNumElements() { return omEvaluatorTupleGetNumElements(value); }
77 
78  PythonValue getElement(intptr_t i);
79  OMEvaluatorValue getValue() const { return value; }
80 
81 private:
82  // The underlying CAPI value.
83  OMEvaluatorValue value;
84 };
85 
86 /// Provides a Map class by simply wrapping the OMObject CAPI.
87 struct Map {
88  // Instantiate a Map with a reference to the underlying OMEvaluatorValue.
89  Map(OMEvaluatorValue value) : value(value) {}
90 
91  /// Return the keys.
92  std::vector<py::str> getKeys() {
93  auto attr = omEvaluatorMapGetKeys(value);
94  intptr_t numFieldNames = mlirArrayAttrGetNumElements(attr);
95 
96  std::vector<py::str> pyFieldNames;
97  for (intptr_t i = 0; i < numFieldNames; ++i) {
98  auto name = mlirStringAttrGetValue(mlirArrayAttrGetElement(attr, i));
99  pyFieldNames.emplace_back(py::str(name.data, name.length));
100  }
101 
102  return pyFieldNames;
103  }
104 
105  /// Look up the value. A key is an integer, string or attribute.
106  PythonValue dunderGetItemAttr(MlirAttribute key);
107  PythonValue dunderGetItemNamed(const std::string &key);
108  PythonValue dunderGetItemIndexed(intptr_t key);
109  PythonValue
110  dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key);
111 
112  /// Return a context from an underlying value.
113  MlirContext getContext() const { return omEvaluatorValueGetContext(value); }
114 
115  OMEvaluatorValue getValue() const { return value; }
116  MlirType getType() { return omEvaluatorMapGetType(value); }
117 
118 private:
119  // The underlying CAPI value.
120  OMEvaluatorValue value;
121 };
122 
123 /// Provides a BasePath class by simply wrapping the OMObject CAPI.
124 struct BasePath {
125  /// Instantiate a BasePath with a reference to the underlying
126  /// OMEvaluatorValue.
127  BasePath(OMEvaluatorValue value) : value(value) {}
128 
129  static BasePath getEmpty(MlirContext context) {
130  return BasePath(omEvaluatorBasePathGetEmpty(context));
131  }
132 
133  /// Return a context from an underlying value.
134  MlirContext getContext() const { return omEvaluatorValueGetContext(value); }
135 
136  OMEvaluatorValue getValue() const { return value; }
137 
138 private:
139  // The underlying CAPI value.
140  OMEvaluatorValue value;
141 };
142 
143 /// Provides a Path class by simply wrapping the OMObject CAPI.
144 struct Path {
145  /// Instantiate a Path with a reference to the underlying OMEvaluatorValue.
146  Path(OMEvaluatorValue value) : value(value) {}
147 
148  /// Return a context from an underlying value.
149  MlirContext getContext() const { return omEvaluatorValueGetContext(value); }
150 
151  OMEvaluatorValue getValue() const { return value; }
152 
153  std::string dunderStr() {
154  auto ref = mlirStringAttrGetValue(omEvaluatorPathGetAsString(getValue()));
155  return std::string(ref.data, ref.length);
156  }
157 
158 private:
159  // The underlying CAPI value.
160  OMEvaluatorValue value;
161 };
162 
163 /// Provides an Object class by simply wrapping the OMObject CAPI.
164 struct Object {
165  // Instantiate an Object with a reference to the underlying OMObject.
166  Object(OMEvaluatorValue value) : value(value) {}
167 
168  /// Get the Type from an Object, which will be a ClassType.
169  MlirType getType() { return omEvaluatorObjectGetType(value); }
170 
171  /// Get the Location from an Object, which will be an MlirLocation.
172  MlirLocation getLocation() { return omEvaluatorValueGetLoc(value); }
173 
174  // Get the field location info.
175  MlirLocation getFieldLoc(const std::string &name) {
176  // Wrap the requested field name in an attribute.
177  MlirContext context = mlirTypeGetContext(omEvaluatorObjectGetType(value));
178  MlirStringRef cName = mlirStringRefCreateFromCString(name.c_str());
179  MlirAttribute nameAttr = mlirStringAttrGet(context, cName);
180 
181  // Get the field's ObjectValue via the CAPI.
182  OMEvaluatorValue result = omEvaluatorObjectGetField(value, nameAttr);
183 
184  return omEvaluatorValueGetLoc(result);
185  }
186 
187  // Get a field from the Object, using pybind's support for variant to return a
188  // Python object that is either an Object or Attribute.
189  PythonValue getField(const std::string &name) {
190  // Wrap the requested field name in an attribute.
191  MlirContext context = mlirTypeGetContext(omEvaluatorObjectGetType(value));
192  MlirStringRef cName = mlirStringRefCreateFromCString(name.c_str());
193  MlirAttribute nameAttr = mlirStringAttrGet(context, cName);
194 
195  // Get the field's ObjectValue via the CAPI.
196  OMEvaluatorValue result = omEvaluatorObjectGetField(value, nameAttr);
197 
198  return omEvaluatorValueToPythonValue(result);
199  }
200 
201  // Get a list with the names of all the fields in the Object.
202  std::vector<std::string> getFieldNames() {
203  MlirAttribute fieldNames = omEvaluatorObjectGetFieldNames(value);
204  intptr_t numFieldNames = mlirArrayAttrGetNumElements(fieldNames);
205 
206  std::vector<std::string> pyFieldNames;
207  for (intptr_t i = 0; i < numFieldNames; ++i) {
208  MlirAttribute fieldName = mlirArrayAttrGetElement(fieldNames, i);
209  MlirStringRef fieldNameStr = mlirStringAttrGetValue(fieldName);
210  pyFieldNames.emplace_back(fieldNameStr.data, fieldNameStr.length);
211  }
212 
213  return pyFieldNames;
214  }
215 
216  // Get the hash of the object
217  unsigned getHash() { return omEvaluatorObjectGetHash(value); }
218 
219  // Check the equality of the underlying values.
220  bool eq(Object &other) { return omEvaluatorObjectIsEq(value, other.value); }
221 
222  OMEvaluatorValue getValue() const { return value; }
223 
224 private:
225  // The underlying CAPI OMObject.
226  OMEvaluatorValue value;
227 };
228 
229 /// Provides an Evaluator class by simply wrapping the OMEvaluator CAPI.
230 struct Evaluator {
231  // Instantiate an Evaluator with a reference to the underlying OMEvaluator.
232  Evaluator(MlirModule mod) : evaluator(omEvaluatorNew(mod)) {}
233 
234  // Instantiate an Object.
235  Object instantiate(MlirAttribute className,
236  std::vector<PythonValue> actualParams) {
237  std::vector<OMEvaluatorValue> values;
238  for (auto &param : actualParams)
239  values.push_back(pythonValueToOMEvaluatorValue(
240  param, mlirModuleGetContext(getModule())));
241 
242  // Instantiate the Object via the CAPI.
244  evaluator, className, values.size(), values.data());
245 
246  // If the Object is null, something failed. Diagnostic handling is
247  // implemented in pure Python, so nothing to do here besides throwing an
248  // error to halt execution.
249  if (omEvaluatorObjectIsNull(result))
250  throw py::value_error(
251  "unable to instantiate object, see previous error(s)");
252 
253  // Return a new Object.
254  return Object(result);
255  }
256 
257  // Get the Module the Evaluator is built from.
258  MlirModule getModule() { return omEvaluatorGetModule(evaluator); }
259 
260 private:
261  // The underlying CAPI OMEvaluator.
262  OMEvaluator evaluator;
263 };
264 
265 class PyListAttrIterator {
266 public:
267  PyListAttrIterator(MlirAttribute attr) : attr(std::move(attr)) {}
268 
269  PyListAttrIterator &dunderIter() { return *this; }
270 
271  MlirAttribute dunderNext() {
272  if (nextIndex >= omListAttrGetNumElements(attr))
273  throw py::stop_iteration();
274  return omListAttrGetElement(attr, nextIndex++);
275  }
276 
277  static void bind(py::module &m) {
278  py::class_<PyListAttrIterator>(m, "ListAttributeIterator",
279  py::module_local())
280  .def("__iter__", &PyListAttrIterator::dunderIter)
281  .def("__next__", &PyListAttrIterator::dunderNext);
282  }
283 
284 private:
285  MlirAttribute attr;
286  intptr_t nextIndex = 0;
287 };
288 
289 PythonValue List::getElement(intptr_t i) {
290  return omEvaluatorValueToPythonValue(omEvaluatorListGetElement(value, i));
291 }
292 
293 class PyMapAttrIterator {
294 public:
295  PyMapAttrIterator(MlirAttribute attr) : attr(std::move(attr)) {}
296 
297  PyMapAttrIterator &dunderIter() { return *this; }
298 
299  py::tuple dunderNext() {
300  if (nextIndex >= omMapAttrGetNumElements(attr))
301  throw py::stop_iteration();
302 
303  MlirIdentifier key = omMapAttrGetElementKey(attr, nextIndex);
304  PythonValue value =
305  omPrimitiveToPythonValue(omMapAttrGetElementValue(attr, nextIndex));
306  nextIndex++;
307 
308  auto keyName = mlirIdentifierStr(key);
309  std::string keyStr(keyName.data, keyName.length);
310  return py::make_tuple(keyStr, value);
311  }
312 
313  static void bind(py::module &m) {
314  py::class_<PyMapAttrIterator>(m, "MapAttributeIterator", py::module_local())
315  .def("__iter__", &PyMapAttrIterator::dunderIter)
316  .def("__next__", &PyMapAttrIterator::dunderNext);
317  }
318 
319 private:
320  MlirAttribute attr;
321  intptr_t nextIndex = 0;
322 };
323 
324 PythonValue Tuple::getElement(intptr_t i) {
325  if (i < 0 || i >= omEvaluatorTupleGetNumElements(value))
326  throw std::out_of_range("tuple index out of range");
327 
328  return omEvaluatorValueToPythonValue(omEvaluatorTupleGetElement(value, i));
329 }
330 
331 PythonValue Map::dunderGetItemNamed(const std::string &key) {
332  MlirType type = omMapTypeGetKeyType(omEvaluatorMapGetType(value));
333  if (!omTypeIsAStringType(type))
334  throw pybind11::key_error("key is not string");
335  MlirAttribute attr =
336  mlirStringAttrTypedGet(type, mlirStringRefCreateFromCString(key.c_str()));
337  return dunderGetItemAttr(attr);
338 }
339 
340 PythonValue Map::dunderGetItemIndexed(intptr_t i) {
341  MlirType type = omMapTypeGetKeyType(omEvaluatorMapGetType(value));
342  if (!mlirTypeIsAInteger(type))
343  throw pybind11::key_error("key is not integer");
344  MlirAttribute attr = mlirIntegerAttrGet(type, i);
345  return dunderGetItemAttr(attr);
346 }
347 
348 PythonValue Map::dunderGetItemAttr(MlirAttribute key) {
349  OMEvaluatorValue result = omEvaluatorMapGetElement(value, key);
350 
351  if (omEvaluatorValueIsNull(result))
352  throw pybind11::key_error("key not found");
353 
354  return omEvaluatorValueToPythonValue(result);
355 }
356 
357 PythonValue
358 Map::dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key) {
359  if (auto *i = std::get_if<intptr_t>(&key))
360  return dunderGetItemIndexed(*i);
361  else if (auto *str = std::get_if<std::string>(&key))
362  return dunderGetItemNamed(*str);
363  return dunderGetItemAttr(std::get<MlirAttribute>(key));
364 }
365 
366 // Convert a generic MLIR Attribute to a PythonValue. This is basically a C++
367 // fast path of the parts of attribute_to_var that we use in the OM dialect.
368 static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
369  if (omAttrIsAIntegerAttr(attr)) {
370  auto strRef = omIntegerAttrToString(attr);
371  return py::int_(py::str(strRef.data, strRef.length));
372  }
373 
374  if (mlirAttributeIsAFloat(attr)) {
375  return py::float_(mlirFloatAttrGetValueDouble(attr));
376  }
377 
378  if (mlirAttributeIsAString(attr)) {
379  auto strRef = mlirStringAttrGetValue(attr);
380  return py::str(strRef.data, strRef.length);
381  }
382 
383  // BoolAttr's are IntegerAttr's, check this first.
384  if (mlirAttributeIsABool(attr)) {
385  return py::bool_(mlirBoolAttrGetValue(attr));
386  }
387 
388  if (mlirAttributeIsAInteger(attr)) {
389  MlirType type = mlirAttributeGetType(attr);
390  if (mlirTypeIsAIndex(type) || mlirIntegerTypeIsSignless(type))
391  return py::int_(mlirIntegerAttrGetValueInt(attr));
392  if (mlirIntegerTypeIsSigned(type))
393  return py::int_(mlirIntegerAttrGetValueSInt(attr));
394  return py::int_(mlirIntegerAttrGetValueUInt(attr));
395  }
396 
397  if (omAttrIsAReferenceAttr(attr)) {
398  auto innerRef = omReferenceAttrGetInnerRef(attr);
399  auto moduleStrRef =
400  mlirStringAttrGetValue(hwInnerRefAttrGetModule(innerRef));
401  auto nameStrRef = mlirStringAttrGetValue(hwInnerRefAttrGetName(innerRef));
402  auto moduleStr = py::str(moduleStrRef.data, moduleStrRef.length);
403  auto nameStr = py::str(nameStrRef.data, nameStrRef.length);
404  return py::make_tuple(moduleStr, nameStr);
405  }
406 
407  if (omAttrIsAListAttr(attr)) {
408  py::list results;
409  for (intptr_t i = 0, e = omListAttrGetNumElements(attr); i < e; ++i)
410  results.append(omPrimitiveToPythonValue(omListAttrGetElement(attr, i)));
411  return results;
412  }
413 
414  if (omAttrIsAMapAttr(attr)) {
415  py::dict results;
416  for (intptr_t i = 0, e = omMapAttrGetNumElements(attr); i < e; ++i) {
417  auto keyStrRef = mlirIdentifierStr(omMapAttrGetElementKey(attr, i));
418  auto key = py::str(keyStrRef.data, keyStrRef.length);
419  auto value = omPrimitiveToPythonValue(omMapAttrGetElementValue(attr, i));
420  results[key] = value;
421  }
422  return results;
423  }
424 
425  mlirAttributeDump(attr);
426  throw py::type_error("Unexpected OM primitive attribute");
427 }
428 
429 // Convert a primitive PythonValue to a generic MLIR Attribute. This is
430 // basically a C++ fast path of the parts of var_to_attribute that we use in the
431 // OM dialect.
432 static MlirAttribute omPythonValueToPrimitive(PythonPrimitive value,
433  MlirContext ctx) {
434  if (auto *intValue = std::get_if<py::int_>(&value)) {
435  auto intType = mlirIntegerTypeGet(ctx, 64);
436  auto intAttr = mlirIntegerAttrGet(intType, intValue->cast<int64_t>());
437  return omIntegerAttrGet(intAttr);
438  }
439 
440  if (auto *attr = std::get_if<py::float_>(&value)) {
441  auto floatType = mlirF64TypeGet(ctx);
442  return mlirFloatAttrDoubleGet(ctx, floatType, attr->cast<double>());
443  }
444 
445  if (auto *attr = std::get_if<py::str>(&value)) {
446  auto str = attr->cast<std::string>();
447  auto strRef = mlirStringRefCreate(str.data(), str.length());
448  return mlirStringAttrGet(ctx, strRef);
449  }
450 
451  if (auto *attr = std::get_if<py::bool_>(&value)) {
452  return mlirBoolAttrGet(ctx, attr->cast<bool>());
453  }
454 
455  throw py::type_error("Unexpected OM primitive value");
456 }
457 
458 PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result) {
459  // If the result is null, something failed. Diagnostic handling is
460  // implemented in pure Python, so nothing to do here besides throwing an
461  // error to halt execution.
462  if (omEvaluatorValueIsNull(result))
463  throw py::value_error("unable to get field, see previous error(s)");
464 
465  // If the field was an Object, return a new Object.
466  if (omEvaluatorValueIsAObject(result))
467  return Object(result);
468 
469  // If the field was a list, return a new List.
470  if (omEvaluatorValueIsAList(result))
471  return List(result);
472 
473  // If the field was a tuple, return a new Tuple.
474  if (omEvaluatorValueIsATuple(result))
475  return Tuple(result);
476 
477  // If the field was a map, return a new Map.
478  if (omEvaluatorValueIsAMap(result))
479  return Map(result);
480 
481  // If the field was a base path, return a new BasePath.
482  if (omEvaluatorValueIsABasePath(result))
483  return BasePath(result);
484 
485  // If the field was a path, return a new Path.
486  if (omEvaluatorValueIsAPath(result))
487  return Path(result);
488 
489  if (omEvaluatorValueIsAReference(result))
490  return omEvaluatorValueToPythonValue(
492 
493  // If the field was a primitive, return the Attribute.
495  return omPrimitiveToPythonValue(omEvaluatorValueGetPrimitive(result));
496 }
497 
498 OMEvaluatorValue pythonValueToOMEvaluatorValue(PythonValue result,
499  MlirContext ctx) {
500  if (auto *list = std::get_if<List>(&result))
501  return list->getValue();
502 
503  if (auto *tuple = std::get_if<Tuple>(&result))
504  return tuple->getValue();
505 
506  if (auto *map = std::get_if<Map>(&result))
507  return map->getValue();
508 
509  if (auto *basePath = std::get_if<BasePath>(&result))
510  return basePath->getValue();
511 
512  if (auto *path = std::get_if<Path>(&result))
513  return path->getValue();
514 
515  if (auto *object = std::get_if<Object>(&result))
516  return object->getValue();
517 
518  auto primitive = std::get<PythonPrimitive>(result);
520  omPythonValueToPrimitive(primitive, ctx));
521 }
522 
523 } // namespace
524 
525 /// Populate the OM Python module.
526 void circt::python::populateDialectOMSubmodule(py::module &m) {
527  m.doc() = "OM dialect Python native extension";
528 
529  // Add the Evaluator class definition.
530  py::class_<Evaluator>(m, "Evaluator")
531  .def(py::init<MlirModule>(), py::arg("module"))
532  .def("instantiate", &Evaluator::instantiate, "Instantiate an Object",
533  py::arg("class_name"), py::arg("actual_params"))
534  .def_property_readonly("module", &Evaluator::getModule,
535  "The Module the Evaluator is built from");
536 
537  // Add the List class definition.
538  py::class_<List>(m, "List")
539  .def(py::init<List>(), py::arg("list"))
540  .def("__getitem__", &List::getElement)
541  .def("__len__", &List::getNumElements);
542 
543  py::class_<Tuple>(m, "Tuple")
544  .def(py::init<Tuple>(), py::arg("tuple"))
545  .def("__getitem__", &Tuple::getElement)
546  .def("__len__", &Tuple::getNumElements);
547 
548  // Add the Map class definition.
549  py::class_<Map>(m, "Map")
550  .def(py::init<Map>(), py::arg("map"))
551  .def("__getitem__", &Map::dunderGetItem)
552  .def("keys", &Map::getKeys)
553  .def_property_readonly("type", &Map::getType, "The Type of the Map");
554 
555  // Add the BasePath class definition.
556  py::class_<BasePath>(m, "BasePath")
557  .def(py::init<BasePath>(), py::arg("basepath"))
558  .def_static("get_empty", &BasePath::getEmpty,
559  py::arg("context") = py::none());
560 
561  // Add the Path class definition.
562  py::class_<Path>(m, "Path")
563  .def(py::init<Path>(), py::arg("path"))
564  .def("__str__", &Path::dunderStr);
565 
566  // Add the Object class definition.
567  py::class_<Object>(m, "Object")
568  .def(py::init<Object>(), py::arg("object"))
569  .def("__getattr__", &Object::getField, "Get a field from an Object",
570  py::arg("name"))
571  .def("get_field_loc", &Object::getFieldLoc,
572  "Get the location of a field from an Object", py::arg("name"))
573  .def_property_readonly("field_names", &Object::getFieldNames,
574  "Get field names from an Object")
575  .def_property_readonly("type", &Object::getType, "The Type of the Object")
576  .def_property_readonly("loc", &Object::getLocation,
577  "The Location of the Object")
578  .def("__hash__", &Object::getHash, "Get object hash")
579  .def("__eq__", &Object::eq, "Check if two objects are same");
580 
581  // Add the ReferenceAttr definition
582  mlir_attribute_subclass(m, "ReferenceAttr", omAttrIsAReferenceAttr)
583  .def_property_readonly("inner_ref", [](MlirAttribute self) {
584  return omReferenceAttrGetInnerRef(self);
585  });
586 
587  // Add the IntegerAttr definition
588  mlir_attribute_subclass(m, "OMIntegerAttr", omAttrIsAIntegerAttr)
589  .def_classmethod("get",
590  [](py::object cls, MlirAttribute intVal) {
591  return cls(omIntegerAttrGet(intVal));
592  })
593  .def_property_readonly(
594  "integer",
595  [](MlirAttribute self) { return omIntegerAttrGetInt(self); })
596  .def("__str__", [](MlirAttribute self) {
597  MlirStringRef str = omIntegerAttrToString(self);
598  return std::string(str.data, str.length);
599  });
600 
601  // Add the OMListAttr definition
602  mlir_attribute_subclass(m, "ListAttr", omAttrIsAListAttr)
603  .def("__getitem__", &omListAttrGetElement)
604  .def("__len__", &omListAttrGetNumElements)
605  .def("__iter__",
606  [](MlirAttribute arr) { return PyListAttrIterator(arr); });
607  PyListAttrIterator::bind(m);
608 
609  // Add the MapAttr definition
610  mlir_attribute_subclass(m, "MapAttr", omAttrIsAMapAttr)
611  .def("__iter__", [](MlirAttribute arr) { return PyMapAttrIterator(arr); })
612  .def("__len__", &omMapAttrGetNumElements);
613  PyMapAttrIterator::bind(m);
614 
615  // Add the AnyType class definition.
616  mlir_type_subclass(m, "AnyType", omTypeIsAAnyType, omAnyTypeGetTypeID);
617 
618  // Add the ClassType class definition.
619  mlir_type_subclass(m, "ClassType", omTypeIsAClassType, omClassTypeGetTypeID)
620  .def_property_readonly("name", [](MlirType type) {
621  MlirStringRef name = mlirIdentifierStr(omClassTypeGetName(type));
622  return std::string(name.data, name.length);
623  });
624 
625  // Add the BasePathType class definition.
626  mlir_type_subclass(m, "BasePathType", omTypeIsAFrozenBasePathType,
628 
629  // Add the ListType class definition.
630  mlir_type_subclass(m, "ListType", omTypeIsAListType, omListTypeGetTypeID)
631  .def_property_readonly("element_type", omListTypeGetElementType);
632 
633  // Add the PathType class definition.
634  mlir_type_subclass(m, "PathType", omTypeIsAFrozenPathType,
636 }
assert(baseType &&"element must be base type")
MLIR_CAPI_EXPORTED MlirAttribute hwInnerRefAttrGetModule(MlirAttribute)
Definition: HW.cpp:245
MLIR_CAPI_EXPORTED MlirAttribute hwInnerRefAttrGetName(MlirAttribute)
Definition: HW.cpp:241
MLIR_CAPI_EXPORTED bool omEvaluatorObjectIsEq(OMEvaluatorValue object, OMEvaluatorValue other)
Check equality of two objects.
Definition: OM.cpp:183
MLIR_CAPI_EXPORTED intptr_t omListAttrGetNumElements(MlirAttribute attr)
Definition: OM.cpp:419
MLIR_CAPI_EXPORTED unsigned omEvaluatorObjectGetHash(OMEvaluatorValue object)
Get the object hash.
Definition: OM.cpp:178
MLIR_CAPI_EXPORTED bool omTypeIsAFrozenBasePathType(MlirType type)
Is the Type a FrozenBasePathType.
Definition: OM.cpp:50
MLIR_CAPI_EXPORTED MlirTypeID omListTypeGetTypeID(void)
Get the TypeID for a ListType.
Definition: OM.cpp:73
MLIR_CAPI_EXPORTED bool omAttrIsAListAttr(MlirAttribute attr)
Definition: OM.cpp:415
MLIR_CAPI_EXPORTED bool omTypeIsAListType(MlirType type)
Is the Type a ListType.
Definition: OM.cpp:70
MLIR_CAPI_EXPORTED MlirTypeID omFrozenPathTypeGetTypeID(void)
Get the TypeID for a FrozenPathType.
Definition: OM.cpp:65
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a BasePath.
Definition: OM.cpp:328
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsNull(OMEvaluatorValue evaluatorValue)
Definition: OM.cpp:234
MLIR_CAPI_EXPORTED MlirAttribute omMapAttrGetElementValue(MlirAttribute attr, intptr_t pos)
Definition: OM.cpp:445
MLIR_CAPI_EXPORTED intptr_t omEvaluatorTupleGetNumElements(OMEvaluatorValue evaluatorValue)
Get the size of the tuple.
Definition: OM.cpp:299
MLIR_CAPI_EXPORTED OMEvaluator omEvaluatorNew(MlirModule mod)
Construct an Evaluator with an IR module.
Definition: OM.cpp:122
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorValueGetReferenceValue(OMEvaluatorValue evaluatorValue)
Dereference a Reference EvaluatorValue.
Definition: OM.cpp:353
MLIR_CAPI_EXPORTED MlirLocation omEvaluatorValueGetLoc(OMEvaluatorValue evaluatorValue)
Definition: OM.cpp:229
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorValueGetPrimitive(OMEvaluatorValue evaluatorValue)
Get the Primitive from an EvaluatorValue, which must contain a Primitive.
Definition: OM.cpp:252
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorBasePathGetEmpty(MlirContext context)
Create an empty BasePath.
Definition: OM.cpp:332
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAPath(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Path.
Definition: OM.cpp:336
MLIR_CAPI_EXPORTED bool omTypeIsAAnyType(MlirType type)
Is the Type an AnyType.
Definition: OM.cpp:33
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAMap(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Map.
Definition: OM.cpp:324
MLIR_CAPI_EXPORTED MlirTypeID omFrozenBasePathTypeGetTypeID(void)
Get the TypeID for a FrozenBasePathType.
Definition: OM.cpp:55
MLIR_CAPI_EXPORTED MlirModule omEvaluatorGetModule(OMEvaluator evaluator)
Get the Module the Evaluator is built from.
Definition: OM.cpp:157
MLIR_CAPI_EXPORTED MlirType omMapTypeGetKeyType(MlirType type)
Return a key type of a map.
Definition: OM.cpp:91
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorInstantiate(OMEvaluator evaluator, MlirAttribute className, intptr_t nActualParams, OMEvaluatorValue *actualParams)
Use the Evaluator to Instantiate an Object from its class name and actual parameters.
Definition: OM.cpp:129
MLIR_CAPI_EXPORTED MlirTypeID omClassTypeGetTypeID(void)
Get the TypeID for a ClassType.
Definition: OM.cpp:42
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorMapGetElement(OMEvaluatorValue evaluatorValue, MlirAttribute attr)
Get an element of the map.
Definition: OM.cpp:313
MLIR_CAPI_EXPORTED intptr_t omEvaluatorListGetNumElements(OMEvaluatorValue evaluatorValue)
Get the length of the list.
Definition: OM.cpp:280
MLIR_CAPI_EXPORTED MlirIdentifier omClassTypeGetName(MlirType type)
Get the name for a ClassType.
Definition: OM.cpp:45
MLIR_CAPI_EXPORTED bool omAttrIsAReferenceAttr(MlirAttribute attr)
Definition: OM.cpp:374
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorTupleGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos)
Get an element of the tuple.
Definition: OM.cpp:306
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAList(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is an Object.
Definition: OM.cpp:267
MLIR_CAPI_EXPORTED MlirType omListTypeGetElementType(MlirType type)
Definition: OM.cpp:76
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsATuple(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Tuple.
Definition: OM.cpp:294
MLIR_CAPI_EXPORTED MlirType omEvaluatorMapGetType(OMEvaluatorValue evaluatorValue)
Get the Type from a Map, which will be a MapType.
Definition: OM.cpp:193
MLIR_CAPI_EXPORTED bool omTypeIsAFrozenPathType(MlirType type)
Is the Type a FrozenPathType.
Definition: OM.cpp:60
MLIR_CAPI_EXPORTED MlirType omEvaluatorObjectGetType(OMEvaluatorValue object)
Get the Type from an Object, which will be a ClassType.
Definition: OM.cpp:173
MLIR_CAPI_EXPORTED bool omAttrIsAIntegerAttr(MlirAttribute attr)
Definition: OM.cpp:387
MLIR_CAPI_EXPORTED bool omTypeIsAStringType(MlirType type)
Is the Type a StringType.
Definition: OM.cpp:81
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos)
Get an element of the list.
Definition: OM.cpp:287
MLIR_CAPI_EXPORTED bool omTypeIsAClassType(MlirType type)
Is the Type a ClassType.
Definition: OM.cpp:39
MLIR_CAPI_EXPORTED bool omEvaluatorObjectIsNull(OMEvaluatorValue object)
Query if the Object is null.
Definition: OM.cpp:167
MLIR_CAPI_EXPORTED intptr_t omMapAttrGetNumElements(MlirAttribute attr)
Definition: OM.cpp:435
MLIR_CAPI_EXPORTED MlirStringRef omIntegerAttrToString(MlirAttribute attr)
Get a string representation of an om::IntegerAttr.
Definition: OM.cpp:402
MLIR_CAPI_EXPORTED MlirIdentifier omMapAttrGetElementKey(MlirAttribute attr, intptr_t pos)
Definition: OM.cpp:440
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorValueFromPrimitive(MlirAttribute primitive)
Get the EvaluatorValue from a Primitive value.
Definition: OM.cpp:261
MLIR_CAPI_EXPORTED MlirAttribute omIntegerAttrGet(MlirAttribute attr)
Get an om::IntegerAttr from mlir::IntegerAttr.
Definition: OM.cpp:395
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAObject(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is an Object.
Definition: OM.cpp:240
MLIR_CAPI_EXPORTED MlirAttribute omListAttrGetElement(MlirAttribute attr, intptr_t pos)
Definition: OM.cpp:424
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAPrimitive(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Primitive.
Definition: OM.cpp:246
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorObjectGetField(OMEvaluatorValue object, MlirAttribute name)
Get a field from an Object, which must contain a field of that name.
Definition: OM.cpp:203
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorMapGetKeys(OMEvaluatorValue object)
Get an ArrayAttr with the keys in a Map.
Definition: OM.cpp:198
MLIR_CAPI_EXPORTED MlirContext omEvaluatorValueGetContext(OMEvaluatorValue evaluatorValue)
Definition: OM.cpp:224
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorObjectGetFieldNames(OMEvaluatorValue object)
Get all the field names from an Object, can be empty if object has no fields.
Definition: OM.cpp:189
MLIR_CAPI_EXPORTED bool omAttrIsAMapAttr(MlirAttribute attr)
Definition: OM.cpp:433
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAReference(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Reference.
Definition: OM.cpp:346
MLIR_CAPI_EXPORTED MlirTypeID omAnyTypeGetTypeID(void)
Get the TypeID for an AnyType.
Definition: OM.cpp:36
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorPathGetAsString(OMEvaluatorValue evaluatorValue)
Get a string representation of a Path.
Definition: OM.cpp:340
MLIR_CAPI_EXPORTED MlirAttribute omReferenceAttrGetInnerRef(MlirAttribute attr)
Definition: OM.cpp:378
MLIR_CAPI_EXPORTED MlirAttribute omIntegerAttrGetInt(MlirAttribute attr)
Given an om::IntegerAttr, return the mlir::IntegerAttr.
Definition: OM.cpp:391
@ None
Don't preserve aggregate at all.
Definition: Passes.h:33
evaluator::ObjectValue Object
Definition: Evaluator.h:411
void populateDialectOMSubmodule(pybind11::module &m)
A value type for use in C APIs that just wraps a pointer to an Object.
Definition: OM.h:90
A value type for use in C APIs that just wraps a pointer to an Evaluator.
Definition: OM.h:79