I’ve created a C block that successfully stops the sim with an exit(retval) in the code. It works!!!
However, when I run the sim with multiple stepping, it exits the entire sim and not just the step that is being run.
Is there a means to stop the step but not the entire multi-step run from the C-block?
No, there isn’t. Multiple steps are run in one process. As soon as you exit the process, the dance is over.
I’m not sure why you would want to use exit() absent some extraordinary condition (like file I/O failures which your code likely doesn’t do). But, you could, of course, reduce the sim time to something less than when your code would otherwise abort to allow all of the steps to complete.
Thank you for the reply and, of course, for QSpice.
Just to let you know why I’m interested in exiting a step prematurely but not the sim.
With QSpice’s ability to do multiple dimensional (parameter) stepping, it allows me to perform “what-if” experiments. I can use more than one parameter to step through.
My sim has either a “PASS” or “FAIL” bounds I am testing. Once it reaches this bounds, it doesn’t need to proceed any further on the step. However it must continue on the next step in the sequence to see if that set of parameters is a better fit.
The multi-dimensional step’d sim I was running had over 30K steps with a .tran of 4 seconds. The sim took over an hour to run and the .meas statements with plotting took at least another hour.
However, many of the steps resolved to the bounds I mentioned above in less than 1 second of .tran time. If I could have exited the step early, I could have saved many minutes of real sim execution time.
See my reply to Mike about why I’m looking for a way to exit the current step execution but continue on to the next step.
But, you could, of course, reduce the sim time to something less than when your code would otherwise abort to allow all of the steps to complete.
Do you mean I can dynamically change the .tran runtime on the fly, let’s say, in a C block?
I know the current sim time is fed into the C block call. However, I didn’t think that I could change it to be accepted by the rest of the sim execution engine.
No, a C-block doesn’t have access to the simulation time.
I’m thinking the only way to do it is if I implement a function, say, abort(bool arg), that terminates the current .tran or .dc or .ac or .noise if arg is true. Something that is called from a Behavioral source.
If you’re interested on implementing abort(), I be interested on beta-testing it.
It would be interesting as this feature can stop simulation after steady state is reached, and not necessary only with C-block if implementation is a function for Behavioral source. Looking forward to it.
If you wanted to put it in C-Block, maybe treat a negative value returned in *timestep from Trunc() as request to terminate?
OK, I implemented it as a behavioral source function. The new function is called AbortSim(double arg). If arg is greater then .5, then the simulation stops and goes to the next step(if any). Otherwise AbortSim() returns the argument in the interest of debugging what input it got.
From a .DLL, you have now two ways of stopping the simulation. You can output a voltage read by behavioral source and have it quit or you can implement the function double MaxExtStepSize() and have it return -1e308. Specifically -1e308. No other number. To implement the function, check the box that reads “Include a double MaxExtStepSize() template” in the Advanced C++ Template Options dialog.
These methods will flush the output files and tidy up the .qraw waveform files appropriately.
Below demonstrates the AbortSim() function for a transient analysis. The function should for .noise, .ac, .dc, as well as .tran.
Thank you. I will try it out ASAP and let you know.
I used AbortSim() as is in your sim example.
With a .tran 10 I get the same results as you.
However if I change to .tran 1000 I get:
I’m assuming that the MAXSTEP size is being automatically adjusted higher yielding few sim points.
Using .tran 1000 with .option MAXSTEP=0.01 gave me results like the .tran 10.
I ran my multi-dimensional step sim with and without AbortSim().
Here are my results:
The major take-aways is that the ability to abort the sim step once the PASS or FAIL criteria is met results in significant reduction in post-processing time. In the sim used in my example, it was at least a 1/3 reduction using the AbortSim(). The major reduction was in post-processing. This is probably due to the significant reduction in .qraw file size. Aborting the sim stops collecting further data for the step being processed. A smaller file size should make it faster to process .meas commands.
The actual simulation time was only minorly reduced in my case. It would be interesting to get feedback from other’s sims to see if it can be improved upon.
PS: Thanks to Mike for entertaining this feature recommendation. Helping to make this tool even more world-class than it already is.
I just tested the replacement for exit() in a DLL call within a C block. It does work!!!
As you stated, I had to pass -1e308 as a return in the MaxExtStepSize().
I used a instance variable that determined the need to stop in the module’s main dll call.
When MaxExtStepSize() gets called, I pass -1e308 when an abort from the step is need. Otherwise I pass the value needed.
This method also doesn’t require me to wait for multiples of 512 points to be collected to be available for plot data. I can abort immediately and still have plot data logged.
Here’s an example of my MaxExtStepSize() code:
extern “C” __declspec(dllexport) double MaxExtStepSize(struct sSTOP *inst)
return (inst->stop_evnt != 0 ? -1e308 : 1e308); // implement a good choice of max timestep size that depends on struct sSTOP
There’s no attempt to simulate to the exact point where the argument of AbortSim() is just over .5. It just stops at the timestep past where AbortSim() says to stop. That’s actually faster than trying to find the point where AbortSim() becomes true for the first time.
BTW, I misspoke earlier when I said AbortSim() works for .ac and .noise. It’s only for .tran and .dc.
I agree. Having the sim abort is a time saver. If I need to have a more accurate point of time, I just have to decrease the MAXSTEP value.