2016-10-18 3 views
0

파이썬에서 멀티 프로세싱을 시도하고 있습니다. 벡터를 추가하는 코드를 작성했지만 함수에서 출력을 가져올 수 없습니다. clocker의 조언을 툭,이 내 코드 변경 : 어느 의미, 출력 Z는 0이 아니라 편집파이썬 멀티 프로세싱 데이터가 잘못 출력되었습니다.

from multiprocessing import Process 
import numpy as np 

numThreads = 16 
num = 16 

numIter = num/numThreads 

X = np.ones((num, 1)) 
Y = np.ones((num, 1)) 
Z = np.zeros((num, 1)) 

def add(X,Y,Z,j): 
    Z[j] = X[j] + Y[j] 

if __name__ == '__main__': 
    jobs = [] 
    for i in range(numThreads): 
    p = Process(target=add, args=(X, Y, Z, i,)) 
    jobs.append(p) 

    for i in range(numThreads): 
    jobs[i].start() 

    for i in range(numThreads): 
    jobs[i].join() 

    print Z[0] 

2.보다 출력합니다

import multiprocessing 
import numpy as np 

numThreads = 16 
numRows = 32000 
numCols = 2 
numOut = 3 

stride = numRows/numThreads 

X = np.ones((numRows, numCols)) 
W = np.ones((numCols, numOut)) 
B = np.ones((numRows, numOut)) 
Y = np.ones((numRows, numOut)) 

def conv(idx): 
    Y[idx*stride:idx*stride+stride] = X[idx*stride:idx*stride+stride].dot(W) + B[idx*stride:idx*stride+stride] 

if __name__=='__main__': 
    pool = multiprocessing.Pool(numThreads) 
    pool.map(conv, range(numThreads)) 
    print Y 

를 출력하는 대신 Saxp의 Y입니다 .

+0

"출력을 얻을 수 없음"이란 무엇을 의미합니까? –

답변

0

최종 줄이 [2] 대신 [0]을 반환하는 이유는 각 프로세스가 수정하기 전에 각 프로세스가 Z의 독립적 복사본을 만듭니다 (또는 Z[j] 일 수 있습니다). 어느 쪽이든 별도의 프로세스를 실행하면 원래 버전이 변경되지 않습니다.

대신 threading module을 사용하는 경우 마지막 줄은 실제로 예상대로 [2]를 반환하지만 다중 처리는 아닙니다.

따라서 multiprocessing.Pool을 대신 사용하고 싶을 것입니다. 실험을 위해 실험을 진행하면 다음을 수행 할 수 있습니다.

In [40]: pool = multiprocessing.Pool() 
In [41]: def add_func(j): 
    ....:  return X[j] + Y[j] 
In [42]: pool = multiprocessing.Pool(numThreads) 
In [43]: pool.map(add_func, range(numThreads)) 
Out[43]: 
[array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.])] 

재미있게 즐겨보세요!

질문에 두 번째 부분은 문제가 conv() 함수를 반환하지 않는 모든 값을 것입니다. 프로세스 풀이 값을 가져 오는 데 X, B 및 W의 복사본을 가져 오는 동안 conv() 내부의 Y는 시작되는 각 프로세스에 대해 로컬입니다. Y의 새로운 계산 된 값을 얻으려면, 당신은 다음과 같이 사용합니다 :

def conv(idx): 
    Ylocal_section = X[idx*stride:idx*stride+stride].dot(W) + B[idx*stride:idx*stride+stride] 
    return Ylocal_section 

results = pool.map(conv, range(numThreads)) # then apply each result to Y 
for idx in range(numThreads): 
    Y[idx*stride:idx*stride+stride] = results[idx] 

병렬 정말 빠르고 복잡 얻을 수있는, 그리고이 시점에서 나는 빠른 2D 컨볼 루션을 수행 할 수있는 기존의 라이브러리를 평가하는 것이다. numpy 및 scipy 라이브러리는 매우 효율적이어서 사용자의 요구 사항을보다 잘 충족시킬 수 있습니다.

+0

안녕하세요. 문제가 많지 않으면 Python에서 멀티 프로세싱이 어떻게 작동하는지 설명해 주실 수 있습니까? 에서와 같이'range (numThreads) '를 사용하면 여러 데이터 세트에서 어떻게 확장됩니까? 나는 C++ 11 스레드 종류의 사람이다. 파이썬 구문은 조금 이상합니다. – ABCD

+0

범위 (numThreads)는 [0, 1, 2, ... numThreads-1]로 해석됩니다. 라인 입력'In [43]'은'pool.map (add_func, [0,1,2,3, ..., 15])'와 동일하다. map 함수는 파이썬 표준 라이브러리에 문서화되어있다; 그것은 다음과 같이 번역됩니다 :'for i in range (numThreads) : add_func (i)' – clocker

+0

안녕하세요, 컨볼 루션을 사용하도록 데이터를 변경했습니다. 같은 오류가 나타납니다. 질문에 게시 된 코드. – ABCD

관련 문제