How should I manage a parallel optimization of an instance method using ThreadPoolExecutor?

209 views Asked by At

Useless intro

Hi everyone,

I'm having trouble with parallel use of nevergrad library. However, my question is about my implementation. It seems my OOP skills are not good. As the code is too long to reproduce here I will hypothesize while being specific.

The problem setup

First, I have a class that inherits from Algorithm, let's say it is Rotation. Second, I created an Optimizer class that helps me optimize any algorithm,

class Optimizer:
  def __init__(self, algorithm):
    self.algorithm = algorithm

and one can define

cfg = some_dict  # configuration dict
rot_algorithm = Rotation(cfg)  # an algorithm instance
rot_optimizer = Optimizer(rot_algorithm)  # an optimizer instance that works over an algorithm instance

Now, two more things:

  1. Inside Optimizer there is a method optimize_params that uses concurrent.futures.ThreadPoolExecutor to optimize another method named Optimizer.obj_fun (see the end of the question).
  2. The algorithms have, in general, internal variables that modify their behavior. For example, we could imagine that rot_algorithm has an internal variable named angle that will be modified during the optimization.

The question

I found that rot_algorithm.angle was a variable that the threads had in common, that is, it could be modified by some thread while another had already set the value. That makes the results useless. How should I refactor my code in order to avoid this behavior?

Use of ThreadPoolExecutor

        with futures.ThreadPoolExecutor(
            max_workers=optimizer.num_workers
        ) as executor:
            r = optimizer.minimize(
                self.obj_fun,
                executor=executor,
                batch_mode=False,
            )
0

There are 0 answers