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

Initializing models in parallel #28

Open
missermann opened this issue Apr 6, 2020 · 5 comments
Open

Initializing models in parallel #28

missermann opened this issue Apr 6, 2020 · 5 comments
Labels
question Issue only concerns a or multiple questions.

Comments

@missermann
Copy link

Hi!
I want to use pyfmi to simulate individual time steps (with do_step) in EnergyPlus. I recognized that initializing the individual EnergyPlus models takes quite some time. Therefore, I hope to find a way to initialize the models in parallel. If it matters, I am on Ubuntu 16.10 and use Python 3.6. Here is what I want to get done in serial:

fmus        = {}
for id in id_list:
    chdir(fmu_path+str(id))
    fmus[id]  = load_fmu('f_' + str(id)+'.fmu',fmu_path+str(id))
    fmus[id].initialize(start_time,final_time)

The result is a dictionary with ids as key and the models as value: {id1:FMUModelCS1,id2:FMUModelCS1}

I tried multiprocessing:

from   multiprocessing               import Process, Manager
from   pyfmi                         import load_fmu

def ep_intialization(bldg,lproxy):
    fmu         = {}
    final_time  = 60*60*24*7
    start_time  = 0
    chdir(fmu_path+str(bldg))
    fmu[bldg]   = load_fmu('f_' + str(bldg)+'.fmu',fmu_path+str(bldg))
    fmu[bldg].initialize(start_time,final_time)
    lproxy.append(fmu)

if __name__ == '__main__':
    manager = Manager()
    lproxy  = manager.list()
    jobs    = []
    for bldg in osmids_list:
        p   = Process(target=ep_intialization, args=(bldg,lproxy))
        jobs.append(p)
        p.start()
    for j in jobs:
        j.join()

This code sucessfully starts several processes on different cores (see in the system monitor), but when the fmus are dumped in the multiprocessing list, I get a pickling error. The multithreading with python's threading works, but the performance gains are marginal. I already tried different parallel processing/serialization approaches, such as dask, joblib, cloudpickle,pathos,dill, but to no avail.

I am aware that the FMUModels are cython classes, and thus really difficult to serialize. Pyfmi has pyfmi.master.Master which allows parallel simulation but not for FMUModelCS1 and with no do_step. There is an interesting point in the changelog:

— PyFMI-2.3 —
Allow do steps to be performed in parallel (ticket:4541).

However, I couldnt find any other reference.

Any ideas on this issue?

@trulede
Copy link

trulede commented May 9, 2020

If pickling is not working then I would leave the fmu object in the process, and then call it indirectly via another python object which you put into the lproxy list. That object might use a bit of python magic to simply proxy calls to the fmu instance in the process, rather than the fmu instance itself being the proxy.

@trulede
Copy link

trulede commented May 9, 2020

@modelonrobinandersson modelonrobinandersson added the question Issue only concerns a or multiple questions. label Jul 29, 2022
@piotre13
Copy link

@missermann Hi, I'm trying to do something similar to what you're doing. can I ask you, how many instances of the same FMU you are initializing and simulating? I'm trying to do that in co-simulation (that should ensure multiprocessing), but with more than 500 instances I get some errors from Eplus with the sockets, did you have a similar experience?
Thanks

@missermann
Copy link
Author

@piotre13 I only tried very few (under 10) since I never could get it working.
How did you succeeded? Would you share your code?

@piotre13
Copy link

@missermann I'm sorry the code is confidential and I would not be able to share it. But yes I'm running several (up to 500) fmu instances of energyplus model (really simple shoeboxes) using Mosaik cosimulation library and a custom-made mosaik API that call the dostep method using pyfmi. They are running and simulating but I still have some perplexities about some of the results that seem quite different when running the idf by itself. I've never tried to run several FMU instances without using the mosaik orchestrator so maybe the difference is this. If you have any doubts or suggestions it could be helpful to keep this thread on because it seems that on the web there are not many people trying to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issue only concerns a or multiple questions.
Projects
None yet
Development

No branches or pull requests

4 participants