forked from OSchip/llvm-project
[mlir] Add Python bindings for AffineExpr
This adds the Python bindings for AffineExpr and a couple of utility functions to the C API. AffineExpr is a top-level context-owned object and is modeled similarly to attributes and types. It is required, e.g., to build layout maps of the built-in memref type. Reviewed By: mehdi_amini Differential Revision: https://reviews.llvm.org/D94225
This commit is contained in:
parent
bcec0f27a2
commit
74628c4305
|
@ -45,6 +45,16 @@ DEFINE_C_API_STRUCT(MlirAffineExpr, const void);
|
||||||
MLIR_CAPI_EXPORTED MlirContext
|
MLIR_CAPI_EXPORTED MlirContext
|
||||||
mlirAffineExprGetContext(MlirAffineExpr affineExpr);
|
mlirAffineExprGetContext(MlirAffineExpr affineExpr);
|
||||||
|
|
||||||
|
/// Returns `true` if the two affine expressions are equal.
|
||||||
|
MLIR_CAPI_EXPORTED bool mlirAffineExprEqual(MlirAffineExpr lhs,
|
||||||
|
MlirAffineExpr rhs);
|
||||||
|
|
||||||
|
/// Returns `true` if the given affine expression is a null expression. Note
|
||||||
|
/// constant zero is not a null expression.
|
||||||
|
inline bool mlirAffineExprIsNull(MlirAffineExpr affineExpr) {
|
||||||
|
return affineExpr.ptr == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** Prints an affine expression by sending chunks of the string representation
|
/** Prints an affine expression by sending chunks of the string representation
|
||||||
* and forwarding `userData to `callback`. Note that the callback may be called
|
* and forwarding `userData to `callback`. Note that the callback may be called
|
||||||
* several times with consecutive chunks of the string. */
|
* several times with consecutive chunks of the string. */
|
||||||
|
@ -82,6 +92,9 @@ MLIR_CAPI_EXPORTED bool mlirAffineExprIsFunctionOfDim(MlirAffineExpr affineExpr,
|
||||||
// Affine Dimension Expression.
|
// Affine Dimension Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// Checks whether the given affine expression is a dimension expression.
|
||||||
|
MLIR_CAPI_EXPORTED bool mlirAffineExprIsADim(MlirAffineExpr affineExpr);
|
||||||
|
|
||||||
/// Creates an affine dimension expression with 'position' in the context.
|
/// Creates an affine dimension expression with 'position' in the context.
|
||||||
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx,
|
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx,
|
||||||
intptr_t position);
|
intptr_t position);
|
||||||
|
@ -94,6 +107,9 @@ mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr);
|
||||||
// Affine Symbol Expression.
|
// Affine Symbol Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// Checks whether the given affine expression is a symbol expression.
|
||||||
|
MLIR_CAPI_EXPORTED bool mlirAffineExprIsASymbol(MlirAffineExpr affineExpr);
|
||||||
|
|
||||||
/// Creates an affine symbol expression with 'position' in the context.
|
/// Creates an affine symbol expression with 'position' in the context.
|
||||||
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx,
|
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx,
|
||||||
intptr_t position);
|
intptr_t position);
|
||||||
|
@ -106,6 +122,9 @@ mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr);
|
||||||
// Affine Constant Expression.
|
// Affine Constant Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// Checks whether the given affine expression is a constant expression.
|
||||||
|
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAConstant(MlirAffineExpr affineExpr);
|
||||||
|
|
||||||
/// Creates an affine constant expression with 'constant' in the context.
|
/// Creates an affine constant expression with 'constant' in the context.
|
||||||
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx,
|
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx,
|
||||||
int64_t constant);
|
int64_t constant);
|
||||||
|
@ -173,6 +192,9 @@ MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs,
|
||||||
// Affine Binary Operation Expression.
|
// Affine Binary Operation Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// Checks whether the given affine expression is binary.
|
||||||
|
MLIR_CAPI_EXPORTED bool mlirAffineExprIsABinary(MlirAffineExpr affineExpr);
|
||||||
|
|
||||||
/** Returns the left hand side affine expression of the given affine binary
|
/** Returns the left hand side affine expression of the given affine binary
|
||||||
* operation expression. */
|
* operation expression. */
|
||||||
MLIR_CAPI_EXPORTED MlirAffineExpr
|
MLIR_CAPI_EXPORTED MlirAffineExpr
|
||||||
|
|
|
@ -23,10 +23,12 @@
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include "mlir-c/AffineExpr.h"
|
||||||
#include "mlir-c/AffineMap.h"
|
#include "mlir-c/AffineMap.h"
|
||||||
#include "mlir-c/IR.h"
|
#include "mlir-c/IR.h"
|
||||||
#include "mlir-c/Pass.h"
|
#include "mlir-c/Pass.h"
|
||||||
|
|
||||||
|
#define MLIR_PYTHON_CAPSULE_AFFINE_EXPR "mlir.ir.AffineExpr._CAPIPtr"
|
||||||
#define MLIR_PYTHON_CAPSULE_AFFINE_MAP "mlir.ir.AffineMap._CAPIPtr"
|
#define MLIR_PYTHON_CAPSULE_AFFINE_MAP "mlir.ir.AffineMap._CAPIPtr"
|
||||||
#define MLIR_PYTHON_CAPSULE_ATTRIBUTE "mlir.ir.Attribute._CAPIPtr"
|
#define MLIR_PYTHON_CAPSULE_ATTRIBUTE "mlir.ir.Attribute._CAPIPtr"
|
||||||
#define MLIR_PYTHON_CAPSULE_CONTEXT "mlir.ir.Context._CAPIPtr"
|
#define MLIR_PYTHON_CAPSULE_CONTEXT "mlir.ir.Context._CAPIPtr"
|
||||||
|
@ -72,6 +74,25 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Creates a capsule object encapsulating the raw C-API MlirAffineExpr. The
|
||||||
|
* returned capsule does not extend or affect ownership of any Python objects
|
||||||
|
* that reference the expression in any way.
|
||||||
|
*/
|
||||||
|
static inline PyObject *mlirPythonAffineExprToCapsule(MlirAffineExpr expr) {
|
||||||
|
return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(expr),
|
||||||
|
MLIR_PYTHON_CAPSULE_AFFINE_EXPR, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extracts an MlirAffineExpr from a capsule as produced from
|
||||||
|
* mlirPythonAffineExprToCapsule. If the capsule is not of the right type, then
|
||||||
|
* a null expression is returned (as checked via mlirAffineExprIsNull). In such
|
||||||
|
* a case, the Python APIs will have already set an error. */
|
||||||
|
static inline MlirAffineExpr mlirPythonCapsuleToAffineExpr(PyObject *capsule) {
|
||||||
|
void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_AFFINE_EXPR);
|
||||||
|
MlirAffineExpr expr = {ptr};
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates a capsule object encapsulating the raw C-API MlirAttribute.
|
/** Creates a capsule object encapsulating the raw C-API MlirAttribute.
|
||||||
* The returned capsule does not extend or affect ownership of any Python
|
* The returned capsule does not extend or affect ownership of any Python
|
||||||
* objects that reference the attribute in any way.
|
* objects that reference the attribute in any way.
|
||||||
|
|
|
@ -2710,6 +2710,238 @@ public:
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// PyAffineExpr and subclasses.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
/// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
|
||||||
|
/// and should be castable from it. Intermediate hierarchy classes can be
|
||||||
|
/// modeled by specifying BaseTy.
|
||||||
|
template <typename DerivedTy, typename BaseTy = PyAffineExpr>
|
||||||
|
class PyConcreteAffineExpr : public BaseTy {
|
||||||
|
public:
|
||||||
|
// Derived classes must define statics for:
|
||||||
|
// IsAFunctionTy isaFunction
|
||||||
|
// const char *pyClassName
|
||||||
|
// and redefine bindDerived.
|
||||||
|
using ClassTy = py::class_<DerivedTy, BaseTy>;
|
||||||
|
using IsAFunctionTy = bool (*)(MlirAffineExpr);
|
||||||
|
|
||||||
|
PyConcreteAffineExpr() = default;
|
||||||
|
PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
|
||||||
|
: BaseTy(std::move(contextRef), affineExpr) {}
|
||||||
|
PyConcreteAffineExpr(PyAffineExpr &orig)
|
||||||
|
: PyConcreteAffineExpr(orig.getContext(), castFrom(orig)) {}
|
||||||
|
|
||||||
|
static MlirAffineExpr castFrom(PyAffineExpr &orig) {
|
||||||
|
if (!DerivedTy::isaFunction(orig)) {
|
||||||
|
auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
|
||||||
|
throw SetPyError(PyExc_ValueError,
|
||||||
|
Twine("Cannot cast affine expression to ") +
|
||||||
|
DerivedTy::pyClassName + " (from " + origRepr + ")");
|
||||||
|
}
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bind(py::module &m) {
|
||||||
|
auto cls = ClassTy(m, DerivedTy::pyClassName);
|
||||||
|
cls.def(py::init<PyAffineExpr &>());
|
||||||
|
DerivedTy::bindDerived(cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implemented by derived classes to add methods to the Python subclass.
|
||||||
|
static void bindDerived(ClassTy &m) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAConstant;
|
||||||
|
static constexpr const char *pyClassName = "AffineConstantExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineConstantExpr get(intptr_t value,
|
||||||
|
DefaultingPyMlirContext context) {
|
||||||
|
MlirAffineExpr affineExpr =
|
||||||
|
mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
|
||||||
|
return PyAffineConstantExpr(context->getRef(), affineExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineConstantExpr::get, py::arg("value"),
|
||||||
|
py::arg("context") = py::none());
|
||||||
|
c.def_property_readonly("value", [](PyAffineConstantExpr &self) {
|
||||||
|
return mlirAffineConstantExprGetValue(self);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsADim;
|
||||||
|
static constexpr const char *pyClassName = "AffineDimExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context) {
|
||||||
|
MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
|
||||||
|
return PyAffineDimExpr(context->getRef(), affineExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineDimExpr::get, py::arg("position"),
|
||||||
|
py::arg("context") = py::none());
|
||||||
|
c.def_property_readonly("position", [](PyAffineDimExpr &self) {
|
||||||
|
return mlirAffineDimExprGetPosition(self);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsASymbol;
|
||||||
|
static constexpr const char *pyClassName = "AffineSymbolExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context) {
|
||||||
|
MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
|
||||||
|
return PyAffineSymbolExpr(context->getRef(), affineExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineSymbolExpr::get, py::arg("position"),
|
||||||
|
py::arg("context") = py::none());
|
||||||
|
c.def_property_readonly("position", [](PyAffineSymbolExpr &self) {
|
||||||
|
return mlirAffineSymbolExprGetPosition(self);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsABinary;
|
||||||
|
static constexpr const char *pyClassName = "AffineBinaryExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
PyAffineExpr lhs() {
|
||||||
|
MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
|
||||||
|
return PyAffineExpr(getContext(), lhsExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyAffineExpr rhs() {
|
||||||
|
MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
|
||||||
|
return PyAffineExpr(getContext(), rhsExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_property_readonly("lhs", &PyAffineBinaryExpr::lhs);
|
||||||
|
c.def_property_readonly("rhs", &PyAffineBinaryExpr::rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineAddExpr
|
||||||
|
: public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAAdd;
|
||||||
|
static constexpr const char *pyClassName = "AffineAddExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineAddExpr get(PyAffineExpr lhs, PyAffineExpr rhs) {
|
||||||
|
MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
|
||||||
|
return PyAffineAddExpr(lhs.getContext(), expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineAddExpr::get);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineMulExpr
|
||||||
|
: public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMul;
|
||||||
|
static constexpr const char *pyClassName = "AffineMulExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineMulExpr get(PyAffineExpr lhs, PyAffineExpr rhs) {
|
||||||
|
MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
|
||||||
|
return PyAffineMulExpr(lhs.getContext(), expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineMulExpr::get);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineModExpr
|
||||||
|
: public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMod;
|
||||||
|
static constexpr const char *pyClassName = "AffineModExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineModExpr get(PyAffineExpr lhs, PyAffineExpr rhs) {
|
||||||
|
MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
|
||||||
|
return PyAffineModExpr(lhs.getContext(), expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineModExpr::get);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineFloorDivExpr
|
||||||
|
: public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAFloorDiv;
|
||||||
|
static constexpr const char *pyClassName = "AffineFloorDivExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineFloorDivExpr get(PyAffineExpr lhs, PyAffineExpr rhs) {
|
||||||
|
MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
|
||||||
|
return PyAffineFloorDivExpr(lhs.getContext(), expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineFloorDivExpr::get);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyAffineCeilDivExpr
|
||||||
|
: public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
|
||||||
|
public:
|
||||||
|
static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsACeilDiv;
|
||||||
|
static constexpr const char *pyClassName = "AffineCeilDivExpr";
|
||||||
|
using PyConcreteAffineExpr::PyConcreteAffineExpr;
|
||||||
|
|
||||||
|
static PyAffineCeilDivExpr get(PyAffineExpr lhs, PyAffineExpr rhs) {
|
||||||
|
MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
|
||||||
|
return PyAffineCeilDivExpr(lhs.getContext(), expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindDerived(ClassTy &c) {
|
||||||
|
c.def_static("get", &PyAffineCeilDivExpr::get);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool PyAffineExpr::operator==(const PyAffineExpr &other) {
|
||||||
|
return mlirAffineExprEqual(affineExpr, other.affineExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
py::object PyAffineExpr::getCapsule() {
|
||||||
|
return py::reinterpret_steal<py::object>(
|
||||||
|
mlirPythonAffineExprToCapsule(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
PyAffineExpr PyAffineExpr::createFromCapsule(py::object capsule) {
|
||||||
|
MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
|
||||||
|
if (mlirAffineExprIsNull(rawAffineExpr))
|
||||||
|
throw py::error_already_set();
|
||||||
|
return PyAffineExpr(
|
||||||
|
PyMlirContext::forContext(mlirAffineExprGetContext(rawAffineExpr)),
|
||||||
|
rawAffineExpr);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// PyAffineMap.
|
// PyAffineMap.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -3414,6 +3646,94 @@ void mlir::python::populateIRSubmodule(py::module &m) {
|
||||||
PyRegionIterator::bind(m);
|
PyRegionIterator::bind(m);
|
||||||
PyRegionList::bind(m);
|
PyRegionList::bind(m);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Mapping of PyAffineExpr and derived classes.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
py::class_<PyAffineExpr>(m, "AffineExpr")
|
||||||
|
.def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
|
||||||
|
&PyAffineExpr::getCapsule)
|
||||||
|
.def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineExpr::createFromCapsule)
|
||||||
|
.def("__add__",
|
||||||
|
[](PyAffineExpr &self, PyAffineExpr &other) {
|
||||||
|
return PyAffineAddExpr::get(self, other);
|
||||||
|
})
|
||||||
|
.def("__mul__",
|
||||||
|
[](PyAffineExpr &self, PyAffineExpr &other) {
|
||||||
|
return PyAffineMulExpr::get(self, other);
|
||||||
|
})
|
||||||
|
.def("__mod__",
|
||||||
|
[](PyAffineExpr &self, PyAffineExpr &other) {
|
||||||
|
return PyAffineModExpr::get(self, other);
|
||||||
|
})
|
||||||
|
.def("__sub__",
|
||||||
|
[](PyAffineExpr &self, PyAffineExpr &other) {
|
||||||
|
auto negOne =
|
||||||
|
PyAffineConstantExpr::get(-1, *self.getContext().get());
|
||||||
|
return PyAffineAddExpr::get(self,
|
||||||
|
PyAffineMulExpr::get(negOne, other));
|
||||||
|
})
|
||||||
|
.def("__eq__", [](PyAffineExpr &self,
|
||||||
|
PyAffineExpr &other) { return self == other; })
|
||||||
|
.def("__eq__",
|
||||||
|
[](PyAffineExpr &self, py::object &other) { return false; })
|
||||||
|
.def("__str__",
|
||||||
|
[](PyAffineExpr &self) {
|
||||||
|
PyPrintAccumulator printAccum;
|
||||||
|
mlirAffineExprPrint(self, printAccum.getCallback(),
|
||||||
|
printAccum.getUserData());
|
||||||
|
return printAccum.join();
|
||||||
|
})
|
||||||
|
.def("__repr__",
|
||||||
|
[](PyAffineExpr &self) {
|
||||||
|
PyPrintAccumulator printAccum;
|
||||||
|
printAccum.parts.append("AffineExpr(");
|
||||||
|
mlirAffineExprPrint(self, printAccum.getCallback(),
|
||||||
|
printAccum.getUserData());
|
||||||
|
printAccum.parts.append(")");
|
||||||
|
return printAccum.join();
|
||||||
|
})
|
||||||
|
.def_property_readonly(
|
||||||
|
"context",
|
||||||
|
[](PyAffineExpr &self) { return self.getContext().getObject(); })
|
||||||
|
.def_static(
|
||||||
|
"get_add", &PyAffineAddExpr::get,
|
||||||
|
"Gets an affine expression containing a sum of two expressions.")
|
||||||
|
.def_static(
|
||||||
|
"get_mul", &PyAffineMulExpr::get,
|
||||||
|
"Gets an affine expression containing a product of two expressions.")
|
||||||
|
.def_static("get_mod", &PyAffineModExpr::get,
|
||||||
|
"Gets an affine expression containing the modulo of dividing "
|
||||||
|
"one expression by another.")
|
||||||
|
.def_static("get_floor_div", &PyAffineFloorDivExpr::get,
|
||||||
|
"Gets an affine expression containing the rounded-down "
|
||||||
|
"result of dividing one expression by another.")
|
||||||
|
.def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
|
||||||
|
"Gets an affine expression containing the rounded-up result "
|
||||||
|
"of dividing one expression by another.")
|
||||||
|
.def_static("get_constant", &PyAffineConstantExpr::get, py::arg("value"),
|
||||||
|
py::arg("context") = py::none(),
|
||||||
|
"Gets a constant affine expression with the given value.")
|
||||||
|
.def_static(
|
||||||
|
"get_dim", &PyAffineDimExpr::get, py::arg("position"),
|
||||||
|
py::arg("context") = py::none(),
|
||||||
|
"Gets an affine expression of a dimension at the given position.")
|
||||||
|
.def_static(
|
||||||
|
"get_symbol", &PyAffineSymbolExpr::get, py::arg("position"),
|
||||||
|
py::arg("context") = py::none(),
|
||||||
|
"Gets an affine expression of a symbol at the given position.")
|
||||||
|
.def(
|
||||||
|
"dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
|
||||||
|
kDumpDocstring);
|
||||||
|
PyAffineConstantExpr::bind(m);
|
||||||
|
PyAffineDimExpr::bind(m);
|
||||||
|
PyAffineSymbolExpr::bind(m);
|
||||||
|
PyAffineBinaryExpr::bind(m);
|
||||||
|
PyAffineAddExpr::bind(m);
|
||||||
|
PyAffineMulExpr::bind(m);
|
||||||
|
PyAffineModExpr::bind(m);
|
||||||
|
PyAffineFloorDivExpr::bind(m);
|
||||||
|
PyAffineCeilDivExpr::bind(m);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Mapping of PyAffineMap.
|
// Mapping of PyAffineMap.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "PybindUtils.h"
|
#include "PybindUtils.h"
|
||||||
|
|
||||||
|
#include "mlir-c/AffineExpr.h"
|
||||||
#include "mlir-c/AffineMap.h"
|
#include "mlir-c/AffineMap.h"
|
||||||
#include "mlir-c/IR.h"
|
#include "mlir-c/IR.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
@ -668,6 +669,34 @@ private:
|
||||||
MlirValue value;
|
MlirValue value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
|
||||||
|
class PyAffineExpr : public BaseContextObject {
|
||||||
|
public:
|
||||||
|
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
|
||||||
|
: BaseContextObject(std::move(contextRef)), affineExpr(affineExpr) {}
|
||||||
|
bool operator==(const PyAffineExpr &other);
|
||||||
|
operator MlirAffineExpr() const { return affineExpr; }
|
||||||
|
MlirAffineExpr get() const { return affineExpr; }
|
||||||
|
|
||||||
|
/// Gets a capsule wrapping the void* within the MlirAffineExpr.
|
||||||
|
pybind11::object getCapsule();
|
||||||
|
|
||||||
|
/// Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
|
||||||
|
/// Note that PyAffineExpr instances are uniqued, so the returned object
|
||||||
|
/// may be a pre-existing object. Ownership of the underlying MlirAffineExpr
|
||||||
|
/// is taken by calling this function.
|
||||||
|
static PyAffineExpr createFromCapsule(pybind11::object capsule);
|
||||||
|
|
||||||
|
PyAffineExpr add(const PyAffineExpr &other) const;
|
||||||
|
PyAffineExpr mul(const PyAffineExpr &other) const;
|
||||||
|
PyAffineExpr floorDiv(const PyAffineExpr &other) const;
|
||||||
|
PyAffineExpr ceilDiv(const PyAffineExpr &other) const;
|
||||||
|
PyAffineExpr mod(const PyAffineExpr &other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MlirAffineExpr affineExpr;
|
||||||
|
};
|
||||||
|
|
||||||
class PyAffineMap : public BaseContextObject {
|
class PyAffineMap : public BaseContextObject {
|
||||||
public:
|
public:
|
||||||
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
|
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
|
||||||
|
|
|
@ -21,6 +21,10 @@ MlirContext mlirAffineExprGetContext(MlirAffineExpr affineExpr) {
|
||||||
return wrap(unwrap(affineExpr).getContext());
|
return wrap(unwrap(affineExpr).getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mlirAffineExprEqual(MlirAffineExpr lhs, MlirAffineExpr rhs) {
|
||||||
|
return unwrap(lhs) == unwrap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback,
|
void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback,
|
||||||
void *userData) {
|
void *userData) {
|
||||||
mlir::detail::CallbackOstream stream(callback, userData);
|
mlir::detail::CallbackOstream stream(callback, userData);
|
||||||
|
@ -56,6 +60,10 @@ bool mlirAffineExprIsFunctionOfDim(MlirAffineExpr affineExpr,
|
||||||
// Affine Dimension Expression.
|
// Affine Dimension Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
bool mlirAffineExprIsADim(MlirAffineExpr affineExpr) {
|
||||||
|
return unwrap(affineExpr).isa<AffineDimExpr>();
|
||||||
|
}
|
||||||
|
|
||||||
MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position) {
|
MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position) {
|
||||||
return wrap(getAffineDimExpr(position, unwrap(ctx)));
|
return wrap(getAffineDimExpr(position, unwrap(ctx)));
|
||||||
}
|
}
|
||||||
|
@ -68,6 +76,10 @@ intptr_t mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr) {
|
||||||
// Affine Symbol Expression.
|
// Affine Symbol Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
bool mlirAffineExprIsASymbol(MlirAffineExpr affineExpr) {
|
||||||
|
return unwrap(affineExpr).isa<AffineSymbolExpr>();
|
||||||
|
}
|
||||||
|
|
||||||
MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position) {
|
MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position) {
|
||||||
return wrap(getAffineSymbolExpr(position, unwrap(ctx)));
|
return wrap(getAffineSymbolExpr(position, unwrap(ctx)));
|
||||||
}
|
}
|
||||||
|
@ -80,6 +92,10 @@ intptr_t mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr) {
|
||||||
// Affine Constant Expression.
|
// Affine Constant Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
bool mlirAffineExprIsAConstant(MlirAffineExpr affineExpr) {
|
||||||
|
return unwrap(affineExpr).isa<AffineConstantExpr>();
|
||||||
|
}
|
||||||
|
|
||||||
MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant) {
|
MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant) {
|
||||||
return wrap(getAffineConstantExpr(constant, unwrap(ctx)));
|
return wrap(getAffineConstantExpr(constant, unwrap(ctx)));
|
||||||
}
|
}
|
||||||
|
@ -159,6 +175,10 @@ MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs,
|
||||||
// Affine Binary Operation Expression.
|
// Affine Binary Operation Expression.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
bool mlirAffineExprIsABinary(MlirAffineExpr affineExpr) {
|
||||||
|
return unwrap(affineExpr).isa<AffineBinaryOpExpr>();
|
||||||
|
}
|
||||||
|
|
||||||
MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr) {
|
MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr) {
|
||||||
return wrap(unwrap(affineExpr).cast<AffineBinaryOpExpr>().getLHS());
|
return wrap(unwrap(affineExpr).cast<AffineBinaryOpExpr>().getLHS());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
# RUN: %PYTHON %s | FileCheck %s
|
||||||
|
|
||||||
|
import gc
|
||||||
|
from mlir.ir import *
|
||||||
|
|
||||||
|
def run(f):
|
||||||
|
print("\nTEST:", f.__name__)
|
||||||
|
f()
|
||||||
|
gc.collect()
|
||||||
|
assert Context._get_live_count() == 0
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprCapsule
|
||||||
|
def testAffineExprCapsule():
|
||||||
|
with Context() as ctx:
|
||||||
|
affine_expr = AffineExpr.get_constant(42)
|
||||||
|
|
||||||
|
affine_expr_capsule = affine_expr._CAPIPtr
|
||||||
|
# CHECK: capsule object
|
||||||
|
# CHECK: mlir.ir.AffineExpr._CAPIPtr
|
||||||
|
print(affine_expr_capsule)
|
||||||
|
|
||||||
|
affine_expr_2 = AffineExpr._CAPICreate(affine_expr_capsule)
|
||||||
|
assert affine_expr == affine_expr_2
|
||||||
|
assert affine_expr_2.context == ctx
|
||||||
|
|
||||||
|
run(testAffineExprCapsule)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprEq
|
||||||
|
def testAffineExprEq():
|
||||||
|
with Context():
|
||||||
|
a1 = AffineExpr.get_constant(42)
|
||||||
|
a2 = AffineExpr.get_constant(42)
|
||||||
|
a3 = AffineExpr.get_constant(43)
|
||||||
|
# CHECK: True
|
||||||
|
print(a1 == a1)
|
||||||
|
# CHECK: True
|
||||||
|
print(a1 == a2)
|
||||||
|
# CHECK: False
|
||||||
|
print(a1 == a3)
|
||||||
|
# CHECK: False
|
||||||
|
print(a1 == None)
|
||||||
|
# CHECK: False
|
||||||
|
print(a1 == "foo")
|
||||||
|
|
||||||
|
run(testAffineExprEq)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprContext
|
||||||
|
def testAffineExprContext():
|
||||||
|
with Context():
|
||||||
|
a1 = AffineExpr.get_constant(42)
|
||||||
|
with Context():
|
||||||
|
a2 = AffineExpr.get_constant(42)
|
||||||
|
|
||||||
|
# CHECK: False
|
||||||
|
print(a1 == a2)
|
||||||
|
|
||||||
|
run(testAffineExprContext)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprConstant
|
||||||
|
def testAffineExprConstant():
|
||||||
|
with Context():
|
||||||
|
a1 = AffineExpr.get_constant(42)
|
||||||
|
# CHECK: 42
|
||||||
|
print(a1.value)
|
||||||
|
# CHECK: 42
|
||||||
|
print(a1)
|
||||||
|
|
||||||
|
a2 = AffineConstantExpr.get(42)
|
||||||
|
# CHECK: 42
|
||||||
|
print(a2.value)
|
||||||
|
# CHECK: 42
|
||||||
|
print(a2)
|
||||||
|
|
||||||
|
assert a1 == a2
|
||||||
|
|
||||||
|
run(testAffineExprConstant)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprDim
|
||||||
|
def testAffineExprDim():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineExpr.get_dim(1)
|
||||||
|
d11 = AffineDimExpr.get(1)
|
||||||
|
d2 = AffineDimExpr.get(2)
|
||||||
|
|
||||||
|
# CHECK: 1
|
||||||
|
print(d1.position)
|
||||||
|
# CHECK: d1
|
||||||
|
print(d1)
|
||||||
|
|
||||||
|
# CHECK: 2
|
||||||
|
print(d2.position)
|
||||||
|
# CHECK: d2
|
||||||
|
print(d2)
|
||||||
|
|
||||||
|
assert d1 == d11
|
||||||
|
assert d1 != d2
|
||||||
|
|
||||||
|
run(testAffineExprDim)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprSymbol
|
||||||
|
def testAffineExprSymbol():
|
||||||
|
with Context():
|
||||||
|
s1 = AffineExpr.get_symbol(1)
|
||||||
|
s11 = AffineSymbolExpr.get(1)
|
||||||
|
s2 = AffineSymbolExpr.get(2)
|
||||||
|
|
||||||
|
# CHECK: 1
|
||||||
|
print(s1.position)
|
||||||
|
# CHECK: s1
|
||||||
|
print(s1)
|
||||||
|
|
||||||
|
# CHECK: 2
|
||||||
|
print(s2.position)
|
||||||
|
# CHEKC: s2
|
||||||
|
print(s2)
|
||||||
|
|
||||||
|
assert s1 == s11
|
||||||
|
assert s1 != s2
|
||||||
|
|
||||||
|
run(testAffineExprSymbol)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineAddExpr
|
||||||
|
def testAffineAddExpr():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
d2 = AffineDimExpr.get(2)
|
||||||
|
d12 = AffineExpr.get_add(d1, d2)
|
||||||
|
# CHECK: d1 + d2
|
||||||
|
print(d12)
|
||||||
|
|
||||||
|
d12op = d1 + d2
|
||||||
|
# CHECK: d1 + d2
|
||||||
|
print(d12op)
|
||||||
|
|
||||||
|
assert d12 == d12op
|
||||||
|
assert d12.lhs == d1
|
||||||
|
assert d12.rhs == d2
|
||||||
|
|
||||||
|
run(testAffineAddExpr)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineMulExpr
|
||||||
|
def testAffineMulExpr():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
c2 = AffineConstantExpr.get(2)
|
||||||
|
expr = AffineExpr.get_mul(d1, c2)
|
||||||
|
# CHECK: d1 * 2
|
||||||
|
print(expr)
|
||||||
|
|
||||||
|
# CHECK: d1 * 2
|
||||||
|
op = d1 * c2
|
||||||
|
print(op)
|
||||||
|
|
||||||
|
assert expr == op
|
||||||
|
assert expr.lhs == d1
|
||||||
|
assert expr.rhs == c2
|
||||||
|
|
||||||
|
run(testAffineMulExpr)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineModExpr
|
||||||
|
def testAffineModExpr():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
c2 = AffineConstantExpr.get(2)
|
||||||
|
expr = AffineExpr.get_mod(d1, c2)
|
||||||
|
# CHECK: d1 mod 2
|
||||||
|
print(expr)
|
||||||
|
|
||||||
|
# CHECK: d1 mod 2
|
||||||
|
op = d1 % c2
|
||||||
|
print(op)
|
||||||
|
|
||||||
|
assert expr == op
|
||||||
|
assert expr.lhs == d1
|
||||||
|
assert expr.rhs == c2
|
||||||
|
|
||||||
|
run(testAffineModExpr)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineFloorDivExpr
|
||||||
|
def testAffineFloorDivExpr():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
c2 = AffineConstantExpr.get(2)
|
||||||
|
expr = AffineExpr.get_floor_div(d1, c2)
|
||||||
|
# CHECK: d1 floordiv 2
|
||||||
|
print(expr)
|
||||||
|
|
||||||
|
assert expr.lhs == d1
|
||||||
|
assert expr.rhs == c2
|
||||||
|
|
||||||
|
run(testAffineFloorDivExpr)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineCeilDivExpr
|
||||||
|
def testAffineCeilDivExpr():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
c2 = AffineConstantExpr.get(2)
|
||||||
|
expr = AffineExpr.get_ceil_div(d1, c2)
|
||||||
|
# CHECK: d1 ceildiv 2
|
||||||
|
print(expr)
|
||||||
|
|
||||||
|
assert expr.lhs == d1
|
||||||
|
assert expr.rhs == c2
|
||||||
|
|
||||||
|
run(testAffineCeilDivExpr)
|
||||||
|
|
||||||
|
|
||||||
|
# CHECK-LABEL: TEST: testAffineExprSub
|
||||||
|
def testAffineExprSub():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
d2 = AffineDimExpr.get(2)
|
||||||
|
expr = d1 - d2
|
||||||
|
# CHECK: d1 - d2
|
||||||
|
print(expr)
|
||||||
|
|
||||||
|
assert expr.lhs == d1
|
||||||
|
rhs = AffineMulExpr(expr.rhs)
|
||||||
|
# CHECK: d2
|
||||||
|
print(rhs.lhs)
|
||||||
|
# CHECK: -1
|
||||||
|
print(rhs.rhs)
|
||||||
|
|
||||||
|
run(testAffineExprSub)
|
||||||
|
|
||||||
|
|
||||||
|
def testClassHierarchy():
|
||||||
|
with Context():
|
||||||
|
d1 = AffineDimExpr.get(1)
|
||||||
|
c2 = AffineConstantExpr.get(2)
|
||||||
|
add = AffineAddExpr.get(d1, c2)
|
||||||
|
mul = AffineMulExpr.get(d1, c2)
|
||||||
|
mod = AffineModExpr.get(d1, c2)
|
||||||
|
floor_div = AffineFloorDivExpr.get(d1, c2)
|
||||||
|
ceil_div = AffineCeilDivExpr.get(d1, c2)
|
||||||
|
|
||||||
|
# CHECK: False
|
||||||
|
print(isinstance(d1, AffineBinaryExpr))
|
||||||
|
# CHECK: False
|
||||||
|
print(isinstance(c2, AffineBinaryExpr))
|
||||||
|
# CHECK: True
|
||||||
|
print(isinstance(add, AffineBinaryExpr))
|
||||||
|
# CHECK: True
|
||||||
|
print(isinstance(mul, AffineBinaryExpr))
|
||||||
|
# CHECK: True
|
||||||
|
print(isinstance(mod, AffineBinaryExpr))
|
||||||
|
# CHECK: True
|
||||||
|
print(isinstance(floor_div, AffineBinaryExpr))
|
||||||
|
# CHECK: True
|
||||||
|
print(isinstance(ceil_div, AffineBinaryExpr))
|
||||||
|
|
||||||
|
try:
|
||||||
|
AffineBinaryExpr(d1)
|
||||||
|
except ValueError as e:
|
||||||
|
# CHECK: Cannot cast affine expression to AffineBinaryExpr
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
try:
|
||||||
|
AffineBinaryExpr(c2)
|
||||||
|
except ValueError as e:
|
||||||
|
# CHECK: Cannot cast affine expression to AffineBinaryExpr
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
run(testClassHierarchy)
|
|
@ -1251,6 +1251,27 @@ int printAffineExpr(MlirContext ctx) {
|
||||||
if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr))
|
if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr))
|
||||||
return 13;
|
return 13;
|
||||||
|
|
||||||
|
if (!mlirAffineExprIsABinary(affineAddExpr))
|
||||||
|
return 14;
|
||||||
|
|
||||||
|
// Test other 'IsA' method on affine expressions.
|
||||||
|
if (!mlirAffineExprIsAConstant(affineConstantExpr))
|
||||||
|
return 15;
|
||||||
|
|
||||||
|
if (!mlirAffineExprIsADim(affineDimExpr))
|
||||||
|
return 16;
|
||||||
|
|
||||||
|
if (!mlirAffineExprIsASymbol(affineSymbolExpr))
|
||||||
|
return 17;
|
||||||
|
|
||||||
|
// Test equality and nullity.
|
||||||
|
MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5);
|
||||||
|
if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr))
|
||||||
|
return 18;
|
||||||
|
|
||||||
|
if (mlirAffineExprIsNull(affineDimExpr))
|
||||||
|
return 19;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue