2017-06-13 26 views
0

現在、Pythonマルチプロセッシングパッケージを使用して、CPUバインドプロセスをより迅速に実行しようとしています。私は非常に大きな数値行列を持っていて、行列に入っている値を計算するためにPoolとapply_asyncを使って仕事を分割したいと思っています。しかし、私が関数の単体テストを実行して動作するかどうかをテストすると、 "NameError:グローバル名 'self'が定義されていないというエラーが出ます。私は、GoogleやStackOverflowで何かを見つけることができませんでした。なぜこれが起こっているかもしれないのか?Pythonマルチプロセッシング - ApplyResult.get()NameError:グローバル名 'self'が定義されていません

Pytest出力:

_____________________ TestBuildEMMatrix.test_build_em_matrix_simple _____________________ 

self = <mixemt_master.mixemt2.preprocess_test.TestBuildEMMatrix testMethod=test_build_em_matrix_simple> 

    def test_build_em_matrix_simple(self): 
      reads = ["1:A,2:C", "1:T,2:C", "3:T,4:T", "2:A,4:T"] 
      in_mat = preprocess.build_em_matrix(self.ref, self.phy, 
>                     reads, self.haps, self.args) 

preprocess_test.py:272: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
preprocess.py:239: in build_em_matrix 
    results[i] = results[i].get() 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <multiprocessing.pool.ApplyResult object at 0x7f4218ea07d0>, timeout = None 

    def get(self, timeout=None): 
     self.wait(timeout) 
     if not self._ready: 
      raise TimeoutError 
     if self._success: 
      return self._value 
     else: 
>   raise self._value 
E   NameError: global name 'self' is not defined 

/vol/hpc/apps/python-anaconda2-4.3.1-abat/install/lib/python2.7/multiprocessing/pool.py:567: NameError 
--------------------------------- Captured stdout call ---------------------------------- 
False 

、関連するPython関数:

def build_em_matrix_process(markers, haplogroups, pos_obs, mut_prob, column_length, start_index, end_index): 

    columns = [[prob_for_vars(markers, haplogroups[j], pos_obs, mut_prob) for j in xrange(column_length)] 
     for i in xrange(start_index, end_index)] 

    return columns 

def build_em_matrix(refseq, phylo, reads, haplogroups, args): 
    """ 
    Returns the matrix that describes the probabiliy of each read 
    originating in each haplotype. 
    """ 
    hvb_mat = HapVarBaseMatrix(refseq, phylo) 
    read_hap_mat = numpy.empty((len(reads), len(haplogroups))) 

    if args.verbose: 
     sys.stderr.write('Building EM input matrix...\n') 

    num_processors = args.p 

    pool = Pool(processes = num_processors); 
    results = [] 
    partition_size = int(math.ceil(len(reads)/float(num_processors))) 

    for i in xrange(num_processors): 
     start_index = i * partition_size 
     end_index = (i + 1) * partition_size 
     pos_obs = pos_obs_from_sig(reads[i]) 

     results.append(pool.apply_async(build_em_matrix_process, (hvb_mat.markers, haplogroups, pos_obs, hvb_mat.mut_prob, len(haplogroups), start_index, end_index))) 

    column = 0 
    for i in xrange(num_processors): 
     results[i].wait() 
     print results[i].successful() 
     results[i] = results[i].get() 
     for j in xrange[len(results)]: 
      read_hap_mat[column] = results[i][j] 
      column += 1 

    if args.verbose: 
     sys.stderr.write('Done.\n\n') 

    return read_hap_mat 

呼び出した後.successful印刷結果[I] 'の結果を[i]を.WAITは、()]のステートメントを追加しました' () 'は、Falseをstdoutに出力します。私はbuild_em_matrix_processでエラーが見つからないので、なぜそれが真実に戻っていないのか分かりません。

+0

ユニットテストコードはどこですか?このエラーは、テスト中のコードではなく、 'TestBuildEMMatrix.test_build_em_matrix_simple'の問題を示しています。 – hpaulj

+0

ユニットテストコードは問題ありません。これは既存のアプリケーションであり、並列処理を利用するためにリファクタリングしています。単体テストは前に働いていましたが、メソッドのシグネチャを変更していないので、メソッドの結果は一度正しくなければなりません。 – AWeston

答えて

0

私はもう少しコードを突っ込んで答えを見つけました!

私は、これを達成するために、build_em_matrix_processによって呼び出されたクラスのインスタンスメソッドをトップレベルメソッドにリファクタリングしました。私は誤ってメソッドの本体に自己への参照を残したことが判明しました。テストを実行したとき、エラーは、呼び出されていた最上位のメソッドのコードではなく、ApplyResult.get()自体のコードから来ているように見えました。

関連する問題