MLIR  20.0.0git
MainModule.cpp
Go to the documentation of this file.
1 //===- MainModule.cpp - Main pybind module --------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PybindUtils.h"
10 
11 #include "Globals.h"
12 #include "IRModule.h"
13 #include "Pass.h"
14 #include "Rewrite.h"
15 
16 namespace py = pybind11;
17 using namespace mlir;
18 using namespace py::literals;
19 using namespace mlir::python;
20 
21 // -----------------------------------------------------------------------------
22 // Module initialization.
23 // -----------------------------------------------------------------------------
24 
25 PYBIND11_MODULE(_mlir, m) {
26  m.doc() = "MLIR Python Native Extension";
27 
28  py::class_<PyGlobals>(m, "_Globals", py::module_local())
29  .def_property("dialect_search_modules",
30  &PyGlobals::getDialectSearchPrefixes,
31  &PyGlobals::setDialectSearchPrefixes)
32  .def(
33  "append_dialect_search_prefix",
34  [](PyGlobals &self, std::string moduleName) {
35  self.getDialectSearchPrefixes().push_back(std::move(moduleName));
36  },
37  "module_name"_a)
38  .def(
39  "_check_dialect_module_loaded",
40  [](PyGlobals &self, const std::string &dialectNamespace) {
41  return self.loadDialectModule(dialectNamespace);
42  },
43  "dialect_namespace"_a)
44  .def("_register_dialect_impl", &PyGlobals::registerDialectImpl,
45  "dialect_namespace"_a, "dialect_class"_a,
46  "Testing hook for directly registering a dialect")
47  .def("_register_operation_impl", &PyGlobals::registerOperationImpl,
48  "operation_name"_a, "operation_class"_a, py::kw_only(),
49  "replace"_a = false,
50  "Testing hook for directly registering an operation");
51 
52  // Aside from making the globals accessible to python, having python manage
53  // it is necessary to make sure it is destroyed (and releases its python
54  // resources) properly.
55  m.attr("globals") =
56  py::cast(new PyGlobals, py::return_value_policy::take_ownership);
57 
58  // Registration decorators.
59  m.def(
60  "register_dialect",
61  [](py::object pyClass) {
62  std::string dialectNamespace =
63  pyClass.attr("DIALECT_NAMESPACE").cast<std::string>();
64  PyGlobals::get().registerDialectImpl(dialectNamespace, pyClass);
65  return pyClass;
66  },
67  "dialect_class"_a,
68  "Class decorator for registering a custom Dialect wrapper");
69  m.def(
70  "register_operation",
71  [](const py::object &dialectClass, bool replace) -> py::cpp_function {
72  return py::cpp_function(
73  [dialectClass, replace](py::object opClass) -> py::object {
74  std::string operationName =
75  opClass.attr("OPERATION_NAME").cast<std::string>();
76  PyGlobals::get().registerOperationImpl(operationName, opClass,
77  replace);
78 
79  // Dict-stuff the new opClass by name onto the dialect class.
80  py::object opClassName = opClass.attr("__name__");
81  dialectClass.attr(opClassName) = opClass;
82  return opClass;
83  });
84  },
85  "dialect_class"_a, py::kw_only(), "replace"_a = false,
86  "Produce a class decorator for registering an Operation class as part of "
87  "a dialect");
88  m.def(
90  [](MlirTypeID mlirTypeID, bool replace) -> py::cpp_function {
91  return py::cpp_function([mlirTypeID,
92  replace](py::object typeCaster) -> py::object {
93  PyGlobals::get().registerTypeCaster(mlirTypeID, typeCaster, replace);
94  return typeCaster;
95  });
96  },
97  "typeid"_a, py::kw_only(), "replace"_a = false,
98  "Register a type caster for casting MLIR types to custom user types.");
99  m.def(
101  [](MlirTypeID mlirTypeID, bool replace) -> py::cpp_function {
102  return py::cpp_function(
103  [mlirTypeID, replace](py::object valueCaster) -> py::object {
104  PyGlobals::get().registerValueCaster(mlirTypeID, valueCaster,
105  replace);
106  return valueCaster;
107  });
108  },
109  "typeid"_a, py::kw_only(), "replace"_a = false,
110  "Register a value caster for casting MLIR values to custom user values.");
111 
112  // Define and populate IR submodule.
113  auto irModule = m.def_submodule("ir", "MLIR IR Bindings");
114  populateIRCore(irModule);
115  populateIRAffine(irModule);
116  populateIRAttributes(irModule);
117  populateIRInterfaces(irModule);
118  populateIRTypes(irModule);
119 
120  auto rewriteModule = m.def_submodule("rewrite", "MLIR Rewrite Bindings");
121  populateRewriteSubmodule(rewriteModule);
122 
123  // Define and populate PassManager submodule.
124  auto passModule =
125  m.def_submodule("passmanager", "MLIR Pass Management Bindings");
126  populatePassManagerSubmodule(passModule);
127 }
#define MLIR_PYTHON_CAPI_VALUE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the value caster registration bindin...
Definition: Interop.h:142
#define MLIR_PYTHON_CAPI_TYPE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the type caster registration binding...
Definition: Interop.h:130
PYBIND11_MODULE(_mlir, m)
Definition: MainModule.cpp:25
Globals that are always accessible once the extension has been initialized.
Definition: Globals.h:28
void populateIRAttributes(pybind11::module &m)
void populateIRTypes(pybind11::module &m)
void populatePassManagerSubmodule(pybind11::module &m)
void populateIRAffine(pybind11::module &m)
void populateIRCore(pybind11::module &m)
void populateRewriteSubmodule(pybind11::module &m)
void populateIRInterfaces(py::module &m)
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...