Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-threading with OMJulia #71

Closed
Wardi0 opened this issue Dec 5, 2022 · 11 comments
Closed

Multi-threading with OMJulia #71

Wardi0 opened this issue Dec 5, 2022 · 11 comments
Assignees

Comments

@Wardi0
Copy link

Wardi0 commented Dec 5, 2022

Hi there! I am using OMJulia in VSCode and am trying to optimise the parameters of dynamic Modelica models.

I was wondering if the multi-threading of simulations is possible with OMJulia? I have tried creating multiple OMCSession objects and running parallel simulations across them but I get a "TaskFailedException" as soon as multiple simulations try to run at once. I am quite new to both OMJulia and multi-threading so I'm not sure if this is a limitation of OMJulia or a mistake on my end.

@casella
Copy link
Contributor

casella commented Dec 5, 2022

@JKRT can you please comment on that?

@JKRT JKRT self-assigned this Dec 6, 2022
@JKRT
Copy link
Member

JKRT commented Dec 6, 2022

Hi there! I am using OMJulia in VSCode and am trying to optimise the parameters of dynamic Modelica models.

I was wondering if the multi-threading of simulations is possible with OMJulia? I have tried creating multiple OMCSession objects and running parallel simulations across them but I get a "TaskFailedException" as soon as multiple simulations try to run at once. I am quite new to both OMJulia and multi-threading so I'm not sure if this is a limitation of OMJulia or a mistake on my end.

Hello @Wardi0 thanks for raising the issue, could you provide a minimal example showcasing the issue, in principle, I believe it should work

@Wardi0
Copy link
Author

Wardi0 commented Dec 6, 2022

Hi JKRT, thank you for helping with this issue! This is my code:

# Create an OMCSession for each thread, add to a vector and load the model on each
sessions = []
for thread in 1:Threads.nthreads()
    push!(sessions, OMJulia.OMCSession())
    sessions[thread].ModelicaSystem("package.mo","FusionPhD.ModelicaFluidModels.RankineCycles.SimpleCycleESSDemo2")
end

# Define the valid domain of the decision variables [gain, time constant]
upper = x -> [2000e-5,300.0]
lower = x -> [1e-5,1.0]
domain = Fresa.Domain(lower,upper)

# Objective function (minimise deviation integral)
function controller_error(x, sessions)
    thread_id = Threads.threadid() 
    dev = Inf64 # Worst-case objective value
    feasibility = 1.0 # Assume infeasible
    try        
        sessions[thread_id].setParameters(["power_PI.k=$(x[1])", "power_PI.T=$(x[2])"]) # Set design parameters
        println("Starting simulation on thread "*string(Int(thread_id)))
        sessions[thread_id].simulate() # Simulate model with design parameters
        dev = sessions[thread_id].getSolutions("controller_error")[1][end] # Extract objective value from simulation results  
        feasibility = 0.0 # Assume feasible if simulation runs with no errors
        println("Simulation on thread "*string(Int(thread_id))*"\nObjective="*string(dev)*" | Feasibility="*string(feasibility))    
    catch TaskFailedException
        println("Caught TaskFailedException on thread "*string(Int(thread_id)))
        return (dev, feasibility)
    end
    return (dev, feasibility)
end

p0 = [Fresa.createpoint([350e-5,50.0], controller_error, sessions)] # Initial solution population
best, pop = Fresa.solve(controller_error, p0, domain; parameters=sessions, multithreading = true, ngen = 5) # Run Fresa optimiser

Based on my print statements, OMJulia is indeed running in parallel. It is just that the multi-threading raises these TaskFailedExceptions (seemingly at random to me); all the simulations ran fine with no errors on a single thread.

@adeas31
Copy link
Member

adeas31 commented Dec 7, 2022

Perhaps you need to set a unique working directory for each OMCSession otherwise simulation will not work since it tries to delete and create files at the same location.

@arun3688
Copy link
Contributor

arun3688 commented Dec 7, 2022

@adeas31 OMJulia creates a new temp directory for each OMCSession() by default and the simulations are done in separate working directory

@JKRT
Copy link
Member

JKRT commented Dec 8, 2022

Hi JKRT, thank you for helping with this issue! This is my code:

# Create an OMCSession for each thread, add to a vector and load the model on each
sessions = []
for thread in 1:Threads.nthreads()
    push!(sessions, OMJulia.OMCSession())
    sessions[thread].ModelicaSystem("package.mo","FusionPhD.ModelicaFluidModels.RankineCycles.SimpleCycleESSDemo2")
end

# Define the valid domain of the decision variables [gain, time constant]
upper = x -> [2000e-5,300.0]
lower = x -> [1e-5,1.0]
domain = Fresa.Domain(lower,upper)

# Objective function (minimise deviation integral)
function controller_error(x, sessions)
    thread_id = Threads.threadid() 
    dev = Inf64 # Worst-case objective value
    feasibility = 1.0 # Assume infeasible
    try        
        sessions[thread_id].setParameters(["power_PI.k=$(x[1])", "power_PI.T=$(x[2])"]) # Set design parameters
        println("Starting simulation on thread "*string(Int(thread_id)))
        sessions[thread_id].simulate() # Simulate model with design parameters
        dev = sessions[thread_id].getSolutions("controller_error")[1][end] # Extract objective value from simulation results  
        feasibility = 0.0 # Assume feasible if simulation runs with no errors
        println("Simulation on thread "*string(Int(thread_id))*"\nObjective="*string(dev)*" | Feasibility="*string(feasibility))    
    catch TaskFailedException
        println("Caught TaskFailedException on thread "*string(Int(thread_id)))
        return (dev, feasibility)
    end
    return (dev, feasibility)
end

p0 = [Fresa.createpoint([350e-5,50.0], controller_error, sessions)] # Initial solution population
best, pop = Fresa.solve(controller_error, p0, domain; parameters=sessions, multithreading = true, ngen = 5) # Run Fresa optimiser

Based on my print statements, OMJulia is indeed running in parallel. It is just that the multi-threading raises these TaskFailedExceptions (seemingly at random to me); all the simulations ran fine with no errors on a single thread.

@Wardi0 What version of OMJulia, and what platform are you on? Furthermore, would it be possible to get model, or if that is not possible that you try the same example with some other model that can be shared?

@Wardi0
Copy link
Author

Wardi0 commented Dec 9, 2022

@JKRT Ah, I was not up-to-date. I was using OMJulia v0.1.0 on VSCode for Windows 10. I have created a repository with the code that produced the errors in that version if you are still interested (https://github.com/Wardi0/OMJulia_multithreading)

Having updated to OMJulia v0.2.1 though, I can no longer start an OMCSession. OMJulia seems to have made 2 files in the current directory, stderr.log and stdout.log, that I cannot edit without admin priveleges (university laptop with admin restrictions....), so trying to create an OMCSession throws:

IOError: open("stderr.log", 769, 420): permission denied (EACCES)

Is there any way around this?

@arun3688
Copy link
Contributor

arun3688 commented Dec 9, 2022

@Wardi0 start your julia repl as administrator and it should work

@Wardi0
Copy link
Author

Wardi0 commented Dec 13, 2022

@arun3688 My university does not give us admin rights on laptops :(

@JKRT
Copy link
Member

JKRT commented Dec 13, 2022

@Wardi0 One workaround to try what Arun suggested is to create a virtual machine and install everything you need in that image; in that way, you can be administrator. Still, of course, there are performance penalties if you do, but at least it can help to pinpoint the issue

@Wardi0
Copy link
Author

Wardi0 commented Mar 1, 2023

Hi @JKRT, just wanted to update this thread. I am now using a Linux machine and have got multi-threading working with OMJulia so I think this issue can be closed.

I still cannot run it on Windows due to the IOError: open("stderr.log", 769, 420): permission denied (EACCES) error I mentioned above; my department's system admin was able to reproduce the error even with administrator priveleges. I can create a new issue for this though.

As an aside, is there a way to suppress the printed terminal output from OMJulia.OMCSession() and OMJulia.simulate? With multiple threads, the simulation output from OpenModelica makes the results quite hard to parse.

@Wardi0 Wardi0 closed this as completed Mar 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants