-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[MLIR][Python] make Sliceable inherit from Sequence #170551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@ingomueller-net can you try this and see if it fixes you? |
e2291a9 to
d865b48
Compare
Yes, it does! So nice! I knew you'd come up with something 😉 |
d865b48 to
3b2ab0c
Compare
|
@llvm/pr-subscribers-mlir Author: Maksim Levental (makslevental) ChangesGenerates type stubs like class RegionSequence(Sequence[Region]):
def __add__(self, arg: RegionSequence, /) -> list[Region]: ...
def __iter__(self) -> RegionIterator:
"""Returns an iterator over the regions in the sequence."""WIP (will polish up if it works for us) Full diff: https://github.com/llvm/llvm-project/pull/170551.diff 2 Files Affected:
diff --git a/mlir/lib/Bindings/Python/NanobindUtils.h b/mlir/lib/Bindings/Python/NanobindUtils.h
index 658e8ad5330ef..4a78ec96346a2 100644
--- a/mlir/lib/Bindings/Python/NanobindUtils.h
+++ b/mlir/lib/Bindings/Python/NanobindUtils.h
@@ -16,9 +16,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
+#include <typeinfo>
#include <variant>
template <>
@@ -344,7 +346,16 @@ class Sliceable {
/// Binds the indexing and length methods in the Python class.
static void bind(nanobind::module_ &m) {
- auto clazz = nanobind::class_<Derived>(m, Derived::pyClassName)
+ const std::type_info &elemTy = typeid(ElementTy);
+ PyObject *elemTyInfo = nanobind::detail::nb_type_lookup(&elemTy);
+ assert(elemTyInfo &&
+ "expected nb_type_lookup to succeed for Sliceable elemTy");
+ nanobind::handle elemTyName = nanobind::detail::nb_type_name(elemTyInfo);
+ std::string sig = std::string("class ") + Derived::pyClassName +
+ "(collections.abc.Sequence[" +
+ nanobind::cast<std::string>(elemTyName) + "])";
+ auto clazz = nanobind::class_<Derived>(m, Derived::pyClassName,
+ nanobind::sig(sig.c_str()))
.def("__add__", &Sliceable::dunderAdd);
Derived::bindDerived(clazz);
diff --git a/mlir/test/python/ir/operation.py b/mlir/test/python/ir/operation.py
index ca99c2a985242..d124c284197b8 100644
--- a/mlir/test/python/ir/operation.py
+++ b/mlir/test/python/ir/operation.py
@@ -43,6 +43,10 @@ def testTraverseOpRegionBlockIterators():
)
op = module.operation
assert op.context is ctx
+ # Note, __nb_signature__ stores the fully-qualified signature - the actual type stub emitted is
+ # class RegionSequence(Sequence[Region])
+ # CHECK: class RegionSequence(collections.abc.Sequence[mlir._mlir_libs._mlir.ir.Region])
+ print(RegionSequence.__nb_signature__)
# Get the block using iterators off of the named collections.
regions = list(op.regions[:])
blocks = list(regions[0].blocks)
|
3b2ab0c to
7b233f7
Compare
| assert(elemTyInfo && | ||
| "expected nb_type_lookup to succeed for Sliceable elemTy"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no way for this to fail - the ElementTy needs to be registered before Sliceable[ElementTy] can be registered...
| nanobind::handle elemTyName = nanobind::detail::nb_type_name(elemTyInfo); | ||
| std::string sig = std::string("class ") + Derived::pyClassName + | ||
| "(collections.abc.Sequence[" + | ||
| nanobind::cast<std::string>(elemTyName) + "])"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have ElementTy::pyClassName similarly to Derived::pyClassName? Maybe not everywhere, but something to consider. This is probably the first time I see typeid being used in non-toy code so I don't know how well it works across platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have ElementTy::pyClassName similarly to Derived::pyClassName?
No:
| class PyRegion { |
This is probably the first time I see typeid being used in non-toy code so I don't know how well it works across platforms.
You realize that all of nanobind/pybind hinges on typeid right?
https://github.com/search?q=repo%3Awjakob%2Fnanobind%20typeid&type=code
Specifically the core impl (the cpp to python mapping) uses std::type_info
Ie that's why RTTI is on for the bindings. So we can be sure it works in all the places the bindings work 🙂.
ingomueller-net
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I am not precluding @ftynse's comments...
| # Note, __nb_signature__ stores the fully-qualified signature - the actual type stub emitted is | ||
| # class RegionSequence(Sequence[Region]) | ||
| # CHECK: class RegionSequence(collections.abc.Sequence[mlir._mlir_libs._mlir.ir.Region]) | ||
| print(RegionSequence.__nb_signature__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's a nice way to test this!
Generates type stubs like