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.");
256 "Returns the value of the AffineMap attribute");
260 class PyIntegerSetAttribute
264 static constexpr
const char *pyClassName =
"IntegerSetAttr";
265 using PyConcreteAttribute::PyConcreteAttribute;
266 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
269 static void bindDerived(ClassTy &c) {
274 return PyIntegerSetAttribute(integerSet.
getContext(), attr);
276 nb::arg(
"integer_set"),
"Gets an attribute wrapping an IntegerSet.");
280 template <
typename T>
281 static T pyTryCast(nb::handle
object) {
283 return nb::cast<T>(
object);
284 }
catch (nb::cast_error &err) {
285 std::string msg = std::string(
"Invalid attribute when attempting to "
286 "create an ArrayAttribute (") +
288 throw std::runtime_error(msg.c_str());
289 }
catch (std::runtime_error &err) {
290 std::string msg = std::string(
"Invalid attribute (None?) when attempting "
291 "to create an ArrayAttribute (") +
293 throw std::runtime_error(msg.c_str());
299 template <
typename EltTy,
typename DerivedT>
305 class PyDenseArrayIterator {
307 PyDenseArrayIterator(
PyAttribute attr) : attr(std::move(attr)) {}
310 PyDenseArrayIterator dunderIter() {
return *
this; }
316 throw nb::stop_iteration();
321 static void bind(nb::module_ &m) {
322 nb::class_<PyDenseArrayIterator>(m, DerivedT::pyIteratorName)
323 .def(
"__iter__", &PyDenseArrayIterator::dunderIter)
324 .def(
"__next__", &PyDenseArrayIterator::dunderNext);
335 EltTy getItem(intptr_t i) {
return DerivedT::getElement(*
this, i); }
340 if constexpr (std::is_same_v<EltTy, bool>) {
344 std::vector<bool> values;
345 for (nb::handle py_value : py_values) {
346 int is_true = PyObject_IsTrue(py_value.ptr());
348 throw nb::python_error();
350 values.push_back(is_true);
352 return getAttribute(values, ctx->getRef());
354 nb::arg(
"values"), nb::arg(
"context").none() = nb::none(),
355 "Gets a uniqued dense array attribute");
360 return getAttribute(values, ctx->getRef());
362 nb::arg(
"values"), nb::arg(
"context").none() = nb::none(),
363 "Gets a uniqued dense array attribute");
366 c.def(
"__getitem__", [](DerivedT &arr, intptr_t i) {
368 throw nb::index_error(
"DenseArray index out of range");
369 return arr.getItem(i);
371 c.def(
"__len__", [](
const DerivedT &arr) {
375 [](
const DerivedT &arr) {
return PyDenseArrayIterator(arr); });
376 c.def(
"__add__", [](DerivedT &arr,
const nb::list &extras) {
377 std::vector<EltTy> values;
379 values.reserve(numOldElements + nb::len(extras));
380 for (intptr_t i = 0; i < numOldElements; ++i)
381 values.push_back(arr.getItem(i));
382 for (nb::handle attr : extras)
383 values.push_back(pyTryCast<EltTy>(attr));
384 return getAttribute(values, arr.getContext());
389 static DerivedT getAttribute(
const std::vector<EltTy> &values,
391 if constexpr (std::is_same_v<EltTy, bool>) {
392 std::vector<int> intValues(values.begin(), values.end());
393 MlirAttribute attr = DerivedT::getAttribute(ctx->
get(), intValues.size(),
395 return DerivedT(ctx, attr);
398 DerivedT::getAttribute(ctx->
get(), values.size(), values.data());
399 return DerivedT(ctx, attr);
405 struct PyDenseBoolArrayAttribute
406 :
public PyDenseArrayAttribute<bool, PyDenseBoolArrayAttribute> {
410 static constexpr
const char *pyClassName =
"DenseBoolArrayAttr";
411 static constexpr
const char *pyIteratorName =
"DenseBoolArrayIterator";
412 using PyDenseArrayAttribute::PyDenseArrayAttribute;
414 struct PyDenseI8ArrayAttribute
415 :
public PyDenseArrayAttribute<int8_t, PyDenseI8ArrayAttribute> {
419 static constexpr
const char *pyClassName =
"DenseI8ArrayAttr";
420 static constexpr
const char *pyIteratorName =
"DenseI8ArrayIterator";
421 using PyDenseArrayAttribute::PyDenseArrayAttribute;
423 struct PyDenseI16ArrayAttribute
424 :
public PyDenseArrayAttribute<int16_t, PyDenseI16ArrayAttribute> {
428 static constexpr
const char *pyClassName =
"DenseI16ArrayAttr";
429 static constexpr
const char *pyIteratorName =
"DenseI16ArrayIterator";
430 using PyDenseArrayAttribute::PyDenseArrayAttribute;
432 struct PyDenseI32ArrayAttribute
433 :
public PyDenseArrayAttribute<int32_t, PyDenseI32ArrayAttribute> {
437 static constexpr
const char *pyClassName =
"DenseI32ArrayAttr";
438 static constexpr
const char *pyIteratorName =
"DenseI32ArrayIterator";
439 using PyDenseArrayAttribute::PyDenseArrayAttribute;
441 struct PyDenseI64ArrayAttribute
442 :
public PyDenseArrayAttribute<int64_t, PyDenseI64ArrayAttribute> {
446 static constexpr
const char *pyClassName =
"DenseI64ArrayAttr";
447 static constexpr
const char *pyIteratorName =
"DenseI64ArrayIterator";
448 using PyDenseArrayAttribute::PyDenseArrayAttribute;
450 struct PyDenseF32ArrayAttribute
451 :
public PyDenseArrayAttribute<float, PyDenseF32ArrayAttribute> {
455 static constexpr
const char *pyClassName =
"DenseF32ArrayAttr";
456 static constexpr
const char *pyIteratorName =
"DenseF32ArrayIterator";
457 using PyDenseArrayAttribute::PyDenseArrayAttribute;
459 struct PyDenseF64ArrayAttribute
460 :
public PyDenseArrayAttribute<double, PyDenseF64ArrayAttribute> {
464 static constexpr
const char *pyClassName =
"DenseF64ArrayAttr";
465 static constexpr
const char *pyIteratorName =
"DenseF64ArrayIterator";
466 using PyDenseArrayAttribute::PyDenseArrayAttribute;
472 static constexpr
const char *pyClassName =
"ArrayAttr";
473 using PyConcreteAttribute::PyConcreteAttribute;
474 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
477 class PyArrayAttributeIterator {
479 PyArrayAttributeIterator(
PyAttribute attr) : attr(std::move(attr)) {}
481 PyArrayAttributeIterator &dunderIter() {
return *
this; }
483 MlirAttribute dunderNext() {
486 throw nb::stop_iteration();
490 static void bind(nb::module_ &m) {
491 nb::class_<PyArrayAttributeIterator>(m,
"ArrayAttributeIterator")
492 .def(
"__iter__", &PyArrayAttributeIterator::dunderIter)
493 .def(
"__next__", &PyArrayAttributeIterator::dunderNext);
501 MlirAttribute getItem(intptr_t i) {
505 static void bindDerived(ClassTy &c) {
510 mlirAttributes.reserve(nb::len(attributes));
511 for (
auto attribute : attributes) {
512 mlirAttributes.push_back(pyTryCast<PyAttribute>(attribute));
515 context->
get(), mlirAttributes.size(), mlirAttributes.data());
516 return PyArrayAttribute(context->getRef(), attr);
518 nb::arg(
"attributes"), nb::arg(
"context").none() = nb::none(),
519 "Gets a uniqued Array attribute");
521 [](PyArrayAttribute &arr, intptr_t i) {
523 throw nb::index_error(
"ArrayAttribute index out of range");
524 return arr.getItem(i);
527 [](
const PyArrayAttribute &arr) {
530 .def(
"__iter__", [](
const PyArrayAttribute &arr) {
531 return PyArrayAttributeIterator(arr);
533 c.def(
"__add__", [](PyArrayAttribute arr, nb::list extras) {
534 std::vector<MlirAttribute> attributes;
536 attributes.reserve(numOldElements + nb::len(extras));
537 for (intptr_t i = 0; i < numOldElements; ++i)
538 attributes.push_back(arr.getItem(i));
539 for (nb::handle attr : extras)
540 attributes.push_back(pyTryCast<PyAttribute>(attr));
542 arr.getContext()->get(), attributes.size(), attributes.data());
543 return PyArrayAttribute(arr.getContext(), arrayAttr);
552 static constexpr
const char *pyClassName =
"FloatAttr";
553 using PyConcreteAttribute::PyConcreteAttribute;
554 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
557 static void bindDerived(ClassTy &c) {
565 return PyFloatAttribute(type.
getContext(), attr);
567 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"loc").none() = nb::none(),
568 "Gets an uniqued float point attribute associated to a type");
574 return PyFloatAttribute(context->getRef(), attr);
576 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
577 "Gets an uniqued float point attribute associated to a f32 type");
583 return PyFloatAttribute(context->getRef(), attr);
585 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
586 "Gets an uniqued float point attribute associated to a f64 type");
588 "Returns the value of the float attribute");
590 "Converts the value of the float attribute to a Python float");
598 static constexpr
const char *pyClassName =
"IntegerAttr";
599 using PyConcreteAttribute::PyConcreteAttribute;
601 static void bindDerived(ClassTy &c) {
604 [](
PyType &type, int64_t value) {
606 return PyIntegerAttribute(type.
getContext(), attr);
608 nb::arg(
"type"), nb::arg(
"value"),
609 "Gets an uniqued integer attribute associated to a type");
610 c.def_prop_ro(
"value", toPyInt,
611 "Returns the value of the integer attribute");
612 c.def(
"__int__", toPyInt,
613 "Converts the value of the integer attribute to a Python int");
614 c.def_prop_ro_static(
"static_typeid",
615 [](nb::object & ) -> MlirTypeID {
621 static int64_t toPyInt(PyIntegerAttribute &
self) {
635 static constexpr
const char *pyClassName =
"BoolAttr";
636 using PyConcreteAttribute::PyConcreteAttribute;
638 static void bindDerived(ClassTy &c) {
643 return PyBoolAttribute(context->getRef(), attr);
645 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
646 "Gets an uniqued bool attribute");
648 "Returns the value of the bool attribute");
650 "Converts the value of the bool attribute to a Python bool");
657 static constexpr
const char *pyClassName =
"SymbolRefAttr";
658 using PyConcreteAttribute::PyConcreteAttribute;
660 static MlirAttribute fromList(
const std::vector<std::string> &symbols,
663 throw std::runtime_error(
"SymbolRefAttr must be composed of at least "
667 for (
size_t i = 1; i < symbols.size(); ++i) {
668 referenceAttrs.push_back(
672 referenceAttrs.size(), referenceAttrs.data());
675 static void bindDerived(ClassTy &c) {
678 [](
const std::vector<std::string> &symbols,
680 return PySymbolRefAttribute::fromList(symbols, context.
resolve());
682 nb::arg(
"symbols"), nb::arg(
"context").none() = nb::none(),
683 "Gets a uniqued SymbolRef attribute from a list of symbol names");
686 [](PySymbolRefAttribute &
self) {
687 std::vector<std::string> symbols = {
697 "Returns the value of the SymbolRef attribute as a list[str]");
701 class PyFlatSymbolRefAttribute
705 static constexpr
const char *pyClassName =
"FlatSymbolRefAttr";
706 using PyConcreteAttribute::PyConcreteAttribute;
708 static void bindDerived(ClassTy &c) {
714 return PyFlatSymbolRefAttribute(context->getRef(), attr);
716 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
717 "Gets a uniqued FlatSymbolRef attribute");
720 [](PyFlatSymbolRefAttribute &
self) {
722 return nb::str(stringRef.
data, stringRef.
length);
724 "Returns the value of the FlatSymbolRef attribute as a string");
731 static constexpr
const char *pyClassName =
"OpaqueAttr";
732 using PyConcreteAttribute::PyConcreteAttribute;
733 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
736 static void bindDerived(ClassTy &c) {
739 [](std::string dialectNamespace, nb_buffer buffer,
PyType &type,
741 const nb_buffer_info bufferInfo = buffer.request();
742 intptr_t bufferSize = bufferInfo.size;
745 static_cast<char *
>(bufferInfo.ptr), type);
746 return PyOpaqueAttribute(context->getRef(), attr);
748 nb::arg(
"dialect_namespace"), nb::arg(
"buffer"), nb::arg(
"type"),
749 nb::arg(
"context").none() = nb::none(),
"Gets an Opaque attribute.");
752 [](PyOpaqueAttribute &
self) {
754 return nb::str(stringRef.
data, stringRef.
length);
756 "Returns the dialect namespace for the Opaque attribute as a string");
759 [](PyOpaqueAttribute &
self) {
761 return nb::bytes(stringRef.
data, stringRef.
length);
763 "Returns the data for the Opaqued attributes as `bytes`");
770 static constexpr
const char *pyClassName =
"StringAttr";
771 using PyConcreteAttribute::PyConcreteAttribute;
772 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
775 static void bindDerived(ClassTy &c) {
781 return PyStringAttribute(context->getRef(), attr);
783 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
784 "Gets a uniqued string attribute");
790 return PyStringAttribute(context->getRef(), attr);
792 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
793 "Gets a uniqued string attribute");
796 [](
PyType &type, std::string value) {
799 return PyStringAttribute(type.
getContext(), attr);
801 nb::arg(
"type"), nb::arg(
"value"),
802 "Gets a uniqued string attribute associated to a type");
805 [](PyStringAttribute &
self) {
807 return nb::str(stringRef.
data, stringRef.
length);
809 "Returns the value of the string attribute");
812 [](PyStringAttribute &
self) {
814 return nb::bytes(stringRef.
data, stringRef.
length);
816 "Returns the value of the string attribute as `bytes`");
821 class PyDenseElementsAttribute
825 static constexpr
const char *pyClassName =
"DenseElementsAttr";
826 using PyConcreteAttribute::PyConcreteAttribute;
828 static PyDenseElementsAttribute
829 getFromList(nb::list attributes, std::optional<PyType> explicitType,
831 const size_t numAttributes = nb::len(attributes);
832 if (numAttributes == 0)
833 throw nb::value_error(
"Attributes list must be non-empty.");
841 llvm::raw_string_ostream os(message);
842 os <<
"Expected a static ShapedType for the shaped_type parameter: "
843 << nb::cast<std::string>(nb::repr(nb::cast(*explicitType)));
844 throw nb::value_error(message.c_str());
846 shapedType = *explicitType;
850 shape.size(), shape.data(),
856 mlirAttributes.reserve(numAttributes);
857 for (
const nb::handle &attribute : attributes) {
858 MlirAttribute mlirAttribute = pyTryCast<PyAttribute>(attribute);
860 mlirAttributes.push_back(mlirAttribute);
864 llvm::raw_string_ostream os(message);
865 os <<
"All attributes must be of the same type and match "
866 <<
"the type parameter: expected="
867 << nb::cast<std::string>(nb::repr(nb::cast(shapedType)))
869 << nb::cast<std::string>(nb::repr(nb::cast(attrType)));
870 throw nb::value_error(message.c_str());
875 shapedType, mlirAttributes.size(), mlirAttributes.data());
877 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
880 static PyDenseElementsAttribute
881 getFromBuffer(nb_buffer array,
bool signless,
882 std::optional<PyType> explicitType,
883 std::optional<std::vector<int64_t>> explicitShape,
886 int flags = PyBUF_ND;
888 flags |= PyBUF_FORMAT;
891 if (PyObject_GetBuffer(array.ptr(), &view, flags) != 0) {
892 throw nb::python_error();
894 auto freeBuffer = llvm::make_scope_exit([&]() { PyBuffer_Release(&view); });
896 MlirContext context = contextWrapper->
get();
897 MlirAttribute attr = getAttributeFromBuffer(view, signless, explicitType,
898 explicitShape, context);
900 throw std::invalid_argument(
901 "DenseElementsAttr could not be constructed from the given buffer. "
902 "This may mean that the Python buffer layout does not match that "
903 "MLIR expected layout and is a bug.");
905 return PyDenseElementsAttribute(contextWrapper->getRef(), attr);
908 static PyDenseElementsAttribute getSplat(
const PyType &shapedType,
910 auto contextWrapper =
914 std::string message =
"Illegal element type for DenseElementsAttr: ";
915 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
916 throw nb::value_error(message.c_str());
920 std::string message =
921 "Expected a static ShapedType for the shaped_type parameter: ";
922 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
923 throw nb::value_error(message.c_str());
928 std::string message =
929 "Shaped element type and attribute type must be equal: shaped=";
930 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
931 message.append(
", element=");
932 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
933 throw nb::value_error(message.c_str());
936 MlirAttribute elements =
938 return PyDenseElementsAttribute(contextWrapper->getRef(), elements);
943 std::unique_ptr<nb_buffer_info> accessBuffer() {
950 return bufferInfo<float>(shapedType);
954 return bufferInfo<double>(shapedType);
958 return bufferInfo<uint16_t>(shapedType,
"e");
962 return bufferInfo<int64_t>(shapedType);
969 return bufferInfo<int32_t>(shapedType);
973 return bufferInfo<uint32_t>(shapedType);
980 return bufferInfo<int64_t>(shapedType);
984 return bufferInfo<uint64_t>(shapedType);
991 return bufferInfo<int8_t>(shapedType);
995 return bufferInfo<uint8_t>(shapedType);
1002 return bufferInfo<int16_t>(shapedType);
1006 return bufferInfo<uint16_t>(shapedType);
1014 return getBooleanBufferFromBitpackedAttribute();
1019 throw std::invalid_argument(
1020 "unsupported data type for conversion to Python buffer");
1023 static void bindDerived(ClassTy &c) {
1024 #if PY_VERSION_HEX < 0x03090000
1025 PyTypeObject *tp =
reinterpret_cast<PyTypeObject *
>(c.ptr());
1026 tp->tp_as_buffer->bf_getbuffer = PyDenseElementsAttribute::bf_getbuffer;
1027 tp->tp_as_buffer->bf_releasebuffer =
1028 PyDenseElementsAttribute::bf_releasebuffer;
1030 c.def(
"__len__", &PyDenseElementsAttribute::dunderLen)
1031 .def_static(
"get", PyDenseElementsAttribute::getFromBuffer,
1032 nb::arg(
"array"), nb::arg(
"signless") =
true,
1033 nb::arg(
"type").none() = nb::none(),
1034 nb::arg(
"shape").none() = nb::none(),
1035 nb::arg(
"context").none() = nb::none(),
1037 .def_static(
"get", PyDenseElementsAttribute::getFromList,
1038 nb::arg(
"attrs"), nb::arg(
"type").none() = nb::none(),
1039 nb::arg(
"context").none() = nb::none(),
1041 .def_static(
"get_splat", PyDenseElementsAttribute::getSplat,
1042 nb::arg(
"shaped_type"), nb::arg(
"element_attr"),
1043 "Gets a DenseElementsAttr where all values are the same")
1044 .def_prop_ro(
"is_splat",
1045 [](PyDenseElementsAttribute &
self) ->
bool {
1048 .def(
"get_splat_value", [](PyDenseElementsAttribute &
self) {
1050 throw nb::value_error(
1051 "get_splat_value called on a non-splat attribute");
1056 static PyType_Slot slots[];
1059 static int bf_getbuffer(PyObject *exporter, Py_buffer *view,
int flags);
1060 static void bf_releasebuffer(PyObject *, Py_buffer *buffer);
1062 static bool isUnsignedIntegerFormat(std::string_view format) {
1065 char code = format[0];
1066 return code ==
'I' || code ==
'B' || code ==
'H' || code ==
'L' ||
1070 static bool isSignedIntegerFormat(std::string_view format) {
1073 char code = format[0];
1074 return code ==
'i' || code ==
'b' || code ==
'h' || code ==
'l' ||
1079 getShapedType(std::optional<MlirType> bulkLoadElementType,
1080 std::optional<std::vector<int64_t>> explicitShape,
1083 if (explicitShape) {
1084 shape.append(explicitShape->begin(), explicitShape->end());
1086 shape.append(view.shape, view.shape + view.ndim);
1090 if (explicitShape) {
1091 throw std::invalid_argument(
"Shape can only be specified explicitly "
1092 "when the type is not a shaped type.");
1094 return *bulkLoadElementType;
1098 *bulkLoadElementType, encodingAttr);
1102 static MlirAttribute getAttributeFromBuffer(
1103 Py_buffer &view,
bool signless, std::optional<PyType> explicitType,
1104 std::optional<std::vector<int64_t>> explicitShape, MlirContext &context) {
1109 std::optional<MlirType> bulkLoadElementType;
1111 bulkLoadElementType = *explicitType;
1113 std::string_view format(view.format);
1114 if (format ==
"f") {
1116 assert(view.itemsize == 4 &&
"mismatched array itemsize");
1118 }
else if (format ==
"d") {
1120 assert(view.itemsize == 8 &&
"mismatched array itemsize");
1122 }
else if (format ==
"e") {
1124 assert(view.itemsize == 2 &&
"mismatched array itemsize");
1126 }
else if (format ==
"?") {
1129 return getBitpackedAttributeFromBooleanBuffer(view, explicitShape,
1131 }
else if (isSignedIntegerFormat(format)) {
1132 if (view.itemsize == 4) {
1134 bulkLoadElementType = signless
1137 }
else if (view.itemsize == 8) {
1139 bulkLoadElementType = signless
1142 }
else if (view.itemsize == 1) {
1146 }
else if (view.itemsize == 2) {
1148 bulkLoadElementType = signless
1152 }
else if (isUnsignedIntegerFormat(format)) {
1153 if (view.itemsize == 4) {
1155 bulkLoadElementType = signless
1158 }
else if (view.itemsize == 8) {
1160 bulkLoadElementType = signless
1163 }
else if (view.itemsize == 1) {
1165 bulkLoadElementType = signless
1168 }
else if (view.itemsize == 2) {
1170 bulkLoadElementType = signless
1175 if (!bulkLoadElementType) {
1176 throw std::invalid_argument(
1177 std::string(
"unimplemented array format conversion from format: ") +
1178 std::string(format));
1182 MlirType type = getShapedType(bulkLoadElementType, explicitShape, view);
1189 static MlirAttribute getBitpackedAttributeFromBooleanBuffer(
1190 Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
1191 MlirContext &context) {
1192 if (llvm::endianness::native != llvm::endianness::little) {
1195 throw nb::type_error(
"Constructing a bit-packed MLIR attribute is "
1196 "unsupported on big-endian systems");
1198 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> unpackedArray(
1199 static_cast<uint8_t *
>(view.buf),
1200 {static_cast<size_t>(view.len)});
1202 nb::module_ numpy = nb::module_::import_(
"numpy");
1203 nb::object packbitsFunc = numpy.attr(
"packbits");
1204 nb::object packedBooleans =
1205 packbitsFunc(nb::cast(unpackedArray),
"bitorder"_a =
"little");
1206 nb_buffer_info pythonBuffer = nb::cast<nb_buffer>(packedBooleans).request();
1208 MlirType bitpackedType =
1210 assert(pythonBuffer.itemsize == 1 &&
"Packbits must return uint8");
1220 std::unique_ptr<nb_buffer_info> getBooleanBufferFromBitpackedAttribute() {
1221 if (llvm::endianness::native != llvm::endianness::little) {
1224 throw nb::type_error(
"Constructing a numpy array from a MLIR attribute "
1225 "is unsupported on big-endian systems");
1230 uint8_t *bitpackedData =
static_cast<uint8_t *
>(
1232 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> packedArray(
1234 {
static_cast<size_t>(numBitpackedBytes)});
1236 nb::module_ numpy = nb::module_::import_(
"numpy");
1237 nb::object unpackbitsFunc = numpy.attr(
"unpackbits");
1238 nb::object equalFunc = numpy.attr(
"equal");
1239 nb::object reshapeFunc = numpy.attr(
"reshape");
1240 nb::object unpackedBooleans =
1241 unpackbitsFunc(nb::cast(packedArray),
"bitorder"_a =
"little");
1248 unpackedBooleans = unpackedBooleans[nb::slice(
1249 nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
1250 unpackedBooleans = equalFunc(unpackedBooleans, 1);
1254 std::vector<intptr_t> shape(rank);
1255 for (intptr_t i = 0; i < rank; ++i) {
1258 unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
1262 nb_buffer pythonBuffer = nb::cast<nb_buffer>(unpackedBooleans);
1263 return std::make_unique<nb_buffer_info>(pythonBuffer.request());
1266 template <
typename Type>
1267 std::unique_ptr<nb_buffer_info>
1268 bufferInfo(MlirType shapedType,
const char *explicitFormat =
nullptr) {
1276 for (intptr_t i = 0; i < rank; ++i)
1282 strides.assign(rank, 0);
1284 for (intptr_t i = 1; i < rank; ++i) {
1285 intptr_t strideFactor = 1;
1286 for (intptr_t
j = i;
j < rank; ++
j)
1288 strides.push_back(
sizeof(
Type) * strideFactor);
1290 strides.push_back(
sizeof(
Type));
1293 if (explicitFormat) {
1294 format = explicitFormat;
1296 format = nb_format_descriptor<Type>::format();
1298 return std::make_unique<nb_buffer_info>(
1299 data,
sizeof(
Type), format, rank, std::move(shape), std::move(strides),
1304 PyType_Slot PyDenseElementsAttribute::slots[] = {
1306 #if PY_VERSION_HEX >= 0x03090000
1308 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_getbuffer)},
1309 {Py_bf_releasebuffer,
1310 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_releasebuffer)},
1315 int PyDenseElementsAttribute::bf_getbuffer(PyObject *obj,
1318 view->obj =
nullptr;
1319 std::unique_ptr<nb_buffer_info> info;
1321 auto *attr = nb::cast<PyDenseElementsAttribute *>(nb::handle(obj));
1322 info = attr->accessBuffer();
1323 }
catch (nb::python_error &e) {
1325 nb::chain_error(PyExc_BufferError,
"Error converting attribute to buffer");
1330 view->buf = info->ptr;
1331 view->itemsize = info->itemsize;
1332 view->len = info->itemsize;
1333 for (
auto s : info->shape) {
1336 view->readonly = info->readonly;
1337 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
1338 view->format =
const_cast<char *
>(info->format);
1340 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
1341 view->ndim =
static_cast<int>(info->ndim);
1342 view->strides = info->strides.data();
1343 view->shape = info->shape.data();
1345 view->suboffsets =
nullptr;
1346 view->internal = info.release();
1351 void PyDenseElementsAttribute::bf_releasebuffer(PyObject *,
1353 delete reinterpret_cast<nb_buffer_info *
>(view->internal);
1358 class PyDenseIntElementsAttribute
1360 PyDenseElementsAttribute> {
1363 static constexpr
const char *pyClassName =
"DenseIntElementsAttr";
1364 using PyConcreteAttribute::PyConcreteAttribute;
1368 nb::object dunderGetItem(intptr_t pos) {
1369 if (pos < 0 || pos >= dunderLen()) {
1370 throw nb::index_error(
"attempt to access out of bounds element");
1376 "expected integer element type in dense int elements attribute");
1417 throw nb::type_error(
"Unsupported integer type");
1420 static void bindDerived(ClassTy &c) {
1421 c.def(
"__getitem__", &PyDenseIntElementsAttribute::dunderGetItem);
1425 class PyDenseResourceElementsAttribute
1428 static constexpr IsAFunctionTy isaFunction =
1430 static constexpr
const char *pyClassName =
"DenseResourceElementsAttr";
1431 using PyConcreteAttribute::PyConcreteAttribute;
1433 static PyDenseResourceElementsAttribute
1434 getFromBuffer(nb_buffer buffer,
const std::string &name,
const PyType &type,
1435 std::optional<size_t> alignment,
bool isMutable,
1438 throw std::invalid_argument(
1439 "Constructing a DenseResourceElementsAttr requires a ShapedType.");
1444 int flags = PyBUF_STRIDES;
1445 std::unique_ptr<Py_buffer> view = std::make_unique<Py_buffer>();
1446 if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
1447 throw nb::python_error();
1452 auto freeBuffer = llvm::make_scope_exit([&]() {
1454 PyBuffer_Release(view.get());
1457 if (!PyBuffer_IsContiguous(view.get(),
'A')) {
1458 throw std::invalid_argument(
"Contiguous buffer is required.");
1462 size_t inferredAlignment;
1464 inferredAlignment = *alignment;
1466 inferredAlignment = view->strides[view->ndim - 1];
1469 auto deleter = [](
void *userData,
const void *data,
size_t size,
1471 Py_buffer *ownedView =
static_cast<Py_buffer *
>(userData);
1472 PyBuffer_Release(ownedView);
1476 size_t rawBufferSize = view->len;
1479 inferredAlignment, isMutable, deleter,
static_cast<void *
>(view.get()));
1481 throw std::invalid_argument(
1482 "DenseResourceElementsAttr could not be constructed from the given "
1484 "This may mean that the Python buffer layout does not match that "
1485 "MLIR expected layout and is a bug.");
1488 return PyDenseResourceElementsAttribute(contextWrapper->getRef(), attr);
1491 static void bindDerived(ClassTy &c) {
1493 "get_from_buffer", PyDenseResourceElementsAttribute::getFromBuffer,
1494 nb::arg(
"array"), nb::arg(
"name"), nb::arg(
"type"),
1495 nb::arg(
"alignment").none() = nb::none(), nb::arg(
"is_mutable") =
false,
1496 nb::arg(
"context").none() = nb::none(),
1504 static constexpr
const char *pyClassName =
"DictAttr";
1505 using PyConcreteAttribute::PyConcreteAttribute;
1506 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1511 bool dunderContains(
const std::string &name) {
1516 static void bindDerived(ClassTy &c) {
1517 c.def(
"__contains__", &PyDictAttribute::dunderContains);
1518 c.def(
"__len__", &PyDictAttribute::dunderLen);
1523 mlirNamedAttributes.reserve(attributes.size());
1524 for (std::pair<nb::handle, nb::handle> it : attributes) {
1525 auto &mlirAttr = nb::cast<PyAttribute &>(it.second);
1526 auto name = nb::cast<std::string>(it.first);
1532 MlirAttribute attr =
1534 mlirNamedAttributes.data());
1535 return PyDictAttribute(context->getRef(), attr);
1537 nb::arg(
"value") = nb::dict(), nb::arg(
"context").none() = nb::none(),
1538 "Gets an uniqued dict attribute");
1539 c.def(
"__getitem__", [](PyDictAttribute &
self,
const std::string &name) {
1540 MlirAttribute attr =
1543 throw nb::key_error(
"attempt to access a non-existent attribute");
1546 c.def(
"__getitem__", [](PyDictAttribute &
self, intptr_t index) {
1547 if (index < 0 || index >=
self.dunderLen()) {
1548 throw nb::index_error(
"attempt to access out of bounds attribute");
1560 class PyDenseFPElementsAttribute
1562 PyDenseElementsAttribute> {
1565 static constexpr
const char *pyClassName =
"DenseFPElementsAttr";
1566 using PyConcreteAttribute::PyConcreteAttribute;
1568 nb::float_ dunderGetItem(intptr_t pos) {
1569 if (pos < 0 || pos >= dunderLen()) {
1570 throw nb::index_error(
"attempt to access out of bounds element");
1586 throw nb::type_error(
"Unsupported floating-point type");
1589 static void bindDerived(ClassTy &c) {
1590 c.def(
"__getitem__", &PyDenseFPElementsAttribute::dunderGetItem);
1597 static constexpr
const char *pyClassName =
"TypeAttr";
1598 using PyConcreteAttribute::PyConcreteAttribute;
1599 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1602 static void bindDerived(ClassTy &c) {
1607 return PyTypeAttribute(context->getRef(), attr);
1609 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
1610 "Gets a uniqued Type attribute");
1611 c.def_prop_ro(
"value", [](PyTypeAttribute &
self) {
1621 static constexpr
const char *pyClassName =
"UnitAttr";
1622 using PyConcreteAttribute::PyConcreteAttribute;
1623 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1626 static void bindDerived(ClassTy &c) {
1630 return PyUnitAttribute(context->getRef(),
1633 nb::arg(
"context").none() = nb::none(),
"Create a Unit attribute.");
1638 class PyStridedLayoutAttribute
1642 static constexpr
const char *pyClassName =
"StridedLayoutAttr";
1643 using PyConcreteAttribute::PyConcreteAttribute;
1644 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1647 static void bindDerived(ClassTy &c) {
1650 [](int64_t offset,
const std::vector<int64_t> strides,
1653 ctx->
get(), offset, strides.size(), strides.data());
1654 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1656 nb::arg(
"offset"), nb::arg(
"strides"),
1657 nb::arg(
"context").none() = nb::none(),
1658 "Gets a strided layout attribute.");
1660 "get_fully_dynamic",
1663 std::vector<int64_t> strides(rank);
1664 std::fill(strides.begin(), strides.end(), dynamic);
1666 ctx->
get(), dynamic, strides.size(), strides.data());
1667 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1669 nb::arg(
"rank"), nb::arg(
"context").none() = nb::none(),
1670 "Gets a strided layout attribute with dynamic offset and strides of "
1675 [](PyStridedLayoutAttribute &
self) {
1678 "Returns the value of the float point attribute");
1681 [](PyStridedLayoutAttribute &
self) {
1683 std::vector<int64_t> strides(size);
1684 for (intptr_t i = 0; i < size; i++) {
1689 "Returns the value of the float point attribute");
1693 nb::object denseArrayAttributeCaster(
PyAttribute &pyAttribute) {
1694 if (PyDenseBoolArrayAttribute::isaFunction(pyAttribute))
1695 return nb::cast(PyDenseBoolArrayAttribute(pyAttribute));
1696 if (PyDenseI8ArrayAttribute::isaFunction(pyAttribute))
1697 return nb::cast(PyDenseI8ArrayAttribute(pyAttribute));
1698 if (PyDenseI16ArrayAttribute::isaFunction(pyAttribute))
1699 return nb::cast(PyDenseI16ArrayAttribute(pyAttribute));
1700 if (PyDenseI32ArrayAttribute::isaFunction(pyAttribute))
1701 return nb::cast(PyDenseI32ArrayAttribute(pyAttribute));
1702 if (PyDenseI64ArrayAttribute::isaFunction(pyAttribute))
1703 return nb::cast(PyDenseI64ArrayAttribute(pyAttribute));
1704 if (PyDenseF32ArrayAttribute::isaFunction(pyAttribute))
1705 return nb::cast(PyDenseF32ArrayAttribute(pyAttribute));
1706 if (PyDenseF64ArrayAttribute::isaFunction(pyAttribute))
1707 return nb::cast(PyDenseF64ArrayAttribute(pyAttribute));
1709 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1710 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1711 throw nb::type_error(msg.c_str());
1714 nb::object denseIntOrFPElementsAttributeCaster(
PyAttribute &pyAttribute) {
1715 if (PyDenseFPElementsAttribute::isaFunction(pyAttribute))
1716 return nb::cast(PyDenseFPElementsAttribute(pyAttribute));
1717 if (PyDenseIntElementsAttribute::isaFunction(pyAttribute))
1718 return nb::cast(PyDenseIntElementsAttribute(pyAttribute));
1721 "Can't cast unknown element type DenseIntOrFPElementsAttr (") +
1722 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1723 throw nb::type_error(msg.c_str());
1726 nb::object integerOrBoolAttributeCaster(
PyAttribute &pyAttribute) {
1727 if (PyBoolAttribute::isaFunction(pyAttribute))
1728 return nb::cast(PyBoolAttribute(pyAttribute));
1729 if (PyIntegerAttribute::isaFunction(pyAttribute))
1730 return nb::cast(PyIntegerAttribute(pyAttribute));
1732 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1733 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1734 throw nb::type_error(msg.c_str());
1737 nb::object symbolRefOrFlatSymbolRefAttributeCaster(
PyAttribute &pyAttribute) {
1738 if (PyFlatSymbolRefAttribute::isaFunction(pyAttribute))
1739 return nb::cast(PyFlatSymbolRefAttribute(pyAttribute));
1740 if (PySymbolRefAttribute::isaFunction(pyAttribute))
1741 return nb::cast(PySymbolRefAttribute(pyAttribute));
1742 std::string msg = std::string(
"Can't cast unknown SymbolRef attribute (") +
1743 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1745 throw nb::type_error(msg.c_str());
1751 PyAffineMapAttribute::bind(m);
1752 PyDenseBoolArrayAttribute::bind(m);
1753 PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
1754 PyDenseI8ArrayAttribute::bind(m);
1755 PyDenseI8ArrayAttribute::PyDenseArrayIterator::bind(m);
1756 PyDenseI16ArrayAttribute::bind(m);
1757 PyDenseI16ArrayAttribute::PyDenseArrayIterator::bind(m);
1758 PyDenseI32ArrayAttribute::bind(m);
1759 PyDenseI32ArrayAttribute::PyDenseArrayIterator::bind(m);
1760 PyDenseI64ArrayAttribute::bind(m);
1761 PyDenseI64ArrayAttribute::PyDenseArrayIterator::bind(m);
1762 PyDenseF32ArrayAttribute::bind(m);
1763 PyDenseF32ArrayAttribute::PyDenseArrayIterator::bind(m);
1764 PyDenseF64ArrayAttribute::bind(m);
1765 PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
1768 nb::cast<nb::callable>(nb::cpp_function(denseArrayAttributeCaster)));
1770 PyArrayAttribute::bind(m);
1771 PyArrayAttribute::PyArrayAttributeIterator::bind(m);
1772 PyBoolAttribute::bind(m);
1773 PyDenseElementsAttribute::bind(m, PyDenseElementsAttribute::slots);
1774 PyDenseFPElementsAttribute::bind(m);
1775 PyDenseIntElementsAttribute::bind(m);
1778 nb::cast<nb::callable>(
1779 nb::cpp_function(denseIntOrFPElementsAttributeCaster)));
1780 PyDenseResourceElementsAttribute::bind(m);
1782 PyDictAttribute::bind(m);
1783 PySymbolRefAttribute::bind(m);
1786 nb::cast<nb::callable>(
1787 nb::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster)));
1789 PyFlatSymbolRefAttribute::bind(m);
1790 PyOpaqueAttribute::bind(m);
1791 PyFloatAttribute::bind(m);
1792 PyIntegerAttribute::bind(m);
1793 PyIntegerSetAttribute::bind(m);
1794 PyStringAttribute::bind(m);
1795 PyTypeAttribute::bind(m);
1798 nb::cast<nb::callable>(nb::cpp_function(integerOrBoolAttributeCaster)));
1799 PyUnitAttribute::bind(m);
1801 PyStridedLayoutAttribute::bind(m);
static const char kDenseElementsAttrGetDocstring[]
static const char kDenseResourceElementsAttrGetFromBufferDocstring[]
static const char kDenseElementsAttrGetFromListDocstring[]
static MlirStringRef toMlirStringRef(const std::string &s)
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.
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.
Represents a Python MlirNamedAttr, carrying an optional owned name.
Wrapper around the generic MlirType.
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 MlirTypeID mlirStringAttrGetTypeID(void)
Returns the typeID of a String attribute.
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 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 bool mlirAttributeIsAString(MlirAttribute attr)
Checks whether the given attribute is a string attribute.
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.