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 nb::ft_lock_guard lock(mutex);
102 nb::object &found = attributeBuilderMap[attributeKind];
103 if (found && !replace) {
104 throw std::runtime_error(
106 "' is already registered with func: ",
107 nb::cast<std::string>(nb::str(found))));
109 found = std::move(pyFunc);
113 nb::callable typeCaster,
bool replace) {
114 nb::ft_lock_guard lock(mutex);
115 nb::object &found = typeCasterMap[mlirTypeID];
116 if (found && !replace)
117 throw std::runtime_error(
"Type caster is already registered with caster: " +
118 nb::cast<std::string>(nb::str(found)));
119 found = std::move(typeCaster);
123 nb::callable valueCaster,
bool replace) {
124 nb::ft_lock_guard lock(mutex);
125 nb::object &found = valueCasterMap[mlirTypeID];
126 if (found && !replace)
127 throw std::runtime_error(
"Value caster is already registered: " +
128 nb::cast<std::string>(nb::repr(found)));
129 found = std::move(valueCaster);
133 nb::object pyClass) {
134 nb::ft_lock_guard lock(mutex);
135 nb::object &found = dialectClassMap[dialectNamespace];
138 "Dialect namespace '", dialectNamespace,
"' is already registered."));
140 found = std::move(pyClass);
144 nb::object pyClass,
bool replace) {
145 nb::ft_lock_guard lock(mutex);
146 nb::object &found = operationClassMap[operationName];
147 if (found && !replace) {
149 "Operation '", operationName,
"' is already registered."));
151 found = std::move(pyClass);
155 nb::object pyClass,
bool replace) {
156 nb::ft_lock_guard lock(mutex);
157 nb::object &found = opAdaptorClassMap[operationName];
158 if (found && !replace) {
160 "Operation adaptor of '", operationName,
"' is already registered."));
162 found = std::move(pyClass);
165std::optional<nb::callable>
167 nb::ft_lock_guard lock(mutex);
168 const auto foundIt = attributeBuilderMap.find(attributeKind);
169 if (foundIt != attributeBuilderMap.end()) {
170 assert(foundIt->second &&
"attribute builder is defined");
171 return foundIt->second;
177 MlirDialect dialect) {
181 nb::ft_lock_guard lock(mutex);
182 const auto foundIt = typeCasterMap.find(mlirTypeID);
183 if (foundIt != typeCasterMap.end()) {
184 assert(foundIt->second &&
"type caster is defined");
185 return foundIt->second;
191 MlirDialect dialect) {
195 nb::ft_lock_guard lock(mutex);
196 const auto foundIt = valueCasterMap.find(mlirTypeID);
197 if (foundIt != valueCasterMap.end()) {
198 assert(foundIt->second &&
"value caster is defined");
199 return foundIt->second;
204std::optional<nb::object>
209 nb::ft_lock_guard lock(mutex);
210 const auto foundIt = dialectClassMap.find(dialectNamespace);
211 if (foundIt != dialectClassMap.end()) {
212 assert(foundIt->second &&
"dialect class is defined");
213 return foundIt->second;
219std::optional<nb::object>
222 std::string_view dialectNamespace =
223 operationName.substr(0, operationName.find(
'.'));
226 nb::ft_lock_guard lock(mutex);
227 std::string operationNameStr(operationName);
228 auto foundIt = operationClassMap.find(operationNameStr);
229 if (foundIt != operationClassMap.end()) {
230 assert(foundIt->second &&
"OpView is defined");
231 return foundIt->second;
237std::optional<nb::object>
240 std::string_view dialectNamespace =
241 operationName.substr(0, operationName.find(
'.'));
244 nb::ft_lock_guard lock(mutex);
245 std::string operationNameStr(operationName);
246 auto foundIt = opAdaptorClassMap.find(operationNameStr);
247 if (foundIt != opAdaptorClassMap.end()) {
248 assert(foundIt->second &&
"OpAdaptor is defined");
249 return foundIt->second;
256 nanobind::ft_lock_guard lock(mutex);
257 return locTracebackEnabled_;
261 nanobind::ft_lock_guard lock(mutex);
262 locTracebackEnabled_ = value;
266 nanobind::ft_lock_guard lock(mutex);
267 return locTracebackFramesLimit_;
271 nanobind::ft_lock_guard lock(mutex);
272 locTracebackFramesLimit_ = std::min(value,
kMaxFrames);
276 const std::string &file) {
277 nanobind::ft_lock_guard lock(mutex);
279 if (userTracebackIncludeFiles.insert(reg).second)
280 rebuildUserTracebackIncludeRegex =
true;
281 if (userTracebackExcludeFiles.count(reg)) {
282 if (userTracebackExcludeFiles.erase(reg))
283 rebuildUserTracebackExcludeRegex =
true;
288 const std::string &file) {
289 nanobind::ft_lock_guard lock(mutex);
291 if (userTracebackExcludeFiles.insert(reg).second)
292 rebuildUserTracebackExcludeRegex =
true;
293 if (userTracebackIncludeFiles.count(reg)) {
294 if (userTracebackIncludeFiles.erase(reg))
295 rebuildUserTracebackIncludeRegex =
true;
300 const std::string_view file) {
301 nanobind::ft_lock_guard lock(mutex);
302 auto joinWithPipe = [](
const std::unordered_set<std::string> &set) {
303 std::ostringstream os;
304 for (
auto it = set.begin(); it != set.end(); ++it) {
305 if (it != set.begin())
311 if (rebuildUserTracebackIncludeRegex) {
312 userTracebackIncludeRegex.assign(joinWithPipe(userTracebackIncludeFiles));
313 rebuildUserTracebackIncludeRegex =
false;
314 isUserTracebackFilenameCache.clear();
316 if (rebuildUserTracebackExcludeRegex) {
317 userTracebackExcludeRegex.assign(joinWithPipe(userTracebackExcludeFiles));
318 rebuildUserTracebackExcludeRegex =
false;
319 isUserTracebackFilenameCache.clear();
321 std::string fileStr(file);
322 const auto foundIt = isUserTracebackFilenameCache.find(fileStr);
323 if (foundIt == isUserTracebackFilenameCache.end()) {
324 bool include = std::regex_search(fileStr, userTracebackIncludeRegex);
325 bool exclude = std::regex_search(fileStr, userTracebackExcludeRegex);
326 isUserTracebackFilenameCache[fileStr] = include || !exclude;
328 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.
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 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::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_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.