How to do parallel Python Gekko?

岁酱吖の 提交于 2021-01-27 08:01:20

问题


Sometimes my Python Gekko application is solved better with one solver over another. It is difficult to predict which solver will perform best. Because Python Gekko supports local or remote solves on different servers with m.GEKKO(server='http://{address}'), is it possible to create a parallel Gekko application that will try all the solvers simultaneously on any number of computers (including local) and then kill the other processes when the first one returns successfully? I've been looking at multi-threading and parallel packages for Python. Are there any that work well with Gekko to do parallel solves? Here is a sequential prototype:

from gekko import GEKKO
m = GEKKO()
x = m.Var(); y = m.Var()
m.Equation(x**2+y**2==1)
m.Maximize(x+y)
# try all solvers
for i in range(1,4):
    m.options.SOLVER = i
    m.solve()
    if m.options.APPSTATUS==1:
        print('Success: ' + str(i))

回答1:


You can solve on any number of servers simultaneously with a multi-threaded application. Here is a parallel version of your serial application using a queue although it doesn't stop the other threads when the first completes. Even though the other threads are not stopped, you could include a MAX_TIME value so that the threads are forced to complete within a specified number of seconds. This approach does allow you to continue the main program while letting the other threads die when they complete or reach the max time limit.

from gekko import GEKKO
import queue, threading

def solve(rq, solver, server):
    #print('Solver ' + str(solver) + ' Server: ' + str(server) + '\n')
    if server=='localhost':
        m = GEKKO(remote=False)
    else:
        m = GEKKO(server=server)
    x = m.Var(); y = m.Var()
    m.Equation(x**2+y**2==1)
    m.Maximize(x+y)
    m.options.SOLVER = solver
    m.options.MAX_TIME = 2
    m.solve(disp=False)
    m.cleanup()
    rq.put(('solver',solver,'server',server))

# Select servers and solvers (1=APOPT, 2=BPOPT, 3=IPOPT, etc)
APOPT = 1; BPOPT = 2; IPOPT = 3
jobs = {'https://byu.apmonitor.com':APOPT,\
        'localhost':APOPT,\
        'https://byu.apmonitor.com':IPOPT,\
        'https://apmonitor.com':IPOPT}

# Run jobs, get only first result
q = queue.Queue()
threads = [threading.Thread(target=solve, args=(q, solver, server)) \
           for server, solver in jobs.items()]
for th in threads:
    th.daemon = True
    th.start()
first = q.get(); print(first)

If you would also like to get the second or more results then you can add another line with more q.get() calls.

second = q.get(); print(second)


来源:https://stackoverflow.com/questions/58887835/how-to-do-parallel-python-gekko

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!