इस उदाहरण के साथ समस्या यह है कि यह केवल वर्ग matrices के लिए काम करता है। यदि मैट्रिस स्क्वायर नहीं हैं तो आप आयाम मिसमैच की वजह से A^t*B^t
की गणना नहीं कर सकते (माना जाता है कि आयाम A*B
के लिए सही थे)।
मेरे पास एक काम करने वाला क्यूब्ला-इंस्टॉलेशन नहीं है, इसलिए यह अंधेरे में एक शॉट है, लेकिन अगर मैं सामान्य ब्लैस की तुलना में अलग-अलग काम करता हूं तो मुझे आश्चर्य होगा। बीएलएएस उम्मीद करता है कि मेट्रिस कॉलम-मेजर-ऑर्डर (उर्फ फोर्ट्रान-ऑर्डर) में हों, लेकिन पंक्ति-प्रमुख क्रम (उर्फ सी-ऑर्डर) में मैट्रिस के लिए भी इस्तेमाल किया जा सकता है।
मेरी राय में, जो पूरी तरह से गलत हो सकता है, gemm_v2
दो सी-ऑर्डर मैट्रिक्स के गुणा को संभालने का सामान्य/सबसे अच्छा तरीका नहीं है, उदाहरण के लिए क्योंकि यदि कोई दो सी-ऑर्डर मैट्रिक्स को गुणा करता है तो एक सी- उत्तर के रूप में क्रम मैट्रिक्स।
चाल gemm
की मदद से दो सी-आदेश-मैट्रिक्स के उत्पाद की गणना करने के इस प्रकार काम करेगा:
यहां तक कि अगर यह शायद आप के लिए जाना जाता है, मैं पर विस्तृत करने के पहले चाहते हैं पंक्ति-major- ऑर्डर (सी-मेमोरी-लेआउट) और कॉलम-मेजर-ऑर्डर (फोर्टन-मेमोरी-लेआउट), मेरे जवाब को दूर करने के लिए।
हमारे पास तो अगर एक 2x3
(यानी 2 पंक्तियाँ और 3 कॉलम) मैट्रिक्स A
, और यह स्टोर कुछ निरंतर स्मृति में हम पाते हैं:
row-major-order(A) = A11, A12, A13, A21, A22, A23
col-major-order(A) = A11, A21, A12, A22, A13, A33
अगर हम एक सतत स्मृति है, जो एक का प्रतिनिधित्व करता है मिल इसका मतलब है कि पंक्ति-प्रमुख क्रम में मैट्रिक्स, और कॉलम-मेजर-ऑर्डर में मैट्रिक्स के रूप में इसकी व्याख्या करने के लिए हमें काफी अलग मैट्रिक्स मिलेगा!
हालांकि, अगर हम स्थानांतरित मैट्रिक्स A^t
पर एक नज़र डालें हम आसानी से देख सकते हैं:
row-major-order(A) = col-major-order(A^t)
col-major-order(A) = row-major-order(A^t)
इसका मतलब है कि, अगर हम परिणाम के रूप में पंक्ति-प्रमुख-क्रम में मैट्रिक्स C
प्राप्त करना चाहते हैं, ब्लैस-रूटीन को कॉलम-मेजर-ऑर्डर में ट्रांसपोज़ेड मैट्रिक्स C
लिखना चाहिए (इसके बाद हम इस बदलाव में नहीं बदल सकते हैं)। हालांकि, C^t=(AB)^t=B^t*A^t
और B^t
एक A^t
मूल मैट्रिक्स कॉलम-प्रमुख-क्रम में पुन: व्याख्या किए गए हैं।
gemm('N', 'N', m, n, k, 1.0, B, m, A, k, 0.0, C, m)
कृपया ध्यान दें::
- हम नहीं
अब, A
एक n x k
मैट्रिक्स और B
एक k x m
मैट्रिक्स, gemm दिनचर्या के कॉल के रूप में निम्नानुसार होना चाहिए रहने दो matrices A
और B
को स्थानांतरित करना होगा, क्योंकि इसे सी-ऑर्डर को फोर्ट्रान-ऑर्डर के रूप में पुन: परिभाषित करके संभाला जाता है।
- परिणामस्वरूप फोरट्रान-क्रम में
C^t
प्राप्त करने के लिए हमें matrices A
और B
के स्थानों को स्वैप करना होगा।
- परिणामी मैट्रिक्स
C
सी-ऑर्डर में है (इसे फोरट्रान-ऑर्डर से सी-ऑर्डर में दोबारा बदलकर हम ^t
से छुटकारा पा सकते हैं)।
कॉल करने के लिए कॉल में, आप रत्न, ट्रांस, ट्रांसब, एम, एन, के, अल्फा, ए: आर, बी: आर, बीटा, सी: डब्ल्यू) निर्दिष्ट करते हैं; जहां ट्रांसका और ट्रांसब मैट्रिस पर ऑपरेशन लागू किए जाते हैं। Gemm_v1 उदाहरण में, यह पहचान ऑपरेशन है, gemm_v2 उदाहरण में यह स्थानांतरित होता है। फिर, आप एम, एन और के निर्दिष्ट करते हैं। ये ए (एम) के #rows, बी (एन) के ए/# पंक्तियों के # कॉलम और बी (के) के कॉलम हैं। यदि आप इसे उदाहरण के सिंटैक्स पर रखते हैं, तो आप इसे स्क्वायर मैट्रिस के रूप में निर्दिष्ट करते हैं, इसलिए इसे बदलने के लिए यह है। सुनिश्चित करें कि आपके matrices का आकार घोषणा से मेल खाता है। – Uvar