Open AnHeuermann opened 1 year ago
We will check this.
PS: In the current release, you don't need to load the FMU multiple times for multithreading. Loading it once and use fmiSimulate
in a Thread-Loop is sufficient (one fmi2Instance is allocated per Thread, all Threads share the same FMU/DLL). But the tutorial "multiprocessing" needs an update (multiple FMUs are loaded there).
Any news on this issue? My scripts are generating a bunch of segmentation faults when running on a single FMU in multiple threads and FMI.jl is reporting errors when I re-use a FMU on a different thread. So I can't let my scripts run over night, because they'll break most of the time.
ERROR: LoadError: TaskFailedException
nested task error: AssertionError: ["No FMU instance allocated (in current thread with ID `18`), have you already called fmiInstantiate?"]
Hm... I am using multithreading on a single FMU quite often. There is no need to load/unload the FMU in this operation mode multiple times. I do this not only for simulation, but also gradinet determination in NeuralFMUs. You should be able to load the FMU a single time (on the main thread), simulate it on different threads (monte carlo style) and being able to unload it after all threads finished (again on the main thread).
I am working on an update for the multithreading tutorial. But there where multiple other ToDos the last months (speed, sensitivities, ...)
So a typical workflow might look like:
(1) load FMU (its a dynamic library, so its ok to just load it once) (2) do things with multiple instances of the FMU (FMI.jl allocates a new instance for every simulation by default) in parallel, but dont load/unload/reload the FMU (no need to do that) (3) finally - after every thread finished - unload the FMU at program end
I think I found my issue. I was
My mwe looks something like this:
FMU from
model HelloWorld "Simple hello world example"
Real x(start=1, fixed=true);
Real y;
Real z;
parameter Real a = -0.5;
equation
der(x) = a*x;
y = sin(x);
z = 2*abs(x);
end HelloWorld;
generated with OpenModelica:
loadFile("helloWorld.mo"); getErrorString();
buildModelFMU(HelloWorld); getErrorString();
import FMI
import FMIImport
ENV["JULIA_DEBUG"] = "FMI,FMIIMport,FMICore"
function runAll()
fmuPath = "fmu/HelloWorld.fmu"
inputVars = ["x"]
outputVars = ["y", "z"]
nInputs = length(inputVars)
nOutputs = length(outputVars)
nVars = nInputs + nOutputs
fmu = FMI.fmiLoad(fmuPath)
Threads.@threads for _ in 1:Threads.nthreads()*10
@info "Thread $(Threads.threadid()) starting!"
comp = FMI.fmiInstantiate!(fmu; loggingOn = false, externalCallbacks=false)
FMI.fmiSetupExperiment(comp)
FMI.fmiEnterInitializationMode(comp)
FMI.fmiExitInitializationMode(comp)
# Set random data
row = Array{Float64}(undef, nVars)
row_vr = FMI.fmiStringToValueReference(fmu.modelDescription, vcat(inputVars,outputVars))
for _ in 1:10
row[1:nInputs] = rand(nInputs)
FMIImport.fmi2SetReal(comp, row_vr, row)
row[nInputs+1:end] .= FMIImport.fmi2GetReal(comp, row_vr[nInputs+1:end])
end
#FMI.fmiFreeInstance!(comp)
@info "Thread $(Threads.threadid()) finished!"
end
FMI.fmiUnload(fmu)
end
Output:
julia> runAll()
[ Info: Thread 2 starting!
[ Info: Thread 13 starting!
[ Info: Thread 19 starting!
[ Info: Thread 14 starting!
[ Info: Thread 3 starting!
[ Info: Thread 11 starting!
[ Info: Thread 5 starting!
[ Info: Thread 9 starting!
[ Info: Thread 11 starting!
[ Info: Thread 3 starting!
[ Info: Thread 8 starting!
[ Info: Thread 18 starting!
[ Info: Thread 16 starting!
[ Info: Thread 19 starting!
[ Info: Thread 10 starting!
[ Info: Thread 1 starting!
[ Info: Thread 4 starting!
[ Info: Thread 14 starting!
[ Info: Thread 13 starting!
[ Info: Thread 6 starting!
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb49ee39ae0, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb59c387290
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb59c387290, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a15b0580, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb594257a50
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb59c387290) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb594257a50, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb59c387290) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb594257a50) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb59c387290, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.007785949875737441, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a14a5150, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb56c31e9c0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb594257a50) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb594257a50, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.5500224536739118, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb59c387290, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.007785871210611238, 0.015571899751474882]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb56c31e9c0, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb59c387290) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb56c31e9c0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb594257a50, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.5227063711065167, 1.1000449073478236]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
[ Info: Thread 2 finished!
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb56c31e9c0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb594257a50) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb499d55420, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb55444f3b0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
[ Info: Thread 3 finished!
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb56c31e9c0, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.8363120420636442, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb55444f3b0, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb56c31e9c0, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.7421764867727053, 1.6726240841272884]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb55444f3b0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a1345750, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb58c44f120
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb55444f3b0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb56c31e9c0) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb58c44f120, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
[ Info: Thread 12 finished!
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb58c44f120) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb55444f3b0, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.8703188848113075, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb58c44f120) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb49db567a0, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb57c2df520
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb55444f3b0, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.7645345235525051, 1.740637769622615]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb57c2df520, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb55444f3b0) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
[ Info: Thread 15 finished!
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb58c44f120, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.3752589544361712, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb57c2df520) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb58c44f120, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.36651347587929817, 0.7505179088723424]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb57c2df520) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb58c44f120) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
[ Info: Thread 6 finished!
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb57c2df520, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.0542789737565329, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a13993f0, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb5441c26e0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb57c2df520, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.054252324833830703, 0.1085579475130658]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb5441c26e0, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb57c2df520) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb5441c26e0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a1225bd0, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb5340b6270
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
[ Info: Thread 9 finished!
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb5441c26e0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb5340b6270, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb5441c26e0, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.5863938555148537, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb5340b6270) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb5441c26e0, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.5533609197270968, 1.1727877110297074]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a1569330, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb5503802b0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb5441c26e0) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb5503802b0, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb5340b6270) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb4a14a5270, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb55c235de0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
[ Info: Thread 13 finished!
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb5503802b0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb55c235de0, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb5340b6270, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.7396688106025051, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb5503802b0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb55c235de0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb5503802b0, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.17655822007580613, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb55c235de0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb5503802b0, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.17564234626318317, 0.35311644015161225]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb55c235de0, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.7221951008339035, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb5503802b0) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
┌ Debug: fmi2Instantiate(instanceName: Ptr{UInt8} @0x00007fb4b12f2038, fmuType: 0, fmuGUID: Ptr{UInt8} @0x00007fb5afcc1cf8, fmuResourceLocation: Ptr{UInt8} @0x00007fb4b0847bd8, functions: Ptr{FMICore.fmi2CallbackFunctions} @0x00007fb49db56770, visible: 0, loggingOn: 0) → Ptr{Nothing} @0x00007fb594374420
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:25
[ Info: Thread 17 finished!
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb5340b6270, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.6740433016954693, 1.4793376212050102]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
[11758] signal (11.1): Segmentation fault
in expression starting at REPL[2]:1
omc_util_get_pool_state at /tmp/fmijl_2A606N/HelloWorld/binaries/linux64/HelloWorld.so (unknown line)
updateIfNeeded at /tmp/fmijl_2A606N/HelloWorld/binaries/linux64/HelloWorld.so (unknown line)
fmi2GetReal at /tmp/fmijl_2A606N/HelloWorld/binaries/linux64/HelloWorld.so (unknown line)
fmi2GetReal! at /home/USER/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:174
fmi2GetReal! at /home/USER/.julia/packages/FMIImport/hLBHK/src/FMI2/c.jl:558 [inlined]
fmi2GetReal at /home/USER/.julia/packages/FMIImport/hLBHK/src/FMI2/int.jl:143
unknown function (ip: 0x7fb4a9936b7f)
┌ Debug: fmi2SetupExperiment(c: Ptr{Nothing} @0x00007fb594374420, toleranceDefined: 0, tolerance: 0.0, startTime: 0.0, stopTimeDefined: 0, stopTime: 0.0) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:103
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb5340b6270) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
[ Info: Thread 19 finished!
┌ Debug: fmi2EnterInitializationMode(c: Ptr{Nothing} @0x00007fb594374420) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:118
_jl_invoke at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/gf.c:2758 [inlined]
ijl_apply_generic at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/gf.c:2940
┌ Debug: fmi2ExitInitializationMode(c: Ptr{Nothing} @0x00007fb594374420) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:133
#fmi2GetReal#10 at /home/USER/.julia/packages/FMI/1VUBe/src/FMI2/comp_wraps.jl:107
fmi2GetReal at /home/USER/.julia/packages/FMI/1VUBe/src/FMI2/comp_wraps.jl:106 [inlined]
macro expansion at /home/USER/workspace/Testitesttest/FMI-multithread/runAllTheFMUs.jl:34 [inlined]
#6#threadsfor_fun#3 at ./threadingconstructs.jl:163
#6#threadsfor_fun at ./threadingconstructs.jl:130 [inlined]
#1 at ./threadingconstructs.jl:108
unknown function (ip: 0x7fb4a992aa0f)
_jl_invoke at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/gf.c:2758 [inlined]
ijl_apply_generic at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/gf.c:2940
┌ Debug: fmi2SetReal(c: Ptr{Nothing} @0x00007fb594374420, vr: UInt32[0x00000000, 0x00000002, 0x00000003], nvr: 3, value: [0.6784114589340956, 0.0, 0.0])
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:193
jl_apply at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/julia.h:1879 [inlined]
start_task at /cache/build/default-amdci4-6/julialang/julia-release-1-dot-9/src/task.c:1092
Allocations: 61803428 (Pool: 61766991; Big: 36437); GC: 98
┌ Debug: fmi2GetReal(c: Ptr{Nothing} @0x00007fb594374420, vr: UInt32[0x00000002, 0x00000003], nvr: 2, value: [0.6275570249747953, 1.3568229178681912]) → 0
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:178
┌ Debug: fmi2FreeInstance(c: Ptr{Nothing} @0x00007fb594374420) → [nothing]
└ @ FMICore ~/.julia/packages/FMICore/JhS6T/src/FMI2/cfunc.jl:41
[ Info: Thread 3 finished!
[1] 11758 segmentation fault julia --threads=auto
Is this error FMU-specific? If no, can you use one public available (like from the modelica refernce FMUs or the FMIZoo.jl). This would be much easier to reproduce, because I don't have OM installed.
I couldn't reproduce the same issue, but with 2.0 VanDerPol FMU from https://github.com/modelica/Reference-FMUs and can trigger an error in FMI.fmiFreeInstance!
.
import FMI
import FMIImport
function runAll()
fmuPath = "fmu/2.0/VanDerPol.fmu"
inputVars = ["x0", "x1"]
outputVars = ["x0", "x1"]
nInputs = length(inputVars)
nOutputs = length(outputVars)
nVars = nInputs + nOutputs
fmu = FMI.fmiLoad(fmuPath)
Threads.@threads for _ in 1:Threads.nthreads()*10
@info "Thread $(Threads.threadid()) starting!"
comp = FMI.fmiInstantiate!(fmu; loggingOn = false, externalCallbacks=false)
FMI.fmiSetupExperiment(comp)
FMI.fmiEnterInitializationMode(comp)
FMI.fmiExitInitializationMode(comp)
# Set random data
row = Array{Float64}(undef, nVars)
row_vr = FMI.fmiStringToValueReference(fmu.modelDescription, vcat(inputVars,outputVars))
for _ in 1:1000
row[1:nInputs] = rand(nInputs)
FMIImport.fmi2SetReal(comp, row_vr, row)
row[nInputs+1:end] .= FMIImport.fmi2GetReal(comp, row_vr[nInputs+1:end])
end
FMI.fmiFreeInstance!(comp)
@info "Thread $(Threads.threadid()) finished!"
end
FMI.fmiUnload(fmu)
end
julia --threads=auto -e "include(\"runAllTheFMUs.jl\"); runAll()"
[ Info: Thread 10 finished!
ERROR: TaskFailedException
nested task error: AssertionError: fmi2FreeInstance!(...): Freeing 2 instances with one call, this is not allowed. Target address `Ptr{Nothing} @0x00007f2d0401a2a0` was found 2 times at indicies [6, 7].
Stacktrace:
[1] (::FMIImport.var"#78#80"{FMICore.FMU2Component{FMICore.FMU2}, Ptr{Nothing}})()
@ FMIImport ~/.julia/packages/FMIImport/hLBHK/src/FMI2/c.jl:126
[2] lock(f::FMIImport.var"#78#80"{FMICore.FMU2Component{FMICore.FMU2}, Ptr{Nothing}}, l::ReentrantLock)
@ Base ./lock.jl:229
[3] fmi2FreeInstance!(c::FMICore.FMU2Component{FMICore.FMU2}; popComponent::Bool)
@ FMIImport ~/.julia/packages/FMIImport/hLBHK/src/FMI2/c.jl:124
[4] fmi2FreeInstance!
@ ~/.julia/packages/FMIImport/hLBHK/src/FMI2/c.jl:117 [inlined]
[5] fmiFreeInstance!(str::FMICore.FMU2Component{FMICore.FMU2})
@ FMI ~/.julia/packages/FMI/1VUBe/src/deprecated.jl:75
[6] macro expansion
@ ~/workspace/Testitesttest/FMI-multithread/runAllTheFMUs.jl:39 [inlined]
[7] (::var"#6#threadsfor_fun#4"{var"#6#threadsfor_fun#3#5"{FMICore.FMU2, Int64, Int64, Vector{String}, Vector{String}, UnitRange{Int64}}})(tid::Int64; onethread::Bool)
@ Main ./threadingconstructs.jl:163
[8] #6#threadsfor_fun
@ ./threadingconstructs.jl:130 [inlined]
[9] (::Base.Threads.var"#1#2"{var"#6#threadsfor_fun#4"{var"#6#threadsfor_fun#3#5"{FMICore.FMU2, Int64, Int64, Vector{String}, Vector{String}, UnitRange{Int64}}}, Int64})()
@ Base.Threads ./threadingconstructs.jl:108
...and 1 more exception.
Stacktrace:
[1] threading_run(fun::var"#6#threadsfor_fun#4"{var"#6#threadsfor_fun#3#5"{FMICore.FMU2, Int64, Int64, Vector{String}, Vector{String}, UnitRange{Int64}}}, static::Bool)
@ Base.Threads ./threadingconstructs.jl:120
[2] macro expansion
@ ./threadingconstructs.jl:168 [inlined]
[3] runAll()
@ Main ~/workspace/Testitesttest/FMI-multithread/runAllTheFMUs.jl:21
[4] top-level scope
@ none:1
I need to run it multiple times to see the error.
Maybe it's more of an OpenModelica issue. What are the requirements for the FMU to be simulated in parallel? The OpenModelica FMUs are not thread-safe and I think are using some global variables that shouldn't be changed by other threads. But would this happen in this case?
I think thread-safety is definitely a hard requirement to simulate FMUs multi-threaded. Ignoring this may lead to wrong simulation results at least (but can also crash of coure, dependent on the implementation).
However, the second issue (fmi2FreeInstance!
) shouldn't appear and will be investigated.
Issue
I want to simulate a number of FMUs in parallel with FMI.jl and reuse the already loaded FMUs for multiple runs, but encounter an error in FMIImport where
cd
is used to change the directory while running in parallel.I believe the issue is the usage of
cd
in FMIImport ext.jl#L245-L252 Iscd
needed here? But I guess there are other problems with using e.g.ccall
in parallel, see https://docs.julialang.org/en/v1/manual/multi-threading/#@threadcall.If it's not possible to use
fmiLoad
andfmiReload
in parallel, maybe add a check to them to test if they are run inside a parallel region?How to reproduce
You can get similar results with