通过外部分配的数据调用 Eigen GEMM

Dar*_*ver 1 c++ allocation matrix-multiplication eigen eigen3

Eigen 具有惊人的快速 GEMM 实现,因此我想在我的宠物项目张量库中使用它。如果我理解正确的话,可以通过 Eigen::Map 来实现。我编写了简单的示例并进行了定义EIGEN_NO_MALLOC,以确保没有不需要的分配。

它适用于简单的矩阵乘法,例如C += A * B. 但不幸的是它无法处理C += alpha * A * B(GEMM 之类)情况。

#include <iostream>
#include <vector>

#define EIGEN_NO_MALLOC
#include "Eigen/Core"

int main()
{
    using Scalar = float;
    using namespace Eigen;
    std::vector<Scalar> aDat = {1, 2, 3, 4};
    std::vector<Scalar> bDat = {1, 2, 3, 4};
    std::vector<Scalar> cDat = {1, 2, 3, 4};
    Map<Matrix<Scalar, -1, -1, RowMajor>, Unaligned> a(aDat.data(), 2, 2);
    Map<Matrix<Scalar, -1, -1, RowMajor>, Unaligned> b(bDat.data(), 2, 2);
    Map<Matrix<Scalar, -1, -1, RowMajor>, Unaligned> c(cDat.data(), 2, 2);

    //Ok
    c.noalias() += a * b;

    //Assertion `false && "heap allocation is forbidden.....
    c.noalias() += 2 * a * b;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c.noalias() += 2 * a * b;给我以下运行时错误

a.out: path_to_eigen/Eigen/src/Core/util/Memory.h:129: void Eigen::internal::check_that_malloc_is_allowed(): Assertion `false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"' failed.
Run Code Online (Sandbox Code Playgroud)

是否可以c.noalias() += someScalar * a * b;在不分配的情况下调用?

PS 我的本征版本是3.3.2gcc版本是7.2.0

抱歉我的英语不好

cht*_*htz 5

这看起来像是小规模优化引入的错误。(KxM)*(MxN)对于其中的产品K+M+N < EIGEN_GEMM_TO_COEFFBASED_THRESHOLD(默认情况下为20),Eigen 切换到惰性产品实现,这显然认为评估临时值是一个好主意。您的示例实际上可以正常工作,例如对于5x5 * 5x10产品。

我针对该问题提交了一个错误:http://eigen.tuxfamily.org/bz/show_bug.cgi ?id=1562

如果您想要快速解决方法,请定义-D EIGEN_GEMM_TO_COEFFBASED_THRESHOLD=1,这将始终使用大矩阵-GEMM 实现。

另一方面,如果您在编译时知道矩阵大小,则最好使用相应的固定大小类型(Matrix<Scalar, 2, 2, RowMajor>在您的情况下)。