Open timhae opened 5 years ago
cc @btut
Sorry for the late reply. I am able to reproduce this issue. What's interesting, this does only happen if you use the installed pyosys library. I will look into it, although I am clueless about why that would make a difference! The only difference between the two ways to import is that the regular way (using the installed copy) calls init.py, but I don't see why that would have such an effect.
A workaround seems to be to use the libyosys.so file directly. You can copy it to the directory your pass sits in and change the import from
from pyosys import libyosys as ys
to
import libyosys as ys
This will not use the installed version of the library, but the one you copied.
The issue seems to lie with the static variable global_refcountstorage in IdString. The size of that vector grows to 179, but at the point it is queried (at position 171) the size is back at 0. This confuses me. I cannot find any place where anything is removed from the vector. The only explanation I can come up with is that the C++ code and the Python code see two different vectors for some reason, but that does not make a lot of sense considering the workaround. Why would this work when using the local copy?
The workaround works for me as well, thanks for getting back to me :)
I still have no solution for this and am running out of places to ask about it (actually I only tried the Cplusplus-sig mailing list, but that one should be very well fitting for such a question / https://mail.python.org/pipermail/cplusplus-sig/2019-July/017551.html). @daveshah1 you worked with boost::python on nextpnr, right? Do you have any idea what might cause this?
I didn't see this in nextpnr because we take a different approach there, with Python more deeply embedded and automatically added to the Inittab: https://github.com/YosysHQ/nextpnr/blob/master/common/pybindings.cc#L235
The problem here is that global constructors are being called twice. I would need to dig into the dynamic linking going on a bit more to work out exactly why. I added the following to rtlil.cc:
class GlobalInitCanary {
public:
GlobalInitCanary() {
printf("***** GlobalInitCanary() *****\n");
};
~GlobalInitCanary() {
printf("***** ~GlobalInitCanary() *****\n");
};
};
GlobalInitCanary global_init_canary;
With pass.py unmodified, Yosys startup prints:
***** GlobalInitCanary() *****
/----------------------------------------------------------------------------\
| |
| yosys -- Yosys Open SYnthesis Suite |
| |
| Copyright (C) 2012 - 2018 Clifford Wolf <clifford@clifford.at> |
| |
| Permission to use, copy, modify, and/or distribute this software for any |
| purpose with or without fee is hereby granted, provided that the above |
| copyright notice and this permission notice appear in all copies. |
| |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| |
\----------------------------------------------------------------------------/
Yosys 0.8+612 (git sha1 d6a289d3, clang 8.0.0 -fPIC -Os)
***** GlobalInitCanary() *****
With the modified pass.py to use import libyosys
, startup now prints:
***** GlobalInitCanary() *****
/----------------------------------------------------------------------------\
| |
| yosys -- Yosys Open SYnthesis Suite |
| |
| Copyright (C) 2012 - 2018 Clifford Wolf <clifford@clifford.at> |
| |
| Permission to use, copy, modify, and/or distribute this software for any |
| purpose with or without fee is hereby granted, provided that the above |
| copyright notice and this permission notice appear in all copies. |
| |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| |
\----------------------------------------------------------------------------/
Yosys 0.8+612 (git sha1 d6a289d3, clang 8.0.0 -fPIC -Os)
Showing that global constructors are only called once.
It seems like import libyosys
is using the built-in libyosys
Python module rather than doing any dynamic linking, hence not re-invoking constructors (similar to how Python scripting in nextpnr works). It seems to work correctly even if I delete every possible location of libyosys.so
.
So I would suggest using just import libyosys
in plugins going forward.
I also want to add 'pass' being a Python keyword we may rename the file to something like cellstatspass.py for better reuse
Steps to reproduce the issue
Expected behavior
output of the frequency of modules as defined in
pass.py
Actual behavior
crash with the following log:
Please describe how the behavior you see differs from the expected behavior.
the comands produce an error instead of a nice graph. This might be simply because I do not know how to create a yosys pass from python but the paper mentions that this should work as well. If this is only because I did not create an shared object file, please let me know how to do so, I could not find any documentation about that.