22#include "llvm/ADT/ScopeExit.h"
23#include "llvm/Support/raw_ostream.h"
26using namespace nanobind::literals;
37 R
"(Gets a DenseElementsAttr from a Python buffer or array.
39When `type` is not provided, then some limited type inferencing is done based
40on the buffer format. Support presently exists for 8/16/32/64 signed and
41unsigned integers and float16/float32/float64. DenseElementsAttrs of these
42types can also be converted back to a corresponding buffer.
44For conversions outside of these types, a `type=` must be explicitly provided
45and the buffer contents must be bit-castable to the MLIR internal
48 * Integer types (except for i1): the buffer must be byte aligned to the
50 * Floating point types: Must be bit-castable to the given floating point
52 * i1 (bool): Bit packed into 8bit words where the bit pattern matches a
53 row major ordering. An arbitrary Numpy `bool_` array can be bit packed to
54 this specification with: `np.packbits(ary, axis=None, bitorder='little')`.
56If a single element buffer is passed (or for i1, a single byte with value 0
57or 255), then a splat will be created.
60 array: The array or buffer to convert.
61 signless: If inferring an appropriate MLIR type, use signless types for
62 integers (defaults True).
63 type: Skips inference of the MLIR element type and uses this instead. The
64 storage size must be consistent with the actual contents of the buffer.
65 shape: Overrides the shape of the buffer when constructing the MLIR
66 shaped type. This is needed when the physical and logical shape differ (as
68 context: Explicit context, if not from context manager.
71 DenseElementsAttr on success.
74 ValueError: If the type of the buffer or array cannot be matched to an MLIR
75 type or if the buffer does not meet expectations.
79 R
"(Gets a DenseElementsAttr from a Python list of attributes.
81Note that it can be expensive to construct attributes individually.
82For a large number of elements, consider using a Python buffer or array instead.
85 attrs: A list of attributes.
86 type: The desired shape and type of the resulting DenseElementsAttr.
87 If not provided, the element type is determined based on the type
88 of the 0th attribute and the shape is `[len(attrs)]`.
89 context: Explicit context, if not from context manager.
92 DenseElementsAttr on success.
95 ValueError: If the type of the attributes does not match the type
96 specified by `shaped_type`.
100 R
"(Gets a DenseResourceElementsAttr from a Python buffer or array.
102This function does minimal validation or massaging of the data, and it is
103up to the caller to ensure that the buffer meets the characteristics
106The backing buffer and any user objects will be retained for the lifetime
107of the resource blob. This is typically bounded to the context but the
108resource can have a shorter lifespan depending on how it is used in
109subsequent processing.
112 buffer: The array or buffer to convert.
113 name: Name to provide to the resource (may be changed upon collision).
114 type: The explicit ShapedType to construct the attribute with.
115 context: Explicit context, if not from context manager.
118 DenseResourceElementsAttr on success.
121 ValueError: If the type of the buffer or array cannot be matched to an MLIR
122 type or if the buffer does not meet expectations.
133 std::unique_ptr<Py_buffer,
void (*)(Py_buffer *)> owned_view_in)
135 shape(std::move(shape_in)),
strides(std::move(strides_in)),
138 for (ssize_t i = 0; i <
ndim; ++i) {
144 int flags = PyBUF_STRIDES | PyBUF_FORMAT;
145 auto *view =
new Py_buffer();
146 if (PyObject_GetBuffer(
ptr(), view, flags) != 0) {
148 throw nb::python_error();
155 static const char *
format() {
return "?"; }
159 static const char *
format() {
return "b"; }
163 static const char *
format() {
return "B"; }
167 static const char *
format() {
return "h"; }
171 static const char *
format() {
return "H"; }
175 static const char *
format() {
return "i"; }
179 static const char *
format() {
return "I"; }
183 static const char *
format() {
return "q"; }
187 static const char *
format() {
return "Q"; }
191 static const char *
format() {
return "f"; }
195 static const char *
format() {
return "d"; }
205 nb::arg(
"affine_map"),
"Gets an attribute wrapping an AffineMap.");
211 "Returns the value of the AffineMap attribute");
221 nb::arg(
"integer_set"),
"Gets an attribute wrapping an IntegerSet.");
224nb::typed<nb::object, PyAttribute>
227 if (PyArrayAttribute::PyArrayAttributeIterator::nextIndex >=
229 PyArrayAttribute::PyArrayAttributeIterator::attr.
get()))
230 throw nb::stop_iteration();
232 this->PyArrayAttribute::PyArrayAttributeIterator::attr
235 PyArrayAttribute::PyArrayAttributeIterator::attr.
get(),
236 PyArrayAttribute::PyArrayAttributeIterator::nextIndex++))
241 nb::class_<PyArrayAttributeIterator>(m,
"ArrayAttributeIterator")
255 mlirAttributes.reserve(nb::len(attributes));
256 for (
auto attribute : attributes) {
260 context->
get(), mlirAttributes.size(), mlirAttributes.data());
263 nb::arg(
"attributes"), nb::arg(
"context") = nb::none(),
264 "Gets a uniqued Array attribute");
267 intptr_t i) -> nb::typed<nb::object, PyAttribute> {
269 throw nb::index_error(
"ArrayAttribute index out of range");
280 std::vector<MlirAttribute> attributes;
282 attributes.reserve(numOldElements + nb::len(extras));
283 for (
intptr_t i = 0; i < numOldElements; ++i)
284 attributes.push_back(arr.
getItem(i));
285 for (nb::handle attr : extras)
288 arr.
getContext()->
get(), attributes.size(), attributes.data());
298 if (mlirAttributeIsNull(attr))
302 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"loc") = nb::none(),
303 "Gets an uniqued float point attribute associated to a type");
310 if (mlirAttributeIsNull(attr))
314 nb::arg(
"type"), nb::arg(
"value"), nb::arg(
"context") = nb::none(),
315 "Gets an uniqued float point attribute associated to a type");
323 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
324 "Gets an uniqued float point attribute associated to a f32 type");
332 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
333 "Gets an uniqued float point attribute associated to a f64 type");
335 "Returns the value of the float attribute");
337 "Converts the value of the float attribute to a Python float");
347 nb::arg(
"type"), nb::arg(
"value"),
348 "Gets an uniqued integer attribute associated to a type");
349 c.def_prop_ro(
"value", toPyInt,
"Returns the value of the integer attribute");
350 c.def(
"__int__", toPyInt,
351 "Converts the value of the integer attribute to a Python int");
352 c.def_prop_ro_static(
357 nb::sig(
"def static_typeid(/) -> TypeID"));
376 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
377 "Gets an uniqued bool attribute");
379 "Returns the value of the bool attribute");
381 "Converts the value of the bool attribute to a Python bool");
388 throw std::runtime_error(
"SymbolRefAttr must be composed of at least "
392 for (
size_t i = 1; i < symbols.size(); ++i) {
393 referenceAttrs.push_back(
398 referenceAttrs.size(),
399 referenceAttrs.data()));
405 [](
const std::vector<std::string> &symbols,
409 nb::arg(
"symbols"), nb::arg(
"context") = nb::none(),
410 "Gets a uniqued SymbolRef attribute from a list of symbol names");
414 std::vector<std::string> symbols = {
423 "Returns the value of the SymbolRef attribute as a list[str]");
434 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
435 "Gets a uniqued FlatSymbolRef attribute");
440 return nb::str(stringRef.
data, stringRef.
length);
442 "Returns the value of the FlatSymbolRef attribute as a string");
448 [](
const std::string &dialectNamespace,
const nb_buffer &buffer,
454 static_cast<char *
>(bufferInfo.
ptr), type);
457 nb::arg(
"dialect_namespace"), nb::arg(
"buffer"), nb::arg(
"type"),
458 nb::arg(
"context") = nb::none(),
460 nb::sig(
"def get(dialect_namespace: str, buffer: typing_extensions.Buffer, type: Type, context: Context | None = None) -> OpaqueAttr"),
462 "Gets an Opaque attribute.");
467 return nb::str(stringRef.
data, stringRef.
length);
469 "Returns the dialect namespace for the Opaque attribute as a string");
474 return nb::bytes(stringRef.
data, stringRef.
length);
476 "Returns the data for the Opaqued attributes as `bytes`");
481 std::optional<PyType> explicitType,
483 const size_t numAttributes = nb::len(attributes);
484 if (numAttributes == 0)
485 throw nb::value_error(
"Attributes list must be non-empty.");
493 llvm::raw_string_ostream os(message);
494 os <<
"Expected a static ShapedType for the shaped_type parameter: "
495 << nb::cast<std::string>(nb::repr(nb::cast(*explicitType)));
496 throw nb::value_error(message.c_str());
498 shapedType = *explicitType;
508 mlirAttributes.reserve(numAttributes);
509 for (
const nb::handle &attribute : attributes) {
512 mlirAttributes.push_back(mlirAttribute);
516 llvm::raw_string_ostream os(message);
517 os <<
"All attributes must be of the same type and match "
518 <<
"the type parameter: expected="
519 << nb::cast<std::string>(nb::repr(nb::cast(shapedType)))
520 <<
", but got=" << nb::cast<std::string>(nb::repr(nb::cast(attrType)));
521 throw nb::value_error(message.c_str());
526 shapedType, mlirAttributes.size(), mlirAttributes.data());
533 const std::optional<PyType> &explicitType,
534 std::optional<std::vector<int64_t>> explicitShape,
537 int flags = PyBUF_ND;
539 flags |= PyBUF_FORMAT;
542 if (PyObject_GetBuffer(array.ptr(), &view, flags) != 0) {
543 throw nb::python_error();
545 llvm::scope_exit freeBuffer([&]() { PyBuffer_Release(&view); });
547 MlirContext context = contextWrapper->
get();
548 MlirAttribute attr = getAttributeFromBuffer(
549 view, signless, explicitType, std::move(explicitShape), context);
550 if (mlirAttributeIsNull(attr)) {
551 throw std::invalid_argument(
552 "DenseElementsAttr could not be constructed from the given buffer. "
553 "This may mean that the Python buffer layout does not match that "
554 "MLIR expected layout and is a bug.");
562 auto contextWrapper =
566 std::string message =
"Illegal element type for DenseElementsAttr: ";
567 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
568 throw nb::value_error(message.c_str());
572 std::string message =
573 "Expected a static ShapedType for the shaped_type parameter: ";
574 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
575 throw nb::value_error(message.c_str());
580 std::string message =
581 "Shaped element type and attribute type must be equal: shaped=";
582 message.append(nb::cast<std::string>(nb::repr(nb::cast(shapedType))));
583 message.append(
", element=");
584 message.append(nb::cast<std::string>(nb::repr(nb::cast(elementAttr))));
585 throw nb::value_error(message.c_str());
588 MlirAttribute elements =
604 return bufferInfo<float>(shapedType);
608 return bufferInfo<double>(shapedType);
612 return bufferInfo<uint16_t>(shapedType,
"e");
616 return bufferInfo<int64_t>(shapedType);
623 return bufferInfo<int32_t>(shapedType);
627 return bufferInfo<uint32_t>(shapedType);
634 return bufferInfo<int64_t>(shapedType);
638 return bufferInfo<uint64_t>(shapedType);
645 return bufferInfo<int8_t>(shapedType);
649 return bufferInfo<uint8_t>(shapedType);
656 return bufferInfo<int16_t>(shapedType);
660 return bufferInfo<uint16_t>(shapedType);
668 return getBooleanBufferFromBitpackedAttribute();
673 throw std::invalid_argument(
674 "unsupported data type for conversion to Python buffer");
678#if PY_VERSION_HEX < 0x03090000
679 PyTypeObject *tp =
reinterpret_cast<PyTypeObject *
>(c.ptr());
680 tp->tp_as_buffer->bf_getbuffer = PyDenseElementsAttribute::bf_getbuffer;
681 tp->tp_as_buffer->bf_releasebuffer =
682 PyDenseElementsAttribute::bf_releasebuffer;
687 nb::arg(
"signless") =
true, nb::arg(
"type") = nb::none(),
688 nb::arg(
"shape") = nb::none(), nb::arg(
"context") = nb::none(),
690 nb::sig(
"def get(array: typing_extensions.Buffer, signless: bool = True, type: Type | None = None, shape: Sequence[int] | None = None, context: Context | None = None) -> DenseElementsAttr"),
694 nb::arg(
"attrs"), nb::arg(
"type") = nb::none(),
695 nb::arg(
"context") = nb::none(),
698 nb::arg(
"shaped_type"), nb::arg(
"element_attr"),
699 "Gets a DenseElementsAttr where all values are the same")
700 .def_prop_ro(
"is_splat",
704 .def(
"get_splat_value",
706 -> nb::typed<nb::object, PyAttribute> {
708 throw nb::value_error(
709 "get_splat_value called on a non-splat attribute");
716bool PyDenseElementsAttribute::isUnsignedIntegerFormat(
717 std::string_view format) {
720 char code = format[0];
721 return code ==
'I' || code ==
'B' || code ==
'H' || code ==
'L' ||
725bool PyDenseElementsAttribute::isSignedIntegerFormat(std::string_view format) {
728 char code = format[0];
729 return code ==
'i' || code ==
'b' || code ==
'h' || code ==
'l' ||
733MlirType PyDenseElementsAttribute::getShapedType(
734 std::optional<MlirType> bulkLoadElementType,
735 std::optional<std::vector<int64_t>> explicitShape, Py_buffer &view) {
738 shape.append(explicitShape->begin(), explicitShape->end());
740 shape.append(view.shape, view.shape + view.ndim);
745 throw std::invalid_argument(
"Shape can only be specified explicitly "
746 "when the type is not a shaped type.");
748 return *bulkLoadElementType;
752 *bulkLoadElementType, encodingAttr);
755MlirAttribute PyDenseElementsAttribute::getAttributeFromBuffer(
756 Py_buffer &view,
bool signless, std::optional<PyType> explicitType,
757 const std::optional<std::vector<int64_t>> &explicitShape,
758 MlirContext &context) {
763 std::optional<MlirType> bulkLoadElementType;
765 bulkLoadElementType = *explicitType;
767 std::string_view format(view.format);
770 assert(view.itemsize == 4 &&
"mismatched array itemsize");
772 }
else if (format ==
"d") {
774 assert(view.itemsize == 8 &&
"mismatched array itemsize");
776 }
else if (format ==
"e") {
778 assert(view.itemsize == 2 &&
"mismatched array itemsize");
780 }
else if (format ==
"?") {
783 return getBitpackedAttributeFromBooleanBuffer(view, explicitShape,
785 }
else if (isSignedIntegerFormat(format)) {
786 if (view.itemsize == 4) {
790 }
else if (view.itemsize == 8) {
794 }
else if (view.itemsize == 1) {
798 }
else if (view.itemsize == 2) {
803 }
else if (isUnsignedIntegerFormat(format)) {
804 if (view.itemsize == 4) {
806 bulkLoadElementType = signless
809 }
else if (view.itemsize == 8) {
811 bulkLoadElementType = signless
814 }
else if (view.itemsize == 1) {
818 }
else if (view.itemsize == 2) {
820 bulkLoadElementType = signless
825 if (!bulkLoadElementType) {
826 throw std::invalid_argument(
827 std::string(
"unimplemented array format conversion from format: ") +
828 std::string(format));
832 MlirType type = getShapedType(bulkLoadElementType, explicitShape, view);
836MlirAttribute PyDenseElementsAttribute::getBitpackedAttributeFromBooleanBuffer(
837 Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
838 MlirContext &context) {
839 if (llvm::endianness::native != llvm::endianness::little) {
842 throw nb::type_error(
"Constructing a bit-packed MLIR attribute is "
843 "unsupported on big-endian systems");
845 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> unpackedArray(
846 static_cast<uint8_t *
>(view.buf),
847 {static_cast<size_t>(view.len)});
849 nb::module_ numpy = nb::module_::import_(
"numpy");
850 nb::object packbitsFunc = numpy.attr(
"packbits");
851 nb::object packedBooleans =
852 packbitsFunc(nb::cast(unpackedArray),
"bitorder"_a =
"little");
853 nb_buffer_info pythonBuffer = nb::cast<nb_buffer>(packedBooleans).request();
856 std::move(explicitShape), view);
857 assert(pythonBuffer.
itemsize == 1 &&
"Packbits must return uint8");
865std::unique_ptr<nb_buffer_info>
866PyDenseElementsAttribute::getBooleanBufferFromBitpackedAttribute()
const {
867 if (llvm::endianness::native != llvm::endianness::little) {
870 throw nb::type_error(
"Constructing a numpy array from a MLIR attribute "
871 "is unsupported on big-endian systems");
875 int64_t numBitpackedBytes = llvm::divideCeil(numBooleans, 8);
876 uint8_t *bitpackedData =
static_cast<uint8_t *
>(
878 nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> packedArray(
880 {
static_cast<size_t>(numBitpackedBytes)});
882 nb::module_ numpy = nb::module_::import_(
"numpy");
883 nb::object unpackbitsFunc = numpy.attr(
"unpackbits");
884 nb::object equalFunc = numpy.attr(
"equal");
885 nb::object reshapeFunc = numpy.attr(
"reshape");
886 nb::object unpackedBooleans =
887 unpackbitsFunc(nb::cast(packedArray),
"bitorder"_a =
"little");
894 unpackedBooleans = unpackedBooleans[nb::slice(
895 nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
896 unpackedBooleans = equalFunc(unpackedBooleans, 1);
900 std::vector<intptr_t> shape(rank);
901 for (intptr_t i = 0; i < rank; ++i) {
904 unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
908 nb_buffer pythonBuffer = nb::cast<nb_buffer>(unpackedBooleans);
909 return std::make_unique<nb_buffer_info>(pythonBuffer.request());
914#if PY_VERSION_HEX >= 0x03090000
916 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_getbuffer)},
917 {Py_bf_releasebuffer,
918 reinterpret_cast<void *
>(PyDenseElementsAttribute::bf_releasebuffer)},
923 int PyDenseElementsAttribute::bf_getbuffer(PyObject *obj,
927 std::unique_ptr<nb_buffer_info> info;
929 auto *attr = nb::cast<PyDenseElementsAttribute *>(nb::handle(obj));
930 info = attr->accessBuffer();
931 }
catch (nb::python_error &e) {
933 nb::chain_error(PyExc_BufferError,
"Error converting attribute to buffer");
935 }
catch (std::exception &e) {
936 nb::chain_error(PyExc_BufferError,
937 "Error converting attribute to buffer: %s", e.what());
942 view->buf = info->ptr;
943 view->itemsize = info->itemsize;
944 view->len = info->itemsize;
945 for (
auto s : info->shape) {
948 view->readonly = info->readonly;
949 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
950 view->format =
const_cast<char *
>(info->format);
952 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
953 view->ndim =
static_cast<int>(info->ndim);
954 view->strides = info->strides.data();
955 view->shape = info->shape.data();
957 view->suboffsets =
nullptr;
958 view->internal = info.release();
963 void PyDenseElementsAttribute::bf_releasebuffer(PyObject *,
965 delete reinterpret_cast<nb_buffer_info *
>(view->internal);
970 throw nb::index_error(
"attempt to access out of bounds element");
979 "dense int elements attribute");
1023 throw nb::type_error(
"Unsupported integer type");
1031#if PY_VERSION_HEX < 0x030d0000
1032#define Py_IsFinalizing _Py_IsFinalizing
1038 std::optional<size_t> alignment,
bool isMutable,
1041 throw std::invalid_argument(
1042 "Constructing a DenseResourceElementsAttr requires a ShapedType.");
1047 int flags = PyBUF_STRIDES;
1048 std::unique_ptr<Py_buffer> view = std::make_unique<Py_buffer>();
1049 if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
1050 throw nb::python_error();
1055 llvm::scope_exit freeBuffer([&]() {
1057 PyBuffer_Release(view.get());
1060 if (!PyBuffer_IsContiguous(view.get(),
'A')) {
1061 throw std::invalid_argument(
"Contiguous buffer is required.");
1065 size_t inferredAlignment;
1067 inferredAlignment = *alignment;
1069 inferredAlignment = view->strides[view->ndim - 1];
1072 auto deleter = [](
void *userData,
const void *data,
size_t size,
1076 assert(Py_IsInitialized() &&
"expected interpreter to be initialized");
1077 Py_buffer *ownedView =
static_cast<Py_buffer *
>(userData);
1078 nb::gil_scoped_acquire gil;
1079 PyBuffer_Release(ownedView);
1083 size_t rawBufferSize = view->len;
1086 isMutable, deleter,
static_cast<void *
>(view.get()));
1087 if (mlirAttributeIsNull(attr)) {
1088 throw std::invalid_argument(
1089 "DenseResourceElementsAttr could not be constructed from the given "
1091 "This may mean that the Python buffer layout does not match that "
1092 "MLIR expected layout and is a bug.");
1101 nb::arg(
"array"), nb::arg(
"name"), nb::arg(
"type"),
1102 nb::arg(
"alignment") = nb::none(), nb::arg(
"is_mutable") =
false,
1103 nb::arg(
"context") = nb::none(),
1105 nb::sig(
"def get_from_buffer(array: typing_extensions.Buffer, name: str, type: Type, alignment: int | None = None, is_mutable: bool = False, context: Context | None = None) -> DenseResourceElementsAttr"),
1115 return !mlirAttributeIsNull(
1126 mlirNamedAttributes.reserve(attributes.size());
1127 for (std::pair<nb::handle, nb::handle> it : attributes) {
1128 auto &mlirAttr = nb::cast<PyAttribute &>(it.second);
1129 auto name = nb::cast<std::string>(it.first);
1135 MlirAttribute attr =
1137 mlirNamedAttributes.data());
1140 nb::arg(
"value") = nb::dict(), nb::arg(
"context") = nb::none(),
1141 "Gets an uniqued dict attribute");
1142 c.def(
"__getitem__",
1144 const std::string &
name) -> nb::typed<nb::object, PyAttribute> {
1145 MlirAttribute attr =
1147 if (mlirAttributeIsNull(attr))
1148 throw nb::key_error(
"attempt to access a non-existent attribute");
1152 if (index < 0 || index >= self.
dunderLen()) {
1153 throw nb::index_error(
"attempt to access out of bounds attribute");
1164 throw nb::index_error(
"attempt to access out of bounds element");
1180 throw nb::type_error(
"Unsupported floating-point type");
1194 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1195 "Gets a uniqued Type attribute");
1210 nb::arg(
"context") = nb::none(),
"Create a Unit attribute.");
1216 [](
int64_t offset,
const std::vector<int64_t> &strides,
1219 ctx->
get(), offset, strides.size(), strides.data());
1222 nb::arg(
"offset"), nb::arg(
"strides"), nb::arg(
"context") = nb::none(),
1223 "Gets a strided layout attribute.");
1225 "get_fully_dynamic",
1228 std::vector<int64_t> strides(rank);
1229 llvm::fill(strides, dynamic);
1231 ctx->
get(), dynamic, strides.size(), strides.data());
1234 nb::arg(
"rank"), nb::arg(
"context") = nb::none(),
1235 "Gets a strided layout attribute with dynamic offset and strides of "
1243 "Returns the value of the float point attribute");
1248 std::vector<int64_t> strides(size);
1249 for (
intptr_t i = 0; i < size; i++) {
1254 "Returns the value of the float point attribute");
1273 std::string(
"Can't cast unknown element type DenseArrayAttr (") +
1274 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1275 throw nb::type_error(msg.c_str());
1285 "Can't cast unknown element type DenseIntOrFPElementsAttr (") +
1286 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
")";
1287 throw nb::type_error(msg.c_str());
1295 std::string msg = std::string(
"Can't cast unknown attribute type Attr (") +
1296 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1298 throw nb::type_error(msg.c_str());
1306 std::string msg = std::string(
"Can't cast unknown SymbolRef attribute (") +
1307 nb::cast<std::string>(nb::repr(nb::cast(pyAttribute))) +
1309 throw nb::type_error(msg.c_str());
1316 MlirAttribute attr =
1320 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1321 "Gets a uniqued string attribute");
1325 MlirAttribute attr =
1329 nb::arg(
"value"), nb::arg(
"context") = nb::none(),
1330 "Gets a uniqued string attribute");
1333 [](
PyType &type,
const std::string &value) {
1334 MlirAttribute attr =
1338 nb::arg(
"type"), nb::arg(
"value"),
1339 "Gets a uniqued string attribute associated to a type");
1344 return nb::str(stringRef.
data, stringRef.
length);
1346 "Returns the value of the string attribute");
1351 return nb::bytes(stringRef.
data, stringRef.
length);
1353 "Returns the value of the string attribute as `bytes`");
1359 PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
1361 PyDenseI8ArrayAttribute::PyDenseArrayIterator::bind(m);
1363 PyDenseI16ArrayAttribute::PyDenseArrayIterator::bind(m);
1365 PyDenseI32ArrayAttribute::PyDenseArrayIterator::bind(m);
1367 PyDenseI64ArrayAttribute::PyDenseArrayIterator::bind(m);
1369 PyDenseF32ArrayAttribute::PyDenseArrayIterator::bind(m);
1371 PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
1384 nb::cast<nb::callable>(
1392 nb::cast<nb::callable>(
static const char kDenseElementsAttrGetDocstring[]
static const char kDenseResourceElementsAttrGetFromBufferDocstring[]
static const char kDenseElementsAttrGetFromListDocstring[]
MlirContext mlirAttributeGetContext(MlirAttribute attribute)
MlirType mlirAttributeGetType(MlirAttribute attribute)
std::string str() const
Converts the diagnostic to a string.
ReferrentTy * get() const
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()
static void bindDerived(ClassTy &c)
MlirAffineMap get() const
nanobind::typed< nanobind::object, PyAttribute > dunderNext()
PyArrayAttributeIterator & dunderIter()
static void bind(nanobind::module_ &m)
MlirAttribute getItem(intptr_t i) const
static void bindDerived(ClassTy &c)
Wrapper around the generic MlirAttribute.
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
MlirAttribute get() const
Bool Attribute subclass - BoolAttr.
static constexpr IsAFunctionTy isaFunction
static void bindDerived(ClassTy &c)
static void bind(nanobind::module_ &m, PyType_Slot *slots=nullptr)
nanobind::class_< PyAffineMapAttribute, PyAttribute > ClassTy
static PyDenseElementsAttribute getSplat(const PyType &shapedType, PyAttribute &elementAttr)
std::unique_ptr< nb_buffer_info > accessBuffer()
intptr_t dunderLen() const
static PyType_Slot slots[]
static void bindDerived(ClassTy &c)
static PyDenseElementsAttribute getFromList(const nanobind::list &attributes, std::optional< PyType > explicitType, DefaultingPyMlirContext contextWrapper)
static PyDenseElementsAttribute getFromBuffer(const nb_buffer &array, bool signless, const std::optional< PyType > &explicitType, std::optional< std::vector< int64_t > > explicitShape, DefaultingPyMlirContext contextWrapper)
Refinement of PyDenseElementsAttribute for attributes containing floating-point values.
static constexpr IsAFunctionTy isaFunction
static void bindDerived(ClassTy &c)
nanobind::float_ dunderGetItem(intptr_t pos) const
Refinement of the PyDenseElementsAttribute for attributes containing integer (and boolean) values.
static void bindDerived(ClassTy &c)
nanobind::int_ dunderGetItem(intptr_t pos) const
Returns the element at the given linear position.
static constexpr IsAFunctionTy isaFunction
static PyDenseResourceElementsAttribute getFromBuffer(const nb_buffer &buffer, const std::string &name, const PyType &type, std::optional< size_t > alignment, bool isMutable, DefaultingPyMlirContext contextWrapper)
static void bindDerived(ClassTy &c)
static const MlirStringRef name
static void bindDerived(ClassTy &c)
intptr_t dunderLen() const
bool dunderContains(const std::string &name) const
static const MlirStringRef name
static constexpr IsAFunctionTy isaFunction
static void bindDerived(ClassTy &c)
Float Point Attribute subclass - FloatAttr.
static void bindDerived(ClassTy &c)
static PyGlobals & get()
Most code should get the globals via this static accessor.
void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster, bool replace=false)
Adds a user-friendly type caster.
Integer Attribute subclass - IntegerAttr.
static constexpr IsAFunctionTy isaFunction
static void bindDerived(ClassTy &c)
static void bindDerived(ClassTy &c)
MlirIntegerSet get() const
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
MlirContext get()
Accesses the underlying MlirContext.
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
Represents a Python MlirNamedAttr, carrying an optional owned name.
static void bindDerived(ClassTy &c)
Strided layout attribute subclass.
static void bindDerived(ClassTy &c)
static void bindDerived(ClassTy &c)
static void bindDerived(ClassTy &c)
static PySymbolRefAttribute fromList(const std::vector< std::string > &symbols, PyMlirContext &context)
static constexpr IsAFunctionTy isaFunction
static void bindDerived(ClassTy &c)
A TypeID provides an efficient and unique identifier for a specific C++ type.
Wrapper around the generic MlirType.
nanobind::typed< nanobind::object, PyType > maybeDownCast()
Unit Attribute subclass. Unit attributes don't have values.
static void bindDerived(ClassTy &c)
mlir::Diagnostic & unwrap(MlirDiagnostic diagnostic)
MLIR_CAPI_EXPORTED MlirAttribute mlirAffineMapAttrGet(MlirAffineMap map)
Creates an affine map attribute wrapping the given map.
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 uint8_t mlirDenseElementsAttrGetUInt8Value(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED int64_t mlirStridedLayoutAttrGetOffset(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 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 uint64_t mlirDenseElementsAttrGetIndexValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED const void * mlirDenseElementsAttrGetRawData(MlirAttribute attr)
Returns the raw data of the given dense elements attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirIntegerAttrGetTypeID(void)
Returns the typeID of an Integer attribute.
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 MlirTypeID mlirDenseIntOrFPElementsAttrGetTypeID(void)
Returns the typeID of an DenseIntOrFPElements 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 MlirAttribute mlirIntegerAttrGet(MlirType type, int64_t value)
Creates an integer attribute of the given type with the given integer value.
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 MlirAttribute mlirSymbolRefAttrGetNestedReference(MlirAttribute attr, intptr_t pos)
Returns pos-th reference nested in the given symbol reference attribute.
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 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 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 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 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 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 float mlirDenseElementsAttrGetFloatValue(MlirAttribute attr, intptr_t pos)
MLIR_CAPI_EXPORTED int64_t mlirElementsAttrGetNumElements(MlirAttribute attr)
Gets the total number of elements in the given elements attribute.
MLIR_CAPI_EXPORTED MlirStringRef mlirOpaqueAttrGetDialectNamespace(MlirAttribute attr)
Returns the namespace of the dialect with which the given opaque attribute is associated.
MLIR_CAPI_EXPORTED 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 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 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 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 MlirAttribute mlirDenseElementsAttrSplatGet(MlirType shapedType, MlirAttribute element)
Creates a dense elements attribute with the given Shaped type containing a single replicated element ...
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 MlirAttribute mlirStringAttrTypedGet(MlirType type, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED MlirStringRef mlirFlatSymbolRefAttrGetValue(MlirAttribute attr)
Returns the referenced symbol as a string reference.
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.
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 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 MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
nb::object denseIntOrFPElementsAttributeCaster(PyAttribute &pyAttribute)
nb::object symbolRefOrFlatSymbolRefAttributeCaster(PyAttribute &pyAttribute)
nb::object integerOrBoolAttributeCaster(PyAttribute &pyAttribute)
MlirStringRef toMlirStringRef(const std::string &s)
static T pyTryCast(nanobind::handle object)
nb::object denseArrayAttributeCaster(PyAttribute &pyAttribute)
MLIR_PYTHON_API_EXPORTED void populateIRAttributes(nanobind::module_ &m)
Include the generated interface declarations.
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.
Instantiate the python dense array classes.
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
static constexpr IsAFunctionTy isaFunction
RAII object that captures any error diagnostics emitted to the provided context.
std::vector< PyDiagnostic::DiagnosticInfo > take()
SmallVector< ssize_t, 4 > strides
nb_buffer_info(void *ptr, ssize_t itemsize, const char *format, ssize_t ndim, SmallVector< ssize_t, 4 > shape_in, SmallVector< ssize_t, 4 > strides_in, bool readonly=false, std::unique_ptr< Py_buffer, void(*)(Py_buffer *)> owned_view_in=std::unique_ptr< Py_buffer, void(*)(Py_buffer *)>(nullptr, nullptr))
SmallVector< ssize_t, 4 > shape
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()
static const char * format()