2014-12-14 2 views
0

학기말 프로젝트를 진행 중이며 매트릭스를 힘을 써야 할 필요가 있으며 문제를 멀티 스레드해야합니다.파이썬 다중 스레드 매트릭스 곱셈

이 코드는 일부 상황에서만 작동하며 다른 상황에서는 작동하지 않습니다. 나는 그것이 process_data 함수에서 중첩 된 루프의 논리와 관련이 있다고 믿지만, 내가 뭘 잘못하고 있는지 확신하지 못한다! 저는 2 주 동안이 일을 해왔고 저는 정말 어려움을 겪었습니다. 그것은 내 스레드가 경계를 벗어나는 것과 관련이있는 것처럼 보이지만 심지어는 스레드가 한계를 벗어나지 만 여전히 매트릭스를 올바르게 계산하는 몇 가지 상황이 있기 때문에 그다지 확실하지 않습니다.

도와주세요!

import copy 
import numpy 
import Queue 
import random 
import threading 
import time 
import timeit 

# Create variable that determines the number of columns and 
# rows in the matrix. 
n = 4 

# Create variable that determines the power we are taking the 
# matrix to. 
p = 2 

# Create variable that determines the number of threads we are 
# using. 
t = 2 

# Create an exit flag. 
exitFlag = 0 

# Create threading class. 
class myThread (threading.Thread): 
    def __init__(self, threadID, name, q): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
     self.q = q 
    def run(self): 
     print "Starting " + self.name 
     process_data(self.name, self.q) 
     print "Exiting " + self.name 

# Create a function that will split our data into multiple threads 
# and do the matrix multiplication. 
def process_data(threadName, q): 
    numCalc = ((n^3)/t) 
    for a in range(p-1): 
     for b in range((numCalc*(q-1)),(numCalc*(q))): 
      for c in range(n): 
       for d in range(n): 
        matrix[a+1][b][c] += matrix[a][b][d] * matrix[0][d][c] 

# Create a three dimensional matrix that will store the ouput for 
# each power of the matrix multiplication. 
matrix = [[[0 for k in xrange(n)] for j in xrange(n)] for i in xrange(p)] 
print matrix 

# This part fills our initial n by n matrix with random numbers 
# ranging from 0 to 9 and then prints it! 
print "Populating Matrix!" 
for i in range(n): 
    for j in range(n): 
     matrix[0][i][j] = random.randint(0,9) 

# Tells the user that we are multiplying matrices and starts the 
# timer. 
print "Taking our matrix to the next level!" 
start = timeit.default_timer() 
threadLock = threading.Lock() 

threads = [] 
threadID = 1 

# Create new threads 
for tName in range(t): 
    thread = myThread(threadID, "Thread-0"+str(tName), threadID) 
    thread.start() 
    threads.append(thread) 
    threadID += 1 
# Wait for all threads to complete 
for x in threads: 
    x.join() 

stop = timeit.default_timer() 
print stop - start 
print "Exiting main thread!" 
print matrix 

제곱 행렬을 복용은 모든 경우에 작동하는 것 같다하지만 난 나머지 힘이 제로로 가득 행렬로 나올 것을 넘어 계산하려고하면! 제가 작품을 올린 경우입니다.

n, p 및 t 변수를 변경하면 올바르게 계산되지 않는 문제가 발생합니다.

감사합니다.

+0

당신은 훨씬 더 앞서'numpy '를 사용하게 될 것이라고 생각합니다. 내부적으로 BLAS 라이브러리를 사용합니다. BLAS 라이브러리는 매우 최적화되어 있으며, 내부적으로 멀티 스레드로 컴파일 될 수 있습니다 (말 그대로 3 배 이상 더 빠름). 원시 파이썬에서 할 수있는 모든 것. –

+0

'numCalc'의 기능은 무엇입니까? –

+0

numCalc는 각 스레드가 수행해야하는 계산 수를 결정합니다. 나는 시작과 끝 인덱스를하기 위해 그것을 사용하려고 노력하고있다. 그러나 나의 수학은 내가 생각하는 어떤 곳에서 여기에서 틀리다. – dennarai

답변

1

이 정확하지 :

numCalc = ((n^3)/t) 

    for b in range((numCalc*(q-1)),(numCalc*(q))): 
예컨대

때 N = 4, t = 2, 제 스레드는 위에 열 [0,1]와 두 번째 스레드 범위 나 범위를 가져야 컬럼 [2,3]. 그러나이 계산은 다음을 제공합니다 :

numCalc = 8/2 = 4 
thread 1 ranges b over range(0, 4) = [0,1,2,3] 
thread 2 ranges b over range(4, 8) = [4,5,6,7] 

따라서 스레드 1은 모든 작업과 스레드 2가 존재하지 않는 열에 액세스하려고 시도합니다!

+0

오케이! 감사! 나는 이것을 고쳐서 고칠 수 있는지 알아볼 것입니다. =) – dennarai