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::object 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, intptr_t i) {
531 throw nb::index_error(
"ArrayAttribute index out of range");
535 [](
const PyArrayAttribute &arr) {
538 .def(
"__iter__", [](
const PyArrayAttribute &arr) {
539 return PyArrayAttributeIterator(arr);
541 c.def(
"__add__", [](PyArrayAttribute arr,
const nb::list &extras) {
542 std::vector<MlirAttribute> attributes;
544 attributes.reserve(numOldElements + nb::len(extras));
545 for (intptr_t i = 0; i < numOldElements; ++i)
546 attributes.push_back(arr.getItem(i));
547 for (nb::handle attr : extras)
548 attributes.push_back(pyTryCast<PyAttribute>(attr));
550 arr.getContext()->get(), attributes.size(), attributes.data());
551 return PyArrayAttribute(arr.getContext(), arrayAttr);
560 static constexpr
const char *pyClassName =
"FloatAttr";
561 using PyConcreteAttribute::PyConcreteAttribute;
562 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
565 static void bindDerived(ClassTy &c) {
573 return PyFloatAttribute(type.
getContext(), attr);
575 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"loc") = nb::none(),
576 "Gets an uniqued float point attribute associated to a type");
582 return PyFloatAttribute(context->getRef(), attr);
584 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
585 "Gets an uniqued float point attribute associated to a f32 type");
591 return PyFloatAttribute(context->getRef(), attr);
593 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
594 "Gets an uniqued float point attribute associated to a f64 type");
596 "Returns the value of the float attribute");
598 "Converts the value of the float attribute to a Python float");
606 static constexpr
const char *pyClassName =
"IntegerAttr";
607 using PyConcreteAttribute::PyConcreteAttribute;
609 static void bindDerived(ClassTy &c) {
612 [](
PyType &type, int64_t value) {
614 return PyIntegerAttribute(type.
getContext(), attr);
616 nb::arg(
"type"), nb::arg(
"value"),
617 "Gets an uniqued integer attribute associated to a type");
618 c.def_prop_ro(
"value", toPyInt,
619 "Returns the value of the integer attribute");
620 c.def(
"__int__", toPyInt,
621 "Converts the value of the integer attribute to a Python int");
622 c.def_prop_ro_static(
627 nanobind::sig(
"def static_typeid(/) -> TypeID"));
631 static int64_t toPyInt(PyIntegerAttribute &
self) {
645 static constexpr
const char *pyClassName =
"BoolAttr";
646 using PyConcreteAttribute::PyConcreteAttribute;
648 static void bindDerived(ClassTy &c) {
653 return PyBoolAttribute(context->getRef(), attr);
655 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
656 "Gets an uniqued bool attribute");
658 "Returns the value of the bool attribute");
660 "Converts the value of the bool attribute to a Python bool");
667 static constexpr
const char *pyClassName =
"SymbolRefAttr";
668 using PyConcreteAttribute::PyConcreteAttribute;
670 static PySymbolRefAttribute fromList(
const std::vector<std::string> &symbols,
673 throw std::runtime_error(
"SymbolRefAttr must be composed of at least "
677 for (
size_t i = 1; i < symbols.size(); ++i) {
678 referenceAttrs.push_back(
681 return PySymbolRefAttribute(context.
getRef(),
683 referenceAttrs.size(),
684 referenceAttrs.data()));
687 static void bindDerived(ClassTy &c) {
690 [](
const std::vector<std::string> &symbols,
692 return PySymbolRefAttribute::fromList(symbols, context.
resolve());
694 nb::arg(
"symbols"), nb::arg(
"context") = nb::none(),
695 "Gets a uniqued SymbolRef attribute from a list of symbol names");
698 [](PySymbolRefAttribute &
self) {
699 std::vector<std::string> symbols = {
709 "Returns the value of the SymbolRef attribute as a list[str]");
713 class PyFlatSymbolRefAttribute
717 static constexpr
const char *pyClassName =
"FlatSymbolRefAttr";
718 using PyConcreteAttribute::PyConcreteAttribute;
720 static void bindDerived(ClassTy &c) {
726 return PyFlatSymbolRefAttribute(context->getRef(), attr);
728 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
729 "Gets a uniqued FlatSymbolRef attribute");
732 [](PyFlatSymbolRefAttribute &
self) {
734 return nb::str(stringRef.
data, stringRef.
length);
736 "Returns the value of the FlatSymbolRef attribute as a string");
743 static constexpr
const char *pyClassName =
"OpaqueAttr";
744 using PyConcreteAttribute::PyConcreteAttribute;
745 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
748 static void bindDerived(ClassTy &c) {
751 [](
const std::string &dialectNamespace,
const nb_buffer &buffer,
753 const nb_buffer_info bufferInfo = buffer.request();
754 intptr_t bufferSize = bufferInfo.size;
757 static_cast<char *
>(bufferInfo.ptr), type);
758 return PyOpaqueAttribute(context->getRef(), attr);
760 nb::arg(
"dialect_namespace"), nb::arg(
"buffer"), nb::arg(
"type"),
761 nb::arg(
"context") = nb::none(),
763 nb::sig(
"def get(dialect_namespace: str, buffer: typing_extensions.Buffer, type: Type, context: Context | None = None) -> OpaqueAttr"),
765 "Gets an Opaque attribute.");
768 [](PyOpaqueAttribute &
self) {
770 return nb::str(stringRef.
data, stringRef.
length);
772 "Returns the dialect namespace for the Opaque attribute as a string");
775 [](PyOpaqueAttribute &
self) {
777 return nb::bytes(stringRef.
data, stringRef.
length);
779 "Returns the data for the Opaqued attributes as `bytes`");
784 class PyDenseElementsAttribute
788 static constexpr
const char *pyClassName =
"DenseElementsAttr";
789 using PyConcreteAttribute::PyConcreteAttribute;
791 static PyDenseElementsAttribute
792 getFromList(
const nb::list &attributes, std::optional<PyType> explicitType,
794 const size_t numAttributes = nb::len(attributes);
795 if (numAttributes == 0)
796 throw nb::value_error(
"Attributes list must be non-empty.");
804 llvm::raw_string_ostream os(message);
805 os <<
"Expected a static ShapedType for the shaped_type parameter: "
806 << nb::cast<std::string>(nb::repr(nb::cast(*explicitType)));
807 throw nb::value_error(message.c_str());
809 shapedType = *explicitType;
813 shape.size(), shape.data(),
819 mlirAttributes.reserve(numAttributes);
820 for (
const nb::handle &attribute : attributes) {
821 MlirAttribute mlirAttribute = pyTryCast<PyAttribute>(attribute);
823 mlirAttributes.push_back(mlirAttribute);
827 llvm::raw_string_ostream os(message);
828 os <<
"All attributes must be of the same type and match "
829 <<
"the type parameter: expected="
830 << nb::cast<std::string>(nb::repr(nb::cast(shapedType)))
832 << nb::cast<std::string>(nb::repr(nb::cast(attrType)));
833 throw nb::value_error(message.c_str());
838 shapedType, mlirAttributes.size(), mlirAttributes.data());
840 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
843 static PyDenseElementsAttribute
844 getFromBuffer(
const nb_buffer &array,
bool signless,
845 const std::optional<PyType> &explicitType,
846 std::optional<std::vector<int64_t>> explicitShape,
849 int flags = PyBUF_ND;
851 flags |= PyBUF_FORMAT;
854 if (PyObject_GetBuffer(array.ptr(), &view, flags) != 0) {
855 throw nb::python_error();
857 auto freeBuffer = llvm::make_scope_exit([&]() { PyBuffer_Release(&view); });
859 MlirContext context = contextWrapper->
get();
860 MlirAttribute attr = getAttributeFromBuffer(
861 view, signless, explicitType, std::move(explicitShape), context);
863 throw std::invalid_argument(
864 "DenseElementsAttr could not be constructed from the given buffer. "
865 "This may mean that the Python buffer layout does not match that "
866 "MLIR expected layout and is a bug.");
868 return PyDenseElementsAttribute(contextWrapper->getRef(), attr);
871 static PyDenseElementsAttribute getSplat(
const PyType &shapedType,
873 auto contextWrapper =
877 std::string message =
"Illegal element type for DenseElementsAttr: ";
878 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
879 throw nb::value_error(message.c_str());
883 std::string message =
884 "Expected a static ShapedType for the shaped_type parameter: ";
885 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
886 throw nb::value_error(message.c_str());
891 std::string message =
892 "Shaped element type and attribute type must be equal: shaped=";
893 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
894 message.append(
", element=");
895 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
896 throw nb::value_error(message.c_str());
899 MlirAttribute elements =
901 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
906 std::unique_ptr<nb_buffer_info> accessBuffer() {
913 return bufferInfo<float>(shapedType);
917 return bufferInfo<double>(shapedType);
921 return bufferInfo<uint16_t>(shapedType,
"e");
925 return bufferInfo<int64_t>(shapedType);
932 return bufferInfo<int32_t>(shapedType);
936 return bufferInfo<uint32_t>(shapedType);
943 return bufferInfo<int64_t>(shapedType);
947 return bufferInfo<uint64_t>(shapedType);
954 return bufferInfo<int8_t>(shapedType);
958 return bufferInfo<uint8_t>(shapedType);
965 return bufferInfo<int16_t>(shapedType);
969 return bufferInfo<uint16_t>(shapedType);
977 return getBooleanBufferFromBitpackedAttribute();
982 throw std::invalid_argument(
983 "unsupported data type for conversion to Python buffer");
986 static void bindDerived(ClassTy &c) {
987 #if PY_VERSION_HEX < 0x03090000
988 PyTypeObject *tp =
reinterpret_cast<PyTypeObject *
>(c.ptr());
989 tp->tp_as_buffer->bf_getbuffer = PyDenseElementsAttribute::bf_getbuffer;
990 tp->tp_as_buffer->bf_releasebuffer =
991 PyDenseElementsAttribute::bf_releasebuffer;
993 c.def(
"__len__", &PyDenseElementsAttribute::dunderLen)
995 "get", PyDenseElementsAttribute::getFromBuffer, nb::arg(
"array"),
996 nb::arg(
"signless") =
true, nb::arg(
"type") = nb::none(),
997 nb::arg(
"shape") = nb::none(), nb::arg(
"context") = nb::none(),
999 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"),
1002 .def_static(
"get", PyDenseElementsAttribute::getFromList,
1003 nb::arg(
"attrs"), nb::arg(
"type") = nb::none(),
1004 nb::arg(
"context") = nb::none(),
1006 .def_static(
"get_splat", PyDenseElementsAttribute::getSplat,
1007 nb::arg(
"shaped_type"), nb::arg(
"element_attr"),
1008 "Gets a DenseElementsAttr where all values are the same")
1009 .def_prop_ro(
"is_splat",
1010 [](PyDenseElementsAttribute &
self) ->
bool {
1013 .def(
"get_splat_value", [](PyDenseElementsAttribute &
self) {
1015 throw nb::value_error(
1016 "get_splat_value called on a non-splat attribute");
1023 static PyType_Slot slots[];
1026 static int bf_getbuffer(PyObject *exporter, Py_buffer *view,
int flags);
1027 static void bf_releasebuffer(PyObject *, Py_buffer *buffer);
1029 static bool isUnsignedIntegerFormat(std::string_view format) {
1032 char code = format[0];
1033 return code ==
'I' || code ==
'B' || code ==
'H' || code ==
'L' ||
1037 static bool isSignedIntegerFormat(std::string_view format) {
1040 char code = format[0];
1041 return code ==
'i' || code ==
'b' || code ==
'h' || code ==
'l' ||
1046 getShapedType(std::optional<MlirType> bulkLoadElementType,
1047 std::optional<std::vector<int64_t>> explicitShape,
1050 if (explicitShape) {
1051 shape.append(explicitShape->begin(), explicitShape->end());
1053 shape.append(view.shape, view.shape + view.ndim);
1057 if (explicitShape) {
1058 throw std::invalid_argument(
"Shape can only be specified explicitly "
1059 "when the type is not a shaped type.");
1061 return *bulkLoadElementType;
1065 *bulkLoadElementType, encodingAttr);
1068 static MlirAttribute getAttributeFromBuffer(
1069 Py_buffer &view,
bool signless, std::optional<PyType> explicitType,
1070 const std::optional<std::vector<int64_t>> &explicitShape,
1071 MlirContext &context) {
1076 std::optional<MlirType> bulkLoadElementType;
1078 bulkLoadElementType = *explicitType;
1080 std::string_view format(view.format);
1081 if (format ==
"f") {
1083 assert(view.itemsize == 4 &&
"mismatched array itemsize");
1085 }
else if (format ==
"d") {
1087 assert(view.itemsize == 8 &&
"mismatched array itemsize");
1089 }
else if (format ==
"e") {
1091 assert(view.itemsize == 2 &&
"mismatched array itemsize");
1093 }
else if (format ==
"?") {
1096 return getBitpackedAttributeFromBooleanBuffer(view, explicitShape,
1098 }
else if (isSignedIntegerFormat(format)) {
1099 if (view.itemsize == 4) {
1101 bulkLoadElementType = signless
1104 }
else if (view.itemsize == 8) {
1106 bulkLoadElementType = signless
1109 }
else if (view.itemsize == 1) {
1113 }
else if (view.itemsize == 2) {
1115 bulkLoadElementType = signless
1119 }
else if (isUnsignedIntegerFormat(format)) {
1120 if (view.itemsize == 4) {
1122 bulkLoadElementType = signless
1125 }
else if (view.itemsize == 8) {
1127 bulkLoadElementType = signless
1130 }
else if (view.itemsize == 1) {
1132 bulkLoadElementType = signless
1135 }
else if (view.itemsize == 2) {
1137 bulkLoadElementType = signless
1142 if (!bulkLoadElementType) {
1143 throw std::invalid_argument(
1144 std::string(
"unimplemented array format conversion from format: ") +
1145 std::string(format));
1149 MlirType type = getShapedType(bulkLoadElementType, explicitShape, view);
1156 static MlirAttribute getBitpackedAttributeFromBooleanBuffer(
1157 Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
1158 MlirContext &context) {
1159 if (llvm::endianness::native != llvm::endianness::little) {
1162 throw nb::type_error(
"Constructing a bit-packed MLIR attribute is "
1163 "unsupported on big-endian systems");
1165 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> unpackedArray(
1166 static_cast<uint8_t *
>(view.buf),
1167 {static_cast<size_t>(view.len)});
1169 nb::module_ numpy = nb::module_::import_(
"numpy");
1170 nb::object packbitsFunc = numpy.attr(
"packbits");
1171 nb::object packedBooleans =
1172 packbitsFunc(nb::cast(unpackedArray),
"bitorder"_a =
"little");
1173 nb_buffer_info pythonBuffer = nb::cast<nb_buffer>(packedBooleans).request();
1176 std::move(explicitShape), view);
1177 assert(pythonBuffer.itemsize == 1 &&
"Packbits must return uint8");
1187 std::unique_ptr<nb_buffer_info> getBooleanBufferFromBitpackedAttribute() {
1188 if (llvm::endianness::native != llvm::endianness::little) {
1191 throw nb::type_error(
"Constructing a numpy array from a MLIR attribute "
1192 "is unsupported on big-endian systems");
1197 uint8_t *bitpackedData =
static_cast<uint8_t *
>(
1199 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> packedArray(
1201 {
static_cast<size_t>(numBitpackedBytes)});
1203 nb::module_ numpy = nb::module_::import_(
"numpy");
1204 nb::object unpackbitsFunc = numpy.attr(
"unpackbits");
1205 nb::object equalFunc = numpy.attr(
"equal");
1206 nb::object reshapeFunc = numpy.attr(
"reshape");
1207 nb::object unpackedBooleans =
1208 unpackbitsFunc(nb::cast(packedArray),
"bitorder"_a =
"little");
1215 unpackedBooleans = unpackedBooleans[nb::slice(
1216 nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
1217 unpackedBooleans = equalFunc(unpackedBooleans, 1);
1221 std::vector<intptr_t> shape(rank);
1222 for (intptr_t i = 0; i < rank; ++i) {
1225 unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
1229 nb_buffer pythonBuffer = nb::cast<nb_buffer>(unpackedBooleans);
1230 return std::make_unique<nb_buffer_info>(pythonBuffer.request());
1233 template <
typename Type>
1234 std::unique_ptr<nb_buffer_info>
1235 bufferInfo(MlirType shapedType,
const char *explicitFormat =
nullptr) {
1243 for (intptr_t i = 0; i < rank; ++i)
1249 strides.assign(rank, 0);
1251 for (intptr_t i = 1; i < rank; ++i) {
1252 intptr_t strideFactor = 1;
1253 for (intptr_t
j = i;
j < rank; ++
j)
1255 strides.push_back(
sizeof(
Type) * strideFactor);
1257 strides.push_back(
sizeof(
Type));
1260 if (explicitFormat) {
1261 format = explicitFormat;
1263 format = nb_format_descriptor<Type>::format();
1265 return std::make_unique<nb_buffer_info>(
1266 data,
sizeof(
Type), format, rank, std::move(shape), std::move(strides),
1271 PyType_Slot PyDenseElementsAttribute::slots[] = {
1273 #if PY_VERSION_HEX >= 0x03090000
1275 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_getbuffer)},
1276 {Py_bf_releasebuffer,
1277 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_releasebuffer)},
1282 int PyDenseElementsAttribute::bf_getbuffer(PyObject *obj,
1285 view->obj =
nullptr;
1286 std::unique_ptr<nb_buffer_info> info;
1288 auto *attr = nb::cast<PyDenseElementsAttribute *>(nb::handle(obj));
1289 info = attr->accessBuffer();
1290 }
catch (nb::python_error &e) {
1292 nb::chain_error(PyExc_BufferError,
"Error converting attribute to buffer");
1297 view->buf = info->ptr;
1298 view->itemsize = info->itemsize;
1299 view->len = info->itemsize;
1300 for (
auto s : info->shape) {
1303 view->readonly = info->readonly;
1304 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
1305 view->format =
const_cast<char *
>(info->format);
1307 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
1308 view->ndim =
static_cast<int>(info->ndim);
1309 view->strides = info->strides.data();
1310 view->shape = info->shape.data();
1312 view->suboffsets =
nullptr;
1313 view->internal = info.release();
1318 void PyDenseElementsAttribute::bf_releasebuffer(PyObject *,
1320 delete reinterpret_cast<nb_buffer_info *
>(view->internal);
1325 class PyDenseIntElementsAttribute
1327 PyDenseElementsAttribute> {
1330 static constexpr
const char *pyClassName =
"DenseIntElementsAttr";
1331 using PyConcreteAttribute::PyConcreteAttribute;
1335 nb::object dunderGetItem(intptr_t pos) {
1336 if (pos < 0 || pos >= dunderLen()) {
1337 throw nb::index_error(
"attempt to access out of bounds element");
1346 "dense int elements attribute");
1390 throw nb::type_error(
"Unsupported integer type");
1393 static void bindDerived(ClassTy &c) {
1394 c.def(
"__getitem__", &PyDenseIntElementsAttribute::dunderGetItem);
1400 #if PY_VERSION_HEX < 0x030d0000
1401 #define Py_IsFinalizing _Py_IsFinalizing
1404 class PyDenseResourceElementsAttribute
1407 static constexpr IsAFunctionTy isaFunction =
1409 static constexpr
const char *pyClassName =
"DenseResourceElementsAttr";
1410 using PyConcreteAttribute::PyConcreteAttribute;
1412 static PyDenseResourceElementsAttribute
1413 getFromBuffer(
const nb_buffer &buffer,
const std::string &name,
1414 const PyType &type, std::optional<size_t> alignment,
1417 throw std::invalid_argument(
1418 "Constructing a DenseResourceElementsAttr requires a ShapedType.");
1423 int flags = PyBUF_STRIDES;
1424 std::unique_ptr<Py_buffer> view = std::make_unique<Py_buffer>();
1425 if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
1426 throw nb::python_error();
1431 auto freeBuffer = llvm::make_scope_exit([&]() {
1433 PyBuffer_Release(view.get());
1436 if (!PyBuffer_IsContiguous(view.get(),
'A')) {
1437 throw std::invalid_argument(
"Contiguous buffer is required.");
1441 size_t inferredAlignment;
1443 inferredAlignment = *alignment;
1445 inferredAlignment = view->strides[view->ndim - 1];
1448 auto deleter = [](
void *userData,
const void *data,
size_t size,
1452 assert(Py_IsInitialized() &&
"expected interpreter to be initialized");
1453 Py_buffer *ownedView =
static_cast<Py_buffer *
>(userData);
1454 nb::gil_scoped_acquire gil;
1455 PyBuffer_Release(ownedView);
1459 size_t rawBufferSize = view->len;
1462 inferredAlignment, isMutable, deleter,
static_cast<void *
>(view.get()));
1464 throw std::invalid_argument(
1465 "DenseResourceElementsAttr could not be constructed from the given "
1467 "This may mean that the Python buffer layout does not match that "
1468 "MLIR expected layout and is a bug.");
1471 return PyDenseResourceElementsAttribute(contextWrapper->getRef(), attr);
1474 static void bindDerived(ClassTy &c) {
1475 c.def_static(
"get_from_buffer",
1476 PyDenseResourceElementsAttribute::getFromBuffer,
1477 nb::arg(
"array"), nb::arg(
"name"), nb::arg(
"type"),
1478 nb::arg(
"alignment") = nb::none(),
1479 nb::arg(
"is_mutable") =
false, nb::arg(
"context") = nb::none(),
1481 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"),
1490 static constexpr
const char *pyClassName =
"DictAttr";
1491 using PyConcreteAttribute::PyConcreteAttribute;
1492 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1497 bool dunderContains(
const std::string &name) {
1502 static void bindDerived(ClassTy &c) {
1503 c.def(
"__contains__", &PyDictAttribute::dunderContains);
1504 c.def(
"__len__", &PyDictAttribute::dunderLen);
1509 mlirNamedAttributes.reserve(attributes.size());
1510 for (std::pair<nb::handle, nb::handle> it : attributes) {
1511 auto &mlirAttr = nb::cast<PyAttribute &>(it.second);
1512 auto name = nb::cast<std::string>(it.first);
1518 MlirAttribute attr =
1520 mlirNamedAttributes.data());
1521 return PyDictAttribute(context->getRef(), attr);
1523 nb::arg(
"value") = nb::dict(), nb::arg(
"context") = nb::none(),
1524 "Gets an uniqued dict attribute");
1525 c.def(
"__getitem__", [](PyDictAttribute &
self,
const std::string &name) {
1526 MlirAttribute attr =
1529 throw nb::key_error(
"attempt to access a non-existent attribute");
1532 c.def(
"__getitem__", [](PyDictAttribute &
self, intptr_t index) {
1533 if (index < 0 || index >=
self.dunderLen()) {
1534 throw nb::index_error(
"attempt to access out of bounds attribute");
1546 class PyDenseFPElementsAttribute
1548 PyDenseElementsAttribute> {
1551 static constexpr
const char *pyClassName =
"DenseFPElementsAttr";
1552 using PyConcreteAttribute::PyConcreteAttribute;
1554 nb::float_ dunderGetItem(intptr_t pos) {
1555 if (pos < 0 || pos >= dunderLen()) {
1556 throw nb::index_error(
"attempt to access out of bounds element");
1572 throw nb::type_error(
"Unsupported floating-point type");
1575 static void bindDerived(ClassTy &c) {
1576 c.def(
"__getitem__", &PyDenseFPElementsAttribute::dunderGetItem);
1583 static constexpr
const char *pyClassName =
"TypeAttr";
1584 using PyConcreteAttribute::PyConcreteAttribute;
1585 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1588 static void bindDerived(ClassTy &c) {
1593 return PyTypeAttribute(context->getRef(), attr);
1595 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1596 "Gets a uniqued Type attribute");
1597 c.def_prop_ro(
"value", [](PyTypeAttribute &
self) {
1608 static constexpr
const char *pyClassName =
"UnitAttr";
1609 using PyConcreteAttribute::PyConcreteAttribute;
1610 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1613 static void bindDerived(ClassTy &c) {
1617 return PyUnitAttribute(context->getRef(),
1620 nb::arg(
"context") = nb::none(),
"Create a Unit attribute.");
1625 class PyStridedLayoutAttribute
1629 static constexpr
const char *pyClassName =
"StridedLayoutAttr";
1630 using PyConcreteAttribute::PyConcreteAttribute;
1631 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1634 static void bindDerived(ClassTy &c) {
1637 [](int64_t offset,
const std::vector<int64_t> &strides,
1640 ctx->
get(), offset, strides.size(), strides.data());
1641 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1643 nb::arg(
"offset"), nb::arg(
"strides"), nb::arg(
"context") = nb::none(),
1644 "Gets a strided layout attribute.");
1646 "get_fully_dynamic",
1649 std::vector<int64_t> strides(rank);
1650 llvm::fill(strides, dynamic);
1652 ctx->
get(), dynamic, strides.size(), strides.data());
1653 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1655 nb::arg(
"rank"), nb::arg(
"context") = nb::none(),
1656 "Gets a strided layout attribute with dynamic offset and strides of "
1661 [](PyStridedLayoutAttribute &
self) {
1664 "Returns the value of the float point attribute");
1667 [](PyStridedLayoutAttribute &
self) {
1669 std::vector<int64_t> strides(size);
1670 for (intptr_t i = 0; i < size; i++) {
1675 "Returns the value of the float point attribute");
1679 nb::object denseArrayAttributeCaster(
PyAttribute &pyAttribute) {
1680 if (PyDenseBoolArrayAttribute::isaFunction(pyAttribute))
1681 return nb::cast(PyDenseBoolArrayAttribute(pyAttribute));
1682 if (PyDenseI8ArrayAttribute::isaFunction(pyAttribute))
1683 return nb::cast(PyDenseI8ArrayAttribute(pyAttribute));
1684 if (PyDenseI16ArrayAttribute::isaFunction(pyAttribute))
1685 return nb::cast(PyDenseI16ArrayAttribute(pyAttribute));
1686 if (PyDenseI32ArrayAttribute::isaFunction(pyAttribute))
1687 return nb::cast(PyDenseI32ArrayAttribute(pyAttribute));
1688 if (PyDenseI64ArrayAttribute::isaFunction(pyAttribute))
1689 return nb::cast(PyDenseI64ArrayAttribute(pyAttribute));
1690 if (PyDenseF32ArrayAttribute::isaFunction(pyAttribute))
1691 return nb::cast(PyDenseF32ArrayAttribute(pyAttribute));
1692 if (PyDenseF64ArrayAttribute::isaFunction(pyAttribute))
1693 return nb::cast(PyDenseF64ArrayAttribute(pyAttribute));
1695 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1696 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1697 throw nb::type_error(msg.c_str());
1700 nb::object denseIntOrFPElementsAttributeCaster(
PyAttribute &pyAttribute) {
1701 if (PyDenseFPElementsAttribute::isaFunction(pyAttribute))
1702 return nb::cast(PyDenseFPElementsAttribute(pyAttribute));
1703 if (PyDenseIntElementsAttribute::isaFunction(pyAttribute))
1704 return nb::cast(PyDenseIntElementsAttribute(pyAttribute));
1707 "Can't cast unknown element type DenseIntOrFPElementsAttr (") +
1708 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1709 throw nb::type_error(msg.c_str());
1712 nb::object integerOrBoolAttributeCaster(
PyAttribute &pyAttribute) {
1713 if (PyBoolAttribute::isaFunction(pyAttribute))
1714 return nb::cast(PyBoolAttribute(pyAttribute));
1715 if (PyIntegerAttribute::isaFunction(pyAttribute))
1716 return nb::cast(PyIntegerAttribute(pyAttribute));
1717 std::string msg = std::string(
"Can't cast unknown attribute type Attr (") +
1718 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1720 throw nb::type_error(msg.c_str());
1723 nb::object symbolRefOrFlatSymbolRefAttributeCaster(
PyAttribute &pyAttribute) {
1724 if (PyFlatSymbolRefAttribute::isaFunction(pyAttribute))
1725 return nb::cast(PyFlatSymbolRefAttribute(pyAttribute));
1726 if (PySymbolRefAttribute::isaFunction(pyAttribute))
1727 return nb::cast(PySymbolRefAttribute(pyAttribute));
1728 std::string msg = std::string(
"Can't cast unknown SymbolRef attribute (") +
1729 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1731 throw nb::type_error(msg.c_str());
1736 void PyStringAttribute::bindDerived(ClassTy &c) {
1740 MlirAttribute attr =
1744 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1745 "Gets a uniqued string attribute");
1749 MlirAttribute attr =
1753 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1754 "Gets a uniqued string attribute");
1757 [](
PyType &type,
const std::string &value) {
1758 MlirAttribute attr =
1762 nb::arg(
"type"), nb::arg(
"value"),
1763 "Gets a uniqued string attribute associated to a type");
1768 return nb::str(stringRef.
data, stringRef.
length);
1770 "Returns the value of the string attribute");
1775 return nb::bytes(stringRef.
data, stringRef.
length);
1777 "Returns the value of the string attribute as `bytes`");
1781 PyAffineMapAttribute::bind(m);
1782 PyDenseBoolArrayAttribute::bind(m);
1783 PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
1784 PyDenseI8ArrayAttribute::bind(m);
1785 PyDenseI8ArrayAttribute::PyDenseArrayIterator::bind(m);
1786 PyDenseI16ArrayAttribute::bind(m);
1787 PyDenseI16ArrayAttribute::PyDenseArrayIterator::bind(m);
1788 PyDenseI32ArrayAttribute::bind(m);
1789 PyDenseI32ArrayAttribute::PyDenseArrayIterator::bind(m);
1790 PyDenseI64ArrayAttribute::bind(m);
1791 PyDenseI64ArrayAttribute::PyDenseArrayIterator::bind(m);
1792 PyDenseF32ArrayAttribute::bind(m);
1793 PyDenseF32ArrayAttribute::PyDenseArrayIterator::bind(m);
1794 PyDenseF64ArrayAttribute::bind(m);
1795 PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
1798 nb::cast<nb::callable>(nb::cpp_function(denseArrayAttributeCaster)));
1800 PyArrayAttribute::bind(m);
1801 PyArrayAttribute::PyArrayAttributeIterator::bind(m);
1802 PyBoolAttribute::bind(m);
1803 PyDenseElementsAttribute::bind(m, PyDenseElementsAttribute::slots);
1804 PyDenseFPElementsAttribute::bind(m);
1805 PyDenseIntElementsAttribute::bind(m);
1808 nb::cast<nb::callable>(
1809 nb::cpp_function(denseIntOrFPElementsAttributeCaster)));
1810 PyDenseResourceElementsAttribute::bind(m);
1812 PyDictAttribute::bind(m);
1813 PySymbolRefAttribute::bind(m);
1816 nb::cast<nb::callable>(
1817 nb::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster)));
1819 PyFlatSymbolRefAttribute::bind(m);
1820 PyOpaqueAttribute::bind(m);
1821 PyFloatAttribute::bind(m);
1822 PyIntegerAttribute::bind(m);
1823 PyIntegerSetAttribute::bind(m);
1824 PyStringAttribute::bind(m);
1825 PyTypeAttribute::bind(m);
1828 nb::cast<nb::callable>(nb::cpp_function(integerOrBoolAttributeCaster)));
1829 PyUnitAttribute::bind(m);
1831 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.