When running multiple solves using rosepy, use threads, not processes, for more stability and reliability.
Threads all share the same memory space, which means they can safely reuse a single WebSocket connection. Processes, on the other hand, each live in their own memory space, so every process will open a new WebSocket connection. That creates unnecessary overhead and can cause issues when scaling concurrent solve requests. Since the solver waits for responses over the network, threading is both lightweight and efficient.
Example code
Below is an example of how to use threading to submit multiple models to the Rose solver simultaneously. Each thread runs a slightly different version of the same model, showing how you can explore parameter variations in parallel.
import threading
import pyomo.environ as pyo
from rosepy.pyomo.pyomo_interface import PyomoInterface
"""
Example: Running multiple solves concurrently using threads.
All threads share a single WebSocket connection managed by the Rose solver.
"""
print_lock = threading.Lock()
def run_solve(solver, delta, options):
"""Build and solve a small brewery model, with sensitivity on the profit of dark beer"""
dark_beer_profit = 23 + delta
model = pyo.ConcreteModel(name=f"Brewery Profit Sensitivity {delta:+}")
model.light_beer = pyo.Var(within=pyo.NonNegativeReals)
model.dark_beer = pyo.Var(domain=pyo.NonNegativeReals)
model.objective = pyo.Objective(expr=13 * model.light_beer + dark_beer_profit * model.dark_beer,
sense=pyo.maximize)
model.corn = pyo.Constraint(expr=5 * model.light_beer + 15 * model.dark_beer <= 480)
model.malt = pyo.Constraint(expr=4 * model.light_beer + 4 * model.dark_beer <= 160)
model.hops = pyo.Constraint(expr=35 * model.light_beer + 20 * model.dark_beer <= 1190)
result = solver.solve(model, options=options)
with print_lock:
print(f"Profit for delta {delta:+} scenario is ${result['Problem']['Lower bound']:.0f}")
def main():
threads = []
solver = pyo.SolverFactory("rose")
options = {"max_time_seconds": 300}
for i in range(-3,4):
t = threading.Thread(target=run_solve, args=(solver, i, options,))
t.start()
threads.append(t)
for t in threads:
t.join()
print("All solves complete.")
if __name__ == "__main__":
main()
Comments
0 comments
Please sign in to leave a comment.