-
Notifications
You must be signed in to change notification settings - Fork 6
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
[WIP] Conversion infrastructure #4
base: master
Are you sure you want to change the base?
Conversation
Thank you !. Please give me a couple days to get back to you on this. |
I'm going through what / how MLIR does it in more detail. Also a friend pointed me to https://mlir.llvm.org/docs/Dialects/PDLOps/, something that MLIR is doing more recently. |
Sure. Initially, I tried to keep API closer to MLIR but some features (typed ops, etc) I was unable to implement in Rust, so I dropped them for now.
This is so cool! I'm going to dig into it. Thanks! |
I'm still contemplating the best way to do dialect conversions and other transforms on the IR. But meanwhile, I had some thoughts on the other changes in your PR: what do you think?
|
Sure. What is your vision for error handling? I see that errors are used only in
Yes, it is a thin wrapper for the passes list and not that useful at this point. I'll remove it for now. |
The way I see it, unwraps and asserts, when they fail means that it's a bug in the core infrastructure. It shouldn't happen at all (ideally). Recoverable errors are for when it isn't a bug in When I suggested that we do
That's extreme and may make it very difficult at a lot of places. Definitely not for |
I've been looking at MLIR's pattern rewriter infrastructure, and the whole thing (how it works, what it provides, and how it provides that - the API) is quite complex. The rewrite drivers (greedy / dialect conversion etc) collect the operations and then the applicator applies the max benefit pattern. The rewrite drivers, if I understand correctly, in a way is provided by the walker in your PR. Before we attempt to implement this complex system, do you think it's a good idea to try and write a conversion manually? See what difficulties, repetitions we face and then see how a system to "automate" that can be designed? If you can point me to your code which needs conversion, I can try playing with it too. That'll give us more clarity. Ideally I'd want something much simpler than what MLIR has. Like maybe just a walker that allows modifications of the graph during the walk. But if we don't have anything good, we can go for what you're attempting - the MLIR way. Thoughts? btw, are you on a timeline / deadline by when you want something done or are more free to explore solutions? |
My initial idea was to take a simplified version of MLIR infra and use it as a starting point. However, during this journey, I scratched my head many times, trying to understand the MLIR's design but plowed on. So, yes, it's pretty complex, and we might not need it as is. Here is the code where I'm implementing the conversions - https://github.com/greenhat/omnizk/blob/add-miden-new-ozkir/crates/ir-transform/src/miden/lowering.rs
I'm not on a deadline, it's my side project, and I'm free to explore solutions.
This makes total sense. I agree.
Will do.
I agree. It's quite extreme, and I choose the wording ("Ideally") poorly. :) |
src/context.rs
Outdated
} | ||
|
||
/// Create a unique (to the arena) name based on the arena index. | ||
pub fn make_name(&self, name_base: &str) -> String { | ||
let idx = self.idx.into_raw_parts(); | ||
name_base.to_string() + "_" + &idx.0.to_string() + "_" + &idx.1.to_string() | ||
} | ||
|
||
/// Returns true if pointee is still in the arena, and not erased/deallocated. | ||
pub fn is_alive(&self, ctx: &Context) -> bool { |
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.
Hi! I was trying to check if an op is erased from the arena and found nothing, so I added Ptr::is_alive
(not a fan of this name). I also make try_deref*
methods to check if the pointee is still in the arena. Besides, I don't like Ptr::is_linked
crash if the pointee is not in the arena. Do you think we should check there as well?
Here is my progress so far in OmniZK in using pass infra - https://github.com/greenhat/omnizk/blob/add-miden-new-ozkir/crates/ir-transform/src/miden/lowering/cf_lowering.rs
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.
@vaivaswatha ☝️
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.
Hi! I was trying to check if an op is erased from the arena and found nothing, so I added
Ptr::is_alive
(not a fan of this name). I also maketry_deref*
methods to check if the pointee is still in the arena. Besides, I don't likePtr::is_linked
crash if the pointee is not in the arena. Do you think we should check there as well?Here is my progress so far in OmniZK in using pass infra - https://github.com/greenhat/omnizk/blob/add-miden-new-ozkir/crates/ir-transform/src/miden/lowering/cf_lowering.rs
Sorry I somehow missed this last week. Just saw it after your ping today.
I'm curious, in what situation is Ptr::is_alive
useful? In other words, I'm trying to see why having a Ptr
to an erased entity isn't always a bug. (It's something like a dangling pointer, but safe as it'll panic if dereferenced).
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.
I'm using it at https://github.com/vaivaswatha/pliron/pull/4/files#diff-bb35f6399df11ed17d92ad8c06ec15cdeb5bfd973838cdedae6d0b593c1b2df1R238 when I'm iterating over the collected(walk) ops to check if the op was not erased by the pass ran on the previous ops.
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.
I'm using it at https://github.com/vaivaswatha/pliron/pull/4/files#diff-bb35f6399df11ed17d92ad8c06ec15cdeb5bfd973838cdedae6d0b593c1b2df1R238 when I'm iterating over the collected(walk) ops to check if the op was not erased by the pass ran on the previous ops.
Isn't it then the Rewriter's responsibility to keep track of erased Op
s (since it's notified about it anyway as the erase happens via the rewriter), and check against that before trying to do something else.
Somehow it seems to me that having dangling pointers is a bad idea and checking if it's a dangling one is just a patch / workaround and not a solution.
Having said that, if this is important for you (ie no other way of doing it otherwise), I'm ok with it.
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.
If I squint enough, I can see that both (interior mutability vs. pointer validity) errors might manifest only in certain conditions depending on the IR that is being processed. That means that on some inputs, my compilation pipeline hard crashes, and in case of pointer validity, I have no way to handle it gracefully.
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.
When iterating over the IR during a transform, it's possible that we arrive at an instruction (Operation) the second time (when it's already borrowed mutably). For such algorithms, this is useful. It isn't an error, but is how the algorithm works. Although I admit, an argument can be made that it can be handled by a check similar to the erased_ops.contains()
one we discussed y'day.
That means that on some inputs
I wouldn't say that it's a function of the input. If it crashes due to a pointer validity, then it's a compiler bug. It isn't something that you attempt to handle post-access at all. There shouldn't have existed a dangling pointer in the first place.
Do you have a requirement for this now? That try_deref
not panic on dangling pointers? (I'm assuming that you already added the erased_op
check in the conversions). If yes, then we can see why that situation arises and take a call. Otherwise, for now let dangling pointers be a panic. We can always add it back if there's a real need for the existence of dangling pointers.
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.
Do you have a requirement for this now? That
try_deref
not panic on dangling pointers? (I'm assuming that you already added theerased_op
check in the conversions). If yes, then we can see why that situation arises and take a call.
No. erased_op
tracking list solved that case.
Otherwise, for now let dangling pointers be a panic. We can always add it back if there's a real need for the existence of dangling pointers.
Ok. I will restore the original behavior and use expect
to explain the error.
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.
That sounds fair.
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.
Done in 733255e
441f1ce
to
418a4c6
Compare
add doc comments;
pointee is still in the arena. Make convert_operations skip erased, unlinked and already legal ops.
add PassError;
605f1c3
to
1e1fb42
Compare
… a helpful message;
733255e
to
17946ac
Compare
make RewritePattern::match and rewrite implementation optional;
I'm doing dialect conversion in OmniZK, so I'm drafting a pass infrastructure in pliron that resembles MLIR's. I'm using mostly the same names for types and functions.
It's still WIP and is not ready for review yet. I want to get your feedback. Let me know what you think of it.
TODO: