c++ - 通过外部分配的数据调用 Eigen GEMM
问题描述
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;
}
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.
是否可以在c.noalias() += someScalar * a * b;
没有分配的情况下调用?
PS我的特征版本是3.3.2
,gcc
版本是7.2.0
对不起我的英语不好
解决方案
这看起来像是小尺寸优化引入的错误。对于(默认为)的产品(KxM)*(MxN)
,Eigen 切换到惰性产品实现,这显然认为评估为临时是一个好主意。您的示例实际上可以正常工作,例如对于产品。K+M+N < EIGEN_GEMM_TO_COEFFBASED_THRESHOLD
20
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>
在您的情况下)。
推荐阅读
- mysql - JSON_EXTRACT 和 mysql 局部变量做错了什么
- google-calendar-api - 日历 ACL 看起来不适用于外部域
- boolean - 带火炬的矢量/矩阵产品,包括布尔值
- c++ - OpenSSL 读取非阻塞套接字意外行为
- nginx - GCP VM 将所有请求重定向到另一个 URL
- elasticsearch - (elasticsearch)不区分大小写的模式分析器无法按预期工作(已解决 - 用户错误)
- javascript - 我需要在我的字符串中过滤连字符(-)和空格(“”),我做错了什么?
- centreon-api - check_sap_status 适用于 cmd 行但不适用于 Centreon
- python - 如何有效地分析数据
- concurrency - Fuseki 并发