विरल मैट्रिक्स गुणन में गैर शून्य की संख्या निर्धारित करने का सबसे अच्छा तरीका क्या है?


17

मैं सोच रहा था कि क्या सीएसआर या सीएसआर प्रारूप में दोनों मैट्रीस मानने वाले विरल मैट्रिक्स गुणन ऑपरेशन के लिए अग्रिम में गैर शून्य की संख्या खोजने के लिए एक तेज और कुशल तरीका है।

मुझे पता है कि smmp पैकेज में एक है लेकिन मुझे कुछ ऐसा चाहिए जो पहले से C या C ++ में लागू हो।

किसी भी तरह की सहायता को आभार समझेंगे। अग्रिम में धन्यवाद।


क्या आपके मेट्रिक्स में कोई समरूपता है, या उनके गैर-शून्य प्रविष्टियों के स्थान के लिए एक संरचना है?
गोड्रिक सीर

@GodricSeer ... नहीं, मैं सिर्फ सामान्य विरल मैट्रिसेस के बारे में बात कर रहा हूं। मल्लातब ने nnz (ए) जहां गैर शून्य की संख्या का पता लगाने के लिए ए स्पार्स मैट्रिक्स विधि है। मैं सोच रहा था कि क्या ऐसी कोई विधि है।
रेक जूल

मैं व्यक्तिगत रूप से उस संख्या की गणना करने के किसी भी तरीके के बारे में नहीं सोच सकता हूं जो कि कुछ समरूपता या संरचना का शोषण किए बिना वास्तविक मैट्रिक्स गुणा करने की तुलना में कम क्रम होगा। मैं मान रहा हूँ कि आप मेमोरी आवंटन के लिए गुणा करना चाहते हैं?
गोड्रिक सीर

इसके अलावा, मुझे यह पेपर मिला, जो बताता है कि बूलियन मैट्रिक्स उत्पाद पर संख्या का अनुमान कैसे लगाया जाए (जो कि किसी भी मैट्रिक्स उत्पाद में तत्वों की गणना करना है)।
गोड्रिक सीर

@ GodricSeer..हाँ आप सही हैं मुझे परिणामी मैट्रिक्स की मेमोरी आवंटन के लिए सटीक संख्या की आवश्यकता है। हालांकि पेपर के लिंक के लिए धन्यवाद। मुझे कुछ समय के लिए किसी दिशा में शुरू करने की आवश्यकता हो सकती है।
रेक जूल

जवाबों:


14

आप दो-स्पर्सिटी पैटर्न के उत्पाद को बनाकर केवल मैट्रिक्स-मैट्रिक्स उत्पाद का अनुकरण कर सकते हैं - अर्थात, आप एक मैट्रिक्स के रूप में स्पार्सिटी पैटर्न (जिसे अलग-अलग सरणियों में संग्रहीत किया जाता है) को एक मैट्रिक्स के रूप में मानते हैं जिसमें एक शून्य या एक होता है। प्रत्येक प्रविष्टि। इस नकली उत्पाद प्रदर्शन केवल फार्म करने की आवश्यकता है औरइन शून्य और लोगों पर संचालन और इस प्रकार वास्तविक मैट्रिक्स-मैट्रिक्स उत्पाद की तुलना में बहुत तेज़ है - वास्तव में, आपको बस इतना करना है कि दो मैट्रिक्स की पंक्तियों और स्तंभों के माध्यम से जाना है और सत्यापित करें कि एक में कम से कम एक प्रविष्टि है पंक्ति और आपके द्वारा स्तंभ जहां दोनों मैट्रिसेस नॉन-जीरो हैं, के साथ गुणा करें। यह एक सस्ता ऑपरेशन है - वास्तव में वास्तविक उत्पाद में फ्लोटिंग पॉइंट गुणा करने की तुलना में किसी भी मामले में बहुत सस्ता है, जो न केवल आपको फ्लोटिंग पॉइंट अंकगणित (महंगा) करने की आवश्यकता है, बल्कि मेमोरी से वास्तविक फ़्लोटिंग पॉइंट संख्या में भी पढ़ें ( और भी महंगा है, लेकिन आपको इसकी आवश्यकता नहीं है कि जब स्पार्सिटी पैटर्न को गुणा किया जाए क्योंकि मैट्रिक्स के गैर-शून्य मान सीएसआर में अलग से संग्रहीत किए जाते हैं)।


6
इसे प्रतीकात्मक गुणन कहा जाता है। यह विशेष रूप से समानांतर में संख्यात्मक गुणा से कम महंगा नहीं है, लेकिन इसे केवल एक बार प्रतिमान पैटर्न के अनुसार किया जाना चाहिए। कई एल्गोरिदम अलग-अलग संख्यात्मक मानों के साथ कई बार ऑपरेशन करेंगे लेकिन समान स्पार्सिटी पैटर्न, जिस स्थिति में प्रतीकात्मक गुणा का पुन: उपयोग किया जा सकता है।
जेड ब्राउन

यह एक अच्छा विचार है, लेकिन लाखों ट्रांजिस्टर दिए गए हैं जो फ्लोट * फ्लोट को समानांतर में कर रहे हैं, हम केवल 50% की गति या यहां उपचार की बचत के बारे में बात कर रहे हैं।
इवगेनी सर्गेव

1
@EvgeniSergeev - बिंदु संगणना में बचत नहीं है, बल्कि स्मृति हस्तांतरण में बचत है। चूँकि आप विरल मैट्रिक्स गुणन के लिए मेमोरी ट्रांसफर के लिए आज 80% या उससे अधिक समय व्यतीत करते हैं, इसलिए यदि आपको / से मेमोरी में फ्लोटिंग पॉइंट डेटा को पढ़ना / लिखना नहीं आता है, तो आपको काफी लाभ होगा।
वोल्फगैंग बंगेरथ

सीहे()

हे()पी=हे(पीलॉगपी)हे(2)

13

मैंने वास्तव में ए * बी, ए और बी दोनों के लिए मतलाब में मूल कोड लिखा था। परिणाम के लिए जगह का पूर्व-आवंटन वास्तव में दिलचस्प हिस्सा था। हमने देखा कि गॉडरिक क्या बताता है - कि एबी में नॉनज़रोज़ की संख्या जानना उतना ही महंगा है जितना कि एबी की गणना करना।

हमने एडिथ कोहेन पेपर से पहले 1990 के आसपास स्पार्स मतलाब का प्रारंभिक कार्यान्वयन किया, जिसने एबी के आकार का सही अनुमान लगाने का पहला व्यावहारिक, तेज़ तरीका दिया। हमने एक अवर आकार अनुमानक को एक साथ रखा, और यदि हम मध्य-संगणना में अंतरिक्ष से बाहर चले गए, तो आवंटन दोगुना हो गया और आंशिक रूप से गणना किए गए परिणाम की प्रतिलिपि बनाई।

मुझे नहीं पता कि अब मतलाब में क्या है।

एक समय में एबी एक कॉलम की गणना करने की एक और संभावना होगी। प्रत्येक स्तंभ को एक विरल संचायक में अस्थायी रूप से संग्रहीत किया जा सकता है (इन की व्याख्या के लिए विरल मैटलैब पेपर देखें), और परिणाम कॉलम के बिल्कुल ज्ञात आकार को रखने के लिए आवंटित स्थान। इसका परिणाम बिखरे हुए संकुचित विरल स्तंभ रूप में होगा - CSC में प्रत्येक स्तंभ पर कोई अंतर-आकृति सन्निधि - लंबाई के 2 वैक्टर का उपयोग करते हुए (col start, col length), बजाय मेटा-डेटा के। इसका भंडारण रूप जो देखने लायक हो सकता है; इसकी एक और ताकत है - आप पूरे मैट्रिक्स को पुनः प्राप्त किए बिना एक कॉलम बढ़ा सकते हैं।


अच्छी तरह से अपने GPU के कार्यान्वयन के लिए, मैंने पहले गैर शून्य संरचना को ढूंढना समाप्त कर दिया और फिर वास्तविक मैट्रिक्स ढूंढ रहा था। सक्रियता अपेक्षा के अनुसार भयानक थी। मुझे लगता है कि वे इस पुस्तक में वर्णित विधि का उपयोग MATLAB पर दो विरल मैट्रिस को कुशलता से गुणा करने के लिए करते हैं।
Recker

2
वास्तव में अच्छा है, ऐतिहासिक परिप्रेक्ष्य के लिए धन्यवाद, और scicomp में आपका स्वागत है :)
एरन अहमदिया

4

यह पत्र दो विरल मैट्रिक्स के मैट्रिक्स उत्पाद से परिणामी के आकार को अनुमानित करने के लिए एक एल्गोरिथ्म का वर्णन करता है।

एक विरल मैट्रिक्स गुणन में गैर-शून्य प्रविष्टियों की सटीक संख्या खोजने के साथ समस्या यह है कि परिणामी में प्रत्येक तत्व दो वैक्टर की बातचीत पर निर्भर करता है, दोनों में कम से कम कुछ गैर-शून्य तत्व शामिल होने की संभावना है। इसलिए, परिणाम में प्रत्येक तत्व के लिए वैक्टर की एक जोड़ी पर तार्किक संचालन का मूल्यांकन करने के लिए आपको संख्या की गणना करने की आवश्यकता है। इसके साथ समस्या यह है कि इसे मैट्रिक्स उत्पाद की गणना करने के लिए आवश्यक संचालन की संख्या के समान कई कार्यों की आवश्यकता होती है। अपनी टिप्पणियों में मैंने मूल मैट्रिस के गैर-शून्य तत्वों में कुछ संरचनाओं के दोहन की संभावना का उल्लेख किया, हालांकि उन समान कारनामों का उपयोग मैट्रिक्स गुणा में किए गए काम को कम करने के लिए भी किया जा सकता है।

मेमोरी की आवश्यकताओं का अनुमान लगाने, गुणा करने और फिर आवंटित मेमोरी को छोटा करने या परिणामी मैट्रिक्स को अधिक उचित आकार के सरणी में स्थानांतरित करने के लिए उपरोक्त पेपर का उपयोग करने के लिए आप बेहतर बंद होंगे। इसके अलावा, विरल मैट्रिक्स उत्पाद एक दुर्लभ घटना नहीं हैं, और मैं लगभग गारंटी देता हूं कि यह समस्या पहले हल हो गई है। कुछ खुले स्रोत में थोड़ी खुदाई, विरल मैट्रिक्स लाइब्रेरी आपको उन एल्गोरिदम तक ले जाना चाहिए जो वे मेमोरी का प्रचार करने के लिए उपयोग करते हैं।


0

CSR या CSC के लिए, क्या आप गारंटी देते हैं कि आपके मैट्रिक्स तत्वों की सरणी में पहले से कोई शून्य नहीं है? उस मामले में यह पता लगाना सरल है कि कितने गैर-शून्य तत्व हैं, कुछ इसी तरह का उपयोग करते हुए:

int nnz = sizeof(My_Array)/sizeof(long int);

हालांकि अगर यह मामला नहीं है (थोड़ा आसान लगता है) तो आप जो कोशिश कर सकते हैं वह कमी है । यदि आपके मैट्रिक्स तत्वों की सरणी बहुत बड़ी है, तो यह गैर-अक्षीय तत्वों की संख्या की गणना करने का सबसे प्रभावी तरीका हो सकता है। कई समानांतर C / C ++ लाइब्रेरी जैसे थ्रस्ट (एक CUDA लाइब्रेरी) या OpenCL (जिसे आपको उपयोग करने के लिए GPU की आवश्यकता नहीं है) में सशर्त कटौती के लिए समर्थन है - प्रत्येक तत्व के लिए, का परिणाम जोड़ें Condition(Element)। यदि आप स्थिति सेट करते हैं Element != 0तो आप गैर-मूल तत्वों की संख्या जोड़ देंगे। आप अपने तत्वों की पंक्ति, पंक्ति / स्तंभ सूचकांकों की सरणी से शून्य मूल्यवान तत्वों को निकालना चाहते हैं और अपने स्तंभ / पंक्ति बिंदुओं को समायोजित कर सकते हैं।


आपके उत्तर के लिए धन्यवाद ... लेकिन मैं ए * बी में गैर शून्य का उल्लेख कर रहा था जहां ए और बी विरल मैट्रेस हैं। मुझे अग्रिम में गैर शून्य की संख्या की आवश्यकता है ताकि मैं परिणामी मैट्रिक्स को संग्रहीत करने के लिए सटीक मात्रा में मेमोरी आवंटित कर सकूं।
रेक जूल

0

CSR को लागू करने का सबसे सरल तरीका है प्रयास करना

std::vector< std::map<int, complex<float>> > 

अपने मैट्रिक्स का प्रतिनिधित्व करने के लिए। उस स्थिति में आप वास्तव में गैर शून्य तत्वों की संख्या के बारे में चिंता नहीं करेंगे, सभी के माध्यम से पहुँचा जाता है

std::map< int, complex<float> >::iterator

प्रत्येक पंक्ति पर। श्रेष्ठ ..


2
एसटीएल, जब आपने सोचा था कि आपके विरल मैट्रिक्स रूटीन को कोई धीमा नहीं बनाया जा सकता है।
जेड ब्राउन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.