Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mlir/include/mlir-c/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location);
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParse(MlirContext context,
MlirStringRef module);

/// Parses a module from file and transfers ownership to the caller.
MLIR_CAPI_EXPORTED MlirModule
mlirModuleCreateParseFromFile(MlirContext context, MlirStringRef fileName);

/// Gets the context that a module was created with.
MLIR_CAPI_EXPORTED MlirContext mlirModuleGetContext(MlirModule module);

Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/Bindings/Python/Nanobind.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#endif
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/stl/filesystem.h>
#include <nanobind/stl/function.h>
#include <nanobind/stl/optional.h>
#include <nanobind/stl/pair.h>
Expand Down
16 changes: 15 additions & 1 deletion mlir/lib/Bindings/Python/IRCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include <filesystem>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this broke the bot, see here: https://lab.llvm.org/buildbot/#/builders/116/builds/9857

#include <optional>
#include <utility>

Expand Down Expand Up @@ -299,7 +300,7 @@ struct PyAttrBuilderMap {
return *builder;
}
static void dunderSetItemNamed(const std::string &attributeKind,
nb::callable func, bool replace) {
nb::callable func, bool replace) {
PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
replace);
}
Expand Down Expand Up @@ -3047,6 +3048,19 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::arg("asm"), nb::arg("context").none() = nb::none(),
kModuleParseDocstring)
.def_static(
"parse",
[](const std::filesystem::path &path,
DefaultingPyMlirContext context) {
PyMlirContext::ErrorCapture errors(context->getRef());
MlirModule module = mlirModuleCreateParseFromFile(
context->get(), toMlirStringRef(path.string()));
if (mlirModuleIsNull(module))
throw MLIRError("Unable to parse module assembly", errors.take());
return PyModule::forModule(module).releaseObject();
},
nb::arg("asm"), nb::arg("context").none() = nb::none(),
kModuleParseDocstring)
.def_static(
"create",
[](DefaultingPyLocation loc) {
Expand Down
10 changes: 10 additions & 0 deletions mlir/lib/CAPI/IR/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "mlir/IR/Location.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/OwningOpRef.h"
#include "mlir/IR/Types.h"
#include "mlir/IR/Value.h"
#include "mlir/IR/Verifier.h"
Expand Down Expand Up @@ -328,6 +329,15 @@ MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module) {
return MlirModule{owning.release().getOperation()};
}

MlirModule mlirModuleCreateParseFromFile(MlirContext context,
MlirStringRef fileName) {
OwningOpRef<ModuleOp> owning =
parseSourceFile<ModuleOp>(unwrap(fileName), unwrap(context));
if (!owning)
return MlirModule{nullptr};
return MlirModule{owning.release().getOperation()};
}

MlirContext mlirModuleGetContext(MlirModule module) {
return wrap(unwrap(module).getContext());
}
Expand Down
3 changes: 2 additions & 1 deletion mlir/python/mlir/_mlir_libs/_mlir/ir.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import abc
import collections
from collections.abc import Callable, Sequence
import io
from pathlib import Path
from typing import Any, ClassVar, TypeVar, overload

__all__ = [
Expand Down Expand Up @@ -2123,7 +2124,7 @@ class Module:
Creates an empty module
"""
@staticmethod
def parse(asm: str | bytes, context: Context | None = None) -> Module:
def parse(asm: str | bytes | Path, context: Context | None = None) -> Module:
"""
Parses a module's assembly format from a string.

Expand Down
20 changes: 20 additions & 0 deletions mlir/test/python/ir/module.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# RUN: %PYTHON %s | FileCheck %s

import gc
from pathlib import Path
from tempfile import NamedTemporaryFile
from mlir.ir import *


Expand All @@ -27,6 +29,24 @@ def testParseSuccess():
print(str(module))


# Verify successful parse from file.
# CHECK-LABEL: TEST: testParseFromFileSuccess
# CHECK: module @successfulParse
@run
def testParseFromFileSuccess():
ctx = Context()
with NamedTemporaryFile(mode="w") as tmp_file:
tmp_file.write(r"""module @successfulParse {}""")
tmp_file.flush()
module = Module.parse(Path(tmp_file.name), ctx)
assert module.context is ctx
print("CLEAR CONTEXT")
ctx = None # Ensure that module captures the context.
gc.collect()
module.dump() # Just outputs to stderr. Verifies that it functions.
print(str(module))


# Verify parse error.
# CHECK-LABEL: TEST: testParseError
# CHECK: testParseError: <
Expand Down