PySpice icon indicating copy to clipboard operation
PySpice copied to clipboard

NgSpice Parallel

Open FabriceSalvaire opened this issue 5 years ago • 1 comments

Manual

19.6 ngspice parallel

The following chapter describes an offer to the advanced user and developer community. If you are interested in evaluating the parallel and synchronized operation of several ngspice instances, this may be one way to go. However, no ready to use implementation is available. You will find a toolbox and some hints how to use it. Parallelization and synchronization is your task by developing a suitable caller! And of course another major input has to come from partitioning the circuit into suitable, loosely coupled pieces, each with its own netlist, one netlist per ngspice instance. And you have to define the coupling between the circuit blocks. Both are not provided by ngspice, but are again your responsibility. Both are under active research, and the toolbox described below is an offer to join that research.

19.6.1 Go parallel!

A simple way to run several invocations of ngspice in parallel for transient simulation is to define a caller that loads two or more ngspice shared libraries. There is one prerequisite however to do so: the shared libraries have to have different names. So compile ngspice shared lib (see 19.1), then copy and rename the library file, e.g. ngspice.dll may become ngspice1.dll, ngspice2.dll etc. Then dynamically load ngspice1.dll, retrieve its address, initialize it by calling ngSpice_init() (see 19.3.2.1), then continue initialization by calling ngSpice_init_Sync() (see 19.6.2.1). An integer identification number may be sent during this step to later uniquely identify each invocation of the shared library, e.g. by having any callback use this identifier. Repeat the sequence with ngspice2.dll and so on. Inter-process communication and synchronization is now done by using three callback func- tions. To understand their interdependence, it might be useful to have a look at the transient simulation sequence as defined in the ngspice source file dctran.c. The following listing in- cludes the shared library option (It differs somewhat from standard procedure) and disregards XSPICE.

  1. initialization
  2. calculation of operating point
  3. next time step: set new breakpoints (VSRC, ISRC, TRA, LTRA)
  4. send simulation data to output, callback function SendData* datfcn
  5. check for autostop and other end conditions
  6. check for interrupting simulation (e.g. by bg_halt)
  7. breakpoint handling (e.g. enforce breakpoint, set new small cktdelta if directly after the breakpoint)
  8. calling ngspice internal function sharedsync() that invokes callback function GetSync- Data* getsync with location flag loc = 0
  9. save the previous states
  10. start endless loop
  11. save cktdelta to olddelta, set new time point by adding cktdelta to ckttime
  12. new iteration of circuit at new time point, which uses callback functions GetVSRCData* getvdat and GetISRCData* getidat to retrieve external voltage or current inputs, returns redostep=0, if converged, redostep=1 if not converged
  13. if not converged, divide cktdelta by 8
  14. check for truncation error with all non-linear devices, if necessary create a new (smaller) cktdelta to limit the error, optionally change integration order
  15. calling ngspice internal function sharedsync() that invokes callback function GetSync- Data* getsync with location flag loc = 1: as a result either goto 3 (next time step) or to 10 (loop start), depending on ngspice and user data, see the next paragraph.

The code of the synchronization procedure is handled in the ngspice internal function sharedsync() and its companion user defined callback function GetSyncData* getsync. The actual setup is as follows:

If no synchronization is asked for (GetSyncData* set to NULL), program control jumps to ’next time step’ (3) if redostep==0, or subtracts olddelta from ckttime and jumps to ’loop start’ (9) if redostep <> 0. This is the standard ngspice behavior.

If GetSyncData* has been set to a valid address by ngSpice_Init_Sync(), the callback function getsync is involved. If redostep <> 0, olddelta is subtracted from ckttime, getsync is called, either the cktdelta time suggested by ngspice is kept or the user provides his own deltatime, and the program execution jumps to (9) for redoing the last step with the new deltatime. The return value of getsync is not used. If redostep == 0, getsync is called. The user may keep the deltatime suggested by ngspice or define a new value. If the user sets the return value of getsync to 0, the program execution then jumps to ’next time step’ (3). If the return value of getsync is 1, olddelta is subtracted from ckttime, and the program execution jumps to (9) for redoing the last step with the new deltatime. Typically the user provided deltatime should be smaller than the value suggested by ngspice.

19.6.2 Additional exported functions

The following functions (exported or callback) are designed to support the parallel action of several ngspice invocations. They may be useful, however, also when only a single library is loaded into a caller, if you want to use external voltage or current sources or ’play’ with advancing simulation time.

19.6.2.1 int ngSpice_Init_Sync(GetVSRCData* , GetISRCData* , GetSyncData* , int*, void*) Pointers to callback functions (details see 19.3.3): GetVSRCData* callback function for retrieving a voltage source value from caller (NULL allowed) GetISRCData* callback function for retrieving a current source value from caller (NULL al- lowed) GetSyncData* callback function for synchronization (NULL allowed)

More pointers

int* pointer to integer unique to this shared library (defaults to 0) void* pointer to user-defined data, will not be modified, but handed over back to caller dur- ing Callback, e.g. address of calling object. If NULL is sent here, userdata info from ngSpice_Init() will be kept, otherwise userdata will be overridden by new value from here.

19.6.2.2 bool ngSpice_SetBkpt(double)

Sets a breakpoint in ngspice, a time point that the simulator is enforced to hit during the transient simulation. After the breakpoint time has been hit, the next delta time starts with a small value and is ramped up again. A breakpoint should be set only when the background thread in ngspice is not running (before the simulation has started, or after the simulation has been paused by bg_halt). The time sent to ngspice should be larger than the current time (which is either 0 before start or given by the callback GetSyncData (19.6.3.3). Several breakpoints may be set.

19.6.3 Additional callback functions

...

19.6.4 Parallel ngspice example

A first example is available as a compacted 7z archive. It contains the source code of a control- ling application, as well as its compiled executable and ngspice.dll (for MS Windows). As the input circuit an inverter chain has been divided into three parts. Three ngspice shared libraries are loaded, each simulates one partition of the circuit. Interconnections between the partitions are provided via a callback function. The simulation time is synchronized among the three ngspice invocations by another callback function.

FabriceSalvaire avatar May 05 '20 12:05 FabriceSalvaire

PySpice

  • ngspice parallel seems voodoo design
  • is there an example somewhere ??? http://ngspice.sourceforge.net/ngspice-shared-lib/ngspice_sync_win.7z but Windows VisualC++ project to be tested on Linux seems to be a complete example
  • change to ffi_string_utf8 ???
  • copy ngspice library to a tmp directory

FabriceSalvaire avatar May 05 '20 12:05 FabriceSalvaire