如何使用cblas_dgemm进行向量外积?

如何使用cblas_dgemm进行向量外积?,c,matrix,vector,blas,intel-mkl,C,Matrix,Vector,Blas,Intel Mkl,我试图用一个行向量和一个列向量相乘。我可以用dgemm吗 换句话说,D=A*B 其中D是矩阵,a是列向量,B是行向量 我遵循了这里找到的文档。我似乎无法为cblas_ggemm获得正确的参数 这是我的尝试。在我的例子中,m=nRows,n=nCols,k=1 问题似乎是土地发展局、土地发展局和土地发展公司。我将它们分别定义为ncol、k、nRows #include <stdio.h> #include <time.h> #include <stdlib.h>

我试图用一个行向量和一个列向量相乘。我可以用dgemm吗

换句话说,D=A*B 其中D是矩阵,a是列向量,B是行向量

我遵循了这里找到的文档。我似乎无法为cblas_ggemm获得正确的参数

这是我的尝试。在我的例子中,m=nRows,n=nCols,k=1

问题似乎是土地发展局、土地发展局和土地发展公司。我将它们分别定义为ncol、k、nRows

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

#include <math.h>
#include <mkl.h>

#define nCols 5
#define nRows 20
#define k 1

void PrintMatrix(double* pMatrix, const size_t nR, const size_t nC, const CBLAS_ORDER Order) {
    unsigned int i, j;
    if (Order == CblasRowMajor)
    {
        for (i = 0; i < nR; i++)
        {
            for (j = 0; j < nC; j++)
            {
                printf("%f \t ", pMatrix[i * nC + j]); // !!!
            }
            printf("\n"); // !!!
        }

    }

    else

    {
        for (i = 0; i < nR; i++) {
            for (j = 0; j < nC; j++) {
                printf("%f \t ", pMatrix[i + j* nR ]); // !!!
            }
            printf("\n"); // !!!
        }

    }
    printf("\n"); // !!!

}

int main(void) {

    double A[] = { 8, 4, 7, 3, 5, 1, 1, 3, 2, 1, 2, 3, 2, 0, 1, 1 , 2, 3, 4, 1};

    double B[] = { -1, 2, -1, 1, 2 };


    double alpha = 1.0, beta = 0.0;
    int i, lda, ldb, ldc;
    double *C, *D;
    D = (double*) malloc(nRows * nCols * sizeof(double));
    C = (double*) malloc(nRows * nCols * sizeof(double));

    for (i = 0; i < nRows*nCols; i++)
        D[i] = 0.0;
    for (i = 0; i < nRows*nCols; i++)
        C[i] = 0.0;

    lda = nCols;
    ldb = k;
    ldc = nRows;

    cblas_dger(CblasRowMajor, nRows, nCols, alpha, A, 1, B, 1, C, nCols);

    PrintMatrix(C, nRows, nCols,CblasRowMajor);
    cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans, nRows,  nCols, k, alpha, A, lda, B, ldb, beta, D, ldc);

    PrintMatrix(D, nRows, nCols, CblasRowMajor);

    free(D);
    free(C);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义NCOL5
#定义nRows 20
#定义k1
无效打印矩阵(双*P矩阵、常数大小\u t nR、常数大小\u t nC、常数CBLAS\u顺序){
无符号整数i,j;
如果(订单==CBLASROWMARY)
{
对于(i=0;i
简而言之,是的,您可以使用
dgemm
进行排名1的更新。当然,建议使用
dger
,因为预计它会针对该操作进行更好的优化

至于使用
cblas_dgemm
。正如您所知,前导尺寸的定义是:

lda:矩阵A的第一维的大小

您尝试执行的操作是: D(20x5)=A(20x1)*B(1x5)

您使用的是
CblasRowMajor
,因此前导标注了所有矩阵的列数(有关说明,请参阅)。意思是:

lda = 1;
ldb = 5;
ldc = 5;

下面的代码可以工作。我转到了major专栏,因为在Fortran BLAS文档的上下文中更容易理解主要维度问题。很抱歉,我没能准确地解决你提出的问题

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

#include <math.h>
#include <mkl.h>

void PrintMatrix(double* pMatrix, const size_t nR, const size_t nC, const CBLAS_ORDER Order) {
    unsigned int i, j;
    if (Order == CblasRowMajor) {
        for (i = 0; i < nR; i++) {
            for (j = 0; j < nC; j++) {
                printf("%f \t ", pMatrix[i * nC + j]); // !!!
            }
            printf("\n"); // !!!
        }
    } else {
        for (i = 0; i < nR; i++) {
            for (j = 0; j < nC; j++) {
                printf("%f \t ", pMatrix[i + j* nR ]); // !!!
            }
            printf("\n"); // !!!
        }
    }
    printf("\n"); // !!!
}

int main(void)
{
    const int m = 20;
    const int n = 5;
    const int k = 1;

    double A[] = { 8, 4, 7, 3, 5, 1, 1, 3, 2, 1, 2, 3, 2, 0, 1, 1, 2, 3, 4, 1};
    double B[] = { -1, 2, -1, 1, 2 };

    double alpha = 1.0, beta = 0.0;

    double * C = (double*) malloc(m * n * sizeof(double));
    double * D = (double*) malloc(m * n * sizeof(double));

    for (int i = 0; i < m*n; i++) C[i] = 0.0;
    for (int i = 0; i < m*n; i++) D[i] = 0.0;

    int lda = 20;
    int ldb = 1;
    int ldc = 20;

    cblas_dger(CblasColMajor, m, n, alpha, A, 1, B, 1, C, ldc);

    cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, 
                m, n, k, 
                alpha, A, lda, 
                B, ldb, beta, 
                D, ldc);

    PrintMatrix(C, m, n, CblasRowMajor);
    PrintMatrix(D, m, n, CblasRowMajor);

    free(D);
    free(C);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
无效打印矩阵(双*P矩阵、常数大小\u t nR、常数大小\u t nC、常数CBLAS\u顺序){
无符号整数i,j;
如果(订单==CBLASROWMARY){
对于(i=0;i
非常感谢ctheo。我试过了,但是我也遇到了同样的问题。它正在崩溃。@themaze我检查了程序,在我的电脑上运行正常。请检查源代码中包含的
cblas.h
。如何定义
CblasRowMajor
CblasNoTrans
?我在不同的linux发行版上测试了这一点。软呢帽和它的工作:)。Thanks@themaze似乎这些变量在一些库中被不小心地实现了。这是一个后续问题。出于其他一些原因,我切换回OpenSuSE 42.2,代码给出了一个核心转储。尽管它在Fedora 23-24赛季表现不错。我正试图弄清楚到底出了什么问题。你有什么想法吗?我用的是MKL 11.3汉克斯杰夫。奇怪的是,cblas_dgemm没有在我的系统上运行。MKL的哪个版本?平台信息?您可以尝试另一个实现(GSL、ATLAS、OpenBLAS)来验证。我使用的是最新的MKL版本11.2。我会试试OpenBlas和GSL。问题是我正在使用vdMul,它似乎只在MKL中。你知道任何有效的元素乘法方法吗?你需要具体一点。对我来说,“最新”是指每晚的工程建设;-)元素矩阵乘法的带宽是有限的,可以用循环实现。如果您注意到vdmul运行速度明显加快,请发布该问题,我将尽力提供帮助。这为我解决了问题。