سؤال

أواجه مشكلة في استخدام CBLAs لأداء منتج خارجي. قانون بلدي على النحو التالي:

//===SET UP===//
double x1[] = {1,2,3,4};
double x2[] = {1,2,3};
int dx1 = 4;
int dx2 = 3;
double X[dx1 * dx2];
for (int i = 0; i < (dx1*dx2); i++) {X[i] = 0.0;}

//===DO THE OUTER PRODUCT===//
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, dx1, dx2, 1, 1.0, x1, dx1, x2, 1, 0.0, X, dx1);

//===PRINT THE RESULTS===//
printf("\nMatrix X (%d x %d) = x1 (*) x2 is:\n", dx1, dx2);
for (i=0; i<4; i++) {
    for (j=0; j<3; j++) {
        printf ("%lf ", X[j+i*3]);
    }
    printf ("\n");
}

انا حصلت:

Matrix X (4 x 3) = x1 (*) x2 is:
1.000000 2.000000 3.000000 
0.000000 -1.000000 -2.000000 
-3.000000 0.000000 7.000000 
14.000000 21.000000 0.000000 

ولكن تم العثور على الإجابة الصحيحة هنا:https://www.sharcnet.ca/help/index.php/blas_and_cblas_usage_and_examples

لقد رأيت: حساب فعال لمنتجات Kronecker في ج

لكن هذا لا يساعدني لأنهم لا يقولون في الواقع كيفية استخدام DGEMM للقيام بذلك فعليًا ...

أي مساعدة؟ ماذا أفعل خطأ هنا؟

هل كانت مفيدة؟

المحلول

يمكنك القيام بذلك باستخدام DGEMM ، ولكن سيكون من الصواب أكثر تصحيحًا لاستخدام DGER ، وهو تنفيذ منتج خارجي مخصص. على هذا النحو ، من الأسهل إلى حد ما الاستخدام بشكل صحيح:

cblas_dger(CblasRowMajor, /* you’re using row-major storage */
           dx1,           /* the matrix X has dx1 rows ...  */
           dx2,           /*  ... and dx2 columns.          */
           1.0,           /* scale factor to apply to x1x2' */
           x1,
           1,             /* stride between elements of x1. */
           x2,
           1,             /* stride between elements of x2. */
           X,
           dx2);          /* leading dimension of matrix X. */

DGEMM يفعل احصل على الميزة الجميلة التي تمر \beta = 0 قم بتهيئة مصفوفة النتيجة لك ، مما يوفر لك من الحاجة إلى صفر صريح بنفسك قبل المكالمة. توفر إجابة Artem Shinkarov وصفًا رائعًا لكيفية استخدام DGEMM.

نصائح أخرى

الواجهات ليست مريحة للغاية في Blas ، ومع ذلك ، دعونا نحاول اكتشاف ذلك. بادئ ذي بدء ، دعنا نقول أن جميع المصفوفات لدينا في Rowmajor. الآن لدينا الإعداد التالي

     row  col
x1:  dx1   1   (A)
x2:   1   dx2  (B)
 X:  dx1  dx2  (C)

الآن ، نحتاج فقط إلى ملء المكالمة وفقًا للوثائق ، والتي تم تحديدها من حيث

C = \alpha A*B + \beta C

لذلك نحصل على:

cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans,
             (int)dx1, /* rows in A         */
             (int)dx2, /* columns in B      */
             (int)1,   /* columns in A      */
             1.0, x1,  /* \alpha, A itself  */
             (int)1,   /* Colums in A       */
             x2,       /* B itself          */
             (int)dx2, /* Columns in B      */
             0.0, X,   /* \beta, C itself   */
             (int)dx2  /* Columns in C  */);

لذلك يجب أن يؤدي هذا الوظيفة التي آملها. فيما يلي وصف لمعلمات DGEMM: نهاية لهذه الغاية

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top