Python 在pygmo中使用队列进行函数求值

Python 在pygmo中使用队列进行函数求值,python,multithreading,python-3.x,queue,python-multiprocessing,Python,Multithreading,Python 3.x,Queue,Python Multiprocessing,我试图使用通过Anaconda3安装的优化库和一些现有代码,这些代码通过一个执行轨迹优化的可执行文件包装参数向量的异步和分布式计算(如果有人感兴趣的话)。为了实现这一点,我在网络上使用multiprocessing.SyncManager和multiprocessing.Queues传递输入、接收输出和日志消息。因此,在这种情况下,pygmo将选择要尝试的向量,支持代码将把它传递到一个输入队列中,一些分布式工作者将获取该队列,通过可执行文件进行计算,并将结果传递回,最终将返回给正在使用的pygm

我试图使用通过Anaconda3安装的优化库和一些现有代码,这些代码通过一个执行轨迹优化的可执行文件包装参数向量的异步和分布式计算(如果有人感兴趣的话)。为了实现这一点,我在网络上使用multiprocessing.SyncManager和multiprocessing.Queues传递输入、接收输出和日志消息。因此,在这种情况下,pygmo将选择要尝试的向量,支持代码将把它传递到一个输入队列中,一些分布式工作者将获取该队列,通过可执行文件进行计算,并将结果传递回,最终将返回给正在使用的pygmo.algorithm进行计算的任何对象

我的问题是,当pygmo初始化一个问题时,它会对所提供的类进行深度复制,在我的例子和下面提供的示例代码中,该类包含多个队列。在执行deepcopy时,我得到了错误

  File "pygmo_testing.py", line 121, in <module>
    main()
  File "pygmo_testing.py", line 108, in main
    prob = pg.problem(my_prob)
  File "C:\Anaconda3\lib\copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\Anaconda3\lib\copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Anaconda3\lib\copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "C:\Anaconda3\lib\copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Anaconda3\lib\copy.py", line 169, in deepcopy
    rv = reductor(4)
  File "C:\Anaconda3\lib\multiprocessing\queues.py", line 58, in __getstate__
    context.assert_spawning(self)
  File "C:\Anaconda3\lib\multiprocessing\context.py", line 356, in assert_spawning
    ' through inheritance' % type(obj).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance

对于发现此问题并需要答案的任何人,collections.deque支持deepcopy

除上述内容外,deques还支持。。。复制。复制(d),复制。复制(d)


但是collections.deque不支持进程,因此它不能用于分发

我读到的所有内容都说队列用于跨线程或进程(分别是collections.Queue和multiprocessing.Queue)的同步,并且它们不能被复制。就像发电机一样,复制它就等于耗尽它。如果pygmo必须复制它所提供的内容,那么我认为您需要找到一种使用可复制数据结构的方法。我还得再看看。。。
"""
****************************** Import Statements ******************************
"""
import pygmo as pg
from multiprocessing import Pool, Queue

"""
****************************** Utility Functions ******************************
"""  
def sphere_fitness(x):
    return sum(x*x)

def worker(inp_q, out_q):

    while True:

        x = inp_q.get()
        print("got {}".format(x))
        if x == False:
            break
        else:
            fit = sphere_fitness(x)
            print("x: {} f: {}".format(x, fit))
            out_q.put_nowait(fit)
            print("submitted {}".format(x))        
"""
********************************** Class(es) ************************************
"""
class distributed_submit(object):
    """ Class for pygmo Problem"""

    def __init__(self, dim, inp_q, out_q):
        self.dim = dim
        self._inp_q = inp_q
        self._out_q = out_q

    def _submit(self, inp_q, x):
        self._inp_q.put_nowait(x)
        print("x delivered")

    def _receive(self, out_q):
        return self._out_q.get()

    def fitness(self, x):
        self._submit(x)
        print("put in {}".format(x))
        fit = self._receive()
        print("got {}".format(fit))
        return [fit]

    def get_bounds(self):
        return ([-1]*self.dim, [1]*self.dim)

    def get_name(self):
        return "Sphere Function"

    def get_extra_info(self):
        return "\tDimensions: {}".format(self.dim)


"""
******************************* Main Function ********************************
"""
def main():

    # Queues from multiprocessing
    _inp_q   = Queue()
    _out_q   = Queue()

    _workers = Pool(initializer=worker,
                    initargs=(_inp_q, _out_q))
    _workers.close()

    my_prob = distributed_submit(3, _inp_q, _out_q)

    prob = pg.problem(my_prob)

    algo = pg.algorithm(pg.bee_colony(gen=20, limit=20))

    pop = pg.population(prob, 10)
    print(pop)

    pop = algo.evolve(pop)

    print(pop.champion_f)


if __name__ == "__main__":
    main()