12 #include <string_view>
21 #include "llvm/ADT/ScopeExit.h"
22 #include "llvm/Support/raw_ostream.h"
25 using namespace nanobind::literals;
36 R
"(Gets a DenseElementsAttr from a Python buffer or array.
38 When `type` is not provided, then some limited type inferencing is done based
39 on the buffer format. Support presently exists for 8/16/32/64 signed and
40 unsigned integers and float16/float32/float64. DenseElementsAttrs of these
41 types can also be converted back to a corresponding buffer.
43 For conversions outside of these types, a `type=` must be explicitly provided
44 and the buffer contents must be bit-castable to the MLIR internal
47 * Integer types (except for i1): the buffer must be byte aligned to the
49 * Floating point types: Must be bit-castable to the given floating point
51 * i1 (bool): Bit packed into 8bit words where the bit pattern matches a
52 row major ordering. An arbitrary Numpy `bool_` array can be bit packed to
53 this specification with: `np.packbits(ary, axis=None, bitorder='little')`.
55 If a single element buffer is passed (or for i1, a single byte with value 0
56 or 255), then a splat will be created.
59 array: The array or buffer to convert.
60 signless: If inferring an appropriate MLIR type, use signless types for
61 integers (defaults True).
62 type: Skips inference of the MLIR element type and uses this instead. The
63 storage size must be consistent with the actual contents of the buffer.
64 shape: Overrides the shape of the buffer when constructing the MLIR
65 shaped type. This is needed when the physical and logical shape differ (as
67 context: Explicit context, if not from context manager.
70 DenseElementsAttr on success.
73 ValueError: If the type of the buffer or array cannot be matched to an MLIR
74 type or if the buffer does not meet expectations.
78 R
"(Gets a DenseElementsAttr from a Python list of attributes.
80 Note that it can be expensive to construct attributes individually.
81 For a large number of elements, consider using a Python buffer or array instead.
84 attrs: A list of attributes.
85 type: The desired shape and type of the resulting DenseElementsAttr.
86 If not provided, the element type is determined based on the type
87 of the 0th attribute and the shape is `[len(attrs)]`.
88 context: Explicit context, if not from context manager.
91 DenseElementsAttr on success.
94 ValueError: If the type of the attributes does not match the type
95 specified by `shaped_type`.
99 R
"(Gets a DenseResourceElementsAttr from a Python buffer or array.
101 This function does minimal validation or massaging of the data, and it is
102 up to the caller to ensure that the buffer meets the characteristics
103 implied by the shape.
105 The backing buffer and any user objects will be retained for the lifetime
106 of the resource blob. This is typically bounded to the context but the
107 resource can have a shorter lifespan depending on how it is used in
108 subsequent processing.
111 buffer: The array or buffer to convert.
112 name: Name to provide to the resource (may be changed upon collision).
113 type: The explicit ShapedType to construct the attribute with.
114 context: Explicit context, if not from context manager.
117 DenseResourceElementsAttr on success.
120 ValueError: If the type of the buffer or array cannot be matched to an MLIR
121 type or if the buffer does not meet expectations.
126 struct nb_buffer_info {
128 ssize_t itemsize = 0;
130 const char *format =
nullptr;
134 bool readonly =
false;
137 void *ptr, ssize_t itemsize,
const char *format, ssize_t ndim,
139 bool readonly =
false,
140 std::unique_ptr<Py_buffer,
void (*)(Py_buffer *)> owned_view_in =
141 std::unique_ptr<Py_buffer,
void (*)(Py_buffer *)>(
nullptr,
nullptr))
142 : ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
143 shape(std::move(shape_in)), strides(std::move(strides_in)),
144 readonly(readonly), owned_view(std::move(owned_view_in)) {
146 for (ssize_t i = 0; i < ndim; ++i) {
151 explicit nb_buffer_info(Py_buffer *view)
152 : nb_buffer_info(view->buf, view->itemsize, view->format, view->ndim,
153 {view->shape, view->shape + view->ndim},
155 {view->strides, view->strides + view->ndim},
157 std::unique_ptr<Py_buffer, void (*)(Py_buffer *)>(
158 view, PyBuffer_Release)) {}
160 nb_buffer_info(
const nb_buffer_info &) =
delete;
161 nb_buffer_info(nb_buffer_info &&) =
default;
162 nb_buffer_info &operator=(
const nb_buffer_info &) =
delete;
163 nb_buffer_info &operator=(nb_buffer_info &&) =
default;
166 std::unique_ptr<Py_buffer, void (*)(Py_buffer *)> owned_view;
169 class nb_buffer :
public nb::object {
170 NB_OBJECT_DEFAULT(nb_buffer,
object,
"Buffer", PyObject_CheckBuffer);
172 nb_buffer_info request()
const {
173 int flags = PyBUF_STRIDES | PyBUF_FORMAT;
174 auto *view =
new Py_buffer();
175 if (PyObject_GetBuffer(ptr(), view, flags) != 0) {
177 throw nb::python_error();
179 return nb_buffer_info(view);
183 template <
typename T>
184 struct nb_format_descriptor {};
187 struct nb_format_descriptor<bool> {
188 static const char *format() {
return "?"; }
191 struct nb_format_descriptor<int8_t> {
192 static const char *format() {
return "b"; }
195 struct nb_format_descriptor<uint8_t> {
196 static const char *format() {
return "B"; }
199 struct nb_format_descriptor<int16_t> {
200 static const char *format() {
return "h"; }
203 struct nb_format_descriptor<uint16_t> {
204 static const char *format() {
return "H"; }
207 struct nb_format_descriptor<int32_t> {
208 static const char *format() {
return "i"; }
211 struct nb_format_descriptor<uint32_t> {
212 static const char *format() {
return "I"; }
215 struct nb_format_descriptor<int64_t> {
216 static const char *format() {
return "q"; }
219 struct nb_format_descriptor<uint64_t> {
220 static const char *format() {
return "Q"; }
223 struct nb_format_descriptor<float> {
224 static const char *format() {
return "f"; }
227 struct nb_format_descriptor<double> {
228 static const char *format() {
return "d"; }
242 static constexpr
const char *pyClassName =
"AffineMapAttr";
243 using PyConcreteAttribute::PyConcreteAttribute;
244 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
247 static void bindDerived(ClassTy &c) {
252 return PyAffineMapAttribute(affineMap.
getContext(), attr);
254 nb::arg(
"affine_map"),
"Gets an attribute wrapping an AffineMap.");
257 [](PyAffineMapAttribute &
self) {
261 "Returns the value of the AffineMap attribute");
265 class PyIntegerSetAttribute
269 static constexpr
const char *pyClassName =
"IntegerSetAttr";
270 using PyConcreteAttribute::PyConcreteAttribute;
271 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
274 static void bindDerived(ClassTy &c) {
279 return PyIntegerSetAttribute(integerSet.
getContext(), attr);
281 nb::arg(
"integer_set"),
"Gets an attribute wrapping an IntegerSet.");
285 template <
typename T>
286 static T pyTryCast(nb::handle
object) {
288 return nb::cast<T>(
object);
289 }
catch (nb::cast_error &err) {
290 std::string msg = std::string(
"Invalid attribute when attempting to "
291 "create an ArrayAttribute (") +
293 throw std::runtime_error(msg.c_str());
294 }
catch (std::runtime_error &err) {
295 std::string msg = std::string(
"Invalid attribute (None?) when attempting "
296 "to create an ArrayAttribute (") +
298 throw std::runtime_error(msg.c_str());
304 template <
typename EltTy,
typename DerivedT>
310 class PyDenseArrayIterator {
312 PyDenseArrayIterator(
PyAttribute attr) : attr(std::move(attr)) {}
315 PyDenseArrayIterator dunderIter() {
return *
this; }
321 throw nb::stop_iteration();
326 static void bind(nb::module_ &m) {
327 nb::class_<PyDenseArrayIterator>(m, DerivedT::pyIteratorName)
328 .def(
"__iter__", &PyDenseArrayIterator::dunderIter)
329 .def(
"__next__", &PyDenseArrayIterator::dunderNext);
340 EltTy getItem(intptr_t i) {
return DerivedT::getElement(*
this, i); }
345 if constexpr (std::is_same_v<EltTy, bool>) {
349 std::vector<bool> values;
350 for (nb::handle py_value : py_values) {
351 int is_true = PyObject_IsTrue(py_value.ptr());
353 throw nb::python_error();
355 values.push_back(is_true);
357 return getAttribute(values, ctx->getRef());
359 nb::arg(
"values"), nb::arg(
"context") = nb::none(),
360 "Gets a uniqued dense array attribute");
365 return getAttribute(values, ctx->getRef());
367 nb::arg(
"values"), nb::arg(
"context") = nb::none(),
368 "Gets a uniqued dense array attribute");
371 c.def(
"__getitem__", [](DerivedT &arr, intptr_t i) {
373 throw nb::index_error(
"DenseArray index out of range");
374 return arr.getItem(i);
376 c.def(
"__len__", [](
const DerivedT &arr) {
380 [](
const DerivedT &arr) {
return PyDenseArrayIterator(arr); });
381 c.def(
"__add__", [](DerivedT &arr,
const nb::list &extras) {
382 std::vector<EltTy> values;
384 values.reserve(numOldElements + nb::len(extras));
385 for (intptr_t i = 0; i < numOldElements; ++i)
386 values.push_back(arr.getItem(i));
387 for (nb::handle attr : extras)
388 values.push_back(pyTryCast<EltTy>(attr));
389 return getAttribute(values, arr.getContext());
394 static DerivedT getAttribute(
const std::vector<EltTy> &values,
396 if constexpr (std::is_same_v<EltTy, bool>) {
397 std::vector<int> intValues(values.begin(), values.end());
398 MlirAttribute attr = DerivedT::getAttribute(ctx->
get(), intValues.size(),
400 return DerivedT(ctx, attr);
403 DerivedT::getAttribute(ctx->
get(), values.size(), values.data());
404 return DerivedT(ctx, attr);
410 struct PyDenseBoolArrayAttribute
411 :
public PyDenseArrayAttribute<bool, PyDenseBoolArrayAttribute> {
415 static constexpr
const char *pyClassName =
"DenseBoolArrayAttr";
416 static constexpr
const char *pyIteratorName =
"DenseBoolArrayIterator";
417 using PyDenseArrayAttribute::PyDenseArrayAttribute;
419 struct PyDenseI8ArrayAttribute
420 :
public PyDenseArrayAttribute<int8_t, PyDenseI8ArrayAttribute> {
424 static constexpr
const char *pyClassName =
"DenseI8ArrayAttr";
425 static constexpr
const char *pyIteratorName =
"DenseI8ArrayIterator";
426 using PyDenseArrayAttribute::PyDenseArrayAttribute;
428 struct PyDenseI16ArrayAttribute
429 :
public PyDenseArrayAttribute<int16_t, PyDenseI16ArrayAttribute> {
433 static constexpr
const char *pyClassName =
"DenseI16ArrayAttr";
434 static constexpr
const char *pyIteratorName =
"DenseI16ArrayIterator";
435 using PyDenseArrayAttribute::PyDenseArrayAttribute;
437 struct PyDenseI32ArrayAttribute
438 :
public PyDenseArrayAttribute<int32_t, PyDenseI32ArrayAttribute> {
442 static constexpr
const char *pyClassName =
"DenseI32ArrayAttr";
443 static constexpr
const char *pyIteratorName =
"DenseI32ArrayIterator";
444 using PyDenseArrayAttribute::PyDenseArrayAttribute;
446 struct PyDenseI64ArrayAttribute
447 :
public PyDenseArrayAttribute<int64_t, PyDenseI64ArrayAttribute> {
451 static constexpr
const char *pyClassName =
"DenseI64ArrayAttr";
452 static constexpr
const char *pyIteratorName =
"DenseI64ArrayIterator";
453 using PyDenseArrayAttribute::PyDenseArrayAttribute;
455 struct PyDenseF32ArrayAttribute
456 :
public PyDenseArrayAttribute<float, PyDenseF32ArrayAttribute> {
460 static constexpr
const char *pyClassName =
"DenseF32ArrayAttr";
461 static constexpr
const char *pyIteratorName =
"DenseF32ArrayIterator";
462 using PyDenseArrayAttribute::PyDenseArrayAttribute;
464 struct PyDenseF64ArrayAttribute
465 :
public PyDenseArrayAttribute<double, PyDenseF64ArrayAttribute> {
469 static constexpr
const char *pyClassName =
"DenseF64ArrayAttr";
470 static constexpr
const char *pyIteratorName =
"DenseF64ArrayIterator";
471 using PyDenseArrayAttribute::PyDenseArrayAttribute;
477 static constexpr
const char *pyClassName =
"ArrayAttr";
478 using PyConcreteAttribute::PyConcreteAttribute;
479 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
482 class PyArrayAttributeIterator {
484 PyArrayAttributeIterator(
PyAttribute attr) : attr(std::move(attr)) {}
486 PyArrayAttributeIterator &dunderIter() {
return *
this; }
488 nb::typed<nb::object, PyAttribute> dunderNext() {
491 throw nb::stop_iteration();
497 static void bind(nb::module_ &m) {
498 nb::class_<PyArrayAttributeIterator>(m,
"ArrayAttributeIterator")
499 .def(
"__iter__", &PyArrayAttributeIterator::dunderIter)
500 .def(
"__next__", &PyArrayAttributeIterator::dunderNext);
508 MlirAttribute getItem(intptr_t i) {
512 static void bindDerived(ClassTy &c) {
517 mlirAttributes.reserve(nb::len(attributes));
518 for (
auto attribute : attributes) {
519 mlirAttributes.push_back(pyTryCast<PyAttribute>(attribute));
522 context->
get(), mlirAttributes.size(), mlirAttributes.data());
523 return PyArrayAttribute(context->getRef(), attr);
525 nb::arg(
"attributes"), nb::arg(
"context") = nb::none(),
526 "Gets a uniqued Array attribute");
529 [](PyArrayAttribute &arr,
530 intptr_t i) -> nb::typed<nb::object, PyAttribute> {
532 throw nb::index_error(
"ArrayAttribute index out of range");
536 [](
const PyArrayAttribute &arr) {
539 .def(
"__iter__", [](
const PyArrayAttribute &arr) {
540 return PyArrayAttributeIterator(arr);
542 c.def(
"__add__", [](PyArrayAttribute arr,
const nb::list &extras) {
543 std::vector<MlirAttribute> attributes;
545 attributes.reserve(numOldElements + nb::len(extras));
546 for (intptr_t i = 0; i < numOldElements; ++i)
547 attributes.push_back(arr.getItem(i));
548 for (nb::handle attr : extras)
549 attributes.push_back(pyTryCast<PyAttribute>(attr));
551 arr.getContext()->get(), attributes.size(), attributes.data());
552 return PyArrayAttribute(arr.getContext(), arrayAttr);
561 static constexpr
const char *pyClassName =
"FloatAttr";
562 using PyConcreteAttribute::PyConcreteAttribute;
563 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
566 static void bindDerived(ClassTy &c) {
574 return PyFloatAttribute(type.
getContext(), attr);
576 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"loc") = nb::none(),
577 "Gets an uniqued float point attribute associated to a type");
586 return PyFloatAttribute(type.
getContext(), attr);
588 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"context") = nb::none(),
589 "Gets an uniqued float point attribute associated to a type");
595 return PyFloatAttribute(context->getRef(), attr);
597 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
598 "Gets an uniqued float point attribute associated to a f32 type");
604 return PyFloatAttribute(context->getRef(), attr);
606 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
607 "Gets an uniqued float point attribute associated to a f64 type");
609 "Returns the value of the float attribute");
611 "Converts the value of the float attribute to a Python float");
619 static constexpr
const char *pyClassName =
"IntegerAttr";
620 using PyConcreteAttribute::PyConcreteAttribute;
622 static void bindDerived(ClassTy &c) {
625 [](
PyType &type, int64_t value) {
627 return PyIntegerAttribute(type.
getContext(), attr);
629 nb::arg(
"type"), nb::arg(
"value"),
630 "Gets an uniqued integer attribute associated to a type");
631 c.def_prop_ro(
"value", toPyInt,
632 "Returns the value of the integer attribute");
633 c.def(
"__int__", toPyInt,
634 "Converts the value of the integer attribute to a Python int");
635 c.def_prop_ro_static(
640 nanobind::sig(
"def static_typeid(/) -> TypeID"));
644 static int64_t toPyInt(PyIntegerAttribute &
self) {
658 static constexpr
const char *pyClassName =
"BoolAttr";
659 using PyConcreteAttribute::PyConcreteAttribute;
661 static void bindDerived(ClassTy &c) {
666 return PyBoolAttribute(context->getRef(), attr);
668 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
669 "Gets an uniqued bool attribute");
671 "Returns the value of the bool attribute");
673 "Converts the value of the bool attribute to a Python bool");
680 static constexpr
const char *pyClassName =
"SymbolRefAttr";
681 using PyConcreteAttribute::PyConcreteAttribute;
683 static PySymbolRefAttribute fromList(
const std::vector<std::string> &symbols,
686 throw std::runtime_error(
"SymbolRefAttr must be composed of at least "
690 for (
size_t i = 1; i < symbols.size(); ++i) {
691 referenceAttrs.push_back(
694 return PySymbolRefAttribute(context.
getRef(),
696 referenceAttrs.size(),
697 referenceAttrs.data()));
700 static void bindDerived(ClassTy &c) {
703 [](
const std::vector<std::string> &symbols,
705 return PySymbolRefAttribute::fromList(symbols, context.
resolve());
707 nb::arg(
"symbols"), nb::arg(
"context") = nb::none(),
708 "Gets a uniqued SymbolRef attribute from a list of symbol names");
711 [](PySymbolRefAttribute &
self) {
712 std::vector<std::string> symbols = {
722 "Returns the value of the SymbolRef attribute as a list[str]");
726 class PyFlatSymbolRefAttribute
730 static constexpr
const char *pyClassName =
"FlatSymbolRefAttr";
731 using PyConcreteAttribute::PyConcreteAttribute;
733 static void bindDerived(ClassTy &c) {
739 return PyFlatSymbolRefAttribute(context->getRef(), attr);
741 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
742 "Gets a uniqued FlatSymbolRef attribute");
745 [](PyFlatSymbolRefAttribute &
self) {
747 return nb::str(stringRef.
data, stringRef.
length);
749 "Returns the value of the FlatSymbolRef attribute as a string");
756 static constexpr
const char *pyClassName =
"OpaqueAttr";
757 using PyConcreteAttribute::PyConcreteAttribute;
758 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
761 static void bindDerived(ClassTy &c) {
764 [](
const std::string &dialectNamespace,
const nb_buffer &buffer,
766 const nb_buffer_info bufferInfo = buffer.request();
767 intptr_t bufferSize = bufferInfo.size;
770 static_cast<char *
>(bufferInfo.ptr), type);
771 return PyOpaqueAttribute(context->getRef(), attr);
773 nb::arg(
"dialect_namespace"), nb::arg(
"buffer"), nb::arg(
"type"),
774 nb::arg(
"context") = nb::none(),
776 nb::sig(
"def get(dialect_namespace: str, buffer: typing_extensions.Buffer, type: Type, context: Context | None = None) -> OpaqueAttr"),
778 "Gets an Opaque attribute.");
781 [](PyOpaqueAttribute &
self) {
783 return nb::str(stringRef.
data, stringRef.
length);
785 "Returns the dialect namespace for the Opaque attribute as a string");
788 [](PyOpaqueAttribute &
self) {
790 return nb::bytes(stringRef.
data, stringRef.
length);
792 "Returns the data for the Opaqued attributes as `bytes`");
797 class PyDenseElementsAttribute
801 static constexpr
const char *pyClassName =
"DenseElementsAttr";
802 using PyConcreteAttribute::PyConcreteAttribute;
804 static PyDenseElementsAttribute
805 getFromList(
const nb::list &attributes, std::optional<PyType> explicitType,
807 const size_t numAttributes = nb::len(attributes);
808 if (numAttributes == 0)
809 throw nb::value_error(
"Attributes list must be non-empty.");
817 llvm::raw_string_ostream os(message);
818 os <<
"Expected a static ShapedType for the shaped_type parameter: "
819 << nb::cast<std::string>(nb::repr(nb::cast(*explicitType)));
820 throw nb::value_error(message.c_str());
822 shapedType = *explicitType;
826 shape.size(), shape.data(),
832 mlirAttributes.reserve(numAttributes);
833 for (
const nb::handle &attribute : attributes) {
834 MlirAttribute mlirAttribute = pyTryCast<PyAttribute>(attribute);
836 mlirAttributes.push_back(mlirAttribute);
840 llvm::raw_string_ostream os(message);
841 os <<
"All attributes must be of the same type and match "
842 <<
"the type parameter: expected="
843 << nb::cast<std::string>(nb::repr(nb::cast(shapedType)))
845 << nb::cast<std::string>(nb::repr(nb::cast(attrType)));
846 throw nb::value_error(message.c_str());
851 shapedType, mlirAttributes.size(), mlirAttributes.data());
853 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
856 static PyDenseElementsAttribute
857 getFromBuffer(
const nb_buffer &array,
bool signless,
858 const std::optional<PyType> &explicitType,
859 std::optional<std::vector<int64_t>> explicitShape,
862 int flags = PyBUF_ND;
864 flags |= PyBUF_FORMAT;
867 if (PyObject_GetBuffer(array.ptr(), &view, flags) != 0) {
868 throw nb::python_error();
870 auto freeBuffer = llvm::make_scope_exit([&]() { PyBuffer_Release(&view); });
872 MlirContext context = contextWrapper->
get();
873 MlirAttribute attr = getAttributeFromBuffer(
874 view, signless, explicitType, std::move(explicitShape), context);
876 throw std::invalid_argument(
877 "DenseElementsAttr could not be constructed from the given buffer. "
878 "This may mean that the Python buffer layout does not match that "
879 "MLIR expected layout and is a bug.");
881 return PyDenseElementsAttribute(contextWrapper->getRef(), attr);
884 static PyDenseElementsAttribute getSplat(
const PyType &shapedType,
886 auto contextWrapper =
890 std::string message =
"Illegal element type for DenseElementsAttr: ";
891 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
892 throw nb::value_error(message.c_str());
896 std::string message =
897 "Expected a static ShapedType for the shaped_type parameter: ";
898 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
899 throw nb::value_error(message.c_str());
904 std::string message =
905 "Shaped element type and attribute type must be equal: shaped=";
906 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
907 message.append(
", element=");
908 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
909 throw nb::value_error(message.c_str());
912 MlirAttribute elements =
914 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
919 std::unique_ptr<nb_buffer_info> accessBuffer() {
926 return bufferInfo<float>(shapedType);
930 return bufferInfo<double>(shapedType);
934 return bufferInfo<uint16_t>(shapedType,
"e");
938 return bufferInfo<int64_t>(shapedType);
945 return bufferInfo<int32_t>(shapedType);
949 return bufferInfo<uint32_t>(shapedType);
956 return bufferInfo<int64_t>(shapedType);
960 return bufferInfo<uint64_t>(shapedType);
967 return bufferInfo<int8_t>(shapedType);
971 return bufferInfo<uint8_t>(shapedType);
978 return bufferInfo<int16_t>(shapedType);
982 return bufferInfo<uint16_t>(shapedType);
990 return getBooleanBufferFromBitpackedAttribute();
995 throw std::invalid_argument(
996 "unsupported data type for conversion to Python buffer");
999 static void bindDerived(ClassTy &c) {
1000 #if PY_VERSION_HEX < 0x03090000
1001 PyTypeObject *tp =
reinterpret_cast<PyTypeObject *
>(c.ptr());
1002 tp->tp_as_buffer->bf_getbuffer = PyDenseElementsAttribute::bf_getbuffer;
1003 tp->tp_as_buffer->bf_releasebuffer =
1004 PyDenseElementsAttribute::bf_releasebuffer;
1006 c.def(
"__len__", &PyDenseElementsAttribute::dunderLen)
1008 "get", PyDenseElementsAttribute::getFromBuffer, nb::arg(
"array"),
1009 nb::arg(
"signless") =
true, nb::arg(
"type") = nb::none(),
1010 nb::arg(
"shape") = nb::none(), nb::arg(
"context") = nb::none(),
1012 nb::sig(
"def get(array: typing_extensions.Buffer, signless: bool = True, type: Type | None = None, shape: Sequence[int] | None = None, context: Context | None = None) -> DenseElementsAttr"),
1015 .def_static(
"get", PyDenseElementsAttribute::getFromList,
1016 nb::arg(
"attrs"), nb::arg(
"type") = nb::none(),
1017 nb::arg(
"context") = nb::none(),
1019 .def_static(
"get_splat", PyDenseElementsAttribute::getSplat,
1020 nb::arg(
"shaped_type"), nb::arg(
"element_attr"),
1021 "Gets a DenseElementsAttr where all values are the same")
1022 .def_prop_ro(
"is_splat",
1023 [](PyDenseElementsAttribute &
self) ->
bool {
1026 .def(
"get_splat_value",
1027 [](PyDenseElementsAttribute &
self)
1028 -> nb::typed<nb::object, PyAttribute> {
1030 throw nb::value_error(
1031 "get_splat_value called on a non-splat attribute");
1038 static PyType_Slot slots[];
1041 static int bf_getbuffer(PyObject *exporter, Py_buffer *view,
int flags);
1042 static void bf_releasebuffer(PyObject *, Py_buffer *buffer);
1044 static bool isUnsignedIntegerFormat(std::string_view format) {
1047 char code = format[0];
1048 return code ==
'I' || code ==
'B' || code ==
'H' || code ==
'L' ||
1052 static bool isSignedIntegerFormat(std::string_view format) {
1055 char code = format[0];
1056 return code ==
'i' || code ==
'b' || code ==
'h' || code ==
'l' ||
1061 getShapedType(std::optional<MlirType> bulkLoadElementType,
1062 std::optional<std::vector<int64_t>> explicitShape,
1065 if (explicitShape) {
1066 shape.append(explicitShape->begin(), explicitShape->end());
1068 shape.append(view.shape, view.shape + view.ndim);
1072 if (explicitShape) {
1073 throw std::invalid_argument(
"Shape can only be specified explicitly "
1074 "when the type is not a shaped type.");
1076 return *bulkLoadElementType;
1080 *bulkLoadElementType, encodingAttr);
1083 static MlirAttribute getAttributeFromBuffer(
1084 Py_buffer &view,
bool signless, std::optional<PyType> explicitType,
1085 const std::optional<std::vector<int64_t>> &explicitShape,
1086 MlirContext &context) {
1091 std::optional<MlirType> bulkLoadElementType;
1093 bulkLoadElementType = *explicitType;
1095 std::string_view format(view.format);
1096 if (format ==
"f") {
1098 assert(view.itemsize == 4 &&
"mismatched array itemsize");
1100 }
else if (format ==
"d") {
1102 assert(view.itemsize == 8 &&
"mismatched array itemsize");
1104 }
else if (format ==
"e") {
1106 assert(view.itemsize == 2 &&
"mismatched array itemsize");
1108 }
else if (format ==
"?") {
1111 return getBitpackedAttributeFromBooleanBuffer(view, explicitShape,
1113 }
else if (isSignedIntegerFormat(format)) {
1114 if (view.itemsize == 4) {
1116 bulkLoadElementType = signless
1119 }
else if (view.itemsize == 8) {
1121 bulkLoadElementType = signless
1124 }
else if (view.itemsize == 1) {
1128 }
else if (view.itemsize == 2) {
1130 bulkLoadElementType = signless
1134 }
else if (isUnsignedIntegerFormat(format)) {
1135 if (view.itemsize == 4) {
1137 bulkLoadElementType = signless
1140 }
else if (view.itemsize == 8) {
1142 bulkLoadElementType = signless
1145 }
else if (view.itemsize == 1) {
1147 bulkLoadElementType = signless
1150 }
else if (view.itemsize == 2) {
1152 bulkLoadElementType = signless
1157 if (!bulkLoadElementType) {
1158 throw std::invalid_argument(
1159 std::string(
"unimplemented array format conversion from format: ") +
1160 std::string(format));
1164 MlirType type = getShapedType(bulkLoadElementType, explicitShape, view);
1171 static MlirAttribute getBitpackedAttributeFromBooleanBuffer(
1172 Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
1173 MlirContext &context) {
1174 if (llvm::endianness::native != llvm::endianness::little) {
1177 throw nb::type_error(
"Constructing a bit-packed MLIR attribute is "
1178 "unsupported on big-endian systems");
1180 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> unpackedArray(
1181 static_cast<uint8_t *
>(view.buf),
1182 {static_cast<size_t>(view.len)});
1184 nb::module_ numpy = nb::module_::import_(
"numpy");
1185 nb::object packbitsFunc = numpy.attr(
"packbits");
1186 nb::object packedBooleans =
1187 packbitsFunc(nb::cast(unpackedArray),
"bitorder"_a =
"little");
1188 nb_buffer_info pythonBuffer = nb::cast<nb_buffer>(packedBooleans).request();
1191 std::move(explicitShape), view);
1192 assert(pythonBuffer.itemsize == 1 &&
"Packbits must return uint8");
1202 std::unique_ptr<nb_buffer_info> getBooleanBufferFromBitpackedAttribute() {
1203 if (llvm::endianness::native != llvm::endianness::little) {
1206 throw nb::type_error(
"Constructing a numpy array from a MLIR attribute "
1207 "is unsupported on big-endian systems");
1212 uint8_t *bitpackedData =
static_cast<uint8_t *
>(
1214 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> packedArray(
1216 {
static_cast<size_t>(numBitpackedBytes)});
1218 nb::module_ numpy = nb::module_::import_(
"numpy");
1219 nb::object unpackbitsFunc = numpy.attr(
"unpackbits");
1220 nb::object equalFunc = numpy.attr(
"equal");
1221 nb::object reshapeFunc = numpy.attr(
"reshape");
1222 nb::object unpackedBooleans =
1223 unpackbitsFunc(nb::cast(packedArray),
"bitorder"_a =
"little");
1230 unpackedBooleans = unpackedBooleans[nb::slice(
1231 nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
1232 unpackedBooleans = equalFunc(unpackedBooleans, 1);
1236 std::vector<intptr_t> shape(rank);
1237 for (intptr_t i = 0; i < rank; ++i) {
1240 unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
1244 nb_buffer pythonBuffer = nb::cast<nb_buffer>(unpackedBooleans);
1245 return std::make_unique<nb_buffer_info>(pythonBuffer.request());
1248 template <
typename Type>
1249 std::unique_ptr<nb_buffer_info>
1250 bufferInfo(MlirType shapedType,
const char *explicitFormat =
nullptr) {
1258 for (intptr_t i = 0; i < rank; ++i)
1264 strides.assign(rank, 0);
1266 for (intptr_t i = 1; i < rank; ++i) {
1267 intptr_t strideFactor = 1;
1268 for (intptr_t
j = i;
j < rank; ++
j)
1270 strides.push_back(
sizeof(
Type) * strideFactor);
1272 strides.push_back(
sizeof(
Type));
1275 if (explicitFormat) {
1276 format = explicitFormat;
1278 format = nb_format_descriptor<Type>::format();
1280 return std::make_unique<nb_buffer_info>(
1281 data,
sizeof(
Type), format, rank, std::move(shape), std::move(strides),
1286 PyType_Slot PyDenseElementsAttribute::slots[] = {
1288 #if PY_VERSION_HEX >= 0x03090000
1290 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_getbuffer)},
1291 {Py_bf_releasebuffer,
1292 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_releasebuffer)},
1297 int PyDenseElementsAttribute::bf_getbuffer(PyObject *obj,
1300 view->obj =
nullptr;
1301 std::unique_ptr<nb_buffer_info> info;
1303 auto *attr = nb::cast<PyDenseElementsAttribute *>(nb::handle(obj));
1304 info = attr->accessBuffer();
1305 }
catch (nb::python_error &e) {
1307 nb::chain_error(PyExc_BufferError,
"Error converting attribute to buffer");
1312 view->buf = info->ptr;
1313 view->itemsize = info->itemsize;
1314 view->len = info->itemsize;
1315 for (
auto s : info->shape) {
1318 view->readonly = info->readonly;
1319 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
1320 view->format =
const_cast<char *
>(info->format);
1322 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
1323 view->ndim =
static_cast<int>(info->ndim);
1324 view->strides = info->strides.data();
1325 view->shape = info->shape.data();
1327 view->suboffsets =
nullptr;
1328 view->internal = info.release();
1333 void PyDenseElementsAttribute::bf_releasebuffer(PyObject *,
1335 delete reinterpret_cast<nb_buffer_info *
>(view->internal);
1340 class PyDenseIntElementsAttribute
1342 PyDenseElementsAttribute> {
1345 static constexpr
const char *pyClassName =
"DenseIntElementsAttr";
1346 using PyConcreteAttribute::PyConcreteAttribute;
1350 nb::int_ dunderGetItem(intptr_t pos) {
1351 if (pos < 0 || pos >= dunderLen()) {
1352 throw nb::index_error(
"attempt to access out of bounds element");
1361 "dense int elements attribute");
1405 throw nb::type_error(
"Unsupported integer type");
1408 static void bindDerived(ClassTy &c) {
1409 c.def(
"__getitem__", &PyDenseIntElementsAttribute::dunderGetItem);
1415 #if PY_VERSION_HEX < 0x030d0000
1416 #define Py_IsFinalizing _Py_IsFinalizing
1419 class PyDenseResourceElementsAttribute
1422 static constexpr IsAFunctionTy isaFunction =
1424 static constexpr
const char *pyClassName =
"DenseResourceElementsAttr";
1425 using PyConcreteAttribute::PyConcreteAttribute;
1427 static PyDenseResourceElementsAttribute
1428 getFromBuffer(
const nb_buffer &buffer,
const std::string &name,
1429 const PyType &type, std::optional<size_t> alignment,
1432 throw std::invalid_argument(
1433 "Constructing a DenseResourceElementsAttr requires a ShapedType.");
1438 int flags = PyBUF_STRIDES;
1439 std::unique_ptr<Py_buffer> view = std::make_unique<Py_buffer>();
1440 if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
1441 throw nb::python_error();
1446 auto freeBuffer = llvm::make_scope_exit([&]() {
1448 PyBuffer_Release(view.get());
1451 if (!PyBuffer_IsContiguous(view.get(),
'A')) {
1452 throw std::invalid_argument(
"Contiguous buffer is required.");
1456 size_t inferredAlignment;
1458 inferredAlignment = *alignment;
1460 inferredAlignment = view->strides[view->ndim - 1];
1463 auto deleter = [](
void *userData,
const void *data,
size_t size,
1467 assert(Py_IsInitialized() &&
"expected interpreter to be initialized");
1468 Py_buffer *ownedView =
static_cast<Py_buffer *
>(userData);
1469 nb::gil_scoped_acquire gil;
1470 PyBuffer_Release(ownedView);
1474 size_t rawBufferSize = view->len;
1477 inferredAlignment, isMutable, deleter,
static_cast<void *
>(view.get()));
1479 throw std::invalid_argument(
1480 "DenseResourceElementsAttr could not be constructed from the given "
1482 "This may mean that the Python buffer layout does not match that "
1483 "MLIR expected layout and is a bug.");
1486 return PyDenseResourceElementsAttribute(contextWrapper->getRef(), attr);
1489 static void bindDerived(ClassTy &c) {
1490 c.def_static(
"get_from_buffer",
1491 PyDenseResourceElementsAttribute::getFromBuffer,
1492 nb::arg(
"array"), nb::arg(
"name"), nb::arg(
"type"),
1493 nb::arg(
"alignment") = nb::none(),
1494 nb::arg(
"is_mutable") =
false, nb::arg(
"context") = nb::none(),
1496 nb::sig(
"def get_from_buffer(array: typing_extensions.Buffer, name: str, type: Type, alignment: int | None = None, is_mutable: bool = False, context: Context | None = None) -> DenseResourceElementsAttr"),
1505 static constexpr
const char *pyClassName =
"DictAttr";
1506 using PyConcreteAttribute::PyConcreteAttribute;
1507 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1512 bool dunderContains(
const std::string &name) {
1517 static void bindDerived(ClassTy &c) {
1518 c.def(
"__contains__", &PyDictAttribute::dunderContains);
1519 c.def(
"__len__", &PyDictAttribute::dunderLen);
1524 mlirNamedAttributes.reserve(attributes.size());
1525 for (std::pair<nb::handle, nb::handle> it : attributes) {
1526 auto &mlirAttr = nb::cast<PyAttribute &>(it.second);
1527 auto name = nb::cast<std::string>(it.first);
1533 MlirAttribute attr =
1535 mlirNamedAttributes.data());
1536 return PyDictAttribute(context->getRef(), attr);
1538 nb::arg(
"value") = nb::dict(), nb::arg(
"context") = nb::none(),
1539 "Gets an uniqued dict attribute");
1540 c.def(
"__getitem__",
1541 [](PyDictAttribute &
self,
1542 const std::string &name) -> nb::typed<nb::object, PyAttribute> {
1543 MlirAttribute attr =
1546 throw nb::key_error(
"attempt to access a non-existent attribute");
1549 c.def(
"__getitem__", [](PyDictAttribute &
self, intptr_t index) {
1550 if (index < 0 || index >=
self.dunderLen()) {
1551 throw nb::index_error(
"attempt to access out of bounds attribute");
1563 class PyDenseFPElementsAttribute
1565 PyDenseElementsAttribute> {
1568 static constexpr
const char *pyClassName =
"DenseFPElementsAttr";
1569 using PyConcreteAttribute::PyConcreteAttribute;
1571 nb::float_ dunderGetItem(intptr_t pos) {
1572 if (pos < 0 || pos >= dunderLen()) {
1573 throw nb::index_error(
"attempt to access out of bounds element");
1589 throw nb::type_error(
"Unsupported floating-point type");
1592 static void bindDerived(ClassTy &c) {
1593 c.def(
"__getitem__", &PyDenseFPElementsAttribute::dunderGetItem);
1600 static constexpr
const char *pyClassName =
"TypeAttr";
1601 using PyConcreteAttribute::PyConcreteAttribute;
1602 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1605 static void bindDerived(ClassTy &c) {
1610 return PyTypeAttribute(context->getRef(), attr);
1612 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1613 "Gets a uniqued Type attribute");
1615 "value", [](PyTypeAttribute &
self) -> nb::typed<nb::object, PyType> {
1626 static constexpr
const char *pyClassName =
"UnitAttr";
1627 using PyConcreteAttribute::PyConcreteAttribute;
1628 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1631 static void bindDerived(ClassTy &c) {
1635 return PyUnitAttribute(context->getRef(),
1638 nb::arg(
"context") = nb::none(),
"Create a Unit attribute.");
1643 class PyStridedLayoutAttribute
1647 static constexpr
const char *pyClassName =
"StridedLayoutAttr";
1648 using PyConcreteAttribute::PyConcreteAttribute;
1649 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1652 static void bindDerived(ClassTy &c) {
1655 [](int64_t offset,
const std::vector<int64_t> &strides,
1658 ctx->
get(), offset, strides.size(), strides.data());
1659 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1661 nb::arg(
"offset"), nb::arg(
"strides"), nb::arg(
"context") = nb::none(),
1662 "Gets a strided layout attribute.");
1664 "get_fully_dynamic",
1667 std::vector<int64_t> strides(rank);
1668 llvm::fill(strides, dynamic);
1670 ctx->
get(), dynamic, strides.size(), strides.data());
1671 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1673 nb::arg(
"rank"), nb::arg(
"context") = nb::none(),
1674 "Gets a strided layout attribute with dynamic offset and strides of "
1679 [](PyStridedLayoutAttribute &
self) {
1682 "Returns the value of the float point attribute");
1685 [](PyStridedLayoutAttribute &
self) {
1687 std::vector<int64_t> strides(size);
1688 for (intptr_t i = 0; i < size; i++) {
1693 "Returns the value of the float point attribute");
1697 nb::object denseArrayAttributeCaster(
PyAttribute &pyAttribute) {
1698 if (PyDenseBoolArrayAttribute::isaFunction(pyAttribute))
1699 return nb::cast(PyDenseBoolArrayAttribute(pyAttribute));
1700 if (PyDenseI8ArrayAttribute::isaFunction(pyAttribute))
1701 return nb::cast(PyDenseI8ArrayAttribute(pyAttribute));
1702 if (PyDenseI16ArrayAttribute::isaFunction(pyAttribute))
1703 return nb::cast(PyDenseI16ArrayAttribute(pyAttribute));
1704 if (PyDenseI32ArrayAttribute::isaFunction(pyAttribute))
1705 return nb::cast(PyDenseI32ArrayAttribute(pyAttribute));
1706 if (PyDenseI64ArrayAttribute::isaFunction(pyAttribute))
1707 return nb::cast(PyDenseI64ArrayAttribute(pyAttribute));
1708 if (PyDenseF32ArrayAttribute::isaFunction(pyAttribute))
1709 return nb::cast(PyDenseF32ArrayAttribute(pyAttribute));
1710 if (PyDenseF64ArrayAttribute::isaFunction(pyAttribute))
1711 return nb::cast(PyDenseF64ArrayAttribute(pyAttribute));
1713 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1714 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1715 throw nb::type_error(msg.c_str());
1718 nb::object denseIntOrFPElementsAttributeCaster(
PyAttribute &pyAttribute) {
1719 if (PyDenseFPElementsAttribute::isaFunction(pyAttribute))
1720 return nb::cast(PyDenseFPElementsAttribute(pyAttribute));
1721 if (PyDenseIntElementsAttribute::isaFunction(pyAttribute))
1722 return nb::cast(PyDenseIntElementsAttribute(pyAttribute));
1725 "Can't cast unknown element type DenseIntOrFPElementsAttr (") +
1726 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1727 throw nb::type_error(msg.c_str());
1730 nb::object integerOrBoolAttributeCaster(
PyAttribute &pyAttribute) {
1731 if (PyBoolAttribute::isaFunction(pyAttribute))
1732 return nb::cast(PyBoolAttribute(pyAttribute));
1733 if (PyIntegerAttribute::isaFunction(pyAttribute))
1734 return nb::cast(PyIntegerAttribute(pyAttribute));
1735 std::string msg = std::string(
"Can't cast unknown attribute type Attr (") +
1736 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1738 throw nb::type_error(msg.c_str());
1741 nb::object symbolRefOrFlatSymbolRefAttributeCaster(
PyAttribute &pyAttribute) {
1742 if (PyFlatSymbolRefAttribute::isaFunction(pyAttribute))
1743 return nb::cast(PyFlatSymbolRefAttribute(pyAttribute));
1744 if (PySymbolRefAttribute::isaFunction(pyAttribute))
1745 return nb::cast(PySymbolRefAttribute(pyAttribute));
1746 std::string msg = std::string(
"Can't cast unknown SymbolRef attribute (") +
1747 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1749 throw nb::type_error(msg.c_str());
1754 void PyStringAttribute::bindDerived(ClassTy &c) {
1758 MlirAttribute attr =
1762 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1763 "Gets a uniqued string attribute");
1767 MlirAttribute attr =
1771 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1772 "Gets a uniqued string attribute");
1775 [](
PyType &type,
const std::string &value) {
1776 MlirAttribute attr =
1780 nb::arg(
"type"), nb::arg(
"value"),
1781 "Gets a uniqued string attribute associated to a type");
1786 return nb::str(stringRef.
data, stringRef.
length);
1788 "Returns the value of the string attribute");
1793 return nb::bytes(stringRef.
data, stringRef.
length);
1795 "Returns the value of the string attribute as `bytes`");
1799 PyAffineMapAttribute::bind(m);
1800 PyDenseBoolArrayAttribute::bind(m);
1801 PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
1802 PyDenseI8ArrayAttribute::bind(m);
1803 PyDenseI8ArrayAttribute::PyDenseArrayIterator::bind(m);
1804 PyDenseI16ArrayAttribute::bind(m);
1805 PyDenseI16ArrayAttribute::PyDenseArrayIterator::bind(m);
1806 PyDenseI32ArrayAttribute::bind(m);
1807 PyDenseI32ArrayAttribute::PyDenseArrayIterator::bind(m);
1808 PyDenseI64ArrayAttribute::bind(m);
1809 PyDenseI64ArrayAttribute::PyDenseArrayIterator::bind(m);
1810 PyDenseF32ArrayAttribute::bind(m);
1811 PyDenseF32ArrayAttribute::PyDenseArrayIterator::bind(m);
1812 PyDenseF64ArrayAttribute::bind(m);
1813 PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
1816 nb::cast<nb::callable>(nb::cpp_function(denseArrayAttributeCaster)));
1818 PyArrayAttribute::bind(m);
1819 PyArrayAttribute::PyArrayAttributeIterator::bind(m);
1820 PyBoolAttribute::bind(m);
1821 PyDenseElementsAttribute::bind(m, PyDenseElementsAttribute::slots);
1822 PyDenseFPElementsAttribute::bind(m);
1823 PyDenseIntElementsAttribute::bind(m);
1826 nb::cast<nb::callable>(
1827 nb::cpp_function(denseIntOrFPElementsAttributeCaster)));
1828 PyDenseResourceElementsAttribute::bind(m);
1830 PyDictAttribute::bind(m);
1831 PySymbolRefAttribute::bind(m);
1834 nb::cast<nb::callable>(
1835 nb::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster)));
1837 PyFlatSymbolRefAttribute::bind(m);
1838 PyOpaqueAttribute::bind(m);
1839 PyFloatAttribute::bind(m);
1840 PyIntegerAttribute::bind(m);
1841 PyIntegerSetAttribute::bind(m);
1842 PyStringAttribute::bind(m);
1843 PyTypeAttribute::bind(m);
1846 nb::cast<nb::callable>(nb::cpp_function(integerOrBoolAttributeCaster)));
1847 PyUnitAttribute::bind(m);
1849 PyStridedLayoutAttribute::bind(m);
static const char kDenseElementsAttrGetDocstring[]
static const char kDenseResourceElementsAttrGetFromBufferDocstring[]
static const char kDenseElementsAttrGetFromListDocstring[]
static MlirStringRef toMlirStringRef(const std::string &s)
static MLIRContext * getContext(OpFoldResult val)
static LogicalResult nextIndex(ArrayRef< int64_t > shape, MutableArrayRef< int64_t > index)
Walks over the indices of the elements of a tensor of a given shape by updating index in place to the...
std::string str() const
Converts the diagnostic to a string.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
PyMlirContextRef & getContext()
Accesses the context reference.
Used in function arguments when None should resolve to the current context manager set instance.
Used in function arguments when None should resolve to the current context manager set instance.
static PyMlirContext & resolve()
ReferrentTy * get() const
MlirAffineMap get() const
Wrapper around the generic MlirAttribute.
nanobind::object maybeDownCast()
MlirAttribute get() const
CRTP base classes for Python attributes that subclass Attribute and should be castable from it (i....
nanobind::class_< DerivedTy, BaseTy > ClassTy
MlirIntegerSet get() const
MlirContext get()
Accesses the underlying MlirContext.
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
Represents a Python MlirNamedAttr, carrying an optional owned name.
A TypeID provides an efficient and unique identifier for a specific C++ type.
Wrapper around the generic MlirType.
nanobind::object maybeDownCast()
mlir::Diagnostic & unwrap(MlirDiagnostic diagnostic)
MLIR_CAPI_EXPORTED MlirAttribute mlirAffineMapAttrGet(MlirAffineMap map)
Creates an affine map attribute wrapping the given map.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseFPElements(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAttribute mlirOpaqueAttrGet(MlirContext ctx, MlirStringRef dialectNamespace, intptr_t dataLength, const char *data, MlirType type)
Creates an opaque attribute in the given context associated with the dialect identified by its namesp...
MLIR_CAPI_EXPORTED MlirAttribute mlirFloatAttrDoubleGetChecked(MlirLocation loc, MlirType type, double value)
Same as "mlirFloatAttrDoubleGet", but if the type is not valid for a construction of a FloatAttr,...
MLIR_CAPI_EXPORTED int16_t mlirDenseI16ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED bool mlirAttributeIsAStridedLayout(MlirAttribute attr)
MLIR_CAPI_EXPORTED uint8_t mlirDenseElementsAttrGetUInt8Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED int64_t mlirStridedLayoutAttrGetOffset(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseI64Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapAttrGetValue(MlirAttribute attr)
Returns the affine map wrapped in the given affine map attribute.
MLIR_CAPI_EXPORTED int64_t mlirStridedLayoutAttrGetStride(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED int8_t mlirDenseElementsAttrGetInt8Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirAttribute mlirStridedLayoutAttrGet(MlirContext ctx, int64_t offset, intptr_t numStrides, const int64_t *strides)
MLIR_CAPI_EXPORTED bool mlirAttributeIsAUnit(MlirAttribute attr)
Checks whether the given attribute is a unit attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseElements(MlirAttribute attr)
Checks whether the given attribute is a dense elements attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAIntegerSet(MlirAttribute attr)
Checks whether the given attribute is an integer set attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAAffineMap(MlirAttribute attr)
Checks whether the given attribute is an affine map attribute.
MLIR_CAPI_EXPORTED int32_t mlirDenseI32ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED double mlirDenseF64ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirAttribute mlirFlatSymbolRefAttrGet(MlirContext ctx, MlirStringRef symbol)
Creates a flat symbol reference attribute in the given context referencing a symbol identified by the...
MLIR_CAPI_EXPORTED MlirTypeID mlirStridedLayoutAttrGetTypeID(void)
Returns the typeID of a StridedLayout attribute.
MLIR_CAPI_EXPORTED uint64_t mlirDenseElementsAttrGetIndexValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirTypeID mlirIntegerAttrGetTypeID(void)
Returns the typeID of an Integer attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseResourceElements(MlirAttribute attr)
MLIR_CAPI_EXPORTED int16_t mlirDenseElementsAttrGetInt16Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolRefAttrGetRootReference(MlirAttribute attr)
Returns the string reference to the root referenced symbol.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAType(MlirAttribute attr)
Checks whether the given attribute is a type attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirDenseIntOrFPElementsAttrGetTypeID(void)
Returns the typeID of an DenseIntOrFPElements attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseIntElements(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool mlirAttributeIsAArray(MlirAttribute attr)
Checks whether the given attribute is an array attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAInteger(MlirAttribute attr)
Checks whether the given attribute is an integer attribute.
MLIR_CAPI_EXPORTED intptr_t mlirDictionaryAttrGetNumElements(MlirAttribute attr)
Returns the number of attributes contained in a dictionary attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirIntegerSetAttrGet(MlirIntegerSet set)
Creates an integer set attribute wrapping the given set.
MLIR_CAPI_EXPORTED uint16_t mlirDenseElementsAttrGetUInt16Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED uint64_t mlirDenseElementsAttrGetUInt64Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED bool mlirBoolAttrGetValue(MlirAttribute attr)
Returns the value stored in the given bool attribute.
MLIR_CAPI_EXPORTED int64_t mlirDenseI64ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirAttribute mlirIntegerAttrGet(MlirType type, int64_t value)
Creates an integer attribute of the given type with the given integer value.
MLIR_CAPI_EXPORTED MlirTypeID mlirIntegerSetAttrGetTypeID(void)
Returns the typeID of an IntegerSet attribute.
MLIR_CAPI_EXPORTED bool mlirDenseElementsAttrGetBoolValue(MlirAttribute attr, intptr_t pos)
Returns the pos-th value (flat contiguous indexing) of a specific type contained by the given dense e...
MLIR_CAPI_EXPORTED MlirAttribute mlirDictionaryAttrGet(MlirContext ctx, intptr_t numElements, MlirNamedAttribute const *elements)
Creates a dictionary attribute containing the given list of elements in the provided context.
MLIR_CAPI_EXPORTED MlirAttribute mlirUnmanagedDenseResourceElementsAttrGet(MlirType shapedType, MlirStringRef name, void *data, size_t dataLength, size_t dataAlignment, bool dataIsMutable, void(*deleter)(void *userData, const void *data, size_t size, size_t align), void *userData)
Unlike the typed accessors below, constructs the attribute with a raw data buffer and no type/alignme...
MLIR_CAPI_EXPORTED bool mlirAttributeIsABool(MlirAttribute attr)
Checks whether the given attribute is a bool attribute.
MLIR_CAPI_EXPORTED bool mlirDenseBoolArrayGetElement(MlirAttribute attr, intptr_t pos)
Get an element of a dense array.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI64ArrayGet(MlirContext ctx, intptr_t size, int64_t const *values)
MLIR_CAPI_EXPORTED MlirTypeID mlirAffineMapAttrGetTypeID(void)
Returns the typeID of an AffineMap attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolRefAttrGetNestedReference(MlirAttribute attr, intptr_t pos)
Returns pos-th reference nested in the given symbol reference attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirArrayAttrGetTypeID(void)
Returns the typeID of an Array attribute.
MLIR_CAPI_EXPORTED float mlirDenseF32ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseF64ArrayGet(MlirContext ctx, intptr_t size, double const *values)
MLIR_CAPI_EXPORTED int64_t mlirIntegerAttrGetValueInt(MlirAttribute attr)
Returns the value stored in the given integer attribute, assuming the value is of signless type and f...
MLIR_CAPI_EXPORTED intptr_t mlirSymbolRefAttrGetNumNestedReferences(MlirAttribute attr)
Returns the number of references nested in the given symbol reference attribute.
MLIR_CAPI_EXPORTED MlirType mlirTypeAttrGetValue(MlirAttribute attr)
Returns the type stored in the given type attribute.
MLIR_CAPI_EXPORTED bool mlirDenseElementsAttrIsSplat(MlirAttribute attr)
Checks whether the given dense elements attribute contains a single replicated value (splat).
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseElementsAttrGet(MlirType shapedType, intptr_t numElements, MlirAttribute const *elements)
Creates a dense elements attribute with the given Shaped type and elements in the same context as the...
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseBoolArray(MlirAttribute attr)
Checks whether the given attribute is a dense array attribute.
MLIR_CAPI_EXPORTED MlirStringRef mlirOpaqueAttrGetData(MlirAttribute attr)
Returns the raw data as a string reference.
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeGetNull(void)
Returns an empty attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirBoolAttrGet(MlirContext ctx, int value)
Creates a bool attribute in the given context with the given value.
MLIR_CAPI_EXPORTED MlirTypeID mlirFloatAttrGetTypeID(void)
Returns the typeID of a Float attribute.
MLIR_CAPI_EXPORTED int64_t mlirIntegerAttrGetValueSInt(MlirAttribute attr)
Returns the value stored in the given integer attribute, assuming the value is of signed type and fit...
MLIR_CAPI_EXPORTED int8_t mlirDenseI8ArrayGetElement(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI32ArrayGet(MlirContext ctx, intptr_t size, int32_t const *values)
MLIR_CAPI_EXPORTED int64_t mlirDenseElementsAttrGetInt64Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirDictionaryAttrGetElement(MlirAttribute attr, intptr_t pos)
Returns pos-th element of the given dictionary attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirUnitAttrGetTypeID(void)
Returns the typeID of a Unit attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseF32ArrayGet(MlirContext ctx, intptr_t size, float const *values)
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseBoolArrayGet(MlirContext ctx, intptr_t size, int const *values)
Create a dense array attribute with the given elements.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAOpaque(MlirAttribute attr)
Checks whether the given attribute is an opaque attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirArrayAttrGetElement(MlirAttribute attr, intptr_t pos)
Returns pos-th element stored in the given array attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirDictionaryAttrGetElementByName(MlirAttribute attr, MlirStringRef name)
Returns the dictionary attribute element with the given name or NULL if the given name does not exist...
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseF32Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirTypeID mlirSymbolRefAttrGetTypeID(void)
Returns the typeID of an SymbolRef attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirDenseArrayAttrGetTypeID(void)
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseElementsAttrGetSplatValue(MlirAttribute attr)
Returns the single replicated value (splat) of a specific type contained by the given dense elements ...
MLIR_CAPI_EXPORTED bool mlirAttributeIsASymbolRef(MlirAttribute attr)
Checks whether the given attribute is a symbol reference attribute.
MLIR_CAPI_EXPORTED float mlirDenseElementsAttrGetFloatValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED int64_t mlirElementsAttrGetNumElements(MlirAttribute attr)
Gets the total number of elements in the given elements attribute.
MLIR_CAPI_EXPORTED MlirStringRef mlirOpaqueAttrGetDialectNamespace(MlirAttribute attr)
Returns the namespace of the dialect with which the given opaque attribute is associated.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADictionary(MlirAttribute attr)
Checks whether the given attribute is a dictionary attribute.
MLIR_CAPI_EXPORTED int32_t mlirDenseElementsAttrGetInt32Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirStringRef mlirStringAttrGetValue(MlirAttribute attr)
Returns the attribute values as a string reference.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI16ArrayGet(MlirContext ctx, intptr_t size, int16_t const *values)
MLIR_CAPI_EXPORTED MlirTypeID mlirOpaqueAttrGetTypeID(void)
Returns the typeID of an Opaque attribute.
MLIR_CAPI_EXPORTED double mlirFloatAttrGetValueDouble(MlirAttribute attr)
Returns the value stored in the given floating point attribute, interpreting the value as double.
MLIR_CAPI_EXPORTED uint64_t mlirIntegerAttrGetValueUInt(MlirAttribute attr)
Returns the value stored in the given integer attribute, assuming the value is of unsigned type and f...
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI8ArrayGet(MlirContext ctx, intptr_t size, int8_t const *values)
MLIR_CAPI_EXPORTED MlirAttribute mlirUnitAttrGet(MlirContext ctx)
Creates a unit attribute in the given context.
MLIR_CAPI_EXPORTED double mlirDenseElementsAttrGetDoubleValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED intptr_t mlirStridedLayoutAttrGetNumStrides(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAttribute mlirFloatAttrDoubleGet(MlirContext ctx, MlirType type, double value)
Creates a floating point attribute in the given context with the given double value and double-precis...
MLIR_CAPI_EXPORTED MlirAttribute mlirArrayAttrGet(MlirContext ctx, intptr_t numElements, MlirAttribute const *elements)
Creates an array element containing the given list of elements in the given context.
MLIR_CAPI_EXPORTED const void * mlirDenseElementsAttrGetRawData(MlirAttribute attr)
Returns the raw data of the given dense elements attribute.
MLIR_CAPI_EXPORTED intptr_t mlirDenseArrayGetNumElements(MlirAttribute attr)
Get the size of a dense array.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAFloat(MlirAttribute attr)
Checks whether the given attribute is a floating point attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolRefAttrGet(MlirContext ctx, MlirStringRef symbol, intptr_t numReferences, MlirAttribute const *references)
Creates a symbol reference attribute in the given context referencing a symbol identified by the give...
MLIR_CAPI_EXPORTED MlirTypeID mlirTypeAttrGetTypeID(void)
Returns the typeID of a Type attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseElementsAttrSplatGet(MlirType shapedType, MlirAttribute element)
Creates a dense elements attribute with the given Shaped type containing a single replicated element ...
MLIR_CAPI_EXPORTED MlirTypeID mlirDictionaryAttrGetTypeID(void)
Returns the typeID of a Dictionary attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrGet(MlirContext ctx, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED MlirAttribute mlirTypeAttrGet(MlirType type)
Creates a type attribute wrapping the given type in the same context as the type.
MLIR_CAPI_EXPORTED intptr_t mlirArrayAttrGetNumElements(MlirAttribute attr)
Returns the number of elements stored in the given array attribute.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseElementsAttrRawBufferGet(MlirType shapedType, size_t rawBufferSize, const void *rawBuffer)
Creates a dense elements attribute with the given Shaped type and elements populated from a packed,...
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseI32Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseI8Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrTypedGet(MlirType type, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAFlatSymbolRef(MlirAttribute attr)
Checks whether the given attribute is a flat symbol reference attribute.
MLIR_CAPI_EXPORTED MlirStringRef mlirFlatSymbolRefAttrGetValue(MlirAttribute attr)
Returns the referenced symbol as a string reference.
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseI16Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool mlirAttributeIsADenseF64Array(MlirAttribute attr)
MLIR_CAPI_EXPORTED uint32_t mlirDenseElementsAttrGetUInt32Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED MlirType mlirRankedTensorTypeGet(intptr_t rank, const int64_t *shape, MlirType elementType, MlirAttribute encoding)
Creates a tensor type of a fixed rank with the given shape, element type, and optional encoding in th...
MLIR_CAPI_EXPORTED bool mlirIntegerTypeIsSignless(MlirType type)
Checks whether the given integer type is signless.
MLIR_CAPI_EXPORTED bool mlirTypeIsAInteger(MlirType type)
Checks whether the given type is an integer type.
MLIR_CAPI_EXPORTED int64_t mlirShapedTypeGetDimSize(MlirType type, intptr_t dim)
Returns the dim-th dimension of the given ranked shaped type.
MLIR_CAPI_EXPORTED MlirType mlirIntegerTypeGet(MlirContext ctx, unsigned bitwidth)
Creates a signless integer type of the given bitwidth in the context.
MLIR_CAPI_EXPORTED bool mlirIntegerTypeIsUnsigned(MlirType type)
Checks whether the given integer type is unsigned.
MLIR_CAPI_EXPORTED unsigned mlirIntegerTypeGetWidth(MlirType type)
Returns the bitwidth of an integer type.
MLIR_CAPI_EXPORTED int64_t mlirShapedTypeGetRank(MlirType type)
Returns the rank of the given ranked shaped type.
MLIR_CAPI_EXPORTED MlirType mlirF64TypeGet(MlirContext ctx)
Creates a f64 type in the given context.
MLIR_CAPI_EXPORTED MlirType mlirIntegerTypeSignedGet(MlirContext ctx, unsigned bitwidth)
Creates a signed integer type of the given bitwidth in the context.
MLIR_CAPI_EXPORTED MlirType mlirF16TypeGet(MlirContext ctx)
Creates an f16 type in the given context.
MLIR_CAPI_EXPORTED bool mlirTypeIsAF64(MlirType type)
Checks whether the given type is an f64 type.
MLIR_CAPI_EXPORTED bool mlirTypeIsAF16(MlirType type)
Checks whether the given type is an f16 type.
MLIR_CAPI_EXPORTED bool mlirIntegerTypeIsSigned(MlirType type)
Checks whether the given integer type is signed.
MLIR_CAPI_EXPORTED MlirType mlirShapedTypeGetElementType(MlirType type)
Returns the element type of the shaped type.
MLIR_CAPI_EXPORTED bool mlirShapedTypeHasStaticShape(MlirType type)
Checks whether the given shaped type has a static shape.
MLIR_CAPI_EXPORTED MlirType mlirF32TypeGet(MlirContext ctx)
Creates an f32 type in the given context.
MLIR_CAPI_EXPORTED bool mlirTypeIsAShaped(MlirType type)
Checks whether the given type is a Shaped type.
MLIR_CAPI_EXPORTED MlirType mlirIntegerTypeUnsignedGet(MlirContext ctx, unsigned bitwidth)
Creates an unsigned integer type of the given bitwidth in the context.
MLIR_CAPI_EXPORTED bool mlirTypeIsAF32(MlirType type)
Checks whether the given type is an f32 type.
MLIR_CAPI_EXPORTED bool mlirTypeIsAIndex(MlirType type)
Checks whether the given type is an index type.
MLIR_CAPI_EXPORTED int64_t mlirShapedTypeGetDynamicStrideOrOffset(void)
Returns the value indicating a dynamic stride or offset in a shaped type.
static bool mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, MlirAttribute attr)
Associates an attribute with the name. Takes ownership of neither.
MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident)
Gets the string value of the identifier.
MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute)
Gets the type of this attribute.
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2)
Checks if two types are equal.
MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Gets the context that an attribute was created with.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator)
Divides the known min value of the numerator by the denominator and rounds the result up to the next ...
void populateIRAttributes(nanobind::module_ &m)
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.
Custom exception that allows access to error diagnostic information.
RAII object that captures any error diagnostics emitted to the provided context.
std::vector< PyDiagnostic::DiagnosticInfo > take()
Eliminates variable at the specified position using Fourier-Motzkin variable elimination.