-
Notifications
You must be signed in to change notification settings - Fork 23
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
[MLIR] How to add attribute and source location #1182
Comments
Do you have an example of how to use a C-extension to get the local variable name? Would you be doing it during the We are also working on a preprocessor that adds in symbol information without having to do it at runtime, so that may be a viable longterm option |
@rsetaluri do you think we can add a generic API for passing through attributes to MLIR for module/wire objects? We could simply expose a dictionary on the objects, or add an "add_attribute" method. |
Both source locations and variable names are inferred if you use |
Yes, see here: magma/magma/backend/mlir/mlir.py Line 145 in 1d7b3b9
Now, not all Ops print the attrs because annoyingly, the formatting can be op-specific. So we would just need to add a few liens for the requisite ops (e.g. sv.Wire) to print the attr dict as well. |
You would do it inside the std::optional<std::pair<std::string, uint32_t>> get_fn_ln(uint32_t num_frame_back) {
using namespace kratos;
// get caller frame info
PyFrameObject *frame = PyThreadState_Get()->frame;
uint32_t i = 0;
while (frame->f_back && (++i) < num_frame_back) {
frame = frame->f_back;
}
if (frame) {
uint32_t line_num = PyFrame_GetLineNumber(frame);
struct py::detail::string_caster<std::string> repr;
py::handle handle(frame->f_code->co_filename);
repr.load(handle, true);
if (repr) {
// resolve full path
std::string filename = fs::abspath(repr);
return std::make_pair(filename, line_num);
}
}
return std::nullopt;
} py::dict get_frame_local(uint32_t num_frame_back) {
PyFrameObject *frame = PyThreadState_Get()->frame;
uint32_t i = 0;
while (frame->f_back && (++i) < num_frame_back) {
frame = frame->f_back;
}
if (frame) {
// implementation copied from
// https://github.com/python/cpython/blob/master/Python/ceval.c
// PyEval_GetLocals(void)
PyFrame_FastToLocals(frame);
auto local = frame->f_locals;
if (local) {
py::handle obj(local);
return obj.cast<py::dict>();
}
}
return py::dict();
} The function above returns the entire local variables, but you can pick test out the names first to avoid copying between C++ and Python. |
Right now we don't actually include any source info in the generated IR. I can work towards this. |
Cool thanks, I can try this out. Perhaps we should consider making a micro pip package that provides a Python API for this info, might be useful in general to people. |
@leonardt That sounds like a good idea. Most of the performance slowsdown with |
@rsetaluri Do you have some ETA on this feature? |
For |
Hmm, now that I think about it, during something like |
I get the whole local variables then iterative them to filter out any integer values or custom type value. Here here is an example: a = 1
b = net()
d = "foo"
local_vars = get_frame_local()
res = {}
for name, value in local_vars.items():
if isinstance(value, (int, net)):
res[name] = value Then you can compute the symbol table based on this information. This filtering can also be done in C-extension for performance reasons.
This should also work, depending on what kind of information you wan to store. The issue is if the left hand side is a new variable, it won't show up in the locals. |
Any progress on this issue? I have been pushing Keyi to get hgdb to work with Magma code before he graduates, and getting source information into the IR is a necessary first step. |
I am working towards a DAC submission this week so quite blocked on that. I will take this up next week if that is ok. |
Prototype C extension almost done, see draft here: #1189 I'll need to check whether this catches all the wiring cases properly, the main issue is making sure the source info is being recorded at the appropriate callsite (e.g. not internally in magma). Also will take some time to setup the package distribution for linux/mac. I think we can add names using the metaclass access to the class namespace, so we don't need a C API extension for this, but we will have the issue of names defined inside loops being overwritten (so only the last value will get named). |
@Kuree Can you provide an exact spec for what you need? Right now we can emit |
I need:
|
Any updates? Using latest magma with |
Try setting |
I got |
Yes we are still adding more locations for the other ops. |
You can use the |
So I have the following magma code:
Here is the generated MLIR:
What I want is something like this
My questions are:
hw.debug.name
Furthermore, if I do something like this:
The output doesn't change, but if magma can generate a
sv.wire
with a symbol name ofa
and annotate the source location, the users can then recognize the symbol in SystemVerilog andhgdb
is able to compute proper breakpoint locations. From a implementation perspective this can be done via checking the local variable, so it shouldn't be that challenging. If C-extension is used, it should only introduce about 10% of overhead based on my experiments. From an end-user's perspective I think it's worth a try.The text was updated successfully, but these errors were encountered: