访问C 中的DGEMM
Accessing dgemm in C++
我需要在C 中实现矩阵类,其中一个操作必须是通过DGEMM进行矩阵乘法。我的教授在C上以C级为例,但是由于某种原因,我无法在C 中工作。这是我的标题文件矩阵:
#include <iostream>
#include <stdlib.h>
extern "C" {
#include "blas.h"
}
[blah blah blah, matrix class here; overloaded * operator will do the matrix
multiplication]
matrix operator* (const matrix &other){
matrix AxB(Nrows, other.Ncolumns, "(" + name + "*" + "other.name" + ")");
char TRANSA = 'N';
char TRANSB = 'N';
int M = Nrows;
int N = other.Ncolumns;
int K = Ncolumns;
double alpha = 1.;
double beta = 0.;
dgemm_ (&TRANSA,
&TRANSB,
&M,
&N,
&K,
&alpha,
data,
&M,
other.data,
&K,
&beta,
AxB.data,
&M);
return AxB;
[blah blah blah, overloaded = operator here; i'm positive this is not the problem
since it works for matrix addition]
主要功能:
#include "matrix.h"
main(){
// entries of A and B are randomized between 0 and 1
matrix A(5,5);
matrix B(5,5);
matrix C = A*B;
}
现在是blas.h头文件:
void dgemm_ (char *TRANSA,
char *TRANSB,
int *M,
int *N,
int *K,
double *ALPHA,
double **A,
int *LDA,
double **B,
int *LDB,
double *BETA,
double **C,
int *LDC);
我要使用此处概述的子例程:http://www.netlib.org/blas/dgemm.mm.f
基本上,我们在类中为C实现做的方式将矩阵构建为一个长数组,使用(double*)calloc(行*列,sizeof(double))。
我的C 插入确实:
double **data;
data = new double[rows];
for(int i=1; i<=rows; ++i){
data[i-1] = new double[columns];
}
然后我可以使用数据[i] [J]索引。但是,由于DGEMM子例程应该会添加double *a,double *b等。但是我的矩阵是double ** a等,我该如何修复?
这是我从Valgrind收到的错误消息:
==18845== Invalid write of size 8
==18845== at 0x4165C1C: ATL_dgezero (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4149DA7: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d680 is 8 bytes after a block of size 16 alloc'd
==18845== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind
/vgpreload_memcheck-x86-linux.so)
==18845== by 0x8049045: dmatrix::dmatrix(int, int, std::string) (dmatrix.hpp:77)
==18845== by 0x8049532: dmatrix::operator*(dmatrix const&) (dmatrix.hpp:218)
==18845== by 0x8048DCB: main (main.cpp:17)
==18845==
==18845== Invalid write of size 8
==18845== at 0x4165C1F: ATL_dgezero (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4149DA7: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d678 is 0 bytes after a block of size 16 alloc'd
==18845== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind
/vgpreload_memcheck-x86-linux.so)
==18845== by 0x8049045: dmatrix::dmatrix(int, int, std::string) (dmatrix.hpp:77)
==18845== by 0x8049532: dmatrix::operator*(dmatrix const&) (dmatrix.hpp:218)
==18845== by 0x8048DCB: main (main.cpp:17)
==18845==
==18845== Invalid write of size 8
==18845== at 0x4165C22: ATL_dgezero (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4149DA7: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d690 is not stack'd, malloc'd or (recently) free'd
==18845==
==18845== Invalid write of size 8
==18845== at 0x4165C25: ATL_dgezero (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4149DA7: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d688 is not stack'd, malloc'd or (recently) free'd
==18845==
==18845== Invalid read of size 8
==18845== at 0x4143D60: ATL_dJIK0x0x0NN0x0x0_aX_bX (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4149A9D: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478cf80 is not stack'd, malloc'd or (recently) free'd
==18845==
==18845== Invalid read of size 8
==18845== at 0x4143D64: ATL_dJIK0x0x0NN0x0x0_aX_bX (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4149A9D: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d130 is 0 bytes after a block of size 16 alloc'd
==18845== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind
/vgpreload_memcheck-x86-linux.so)
==18845== by 0x8049045: dmatrix::dmatrix(int, int, std::string) (dmatrix.hpp:77)
==18845== by 0x8048D49: main (main.cpp:6)
==18845==
==18845== Invalid read of size 8
==18845== at 0x4143D4C: ATL_dJIK0x0x0NN0x0x0_aX_bX (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4149A9D: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d678 is 0 bytes after a block of size 16 alloc'd
==18845== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind
/vgpreload_memcheck-x86-linux.so)
==18845== by 0x8049045: dmatrix::dmatrix(int, int, std::string) (dmatrix.hpp:77)
==18845== by 0x8049532: dmatrix::operator*(dmatrix const&) (dmatrix.hpp:218)
==18845== by 0x8048DCB: main (main.cpp:17)
==18845==
==18845== Invalid write of size 8
==18845== at 0x4143D93: ATL_dJIK0x0x0NN0x0x0_aX_bX (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4149A9D: ATL_dNCmmJIK (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x415BE8E: ATL_dgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x4182F54: ATL_dptgemm_nt (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4183140: ATL_dptgemm (in /usr/lib/atlas-base/atlas/libblas.so.3gf.0)
==18845== by 0x40818F6: atl_f77wrap_dgemm_ (in /usr/lib/atlas-base/atlas
/libblas.so.3gf.0)
==18845== by 0x4E4E0004: ???
==18845== Address 0x478d678 is 0 bytes after a block of size 16 alloc'd
==18845== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind
/vgpreload_memcheck-x86-linux.so)
==18845== by 0x8049045: dmatrix::dmatrix(int, int, std::string) (dmatrix.hpp:77)
==18845== by 0x8049532: dmatrix::operator*(dmatrix const&) (dmatrix.hpp:218)
==18845== by 0x8048DCB: main (main.cpp:17)
==18845==
==18845== Invalid read of size 8
==18845== at 0x8048DEA: main (main.cpp:19)
==18845== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==18845==
==18845==
==18845== Process terminating with default action of signal 11 (SIGSEGV)
==18845== Access not within mapped region at address 0x0
==18845== at 0x8048DEA: main (main.cpp:19)
==18845== If you believe this happened as a result of a stack
==18845== overflow in your program's main thread (unlikely but
==18845== possible), you can try to increase the size of the
==18845== main thread stack using the --main-stacksize= flag.
==18845== The main thread stack size used in this run was 8388608.
==18845==
==18845== HEAP SUMMARY:
==18845== in use at exit: 3,581 bytes in 39 blocks
==18845== total heap usage: 49 allocs, 10 frees, 7,760 bytes allocated
==18845==
==18845== LEAK SUMMARY:
==18845== definitely lost: 128 bytes in 4 blocks
==18845== indirectly lost: 0 bytes in 0 blocks
==18845== possibly lost: 88 bytes in 4 blocks
==18845== still reachable: 3,365 bytes in 31 blocks
==18845== suppressed: 0 bytes in 0 blocks
==18845== Rerun with --leak-check=full to see details of leaked memory
==18845==
==18845== For counts of detected and suppressed errors, rerun with: -v
==18845== ERROR SUMMARY: 111 errors from 9 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
直到我尝试实现DGEMM矩阵乘法之前,我没有错误,也没有泄漏,所以我敢肯定,我所有的麻烦都在DGEMM实现
C版本的内存布局与C 版本中的内存布局不同。正如Blas期望C版本使用的布局类型一样,您的C 版本将无法使用。
因此,您还需要在C 版本中分配一个大的1D数组;您可以超载Operator()以获取2D数组的索引。或用于生产代码,请使用诸如eigen之类的库。
对不起,我没有意识到在响应时击中输入会发送回复。
我更改了索引:
double *data;
data = new double[rows*columns];
然后,每次我想索引它时,我都会以数据[(i-1)*列 (j-1)]进行行索引。该代码现在肯定可以工作,并以0个错误和0个内存泄漏进行编译!唯一的事情是我现在得到一个完全的凝结结果。
这与fortran进行列订购的事实有关,而我正在做行 - 马约尔?我将如何调和这个?
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 将字符串存储在c++中的稳定内存中
- 文本文件中的单词链表
- 递归函数计算序列中的平方和(并输出过程)
- 如何从C++中的依赖类型中获得它所依赖的类型
- C++中的"inline"关键字
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 用C++中的一个变量定义一个常量
- vector.resize()中的分配错误
- 使用指针从C++中的数组中获取最大值
- arr[-1]在c++中的奇怪行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 将值指定给向量(2D)的向量中的某个位置
- 访问C 中的DGEMM