MLIR 23.0.0git
Globals.h
Go to the documentation of this file.
1//===- Globals.h - MLIR Python extension globals --------------------------===//
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#ifndef MLIR_BINDINGS_PYTHON_GLOBALS_H
10#define MLIR_BINDINGS_PYTHON_GLOBALS_H
11
12#include <optional>
13#include <regex>
14#include <string>
15#include <string_view>
16#include <unordered_map>
17#include <unordered_set>
18#include <vector>
19
20#include "mlir-c/IR.h"
21#include "mlir-c/Support.h"
23
24namespace mlir {
25namespace python {
27/// Globals that are always accessible once the extension has been initialized.
28/// Methods of this class are thread-safe.
30public:
31 PyGlobals();
32 ~PyGlobals();
33
34 /// Most code should get the globals via this static accessor.
35 static PyGlobals &get();
36
37 /// Get and set the list of parent modules to search for dialect
38 /// implementation classes.
39 std::vector<std::string> getDialectSearchPrefixes() {
40 nanobind::ft_lock_guard lock(mutex);
41 return dialectSearchPrefixes;
42 }
43 void setDialectSearchPrefixes(std::vector<std::string> newValues) {
44 nanobind::ft_lock_guard lock(mutex);
45 dialectSearchPrefixes.swap(newValues);
46 }
47 void addDialectSearchPrefix(std::string value) {
48 nanobind::ft_lock_guard lock(mutex);
49 dialectSearchPrefixes.push_back(std::move(value));
50 }
51
52 /// Loads a python module corresponding to the given dialect namespace.
53 /// No-ops if the module has already been loaded or is not found. Raises
54 /// an error on any evaluation issues.
55 /// Note that this returns void because it is expected that the module
56 /// contains calls to decorators and helpers that register the salient
57 /// entities. Returns true if dialect is successfully loaded.
58 bool loadDialectModule(std::string_view dialectNamespace);
59
60 /// Adds a user-friendly Attribute builder.
61 /// Raises an exception if the mapping already exists and replace == false
62 /// and allow_existing == false.
63 /// Silently skips registration if allow_existing == true and the mapping
64 /// already exists (first registration wins).
65 /// This is intended to be called by implementation code.
66 void registerAttributeBuilder(const std::string &attributeKind,
67 nanobind::callable pyFunc, bool replace = false,
68 bool allow_existing = false);
69
70 /// Adds a user-friendly type caster. Raises an exception if the mapping
71 /// already exists and replace == false. This is intended to be called by
72 /// implementation code.
73 void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster,
74 bool replace = false);
75
76 /// Adds a user-friendly value caster. Raises an exception if the mapping
77 /// already exists and replace == false. This is intended to be called by
78 /// implementation code.
79 void registerValueCaster(MlirTypeID mlirTypeID,
80 nanobind::callable valueCaster,
81 bool replace = false);
82
83 /// Adds a concrete implementation dialect class.
84 /// Raises an exception if the mapping already exists and replace == false.
85 /// This is intended to be called by implementation code.
86 void registerDialectImpl(const std::string &dialectNamespace,
87 nanobind::object pyClass, bool replace = false);
88
89 /// Adds a concrete implementation operation class.
90 /// Raises an exception if the mapping already exists and replace == false.
91 /// This is intended to be called by implementation code.
92 void registerOperationImpl(const std::string &operationName,
93 nanobind::object pyClass, bool replace = false);
94
95 /// Adds an operation adaptor class.
96 /// Raises an exception if the mapping already exists and replace == false.
97 /// This is intended to be called by implementation code.
98 void registerOpAdaptorImpl(const std::string &operationName,
99 nanobind::object pyClass, bool replace = false);
100
101 /// Returns the custom Attribute builder for Attribute kind.
102 std::optional<nanobind::callable>
103 lookupAttributeBuilder(const std::string &attributeKind);
104
105 /// Returns the custom type caster for MlirTypeID mlirTypeID.
106 std::optional<nanobind::callable> lookupTypeCaster(MlirTypeID mlirTypeID,
107 MlirDialect dialect);
108
109 /// Returns the custom value caster for MlirTypeID mlirTypeID.
110 std::optional<nanobind::callable> lookupValueCaster(MlirTypeID mlirTypeID,
111 MlirDialect dialect);
112
113 /// Looks up a registered dialect class by namespace. Note that this may
114 /// trigger loading of the defining module and can arbitrarily re-enter.
115 std::optional<nanobind::object>
116 lookupDialectClass(const std::string &dialectNamespace);
117
118 /// Looks up a registered operation class (deriving from OpView) by operation
119 /// name. Note that this may trigger a load of the dialect, which can
120 /// arbitrarily re-enter.
121 std::optional<nanobind::object>
122 lookupOperationClass(std::string_view operationName);
123
124 /// Looks up a registered operation adaptor class by operation
125 /// name. Note that this may trigger a load of the dialect, which can
126 /// arbitrarily re-enter.
127 std::optional<nanobind::object>
128 lookupOpAdaptorClass(std::string_view operationName);
129
131 public:
133
134 void setLocTracebacksEnabled(bool value);
135
137
138 void setLocTracebackFramesLimit(size_t value);
139
140 void registerTracebackFileInclusion(const std::string &file);
141
142 void registerTracebackFileExclusion(const std::string &file);
143
144 bool isUserTracebackFilename(std::string_view file);
145
146 static constexpr size_t kMaxFrames = 512;
147
148 private:
149 nanobind::ft_mutex mutex;
150 bool locTracebackEnabled_ = false;
151 size_t locTracebackFramesLimit_ = 10;
152 std::unordered_set<std::string> userTracebackIncludeFiles;
153 std::unordered_set<std::string> userTracebackExcludeFiles;
154 std::regex userTracebackIncludeRegex;
155 bool rebuildUserTracebackIncludeRegex = false;
156 std::regex userTracebackExcludeRegex;
157 bool rebuildUserTracebackExcludeRegex = false;
158 std::unordered_map<std::string, bool> isUserTracebackFilenameCache;
159 };
160
161 TracebackLoc &getTracebackLoc() { return tracebackLoc; }
162
164 public:
167 if (allocator.ptr)
169 }
171 TypeIDAllocator(TypeIDAllocator &&other) : allocator(other.allocator) {
172 other.allocator.ptr = nullptr;
173 }
174
175 MlirTypeIDAllocator get() { return allocator; }
176 MlirTypeID allocate() {
177 return mlirTypeIDAllocatorAllocateTypeID(allocator);
178 }
179
180 private:
181 MlirTypeIDAllocator allocator;
182 };
183
184 MlirTypeID allocateTypeID() { return typeIDAllocator.allocate(); }
185
186private:
187 static PyGlobals *instance;
188
189 nanobind::ft_mutex mutex;
190
191 /// Module name prefixes to search under for dialect implementation modules.
192 std::vector<std::string> dialectSearchPrefixes;
193 /// Map of dialect namespace to external dialect class object.
194 std::unordered_map<std::string, nanobind::object> dialectClassMap;
195 /// Map of full operation name to external operation class object.
196 std::unordered_map<std::string, nanobind::object> operationClassMap;
197 /// Map of full operation name to external operation adaptor class object.
198 std::unordered_map<std::string, nanobind::object> opAdaptorClassMap;
199 /// Map of attribute ODS name to custom builder.
200 std::unordered_map<std::string, nanobind::callable> attributeBuilderMap;
201 /// Map of MlirTypeID to custom type caster.
202 std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
204 typeCasterMap;
205 /// Map of MlirTypeID to custom value caster.
206 std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
208 valueCasterMap;
209 /// Set of dialect namespaces that we have attempted to import implementation
210 /// modules for.
211 std::unordered_set<std::string> loadedDialectModules;
212
213 TracebackLoc tracebackLoc;
214 TypeIDAllocator typeIDAllocator;
215};
216} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
217} // namespace python
218} // namespace mlir
219
220#endif // MLIR_BINDINGS_PYTHON_GLOBALS_H
This class provides a way to define new TypeIDs at runtime.
Definition TypeID.h:349
Globals that are always accessible once the extension has been initialized.
Definition Globals.h:29
static PyGlobals & get()
Most code should get the globals via this static accessor.
Definition Globals.cpp:59
void setDialectSearchPrefixes(std::vector< std::string > newValues)
Definition Globals.h:43
std::vector< std::string > getDialectSearchPrefixes()
Get and set the list of parent modules to search for dialect implementation classes.
Definition Globals.h:39
MLIR_CAPI_EXPORTED void mlirTypeIDAllocatorDestroy(MlirTypeIDAllocator allocator)
Deallocates the allocator and all allocated type ids.
Definition Support.cpp:105
MLIR_CAPI_EXPORTED MlirTypeID mlirTypeIDAllocatorAllocateTypeID(MlirTypeIDAllocator allocator)
Allocates a type id that is valid for the lifetime of the allocator.
Definition Support.cpp:109
MLIR_CAPI_EXPORTED MlirTypeIDAllocator mlirTypeIDAllocatorCreate(void)
Creates a type id allocator for dynamic type id creation.
Definition Support.cpp:101
#define MLIR_PYTHON_API_EXPORTED
Definition Support.h:49
Include the generated interface declarations.