PySpice
PySpice copied to clipboard
Fix NgSpice shared FFI duplication
When creating more than one NgSpiceShared instances, like in https://pyspice.fabrice-salvaire.fr/examples/ngspice-shared/external-source.html, for example to do two simulations in a row, there was an exception thrown from PySpice:
File "/usr/local/lib/python3.6/dist-packages/PySpice/Spice/NgSpice/Shared.py", line 356, in __init__
self._load_library()
File "/usr/local/lib/python3.6/dist-packages/PySpice/Spice/NgSpice/Shared.py", line 374, in _load_library
ffi.cdef(f.read())
File "/usr/local/lib/python3.6/dist-packages/cffi/api.py", line 107, in cdef
self._cdef(csource, override=override, packed=packed)
File "/usr/local/lib/python3.6/dist-packages/cffi/api.py", line 121, in _cdef
self._parser.parse(csource, override=override, **options)
File "/usr/local/lib/python3.6/dist-packages/cffi/cparser.py", line 315, in parse
self._internal_parse(csource)
File "/usr/local/lib/python3.6/dist-packages/cffi/cparser.py", line 355, in _internal_parse
decl.type, name=decl.name, partial_length_ok=True)
File "/usr/local/lib/python3.6/dist-packages/cffi/cparser.py", line 587, in _get_type_and_quals
tp = self._get_struct_union_enum_type('struct', type, name)
File "/usr/local/lib/python3.6/dist-packages/cffi/cparser.py", line 734, in _get_struct_union_enum_type
raise CDefError("duplicate declaration of struct %s" % name)
cffi.error.CDefError: <cdef source string>:7: duplicate declaration of struct ngcomplex
Tracing the source of the error showed that global ffi variable in PySpice was filled twice with API structures, which caused it to fail with duplicate declaration error. The simple fix in pull request is to just remember that API data was already read and not do it again.
Also, for anyone having this issue - a temporary workaround, without having to modify PySpice sources, is to reset the FFI before constructing the object:
class Shared(NgSpiceShared):
def __init__(self, inputs, dt):
PySpice.Spice.NgSpice.Shared.ffi = FFI()
super().__init__()
Thanks for reporting this issue.
Could you explain a bit more what you are doing ? Do you mean simulate in parallel a circuit ? As far I know it requires several ngspice libraries clones (cf. user manual).
Not necessairly in parallel, but in the same Python script. Right now, even the code I linked to, when pasted twice, will fail with the error I described.
I believe the wrapper must be a singleton due to ngspice design.
Could you provide a basic example ? To be sure on the use case.
A dumb example: https://gist.github.com/akrasuski1/d4a0e5c524202b0c3aa2511159101d91
There, I create two experiments, one with voltage divider driven by a sine source, the other with cosine (yeah, I know they are the same, but imagine cosine was square or something). I would expect to be able to analyze the same circuit using both voltage sources (one at a time), but instead, the code crashes.
Thanks it is now clear.
Use case is
class Imp1(NgSpiceShared):
def get_vsrc_data(self, voltage, time, node, ngspice_id):
...
class Imp2(NgSpiceShared):
def get_vsrc_data(self, voltage, time, node, ngspice_id):
...
But NgSpiceShared is a singleton that must be created by new_instance and not __init__
It is a limitation of NgSpice since we cannot instantiate more than one simulator.
A solution is to implement a switch in the callback :
class MyNgSpiceShared(NgSpiceShared):
mode = 1
def get_vsrc_data(self, voltage, time, node, ngspice_id):
if mode == 1:
return self.get_vsrc_data1(voltage, time, node, ngspice_id)
I am getting the exact same error originally described (CDefError: duplicate declaration of struct ngcomplex), except I am am getting it when I run the external source example https://pyspice.fabrice-salvaire.fr/examples/ngspice-shared/external-source.html as written, without trying to create multiple instances.
How do you run this example ?
I was running it out of a ipython notebook, but I think I found the issue. It was with the kernel, not the example. Now, however, I'm getting the following errors:
2018-02-15 16:55:18,889 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Note: can't find init file.
2018-02-15 16:55:18,904 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.DEBUG - Execute command: set nomoremode
only first is an error, you have to check your ngspice installation, on Linux /usr/share/ngspice/scripts/spinit
I'm on windows 10, the init file looks good; it's in Program FIles\Spice64\share\ngspice\scripts. Where does the module expect to find it?
It is not related to PySpice, but Ngspice. I don't know why your setup is wrong.
I have the same problem on my win10 64bit setup. The spinit file is residing in C:\Program Files\Spice64\share\ngspice\scripts and the dll is found (also by pyspice) in C:\Program Files\Spice64\bin_dll. ngspice or pyspice is not able to locate the spinit file. Where does pyspice/ngspice look for it?
I tried copying it to the current working directory, which works but then the paths within spinit must be updated to absolute paths.
Setting SPICE_LIB_DIR or SPICE_PATH doesn't seem to alter anything.
I was running it out of a ipython notebook, but I think I found the issue. It was with the kernel, not the example. Now, however, I'm getting the following errors:
2018-02-15 16:55:18,889 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Note: can't find init file.
2018-02-15 16:55:18,904 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.DEBUG - Execute command: set nomoremode
What was the issue? how did you resolve it? I'm facing the same problem.
I have the same problem, can't find the init file, on Windows 10 x64. Is there any solution yet?
@peter-ch, read the ngspice manual:
(...) The path may be overridden by setting the environmental variable SPICE_SCRIPTS to a path where spinit is located.
So, on OSX:
export SPICE_SCRIPTS=/usr/local/Cellar/ngspice/31/share/ngspice/scripts/
Changing that environment variable had no effect on the error. I changed it from both Python (os.environ) and Windows GUI, same thing.
2020-04-06 21:52:52,869 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.INFO - New instance for id 0 2020-04-06 21:52:52,907 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Note: can't find init file.
So is the problem fixed or no? Any updates? Thanks.