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:
132 /// Policy for handling explicit loc= when loc_tracebacks() is active.
133 enum class OnExplicitAction : uint8_t {
134 UseExplicit, // use loc= as base (default)
135 UseTraceback, // discard loc=, generate traceback
136 };
137
138 /// Policy for composing Location.current with the computed location.
139 /// TODO: possibly add CallSiteLoc wrap and a generic Fuse option
140 /// (`fused[Location.current, baseLoc]`) for non-NameLoc cases.
141 enum class CurrentLocAction : uint8_t {
142 Fallback, // use Location.current only as fallback (default)
143 NamelocWrap, // extract NameLoc names, wrap computed loc
144 };
145
146 bool locTracebacksEnabled();
147
148 void setLocTracebacksEnabled(bool value);
149
150 size_t locTracebackFramesLimit();
151
152 void setLocTracebackFramesLimit(size_t value);
153
154 void registerTracebackFileInclusion(const std::string &file);
155
156 void registerTracebackFileExclusion(const std::string &file);
157
158 bool isUserTracebackFilename(std::string_view file);
159
160 OnExplicitAction tracebackActionOnExplicitLoc();
161
162 void setTracebackActionOnExplicitLoc(OnExplicitAction action);
163
164 CurrentLocAction tracebackActionOnCurrentLoc();
165
166 void setTracebackActionOnCurrentLoc(CurrentLocAction action);
167
168 static constexpr size_t kMaxFrames = 512;
169
170 private:
171 nanobind::ft_mutex mutex;
172 bool locTracebackEnabled_ = false;
173 size_t locTracebackFramesLimit_ = 10;
176 std::unordered_set<std::string> userTracebackIncludeFiles;
177 std::unordered_set<std::string> userTracebackExcludeFiles;
178 std::regex userTracebackIncludeRegex;
179 bool rebuildUserTracebackIncludeRegex = false;
180 std::regex userTracebackExcludeRegex;
181 bool rebuildUserTracebackExcludeRegex = false;
182 std::unordered_map<std::string, bool> isUserTracebackFilenameCache;
183 };
184
185 TracebackLoc &getTracebackLoc() { return tracebackLoc; }
186
188 public:
191 if (allocator.ptr)
193 }
195 TypeIDAllocator(TypeIDAllocator &&other) : allocator(other.allocator) {
196 other.allocator.ptr = nullptr;
197 }
198
199 MlirTypeIDAllocator get() { return allocator; }
200 MlirTypeID allocate() {
201 return mlirTypeIDAllocatorAllocateTypeID(allocator);
202 }
203
204 private:
205 MlirTypeIDAllocator allocator;
206 };
207
208 MlirTypeID allocateTypeID() { return typeIDAllocator.allocate(); }
209
210private:
211 static PyGlobals *instance;
212
213 nanobind::ft_mutex mutex;
214
215 /// Module name prefixes to search under for dialect implementation modules.
216 std::vector<std::string> dialectSearchPrefixes;
217 /// Map of dialect namespace to external dialect class object.
218 std::unordered_map<std::string, nanobind::object> dialectClassMap;
219 /// Map of full operation name to external operation class object.
220 std::unordered_map<std::string, nanobind::object> operationClassMap;
221 /// Map of full operation name to external operation adaptor class object.
222 std::unordered_map<std::string, nanobind::object> opAdaptorClassMap;
223 /// Map of attribute ODS name to custom builder.
224 std::unordered_map<std::string, nanobind::callable> attributeBuilderMap;
225 /// Map of MlirTypeID to custom type caster.
226 std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
228 typeCasterMap;
229 /// Map of MlirTypeID to custom value caster.
230 std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
232 valueCasterMap;
233 /// Set of dialect namespaces that we have attempted to import implementation
234 /// modules for.
235 std::unordered_set<std::string> loadedDialectModules;
236
237 TracebackLoc tracebackLoc;
238 TypeIDAllocator typeIDAllocator;
239};
240} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
241} // namespace python
242} // namespace mlir
243
244#endif // MLIR_BINDINGS_PYTHON_GLOBALS_H
This class provides a way to define new TypeIDs at runtime.
Definition TypeID.h:349
CurrentLocAction
Policy for composing Location.current with the computed location.
Definition Globals.h:141
OnExplicitAction
Policy for handling explicit loc= when loc_tracebacks() is active.
Definition Globals.h:133
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.