Using parsim with SIMULINK model containing c-mex s-functions

I have a simulation with multiple S-functions (level 2 written in c++). I want to run a Monte-Carlo analysis for my problem and to speed up the process, I want to run the simulations in parallel using the parsim command. There's a parameter for the S-functions "DX" which would be different for every simulation.
model = 'my_model';
load_system(model);
numSims = 10;
for i = 1:numSims
in(i) = Simulink.SimulationInput(model);
in(i) = in(i).setVariable('DX',my_data(:,i));
end
simOut = parsim(in);
According to my understanding, this should work but it gives me errors.
My c++ S-functions is supposed to load and read some DAT files in order to run and they are in a different folder. The path to access the files is written inside the code. I have added an exception in the code that it should give error "Data could not be loaded" in case the code fails to load and read the files. I get this error when I try to run the simulation using "parsim" command. However, it works fine using the "sim" command.
What could I be doing wrong here? Am I missing something? Any help would be highly appreciated.

9 Comments

Can you post the error messages, and maybe the model itself so the Community can better understand the problem?
Sorry for the late response. I'm attaching the files. Kindly check it please? Thank you
The .cpp (c++ s-function file) and my data file (Data.inp) could not be attached here, that's why I added them in a zip file.
This is the error I'm getting in my simulation. I reproduced the same error in this test case example. If this error could be fixed, I can run my simulation properly using parsim then.
The error is basically the exception thrown when the data file cannot be read. It works fine when I run it using sim('exMdl') command. But doesn't work with parsim. However, if I skip the data file reading from the code, it works.
In your C++ code you use fopen to open the file and assign the file handle to a global variable fp. But then you do not use the file handle in mdlOutput. Are you intending to read data from the file in mdlOutput? If so, call fread to read maybe one item of data, type double, size 8 bytes, from the input file handle. Copy that data to your output Y if successful. Remove the S-Function input U from your code if you intend the data file to be the input.
Your global variable fp should be initialized to NULL. In mdlOutput test that fp is not NULL before using fread.
Try using ssPrintf instead of printf to see any debug messages that your code needs to send to the user. Call ssSetErrorStatus if you need to terminate the simulation due to a problem with the input file.
You will have a problem running more than one copy of this block, because they will share one instance of the global variable fp. If each simulation is going to use a different input file, you may want to pass a file name or file number to the C++ code from Simulink. See the help about adding parameters to your S-Function, so maybe you can load data0.inp, data1.inp, data2.inp in each simulation run as required.
Use pwork vectors if you need each simulation run to have its own input file handle. See ssSetNumPWork and ssSetPWorkValue documentation for information and examples.
Actually my simulation consists of a lot of c++ s-functions with other .cpp files as well which contain a lot of functions. I've defined a class in one of the c++ files which reads the data using fscanf function and stores it into a variable and then I use it over different files using the extern command as well or like you said using PWork or RWork variables. I've also initialized the fp variable (and all similar ones) to NULL at the start of my simulation and in mdlTerminate I delete them as well (as they're pointers).
My problem is that it doesn't read the data file when I try to use parsim command. It works with the sim command.
I found a link
After reading this, I think that parsim creates temporary directories for each of its workers and sends them the files listed in the model dependency analyzer. In the model dependency analyzer, my data files aren't listed there. Maybe that's the reason it's unable to read/load them.
I've tried to use SetupFcn and setPreSimFcn to copy files to the current working directory of each model but I can't seem to do it correctly. Do you know anything about it?
Following up on this threat to see if OP has found anything on this topic. I'm running into a nearly identical issue. I've added the search paths to the parallel workers for the files the S-function tries to refer to, and no luck. I've also tried to use addAttachedFiles() to the parallel pool to add the files needed, but this also does not work. Any updates?
@Fawad Farooq Ashraf: we are facing a similar issue with using an FMU with dependencies in the parsim context. Were you able to resolve this issue?

Sign in to comment.

Answers (1)

Alternatively, you can read data from a binary file using fopen and fread in an M file in MATLAB. Read each dataset into the MATLAB workspace and use a Simulink foreach subsystem to pass data to the sin function in Simulink.

1 Comment

Like I mentioned that my actual simulation consists of a lot of files and doing this would be cumbersome. I do not want to change my validated code which is working perfectly with the sim command.

Sign in to comment.

Categories

Products

Release

R2020b

Asked:

on 3 Feb 2022

Commented:

on 19 Jul 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!