0

関数にマルチプロセッシングを実装するにはどうすればよいですか。このように試してみましたが、うまくいきませんでした。

def steric_clashes_parallel(system):
    rna_st = system[MolWithResID("G")].molecule()
    for i in system.molNums():
        peg_st = system[i].molecule()
        if rna_st != peg_st:
            print(peg_st)
            for i in rna_st.atoms(AtomIdx()):
                for j in peg_st.atoms(AtomIdx()):
#                    print(Vector.distance(i.evaluate().center(), j.evaluate().center()))
                    dist = Vector.distance(i.evaluate().center(), j.evaluate().center())
                    if dist<2:
                        return print("there is a steric clash")
    return print("there is no steric clashes")  

mix = PDB().read("clash_1.pdb")
system = System()
system.add(mix)    
from multiprocessing import Pool
p = Pool(4)
p.map(steric_clashes_parallel,system)

この関数を使用してテストする何千もの pdb ファイルまたはシステム ファイルがあります。マルチプロセッシング モジュールを使用しない場合、シングル コアで 1 つのファイルに 2 時間かかりました。どんな提案でも大いに役立ちます。

私のトレースバックは次のようになります。

self.run()
File "/home/sajid/sire.app/bundled/lib/python3.3/threading.py", line 858,
  in run self._target(*self._args, **self._kwargs)
    File "/home/sajid/sire.app/bundled/lib/python3.3/multiprocessing/pool.py", line 351,
      in _handle_tasks put(task)
        File "/home/sajid/sire.app/bundled/lib/python3.3/multiprocessing/connection.py", line 206,
          in send ForkingPickler(buf, pickle.HIGHEST_PROTOCOL).dump(obj)
RuntimeError: Pickling of "Sire.System._System.System" instances is not enabled
(boost.org/libs/python/doc/v2/pickle.html)
4

3 に答える 3

0

各ファイルの計算を高速化するためにできるトリックが 1 つあります。つまり、各ファイルを順番に処理し、ファイルの内容を並列に処理します。これは、いくつかの注意事項に依存しています。

  1. プロセスをフォークできるシステム (Linux など) で実行している。
  2. 実行中の計算には、将来の計算の結果に影響を与える副作用はありません。

これはあなたの状況に当てはまるようですが、100%確実ではありません。

プロセスがフォークされると、子プロセスのすべてのメモリが親プロセスから複製されます (さらに、効率的な方法で複製されます。読み取り専用のメモリのビットは複製されません)。これにより、大きくて複雑な初期状態をプロセス間で簡単に共有できます。ただし、子プロセスが開始されると、親プロセスで行われたオブジェクトへの変更は表示されません (逆も同様です)。

サンプルコード:

import multiprocessing

system = None
rna_st = None

class StericClash(Exception):
    """Exception used to halt processing of a file. Could be modified to 
    include information about what caused the clash if this is useful."""
    pass


def steric_clashes_parallel(system_index):
    peg_st = system[system_index].molecule()
    if rna_st != peg_st:
        for i in rna_st.atoms(AtomIdx()):
            for j in peg_st.atoms(AtomIdx()):
                dist = Vector.distance(i.evaluate().center(), 
                    j.evaluate().center())
                if dist < 2:
                    raise StericClash()


def process_file(filename):
    global system, rna_st

    # initialise global values before creating pool     
    mix = PDB().read(filename)
    system = System()
    system.add(mix)
    rna_st = system[MolWithResID("G")].molecule()

    with multiprocessing.Pool() as pool:
        # contents of file processed in parallel
        try:
            pool.map(steric_clashes_parallel, range(system.molNums()))
        except StericClash:
            # terminate called to halt current jobs and further processing 
            # of file
            pool.terminate()
            # wait for pool processes to terminate before returning
            pool.join()
            return False
        else:
            pool.close()
            pool.join()
            return True
        finally:
            # reset globals
            system = rna_st = None

if __name__ == "__main__":
    for filename in get_files_to_be_processed():
        # files are being processed in serial
        result = process_file(filename)
        save_result_to_disk(filename, result)
于 2014-12-22T23:00:41.647 に答える
0

@ martineau: pickle コマンドをテストしたところ、結果が得られました。

 ----> 1 pickle.dumps(clash_1.pdb)
    RuntimeError: Pickling of "Sire.Mol._Mol.MoleculeGroup" instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)
    ----> 1 pickle.dumps(system)
    RuntimeError: Pickling of "Sire.System._System.System" instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)

あなたのスクリプトでは、同じ時間がかかり、単一のコアのみを使用していました。ただし、dist行は反復可能です。この単一行をマルチコアで実行できますか? 行を次のように変更します。

for i in rna_st.atoms(AtomIdx()):
                    icent = i.evaluate().center()
                    for j in peg_st.atoms(AtomIdx()):
                        dist = Vector.distance(icent, j.evaluate().center())
于 2014-12-22T22:48:53.783 に答える