11 #include "mlir-c/BuiltinAttributes.h"
12 #include "mlir-c/BuiltinTypes.h"
13 #include "mlir-c/IR.h"
14 #include "mlir/Bindings/Python/PybindAdaptors.h"
15 #include <pybind11/pybind11.h>
16 #include <pybind11/stl.h>
20 using namespace mlir::python;
21 using namespace mlir::python::adaptors;
39 std::variant<None, Object, List, Tuple, Map, BasePath, Path, MlirAttribute>;
53 PythonValue getElement(intptr_t i);
68 PythonValue getElement(intptr_t i);
82 std::vector<MlirAttribute> getKeys() {
84 intptr_t numFieldNames = mlirArrayAttrGetNumElements(attr);
86 std::vector<MlirAttribute> pyFieldNames;
87 for (intptr_t i = 0; i < numFieldNames; ++i)
88 pyFieldNames.emplace_back(mlirArrayAttrGetElement(attr, i));
94 PythonValue dunderGetItemAttr(MlirAttribute key);
95 PythonValue dunderGetItemNamed(
const std::string &key);
96 PythonValue dunderGetItemIndexed(intptr_t key);
98 dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key);
117 static BasePath getEmpty(MlirContext context) {
141 std::string dunderStr() {
143 return std::string(ref.data, ref.length);
160 MlirLocation getFieldLoc(
const std::string &name) {
163 MlirStringRef cName = mlirStringRefCreateFromCString(name.c_str());
164 MlirAttribute nameAttr = mlirStringAttrGet(context, cName);
174 PythonValue getField(
const std::string &name) {
177 MlirStringRef cName = mlirStringRefCreateFromCString(name.c_str());
178 MlirAttribute nameAttr = mlirStringAttrGet(context, cName);
183 return omEvaluatorValueToPythonValue(result);
187 std::vector<std::string> getFieldNames() {
189 intptr_t numFieldNames = mlirArrayAttrGetNumElements(fieldNames);
191 std::vector<std::string> pyFieldNames;
192 for (intptr_t i = 0; i < numFieldNames; ++i) {
193 MlirAttribute fieldName = mlirArrayAttrGetElement(fieldNames, i);
194 MlirStringRef fieldNameStr = mlirStringAttrGetValue(fieldName);
195 pyFieldNames.emplace_back(fieldNameStr.data, fieldNameStr.length);
220 Object instantiate(MlirAttribute className,
221 std::vector<PythonValue> actualParams) {
222 std::vector<OMEvaluatorValue> values;
223 for (
auto ¶m : actualParams)
224 values.push_back(pythonValueToOMEvaluatorValue(param));
228 evaluator, className, values.size(), values.data());
234 throw py::value_error(
235 "unable to instantiate object, see previous error(s)");
249 class PyListAttrIterator {
251 PyListAttrIterator(MlirAttribute attr) : attr(std::move(attr)) {}
253 PyListAttrIterator &dunderIter() {
return *
this; }
255 MlirAttribute dunderNext() {
257 throw py::stop_iteration();
261 static void bind(py::module &m) {
262 py::class_<PyListAttrIterator>(m,
"ListAttributeIterator",
264 .def(
"__iter__", &PyListAttrIterator::dunderIter)
265 .def(
"__next__", &PyListAttrIterator::dunderNext);
270 intptr_t nextIndex = 0;
273 PythonValue List::getElement(intptr_t i) {
277 class PyMapAttrIterator {
279 PyMapAttrIterator(MlirAttribute attr) : attr(std::move(attr)) {}
281 PyMapAttrIterator &dunderIter() {
return *
this; }
283 py::tuple dunderNext() {
285 throw py::stop_iteration();
291 auto keyName = mlirIdentifierStr(key);
292 std::string keyStr(keyName.data, keyName.length);
293 return py::make_tuple(keyStr, value);
296 static void bind(py::module &m) {
297 py::class_<PyMapAttrIterator>(m,
"MapAttributeIterator", py::module_local())
298 .def(
"__iter__", &PyMapAttrIterator::dunderIter)
299 .def(
"__next__", &PyMapAttrIterator::dunderNext);
304 intptr_t nextIndex = 0;
307 PythonValue Tuple::getElement(intptr_t i) {
309 throw std::out_of_range(
"tuple index out of range");
314 PythonValue Map::dunderGetItemNamed(
const std::string &key) {
317 throw pybind11::key_error(
"key is not string");
319 mlirStringAttrTypedGet(type, mlirStringRefCreateFromCString(key.c_str()));
320 return dunderGetItemAttr(attr);
323 PythonValue Map::dunderGetItemIndexed(intptr_t i) {
325 if (!mlirTypeIsAInteger(type))
326 throw pybind11::key_error(
"key is not integer");
327 MlirAttribute attr = mlirIntegerAttrGet(type, i);
328 return dunderGetItemAttr(attr);
331 PythonValue Map::dunderGetItemAttr(MlirAttribute key) {
335 throw pybind11::key_error(
"key not found");
337 return omEvaluatorValueToPythonValue(result);
341 Map::dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key) {
342 if (
auto *i = std::get_if<intptr_t>(&key))
343 return dunderGetItemIndexed(*i);
344 else if (
auto *str = std::get_if<std::string>(&key))
345 return dunderGetItemNamed(*str);
346 return dunderGetItemAttr(std::get<MlirAttribute>(key));
354 throw py::value_error(
"unable to get field, see previous error(s)");
366 return Tuple(result);
374 return BasePath(result);
381 return omEvaluatorValueToPythonValue(
390 if (
auto *attr = std::get_if<MlirAttribute>(&result))
393 if (
auto *list = std::get_if<List>(&result))
394 return list->getValue();
396 if (
auto *tuple = std::get_if<Tuple>(&result))
397 return tuple->getValue();
399 if (
auto *map = std::get_if<Map>(&result))
400 return map->getValue();
402 if (
auto *basePath = std::get_if<BasePath>(&result))
403 return basePath->getValue();
405 if (
auto *path = std::get_if<Path>(&result))
406 return path->getValue();
408 return std::get<Object>(result).getValue();
415 m.doc() =
"OM dialect Python native extension";
418 py::class_<Evaluator>(m,
"Evaluator")
419 .def(py::init<MlirModule>(), py::arg(
"module"))
420 .def(
"instantiate", &Evaluator::instantiate,
"Instantiate an Object",
421 py::arg(
"class_name"), py::arg(
"actual_params"))
422 .def_property_readonly(
"module", &Evaluator::getModule,
423 "The Module the Evaluator is built from");
426 py::class_<List>(m,
"List")
427 .def(py::init<List>(), py::arg(
"list"))
428 .def(
"__getitem__", &List::getElement)
429 .def(
"__len__", &List::getNumElements);
431 py::class_<Tuple>(m,
"Tuple")
432 .def(py::init<Tuple>(), py::arg(
"tuple"))
433 .def(
"__getitem__", &Tuple::getElement)
434 .def(
"__len__", &Tuple::getNumElements);
437 py::class_<Map>(m,
"Map")
438 .def(py::init<Map>(), py::arg(
"map"))
439 .def(
"__getitem__", &Map::dunderGetItem)
440 .def(
"keys", &Map::getKeys)
441 .def_property_readonly(
"type", &Map::getType,
"The Type of the Map");
444 py::class_<BasePath>(m,
"BasePath")
445 .def(py::init<BasePath>(), py::arg(
"basepath"))
446 .def_static(
"get_empty", &BasePath::getEmpty,
447 py::arg(
"context") = py::none());
450 py::class_<Path>(m,
"Path")
451 .def(py::init<Path>(), py::arg(
"path"))
452 .def(
"__str__", &Path::dunderStr);
455 py::class_<Object>(m,
"Object")
456 .def(py::init<Object>(), py::arg(
"object"))
457 .def(
"__getattr__", &Object::getField,
"Get a field from an Object",
459 .def(
"get_field_loc", &Object::getFieldLoc,
460 "Get the location of a field from an Object", py::arg(
"name"))
461 .def_property_readonly(
"field_names", &Object::getFieldNames,
462 "Get field names from an Object")
463 .def_property_readonly(
"type", &Object::getType,
"The Type of the Object")
464 .def(
"__hash__", &Object::getHash,
"Get object hash")
465 .def(
"__eq__", &Object::eq,
"Check if two objects are same");
469 .def_property_readonly(
"inner_ref", [](MlirAttribute
self) {
475 .def_classmethod(
"get",
476 [](py::object cls, MlirAttribute intVal) {
479 .def_property_readonly(
482 .def(
"__str__", [](MlirAttribute
self) {
484 return std::string(str.data, str.length);
492 [](MlirAttribute arr) {
return PyListAttrIterator(arr); });
493 PyListAttrIterator::bind(m);
497 .def(
"__iter__", [](MlirAttribute arr) {
return PyMapAttrIterator(arr); })
499 PyMapAttrIterator::bind(m);
503 .def_property_readonly(
"name", [](MlirType type) {
505 return std::string(name.data, name.length);
assert(baseType &&"element must be base type")
MLIR_CAPI_EXPORTED bool omEvaluatorObjectIsEq(OMEvaluatorValue object, OMEvaluatorValue other)
Check equality of two objects.
MLIR_CAPI_EXPORTED intptr_t omListAttrGetNumElements(MlirAttribute attr)
MLIR_CAPI_EXPORTED unsigned omEvaluatorObjectGetHash(OMEvaluatorValue object)
Get the object hash.
MLIR_CAPI_EXPORTED bool omTypeIsAFrozenBasePathType(MlirType type)
Is the Type a FrozenBasePathType.
MLIR_CAPI_EXPORTED bool omAttrIsAListAttr(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirTypeID omFrozenPathTypeGetTypeID(void)
Get the TypeID for a FrozenPathType.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a BasePath.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsNull(OMEvaluatorValue evaluatorValue)
MLIR_CAPI_EXPORTED MlirAttribute omMapAttrGetElementValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED intptr_t omEvaluatorTupleGetNumElements(OMEvaluatorValue evaluatorValue)
Get the size of the tuple.
MLIR_CAPI_EXPORTED OMEvaluator omEvaluatorNew(MlirModule mod)
Construct an Evaluator with an IR module.
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorValueGetReferenceValue(OMEvaluatorValue evaluatorValue)
Dereference a Reference EvaluatorValue.
MLIR_CAPI_EXPORTED MlirLocation omEvaluatorValueGetLoc(OMEvaluatorValue evaluatorValue)
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorValueGetPrimitive(OMEvaluatorValue evaluatorValue)
Get the Primitive from an EvaluatorValue, which must contain a Primitive.
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorBasePathGetEmpty(MlirContext context)
Create an empty BasePath.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAPath(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Path.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAMap(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Map.
MLIR_CAPI_EXPORTED MlirTypeID omFrozenBasePathTypeGetTypeID(void)
Get the TypeID for a FrozenBasePathType.
MLIR_CAPI_EXPORTED MlirModule omEvaluatorGetModule(OMEvaluator evaluator)
Get the Module the Evaluator is built from.
MLIR_CAPI_EXPORTED MlirType omMapTypeGetKeyType(MlirType type)
Return a key type of a map.
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.
MLIR_CAPI_EXPORTED MlirTypeID omClassTypeGetTypeID(void)
Get the TypeID for a ClassType.
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorMapGetElement(OMEvaluatorValue evaluatorValue, MlirAttribute attr)
Get an element of the map.
MLIR_CAPI_EXPORTED intptr_t omEvaluatorListGetNumElements(OMEvaluatorValue evaluatorValue)
Get the length of the list.
MLIR_CAPI_EXPORTED MlirIdentifier omClassTypeGetName(MlirType type)
Get the name for a ClassType.
MLIR_CAPI_EXPORTED bool omAttrIsAReferenceAttr(MlirAttribute attr)
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorTupleGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos)
Get an element of the tuple.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAList(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is an Object.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsATuple(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Tuple.
MLIR_CAPI_EXPORTED MlirType omEvaluatorMapGetType(OMEvaluatorValue evaluatorValue)
Get the Type from a Map, which will be a MapType.
MLIR_CAPI_EXPORTED bool omTypeIsAFrozenPathType(MlirType type)
Is the Type a FrozenPathType.
MLIR_CAPI_EXPORTED MlirType omEvaluatorObjectGetType(OMEvaluatorValue object)
Get the Type from an Object, which will be a ClassType.
MLIR_CAPI_EXPORTED bool omAttrIsAIntegerAttr(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool omTypeIsAStringType(MlirType type)
Is the Type a StringType.
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos)
Get an element of the list.
MLIR_CAPI_EXPORTED bool omTypeIsAClassType(MlirType type)
Is the Type a ClassType.
MLIR_CAPI_EXPORTED bool omEvaluatorObjectIsNull(OMEvaluatorValue object)
Query if the Object is null.
MLIR_CAPI_EXPORTED intptr_t omMapAttrGetNumElements(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirStringRef omIntegerAttrToString(MlirAttribute attr)
Get a string representation of an om::IntegerAttr.
MLIR_CAPI_EXPORTED MlirIdentifier omMapAttrGetElementKey(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorValueFromPrimitive(MlirAttribute primitive)
Get the EvaluatorValue from a Primitive value.
MLIR_CAPI_EXPORTED MlirAttribute omIntegerAttrGet(MlirAttribute attr)
Get an om::IntegerAttr from mlir::IntegerAttr.
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAObject(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is an Object.
MLIR_CAPI_EXPORTED MlirAttribute omListAttrGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAPrimitive(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Primitive.
MLIR_CAPI_EXPORTED OMEvaluatorValue omEvaluatorObjectGetField(OMEvaluatorValue object, MlirAttribute name)
Get a field from an Object, which must contain a field of that name.
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorMapGetKeys(OMEvaluatorValue object)
Get an ArrayAttr with the keys in a Map.
MLIR_CAPI_EXPORTED MlirContext omEvaluatorValueGetContext(OMEvaluatorValue evaluatorValue)
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorObjectGetFieldNames(OMEvaluatorValue object)
Get all the field names from an Object, can be empty if object has no fields.
MLIR_CAPI_EXPORTED bool omAttrIsAMapAttr(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAReference(OMEvaluatorValue evaluatorValue)
Query if the EvaluatorValue is a Reference.
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorPathGetAsString(OMEvaluatorValue evaluatorValue)
Get a string representation of a Path.
MLIR_CAPI_EXPORTED MlirAttribute omReferenceAttrGetInnerRef(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAttribute omIntegerAttrGetInt(MlirAttribute attr)
Given an om::IntegerAttr, return the mlir::IntegerAttr.
evaluator::ObjectValue Object
void populateDialectOMSubmodule(pybind11::module &m)
A value type for use in C APIs that just wraps a pointer to an Object.
A value type for use in C APIs that just wraps a pointer to an Evaluator.