मेरे पास scipy.sparse.csr_matrix प्रारूप में एक बड़ा स्पैर मैट्रिक्स एक्स है और मैं समानांतरता का उपयोग करने वाले एक numpy array w द्वारा इसे गुणा करना चाहता हूं। कुछ शोधों के बाद मुझे पता चला कि मुझे प्रक्रियाओं के बीच एक्स और डब्ल्यू की प्रतिलिपि बनाने से बचने के लिए मल्टीप्रोसेसिंग में ऐरे का उपयोग करने की आवश्यकता है (उदा। यहां: How to combine Pool.map with Array (shared memory) in Python multiprocessing? और Is shared readonly data copied to different processes for Python multiprocessing?)। (4.431, 0.165) समानांतर संस्करण का संकेत गैर समानांतर गुणा तुलना में बहुत धीमी है: यहाँ मेरी नवीनतम प्रयासscipy sparse matrix गुणा को समानांतर करने के लिए कैसे करें
import multiprocessing
import numpy
import scipy.sparse
import time
def initProcess(data, indices, indptr, shape, Warr, Wshp):
global XData
global XIndices
global XIntptr
global Xshape
XData = data
XIndices = indices
XIntptr = indptr
Xshape = shape
global WArray
global WShape
WArray = Warr
WShape = Wshp
def dot2(args):
rowInds, i = args
global XData
global XIndices
global XIntptr
global Xshape
data = numpy.frombuffer(XData, dtype=numpy.float)
indices = numpy.frombuffer(XIndices, dtype=numpy.int32)
indptr = numpy.frombuffer(XIntptr, dtype=numpy.int32)
Xr = scipy.sparse.csr_matrix((data, indices, indptr), shape=Xshape)
global WArray
global WShape
W = numpy.frombuffer(WArray, dtype=numpy.float).reshape(WShape)
return Xr[rowInds[i]:rowInds[i+1], :].dot(W)
def getMatmat(X):
numJobs = multiprocessing.cpu_count()
rowInds = numpy.array(numpy.linspace(0, X.shape[0], numJobs+1), numpy.int)
#Store the data in X as RawArray objects so we can share it amoung processes
XData = multiprocessing.RawArray("d", X.data)
XIndices = multiprocessing.RawArray("i", X.indices)
XIndptr = multiprocessing.RawArray("i", X.indptr)
def matmat(W):
WArray = multiprocessing.RawArray("d", W.flatten())
pool = multiprocessing.Pool(processes=multiprocessing.cpu_count(), initializer=initProcess, initargs=(XData, XIndices, XIndptr, X.shape, WArray, W.shape))
params = []
for i in range(numJobs):
params.append((rowInds, i))
iterator = pool.map(dot2, params)
P = numpy.zeros((X.shape[0], W.shape[1]))
for i in range(numJobs):
P[rowInds[i]:rowInds[i+1], :] = iterator[i]
return P
return matmat
if __name__ == '__main__':
#Create a random sparse matrix X and a random dense one W
X = scipy.sparse.rand(10000, 8000, 0.1)
X = X.tocsr()
W = numpy.random.rand(8000, 20)
startTime = time.time()
A = getMatmat(X)(W)
parallelTime = time.time()-startTime
startTime = time.time()
B = X.dot(W)
nonParallelTime = time.time()-startTime
print(parallelTime, nonParallelTime)
हालांकि उत्पादन की तरह कुछ है।
मेरा मानना है कि मंदी का कारण इसी तरह की परिस्थितियों में हो सकता है जब कोई प्रक्रियाओं में बड़े डेटा की प्रतिलिपि बना रहा है, लेकिन यह मामला यहां नहीं है क्योंकि मैं साझा चर को संग्रहीत करने के लिए ऐरे का उपयोग करता हूं (जब तक यह numpy.frombuffer में नहीं होता है या जब एक csr_matrix बनाना, लेकिन तब मुझे सीधे csr_matrix साझा करने का कोई तरीका नहीं मिला)। धीमी गति का एक अन्य संभावित कारण प्रत्येक प्रक्रिया के लिए प्रत्येक मैट्रिक्स गुणा का एक बड़ा परिणाम लौटा रहा है, हालांकि मुझे इस बारे में कोई जानकारी नहीं है।
क्या कोई देख सकता है कि मैं कहां गलत हूं? किसी भी मदद के लिए धन्यवाद!
अपडेट: मुझे यकीन नहीं है लेकिन मुझे लगता है कि प्रक्रियाओं के बीच बड़ी मात्रा में डेटा साझा करना केवल इतना कुशल नहीं है, और आदर्श रूप में मुझे मल्टीथ्रेडिंग का उपयोग करना चाहिए (हालांकि ग्लोबल इंटरप्रेटर लॉक (जीआईएल) बहुत कठिन बनाता है)। इसके आस-पास एक तरीका है उदाहरण के लिए साइथन का उपयोग करके जीआईएल जारी करना (http://docs.cython.org/src/userguide/parallelism.html देखें), हालांकि बहुत सारे निष्क्रिय कार्यों को जीआईएल के माध्यम से जाना होगा।
क्या आपके पास एक अनुकूलित, बहुप्रचारित ATLAS निर्माण से जुड़ा हुआ numpy/scipy है?यदि आप ऐसा करते हैं, तो आप np.dot का उपयोग करते समय समानांतर मैट्रिक्स गुणा को मुफ्त में प्राप्त करना चाहिए। –
मैं एक मल्टीथ्रेडेड बीएलएएस लाइब्रेरी (ओपनबीएलएस) का उपयोग कर रहा हूं जो numpy/scipy से जुड़ा हुआ है लेकिन मैंने X.dot (W) और numpy.dot (X, W) का परीक्षण किया है (बाद वाला स्पैस एक्स के लिए काम नहीं करता है) और यह नहीं है parallelised। – Charanpal