30 static constexpr char RegexMetachars[] =
"()^$|*+?.[]\\{}";
33 if (std::strchr(RegexMetachars, C))
50 assert(!instance &&
"PyGlobals already constructed");
60 assert(instance &&
"PyGlobals is null");
66 nb::ft_lock_guard lock(mutex);
67 std::string dialectNamespaceStr(dialectNamespace);
68 if (loadedDialectModules.find(dialectNamespaceStr) !=
69 loadedDialectModules.end())
73 std::vector<std::string> localSearchPrefixes = dialectSearchPrefixes;
74 nb::object loaded = nb::none();
75 for (std::string moduleName : localSearchPrefixes) {
76 moduleName.push_back(
'.');
77 moduleName.append(dialectNamespace.data(), dialectNamespace.size());
80 loaded = nb::module_::import_(moduleName.c_str());
81 }
catch (nb::python_error &e) {
82 if (e.matches(PyExc_ModuleNotFoundError)) {
94 nb::ft_lock_guard lock(mutex);
95 loadedDialectModules.insert(std::string(dialectNamespace));
100 nb::callable pyFunc,
bool replace,
101 bool allowExisting) {
102 nb::ft_lock_guard lock(mutex);
103 nb::object &found = attributeBuilderMap[attributeKind];
107 "' is already registered with func: ",
108 nb::cast<std::string>(nb::str(found)));
111 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg.c_str(), 1) < 0) {
114 throw nb::python_error();
120 throw std::runtime_error(msg);
122 found = std::move(pyFunc);
126 nb::callable typeCaster,
bool replace) {
127 nb::ft_lock_guard lock(mutex);
128 nb::object &found = typeCasterMap[mlirTypeID];
129 if (found && !replace)
130 throw std::runtime_error(
"Type caster is already registered with caster: " +
131 nb::cast<std::string>(nb::str(found)));
132 found = std::move(typeCaster);
136 nb::callable valueCaster,
bool replace) {
137 nb::ft_lock_guard lock(mutex);
138 nb::object &found = valueCasterMap[mlirTypeID];
139 if (found && !replace)
140 throw std::runtime_error(
"Value caster is already registered: " +
141 nb::cast<std::string>(nb::repr(found)));
142 found = std::move(valueCaster);
146 nb::object pyClass,
bool replace) {
147 nb::ft_lock_guard lock(mutex);
148 nb::object &found = dialectClassMap[dialectNamespace];
149 if (found && !replace) {
151 "Dialect namespace '", dialectNamespace,
"' is already registered."));
153 found = std::move(pyClass);
157 nb::object pyClass,
bool replace) {
158 nb::ft_lock_guard lock(mutex);
159 nb::object &found = operationClassMap[operationName];
160 if (found && !replace) {
162 "Operation '", operationName,
"' is already registered."));
164 found = std::move(pyClass);
168 nb::object pyClass,
bool replace) {
169 nb::ft_lock_guard lock(mutex);
170 nb::object &found = opAdaptorClassMap[operationName];
171 if (found && !replace) {
173 "Operation adaptor of '", operationName,
"' is already registered."));
175 found = std::move(pyClass);
178std::optional<nb::callable>
180 nb::ft_lock_guard lock(mutex);
181 const auto foundIt = attributeBuilderMap.find(attributeKind);
182 if (foundIt != attributeBuilderMap.end()) {
183 assert(foundIt->second &&
"attribute builder is defined");
184 return foundIt->second;
190 MlirDialect dialect) {
194 nb::ft_lock_guard lock(mutex);
195 const auto foundIt = typeCasterMap.find(mlirTypeID);
196 if (foundIt != typeCasterMap.end()) {
197 assert(foundIt->second &&
"type caster is defined");
198 return foundIt->second;
204 MlirDialect dialect) {
208 nb::ft_lock_guard lock(mutex);
209 const auto foundIt = valueCasterMap.find(mlirTypeID);
210 if (foundIt != valueCasterMap.end()) {
211 assert(foundIt->second &&
"value caster is defined");
212 return foundIt->second;
217std::optional<nb::object>
222 nb::ft_lock_guard lock(mutex);
223 const auto foundIt = dialectClassMap.find(dialectNamespace);
224 if (foundIt != dialectClassMap.end()) {
225 assert(foundIt->second &&
"dialect class is defined");
226 return foundIt->second;
232std::optional<nb::object>
235 std::string_view dialectNamespace =
236 operationName.substr(0, operationName.find(
'.'));
239 nb::ft_lock_guard lock(mutex);
240 std::string operationNameStr(operationName);
241 auto foundIt = operationClassMap.find(operationNameStr);
242 if (foundIt != operationClassMap.end()) {
243 assert(foundIt->second &&
"OpView is defined");
244 return foundIt->second;
250std::optional<nb::object>
253 std::string_view dialectNamespace =
254 operationName.substr(0, operationName.find(
'.'));
257 nb::ft_lock_guard lock(mutex);
258 std::string operationNameStr(operationName);
259 auto foundIt = opAdaptorClassMap.find(operationNameStr);
260 if (foundIt != opAdaptorClassMap.end()) {
261 assert(foundIt->second &&
"OpAdaptor is defined");
262 return foundIt->second;
269 nanobind::ft_lock_guard lock(mutex);
270 return locTracebackEnabled_;
274 nanobind::ft_lock_guard lock(mutex);
275 locTracebackEnabled_ = value;
279 nanobind::ft_lock_guard lock(mutex);
280 return locTracebackFramesLimit_;
284 nanobind::ft_lock_guard lock(mutex);
285 locTracebackFramesLimit_ = std::min(value,
kMaxFrames);
289 const std::string &file) {
290 nanobind::ft_lock_guard lock(mutex);
292 if (userTracebackIncludeFiles.insert(reg).second)
293 rebuildUserTracebackIncludeRegex =
true;
294 if (userTracebackExcludeFiles.count(reg)) {
295 if (userTracebackExcludeFiles.erase(reg))
296 rebuildUserTracebackExcludeRegex =
true;
301 const std::string &file) {
302 nanobind::ft_lock_guard lock(mutex);
304 if (userTracebackExcludeFiles.insert(reg).second)
305 rebuildUserTracebackExcludeRegex =
true;
306 if (userTracebackIncludeFiles.count(reg)) {
307 if (userTracebackIncludeFiles.erase(reg))
308 rebuildUserTracebackIncludeRegex =
true;
313 const std::string_view file) {
314 nanobind::ft_lock_guard lock(mutex);
315 auto joinWithPipe = [](
const std::unordered_set<std::string> &set) {
316 std::ostringstream os;
317 for (
auto it = set.begin(); it != set.end(); ++it) {
318 if (it != set.begin())
324 if (rebuildUserTracebackIncludeRegex) {
325 userTracebackIncludeRegex.assign(joinWithPipe(userTracebackIncludeFiles));
326 rebuildUserTracebackIncludeRegex =
false;
327 isUserTracebackFilenameCache.clear();
329 if (rebuildUserTracebackExcludeRegex) {
330 userTracebackExcludeRegex.assign(joinWithPipe(userTracebackExcludeFiles));
331 rebuildUserTracebackExcludeRegex =
false;
332 isUserTracebackFilenameCache.clear();
334 std::string fileStr(file);
335 const auto foundIt = isUserTracebackFilenameCache.find(fileStr);
336 if (foundIt == isUserTracebackFilenameCache.end()) {
337 bool include = std::regex_search(fileStr, userTracebackIncludeRegex);
338 bool exclude = std::regex_search(fileStr, userTracebackExcludeRegex);
339 isUserTracebackFilenameCache[fileStr] = include || !exclude;
341 return isUserTracebackFilenameCache[fileStr];
static std::string escapeRegex(std::string_view String)
Local helper adapted from llvm::Regex::escape.
#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(std::string_view file)
bool locTracebacksEnabled()
Globals that are always accessible once the extension has been initialized.
void registerOpAdaptorImpl(const std::string &operationName, nanobind::object pyClass, bool replace=false)
Adds an operation adaptor class.
std::optional< nanobind::callable > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
bool loadDialectModule(std::string_view dialectNamespace)
Loads a python module corresponding to the given dialect namespace.
std::optional< nanobind::object > lookupOpAdaptorClass(std::string_view operationName)
Looks up a registered operation adaptor class by operation name.
void registerDialectImpl(const std::string &dialectNamespace, nanobind::object pyClass, bool replace=false)
Adds a concrete implementation dialect class.
static PyGlobals & get()
Most code should get the globals via this static accessor.
std::optional< nanobind::object > lookupOperationClass(std::string_view operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster, bool replace=false)
Adds a user-friendly type caster.
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::callable > lookupAttributeBuilder(const std::string &attributeKind)
Returns the custom Attribute builder for Attribute kind.
std::optional< nanobind::object > lookupDialectClass(const std::string &dialectNamespace)
Looks up a registered dialect class by namespace.
void registerAttributeBuilder(const std::string &attributeKind, nanobind::callable pyFunc, bool replace=false, bool allow_existing=false)
Adds a user-friendly Attribute builder.
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
Include the generated interface declarations.
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.