开发者

Pickling boost python functions

For the use with joblib.Parallel, I need to be able to pickle a boost::python function. When I try to do so, I get a

TypeError: can't pickle bui开发者_Python百科ltin_function_or_method objects

As far as I understand, the function should be pickled by fully qualified name only. I don't see why this is not possible. Any ideas?


If you want to use your boost method in a joblib.Parallel object, maybe you could use a wrapper around your boost method :

from joblib import Parallel, delayed
from boost import boost_function

class Wrapper(object):
    def __init__(self, method_name, module_name):
        self.method_name = method_name
        self.module_name = module_name

    def __call__(self, *args, **kwargs):
        method = __import__(self.module_name, globals(), locals(), [self.method_name,])
        return method(*args, **kwargs)

Parallel(n_jobs=1)(delayed(Wrapper("boost_module_name_with_dots", "boost_method_name")(i) for i in range(10))


The problem is that joblib is trying to transform into a pickle function that is fed into joblib.delayed. It cannot transform the Boost.Python.function object. To solve this problem, you can feed a callable that does not directly have a Boost.Python.function in it. To do this, you can use the approach suggested by https://stackoverflow.com/a/7089719/20222376 with the wrapper.

I ran into this problem when using rdkit. Here is an example of a solution with it that works in 2022.

import importlib

from joblib import Parallel, delayed


class Wrapper:
    def __init__(self, method_name, module_name):
        self.method_name = method_name
        self.module = importlib.import_module(module_name)

    @property
    def method(self):
        return getattr(self.module, self.method_name)

    def __call__(self, *args, **kwargs):
        return self.method(*args, **kwargs)


wrapped_mol_from_smiles = Wrapper("MolFromSmiles", "rdkit.Chem")
smiles = ["CCC", "CC"]
mols = Parallel(n_jobs=2, backend="loky")(
    delayed(wrapped_mol_from_smiles)(x) for x in smiles
)
print(mols)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜