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");
1379 "dense int elements attribute");
1423 throw nb::type_error(
"Unsupported integer type");
1426 static void bindDerived(ClassTy &c) {
1427 c.def(
"__getitem__", &PyDenseIntElementsAttribute::dunderGetItem);
1431 class PyDenseResourceElementsAttribute
1434 static constexpr IsAFunctionTy isaFunction =
1436 static constexpr
const char *pyClassName =
"DenseResourceElementsAttr";
1437 using PyConcreteAttribute::PyConcreteAttribute;
1439 static PyDenseResourceElementsAttribute
1440 getFromBuffer(nb_buffer buffer,
const std::string &name,
const PyType &type,
1441 std::optional<size_t> alignment,
bool isMutable,
1444 throw std::invalid_argument(
1445 "Constructing a DenseResourceElementsAttr requires a ShapedType.");
1450 int flags = PyBUF_STRIDES;
1451 std::unique_ptr<Py_buffer> view = std::make_unique<Py_buffer>();
1452 if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
1453 throw nb::python_error();
1458 auto freeBuffer = llvm::make_scope_exit([&]() {
1460 PyBuffer_Release(view.get());
1463 if (!PyBuffer_IsContiguous(view.get(),
'A')) {
1464 throw std::invalid_argument(
"Contiguous buffer is required.");
1468 size_t inferredAlignment;
1470 inferredAlignment = *alignment;
1472 inferredAlignment = view->strides[view->ndim - 1];
1475 auto deleter = [](
void *userData,
const void *data,
size_t size,
1477 if (!Py_IsInitialized())
1479 Py_buffer *ownedView =
static_cast<Py_buffer *
>(userData);
1480 nb::gil_scoped_acquire gil;
1481 PyBuffer_Release(ownedView);
1485 size_t rawBufferSize = view->len;
1488 inferredAlignment, isMutable, deleter,
static_cast<void *
>(view.get()));
1490 throw std::invalid_argument(
1491 "DenseResourceElementsAttr could not be constructed from the given "
1493 "This may mean that the Python buffer layout does not match that "
1494 "MLIR expected layout and is a bug.");
1497 return PyDenseResourceElementsAttribute(contextWrapper->getRef(), attr);
1500 static void bindDerived(ClassTy &c) {
1502 "get_from_buffer", PyDenseResourceElementsAttribute::getFromBuffer,
1503 nb::arg(
"array"), nb::arg(
"name"), nb::arg(
"type"),
1504 nb::arg(
"alignment").none() = nb::none(), nb::arg(
"is_mutable") =
false,
1505 nb::arg(
"context").none() = nb::none(),
1513 static constexpr
const char *pyClassName =
"DictAttr";
1514 using PyConcreteAttribute::PyConcreteAttribute;
1515 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1520 bool dunderContains(
const std::string &name) {
1525 static void bindDerived(ClassTy &c) {
1526 c.def(
"__contains__", &PyDictAttribute::dunderContains);
1527 c.def(
"__len__", &PyDictAttribute::dunderLen);
1532 mlirNamedAttributes.reserve(attributes.size());
1533 for (std::pair<nb::handle, nb::handle> it : attributes) {
1534 auto &mlirAttr = nb::cast<PyAttribute &>(it.second);
1535 auto name = nb::cast<std::string>(it.first);
1541 MlirAttribute attr =
1543 mlirNamedAttributes.data());
1544 return PyDictAttribute(context->getRef(), attr);
1546 nb::arg(
"value") = nb::dict(), nb::arg(
"context").none() = nb::none(),
1547 "Gets an uniqued dict attribute");
1548 c.def(
"__getitem__", [](PyDictAttribute &
self,
const std::string &name) {
1549 MlirAttribute attr =
1552 throw nb::key_error(
"attempt to access a non-existent attribute");
1555 c.def(
"__getitem__", [](PyDictAttribute &
self, intptr_t index) {
1556 if (index < 0 || index >=
self.dunderLen()) {
1557 throw nb::index_error(
"attempt to access out of bounds attribute");
1569 class PyDenseFPElementsAttribute
1571 PyDenseElementsAttribute> {
1574 static constexpr
const char *pyClassName =
"DenseFPElementsAttr";
1575 using PyConcreteAttribute::PyConcreteAttribute;
1577 nb::float_ dunderGetItem(intptr_t pos) {
1578 if (pos < 0 || pos >= dunderLen()) {
1579 throw nb::index_error(
"attempt to access out of bounds element");
1595 throw nb::type_error(
"Unsupported floating-point type");
1598 static void bindDerived(ClassTy &c) {
1599 c.def(
"__getitem__", &PyDenseFPElementsAttribute::dunderGetItem);
1606 static constexpr
const char *pyClassName =
"TypeAttr";
1607 using PyConcreteAttribute::PyConcreteAttribute;
1608 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1611 static void bindDerived(ClassTy &c) {
1616 return PyTypeAttribute(context->getRef(), attr);
1618 nb::arg(
"value"), nb::arg(
"context").none() = nb::none(),
1619 "Gets a uniqued Type attribute");
1620 c.def_prop_ro(
"value", [](PyTypeAttribute &
self) {
1630 static constexpr
const char *pyClassName =
"UnitAttr";
1631 using PyConcreteAttribute::PyConcreteAttribute;
1632 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1635 static void bindDerived(ClassTy &c) {
1639 return PyUnitAttribute(context->getRef(),
1642 nb::arg(
"context").none() = nb::none(),
"Create a Unit attribute.");
1647 class PyStridedLayoutAttribute
1651 static constexpr
const char *pyClassName =
"StridedLayoutAttr";
1652 using PyConcreteAttribute::PyConcreteAttribute;
1653 static constexpr GetTypeIDFunctionTy getTypeIdFunction =
1656 static void bindDerived(ClassTy &c) {
1659 [](int64_t offset,
const std::vector<int64_t> strides,
1662 ctx->
get(), offset, strides.size(), strides.data());
1663 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1665 nb::arg(
"offset"), nb::arg(
"strides"),
1666 nb::arg(
"context").none() = nb::none(),
1667 "Gets a strided layout attribute.");
1669 "get_fully_dynamic",
1672 std::vector<int64_t> strides(rank);
1673 std::fill(strides.begin(), strides.end(), dynamic);
1675 ctx->
get(), dynamic, strides.size(), strides.data());
1676 return PyStridedLayoutAttribute(ctx->getRef(), attr);
1678 nb::arg(
"rank"), nb::arg(
"context").none() = nb::none(),
1679 "Gets a strided layout attribute with dynamic offset and strides of "
1684 [](PyStridedLayoutAttribute &
self) {
1687 "Returns the value of the float point attribute");
1690 [](PyStridedLayoutAttribute &
self) {
1692 std::vector<int64_t> strides(size);
1693 for (intptr_t i = 0; i < size; i++) {
1698 "Returns the value of the float point attribute");
1702 nb::object denseArrayAttributeCaster(
PyAttribute &pyAttribute) {
1703 if (PyDenseBoolArrayAttribute::isaFunction(pyAttribute))
1704 return nb::cast(PyDenseBoolArrayAttribute(pyAttribute));
1705 if (PyDenseI8ArrayAttribute::isaFunction(pyAttribute))
1706 return nb::cast(PyDenseI8ArrayAttribute(pyAttribute));
1707 if (PyDenseI16ArrayAttribute::isaFunction(pyAttribute))
1708 return nb::cast(PyDenseI16ArrayAttribute(pyAttribute));
1709 if (PyDenseI32ArrayAttribute::isaFunction(pyAttribute))
1710 return nb::cast(PyDenseI32ArrayAttribute(pyAttribute));
1711 if (PyDenseI64ArrayAttribute::isaFunction(pyAttribute))
1712 return nb::cast(PyDenseI64ArrayAttribute(pyAttribute));
1713 if (PyDenseF32ArrayAttribute::isaFunction(pyAttribute))
1714 return nb::cast(PyDenseF32ArrayAttribute(pyAttribute));
1715 if (PyDenseF64ArrayAttribute::isaFunction(pyAttribute))
1716 return nb::cast(PyDenseF64ArrayAttribute(pyAttribute));
1718 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1719 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1720 throw nb::type_error(msg.c_str());
1723 nb::object denseIntOrFPElementsAttributeCaster(
PyAttribute &pyAttribute) {
1724 if (PyDenseFPElementsAttribute::isaFunction(pyAttribute))
1725 return nb::cast(PyDenseFPElementsAttribute(pyAttribute));
1726 if (PyDenseIntElementsAttribute::isaFunction(pyAttribute))
1727 return nb::cast(PyDenseIntElementsAttribute(pyAttribute));
1730 "Can't cast unknown element type DenseIntOrFPElementsAttr (") +
1731 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1732 throw nb::type_error(msg.c_str());
1735 nb::object integerOrBoolAttributeCaster(
PyAttribute &pyAttribute) {
1736 if (PyBoolAttribute::isaFunction(pyAttribute))
1737 return nb::cast(PyBoolAttribute(pyAttribute));
1738 if (PyIntegerAttribute::isaFunction(pyAttribute))
1739 return nb::cast(PyIntegerAttribute(pyAttribute));
1741 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1742 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1743 throw nb::type_error(msg.c_str());
1746 nb::object symbolRefOrFlatSymbolRefAttributeCaster(
PyAttribute &pyAttribute) {
1747 if (PyFlatSymbolRefAttribute::isaFunction(pyAttribute))
1748 return nb::cast(PyFlatSymbolRefAttribute(pyAttribute));
1749 if (PySymbolRefAttribute::isaFunction(pyAttribute))
1750 return nb::cast(PySymbolRefAttribute(pyAttribute));
1751 std::string msg = std::string(
"Can't cast unknown SymbolRef attribute (") +
1752 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1754 throw nb::type_error(msg.c_str());
1760 PyAffineMapAttribute::bind(m);
1761 PyDenseBoolArrayAttribute::bind(m);
1762 PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
1763 PyDenseI8ArrayAttribute::bind(m);
1764 PyDenseI8ArrayAttribute::PyDenseArrayIterator::bind(m);
1765 PyDenseI16ArrayAttribute::bind(m);
1766 PyDenseI16ArrayAttribute::PyDenseArrayIterator::bind(m);
1767 PyDenseI32ArrayAttribute::bind(m);
1768 PyDenseI32ArrayAttribute::PyDenseArrayIterator::bind(m);
1769 PyDenseI64ArrayAttribute::bind(m);
1770 PyDenseI64ArrayAttribute::PyDenseArrayIterator::bind(m);
1771 PyDenseF32ArrayAttribute::bind(m);
1772 PyDenseF32ArrayAttribute::PyDenseArrayIterator::bind(m);
1773 PyDenseF64ArrayAttribute::bind(m);
1774 PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
1777 nb::cast<nb::callable>(nb::cpp_function(denseArrayAttributeCaster)));
1779 PyArrayAttribute::bind(m);
1780 PyArrayAttribute::PyArrayAttributeIterator::bind(m);
1781 PyBoolAttribute::bind(m);
1782 PyDenseElementsAttribute::bind(m, PyDenseElementsAttribute::slots);
1783 PyDenseFPElementsAttribute::bind(m);
1784 PyDenseIntElementsAttribute::bind(m);
1787 nb::cast<nb::callable>(
1788 nb::cpp_function(denseIntOrFPElementsAttributeCaster)));
1789 PyDenseResourceElementsAttribute::bind(m);
1791 PyDictAttribute::bind(m);
1792 PySymbolRefAttribute::bind(m);
1795 nb::cast<nb::callable>(
1796 nb::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster)));
1798 PyFlatSymbolRefAttribute::bind(m);
1799 PyOpaqueAttribute::bind(m);
1800 PyFloatAttribute::bind(m);
1801 PyIntegerAttribute::bind(m);
1802 PyIntegerSetAttribute::bind(m);
1803 PyStringAttribute::bind(m);
1804 PyTypeAttribute::bind(m);
1807 nb::cast<nb::callable>(nb::cpp_function(integerOrBoolAttributeCaster)));
1808 PyUnitAttribute::bind(m);
1810 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 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 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.