35 assert(!instance &&
"PyGlobals already constructed");
45 assert(instance &&
"PyGlobals is null");
51 nb::ft_lock_guard lock(mutex);
52 if (loadedDialectModules.contains(dialectNamespace))
56 std::vector<std::string> localSearchPrefixes = dialectSearchPrefixes;
57 nb::object loaded = nb::none();
58 for (std::string moduleName : localSearchPrefixes) {
59 moduleName.push_back(
'.');
60 moduleName.append(dialectNamespace.data(), dialectNamespace.size());
63 loaded = nb::module_::import_(moduleName.c_str());
64 }
catch (nb::python_error &e) {
65 if (e.matches(PyExc_ModuleNotFoundError)) {
77 nb::ft_lock_guard lock(mutex);
78 loadedDialectModules.insert(dialectNamespace);
83 nb::callable pyFunc,
bool replace) {
84 nb::ft_lock_guard lock(mutex);
85 nb::object &found = attributeBuilderMap[attributeKind];
86 if (found && !replace) {
87 throw std::runtime_error((llvm::Twine(
"Attribute builder for '") +
89 "' is already registered with func: " +
90 nb::cast<std::string>(nb::str(found)))
93 found = std::move(pyFunc);
97 nb::callable typeCaster,
bool replace) {
98 nb::ft_lock_guard lock(mutex);
99 nb::object &found = typeCasterMap[mlirTypeID];
100 if (found && !replace)
101 throw std::runtime_error(
"Type caster is already registered with caster: " +
102 nb::cast<std::string>(nb::str(found)));
103 found = std::move(typeCaster);
107 nb::callable valueCaster,
bool replace) {
108 nb::ft_lock_guard lock(mutex);
109 nb::object &found = valueCasterMap[mlirTypeID];
110 if (found && !replace)
111 throw std::runtime_error(
"Value caster is already registered: " +
112 nb::cast<std::string>(nb::repr(found)));
113 found = std::move(valueCaster);
117 nb::object pyClass) {
118 nb::ft_lock_guard lock(mutex);
119 nb::object &found = dialectClassMap[dialectNamespace];
121 throw std::runtime_error((llvm::Twine(
"Dialect namespace '") +
122 dialectNamespace +
"' is already registered.")
125 found = std::move(pyClass);
129 nb::object pyClass,
bool replace) {
130 nb::ft_lock_guard lock(mutex);
131 nb::object &found = operationClassMap[operationName];
132 if (found && !replace) {
133 throw std::runtime_error((llvm::Twine(
"Operation '") + operationName +
134 "' is already registered.")
137 found = std::move(pyClass);
140std::optional<nb::callable>
142 nb::ft_lock_guard lock(mutex);
143 const auto foundIt = attributeBuilderMap.find(attributeKind);
144 if (foundIt != attributeBuilderMap.end()) {
145 assert(foundIt->second &&
"attribute builder is defined");
146 return foundIt->second;
152 MlirDialect dialect) {
155 nb::ft_lock_guard lock(mutex);
156 const auto foundIt = typeCasterMap.find(mlirTypeID);
157 if (foundIt != typeCasterMap.end()) {
158 assert(foundIt->second &&
"type caster is defined");
159 return foundIt->second;
165 MlirDialect dialect) {
168 nb::ft_lock_guard lock(mutex);
169 const auto foundIt = valueCasterMap.find(mlirTypeID);
170 if (foundIt != valueCasterMap.end()) {
171 assert(foundIt->second &&
"value caster is defined");
172 return foundIt->second;
177std::optional<nb::object>
182 nb::ft_lock_guard lock(mutex);
183 const auto foundIt = dialectClassMap.find(dialectNamespace);
184 if (foundIt != dialectClassMap.end()) {
185 assert(foundIt->second &&
"dialect class is defined");
186 return foundIt->second;
192std::optional<nb::object>
195 auto split = operationName.split(
'.');
196 llvm::StringRef dialectNamespace = split.first;
200 nb::ft_lock_guard lock(mutex);
201 auto foundIt = operationClassMap.find(operationName);
202 if (foundIt != operationClassMap.end()) {
203 assert(foundIt->second &&
"OpView is defined");
204 return foundIt->second;
211 nanobind::ft_lock_guard lock(mutex);
212 return locTracebackEnabled_;
216 nanobind::ft_lock_guard lock(mutex);
217 locTracebackEnabled_ = value;
221 nanobind::ft_lock_guard lock(mutex);
222 return locTracebackFramesLimit_;
226 nanobind::ft_lock_guard lock(mutex);
227 locTracebackFramesLimit_ = std::min(value,
kMaxFrames);
231 const std::string &file) {
232 nanobind::ft_lock_guard lock(mutex);
233 auto reg =
"^" + llvm::Regex::escape(file);
234 if (userTracebackIncludeFiles.insert(reg).second)
235 rebuildUserTracebackIncludeRegex =
true;
236 if (userTracebackExcludeFiles.count(reg)) {
237 if (userTracebackExcludeFiles.erase(reg))
238 rebuildUserTracebackExcludeRegex =
true;
243 const std::string &file) {
244 nanobind::ft_lock_guard lock(mutex);
245 auto reg =
"^" + llvm::Regex::escape(file);
246 if (userTracebackExcludeFiles.insert(reg).second)
247 rebuildUserTracebackExcludeRegex =
true;
248 if (userTracebackIncludeFiles.count(reg)) {
249 if (userTracebackIncludeFiles.erase(reg))
250 rebuildUserTracebackIncludeRegex =
true;
255 const llvm::StringRef file) {
256 nanobind::ft_lock_guard lock(mutex);
257 if (rebuildUserTracebackIncludeRegex) {
258 userTracebackIncludeRegex.assign(
259 llvm::join(userTracebackIncludeFiles,
"|"));
260 rebuildUserTracebackIncludeRegex =
false;
261 isUserTracebackFilenameCache.clear();
263 if (rebuildUserTracebackExcludeRegex) {
264 userTracebackExcludeRegex.assign(
265 llvm::join(userTracebackExcludeFiles,
"|"));
266 rebuildUserTracebackExcludeRegex =
false;
267 isUserTracebackFilenameCache.clear();
269 if (!isUserTracebackFilenameCache.contains(file)) {
270 std::string fileStr = file.str();
271 bool include = std::regex_search(fileStr, userTracebackIncludeRegex);
272 bool exclude = std::regex_search(fileStr, userTracebackExcludeRegex);
273 isUserTracebackFilenameCache[file] = include || !exclude;
275 return isUserTracebackFilenameCache[file];
#define MAKE_MLIR_PYTHON_QUALNAME(local)
size_t locTracebackFramesLimit()
void setLocTracebackFramesLimit(size_t value)
void registerTracebackFileExclusion(const std::string &file)
void registerTracebackFileInclusion(const std::string &file)
static constexpr size_t kMaxFrames
void setLocTracebacksEnabled(bool value)
bool isUserTracebackFilename(llvm::StringRef file)
bool locTracebacksEnabled()
Globals that are always accessible once the extension has been initialized.
std::optional< nanobind::callable > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
bool loadDialectModule(llvm::StringRef dialectNamespace)
Loads a python module corresponding to the given dialect namespace.
static PyGlobals & get()
Most code should get the globals via this static accessor.
void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster, bool replace=false)
Adds a user-friendly type caster.
void registerAttributeBuilder(const std::string &attributeKind, nanobind::callable pyFunc, bool replace=false)
Adds a user-friendly Attribute builder.
void registerOperationImpl(const std::string &operationName, nanobind::object pyClass, bool replace=false)
Adds a concrete implementation operation class.
std::optional< nanobind::callable > lookupTypeCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom type caster for MlirTypeID mlirTypeID.
void registerValueCaster(MlirTypeID mlirTypeID, nanobind::callable valueCaster, bool replace=false)
Adds a user-friendly value caster.
std::optional< nanobind::object > lookupOperationClass(llvm::StringRef operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
std::optional< nanobind::callable > lookupAttributeBuilder(const std::string &attributeKind)
Returns the custom Attribute builder for Attribute kind.
void registerDialectImpl(const std::string &dialectNamespace, nanobind::object pyClass)
Adds a concrete implementation dialect class.
std::optional< nanobind::object > lookupDialectClass(const std::string &dialectNamespace)
Looks up a registered dialect class by namespace.
mlir::Diagnostic & unwrap(MlirDiagnostic diagnostic)
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
Include the generated interface declarations.