[Mlir-commits] [mlir] e78b745 - [mlir][python] Makes C++ extension code relocatable by way of a macro.

Stella Laurenzo llvmlistbot at llvm.org
Sun Aug 22 14:26:35 PDT 2021


Author: Stella Laurenzo
Date: 2021-08-22T13:46:14-07:00
New Revision: e78b745cf259472f58eb0790cfc6eb0443e009e1

URL: https://github.com/llvm/llvm-project/commit/e78b745cf259472f58eb0790cfc6eb0443e009e1
DIFF: https://github.com/llvm/llvm-project/commit/e78b745cf259472f58eb0790cfc6eb0443e009e1.diff

LOG: [mlir][python] Makes C++ extension code relocatable by way of a macro.

* Resolves a TODO by making this configurable by downstreams.
* This seems to be the last thing allowing full use of the Python bindings as a library within another project (i.e. be embedding them).

Differential Revision: https://reviews.llvm.org/D108523

Added: 
    

Modified: 
    mlir/include/mlir-c/Bindings/Python/Interop.h
    mlir/include/mlir/Bindings/Python/PybindAdaptors.h

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir-c/Bindings/Python/Interop.h b/mlir/include/mlir-c/Bindings/Python/Interop.h
index 882f73d84383e..7fcfd028b407d 100644
--- a/mlir/include/mlir-c/Bindings/Python/Interop.h
+++ b/mlir/include/mlir-c/Bindings/Python/Interop.h
@@ -30,19 +30,44 @@
 #include "mlir-c/IntegerSet.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_ATTRIBUTE "mlir.ir.Attribute._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_CONTEXT "mlir.ir.Context._CAPIPtr"
+// The 'mlir' Python package is relocatable and supports co-existing in multiple
+// projects. Each project must define its outer package prefix with this define
+// in order to provide proper isolation and local name resolution.
+// The default is for the upstream "import mlir" package layout.
+// Note that this prefix is internally stringified, allowing it to be passed
+// unquoted on the compiler command line without shell quote escaping issues.
+#ifndef MLIR_PYTHON_PACKAGE_PREFIX
+#define MLIR_PYTHON_PACKAGE_PREFIX mlir.
+#endif
+
+// Makes a fully-qualified name relative to the MLIR python package.
+#define MLIR_PYTHON_STRINGIZE(s) #s
+#define MLIR_PYTHON_STRINGIZE_ARG(arg) MLIR_PYTHON_STRINGIZE(arg)
+#define MAKE_MLIR_PYTHON_QUALNAME(local)                                       \
+  MLIR_PYTHON_STRINGIZE_ARG(MLIR_PYTHON_PACKAGE_PREFIX) local
+
+#define MLIR_PYTHON_CAPSULE_AFFINE_EXPR                                        \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.AffineExpr._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_AFFINE_MAP                                         \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.AffineMap._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_ATTRIBUTE                                          \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.Attribute._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_CONTEXT                                            \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.Context._CAPIPtr")
 #define MLIR_PYTHON_CAPSULE_EXECUTION_ENGINE                                   \
-  "mlir.execution_engine.ExecutionEngine._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_INTEGER_SET "mlir.ir.IntegerSet._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_LOCATION "mlir.ir.Location._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_MODULE "mlir.ir.Module._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_OPERATION "mlir.ir.Operation._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_TYPE "mlir.ir.Type._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_PASS_MANAGER "mlir.passmanager.PassManager._CAPIPtr"
-#define MLIR_PYTHON_CAPSULE_VALUE "mlir.ir.Value._CAPIPtr"
+  MAKE_MLIR_PYTHON_QUALNAME("execution_engine.ExecutionEngine._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_INTEGER_SET                                        \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.IntegerSet._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_LOCATION                                           \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.Location._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_MODULE                                             \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.Module._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_OPERATION                                          \
+  MAKE_MLIR_PYTHON_QUALNAME("ir.Operation._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_TYPE MAKE_MLIR_PYTHON_QUALNAME("ir.Type._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_PASS_MANAGER                                       \
+  MAKE_MLIR_PYTHON_QUALNAME("passmanager.PassManager._CAPIPtr")
+#define MLIR_PYTHON_CAPSULE_VALUE MAKE_MLIR_PYTHON_QUALNAME("ir.Value._CAPIPtr")
 
 /** Attribute on MLIR Python objects that expose their C-API pointer.
  * This will be a type-specific capsule created as per one of the helpers

diff  --git a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
index db8769d3c35f3..61b982193c029 100644
--- a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
@@ -30,10 +30,6 @@
 
 namespace py = pybind11;
 
-// TODO: Move this to Interop.h and make it externally configurable/use it
-// consistently to locate the "import mlir" top-level.
-#define MLIR_PYTHON_PACKAGE_PREFIX "mlir."
-
 // Raw CAPI type casters need to be declared before use, so always include them
 // first.
 namespace pybind11 {
@@ -76,7 +72,7 @@ struct type_caster<MlirAffineMap> {
   static handle cast(MlirAffineMap v, return_value_policy, handle) {
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonAffineMapToCapsule(v));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("AffineMap")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -98,7 +94,7 @@ struct type_caster<MlirAttribute> {
   static handle cast(MlirAttribute v, return_value_policy, handle) {
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonAttributeToCapsule(v));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("Attribute")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -115,7 +111,7 @@ struct type_caster<MlirContext> {
       // TODO: This raises an error of "No current context" currently.
       // Update the implementation to pretty-print the helpful error that the
       // core implementations print in this case.
-      src = py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+      src = py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
                 .attr("Context")
                 .attr("current");
     }
@@ -144,7 +140,7 @@ struct type_caster<MlirLocation> {
   static handle cast(MlirLocation v, return_value_policy, handle) {
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonLocationToCapsule(v));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("Location")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -166,7 +162,7 @@ struct type_caster<MlirModule> {
   static handle cast(MlirModule v, return_value_policy, handle) {
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonModuleToCapsule(v));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("Module")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -190,7 +186,7 @@ struct type_caster<MlirOperation> {
       return py::none();
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonOperationToCapsule(v));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("Operation")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -226,7 +222,7 @@ struct type_caster<MlirType> {
   static handle cast(MlirType t, return_value_policy, handle) {
     py::object capsule =
         py::reinterpret_steal<py::object>(mlirPythonTypeToCapsule(t));
-    return py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+    return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
         .attr("Type")
         .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
         .release();
@@ -266,7 +262,7 @@ class pure_subclass {
   }
 
   template <typename Func, typename... Extra>
-  pure_subclass &def(const char *name, Func &&f, const Extra &...extra) {
+  pure_subclass &def(const char *name, Func &&f, const Extra &... extra) {
     py::cpp_function cf(
         std::forward<Func>(f), py::name(name), py::is_method(py::none()),
         py::sibling(py::getattr(thisClass, name, py::none())), extra...);
@@ -276,7 +272,7 @@ class pure_subclass {
 
   template <typename Func, typename... Extra>
   pure_subclass &def_property_readonly(const char *name, Func &&f,
-                                       const Extra &...extra) {
+                                       const Extra &... extra) {
     py::cpp_function cf(
         std::forward<Func>(f), py::name(name), py::is_method(py::none()),
         py::sibling(py::getattr(thisClass, name, py::none())), extra...);
@@ -288,7 +284,7 @@ class pure_subclass {
 
   template <typename Func, typename... Extra>
   pure_subclass &def_staticmethod(const char *name, Func &&f,
-                                  const Extra &...extra) {
+                                  const Extra &... extra) {
     static_assert(!std::is_member_function_pointer<Func>::value,
                   "def_staticmethod(...) called with a non-static member "
                   "function pointer");
@@ -301,7 +297,7 @@ class pure_subclass {
 
   template <typename Func, typename... Extra>
   pure_subclass &def_classmethod(const char *name, Func &&f,
-                                 const Extra &...extra) {
+                                 const Extra &... extra) {
     static_assert(!std::is_member_function_pointer<Func>::value,
                   "def_classmethod(...) called with a non-static member "
                   "function pointer");
@@ -329,7 +325,7 @@ class mlir_attribute_subclass : public pure_subclass {
                           IsAFunctionTy isaFunction)
       : mlir_attribute_subclass(
             scope, attrClassName, isaFunction,
-            py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir")
+            py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
                 .attr("Attribute")) {}
 
   /// Subclasses with a provided mlir.ir.Attribute super-class. This must
@@ -381,7 +377,7 @@ class mlir_type_subclass : public pure_subclass {
                      IsAFunctionTy isaFunction)
       : mlir_type_subclass(
             scope, typeClassName, isaFunction,
-            py::module::import(MLIR_PYTHON_PACKAGE_PREFIX "ir").attr("Type")) {}
+            py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir")).attr("Type")) {}
 
   /// Subclasses with a provided mlir.ir.Type super-class. This must
   /// be used if the subclass is being defined in the same extension module


        


More information about the Mlir-commits mailing list