- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试编写的简单程序的想法是从用户那里获取输入以查看要相乘的矩阵的大小。
dd@cuda-Linux:~/Desktop/multi$ ./program
What is the rowSize of a? 33
What is the colSize of a? 33
What is the rowSize of b? 33
What is the colSize of b? 33
Would you like to write the results to a file?(y or n)
y
Creating the random numbers now
Writing Matrix A to file now...
Writing Matrix B to file now...
Starting it on the device
Writing Matrix C to file now...
Finish
float* deviceMatrixA;
float* deviceMatrixB;
cudaMalloc((void**) &deviceMatrixA, mem_size_A);//allocate mem_size_x on the device.
cudaMalloc((void**) &deviceMatrixB, mem_size_B);
cudaMemcpy(deviceMatrixA, a.elements, mem_size_A, cudaMemcpyHostToDevice);
cudaMemcpy(deviceMatrixB, b.elements, mem_size_B, cudaMemcpyHostToDevice);
int size_C = c.rowSize * c.colSize;
int mem_size_C = sizeof(float) * size_C;
c.elements = (float*) malloc(mem_size_C);
float* deviceMatrixC;
cudaMalloc((void**) &deviceMatrixC, mem_size_C);
dim3 threads(block_size, block_size);
dim3 grid(c.colSize / threads.x, c.rowSize / threads.y);
matrixMul<<< grid, threads,2*block_size*block_size*sizeof(float)>>>(deviceMatrixC, deviceMatrixA, deviceMatrixB, a.colSize, b.colSize, block_size);//sizeof(float)*block_size*block_size
cudaThreadSynchronize();
// CUDA Kernel
__global__ void matrixMul( float* C, float* A, float* B, int wA, int wB,size_t block_size)
{
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int aBegin = wA * block_size * by;
int aEnd = aBegin + wA - 1;
int aStep = block_size;
int bBegin = block_size * bx;
int bStep = block_size * wB;
float Csub=0;
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep)
{
extern __shared__ float As[];
extern __shared__ float Bs[];
extern __shared__ float smem[];
smem[ty*block_size+tx] = A[a + wA * ty + tx];
smem[block_size*block_size+ty*block_size+tx] = B[b + wB * ty + tx];
__syncthreads();
for (int k = 0; k < block_size; ++k)
Csub += smem[ty*block_size+k] * smem[block_size*block_size+k*block_size+tx] ;
__syncthreads();
}
int c = wB * block_size * by + block_size * bx;
C[c + wB * ty + tx] = Csub;
}
最佳答案
正如我在您的 earlier, almost identical question 上告诉您的那样,此矩阵乘法代码仅用于对维度为 block_size 的整数倍的矩阵进行计算。如果你选择block_size=32,那么它只能用于32x32、64x64、96x96、128x128等。没什么你have done with dynamically allocated shared memory改变这一点。
为了验证情况是否如此,让我们从一个完整的、可编译的重现案例开始,它将运行您的内核,检查它是否执行并将其输出与在主机上完成的简单引用计算进行比较。此代码是您发布的内核,加上您的启动参数计算的核心。它将从 stdin 读取大小,然后运行案例。如果结果相差超过某个容差,则会引发断言错误。这是代码,它应该在 CUDA 3.0 或更高版本上编译并在任何与 CUDA 兼容的 GPU 上运行:
#include <assert.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
inline void GPUassert(cudaError_t code, char * file, int line, bool Abort=true)
{
if (code != 0) {
fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code),file,line);
if (Abort) exit(code);
}
}
#define GPUerrchk(ans) { GPUassert((ans), __FILE__, __LINE__); }
__global__ void matrixMul( float* C, float* A, float* B, int wA, int wB, size_t block_size)
{
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int aBegin = wA * block_size * by;
int aEnd = aBegin + wA - 1;
int aStep = block_size;
int bBegin = block_size * bx;
int bStep = block_size * wB;
float Csub=0.f;
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep)
{
extern __shared__ float smem[];
smem[ty*block_size+tx] = A[a + wA * ty + tx];
smem[block_size*block_size+ty*block_size+tx] = B[b + wB * ty + tx];
__syncthreads();
for (int k = 0; k < block_size; ++k)
Csub += smem[ty*block_size+k] * smem[block_size*block_size+k*block_size+tx] ;
__syncthreads();
}
int c = wB * block_size * by + block_size * bx;
C[c + wB * ty + tx] = Csub;
}
inline float frand(){
return (float)rand()/(float)RAND_MAX;
}
void matmul(float *C, const float *A, const float *B, int wA, int wB)
{
for(int k=0; k<wB; k++) {
for(int j=0; j<wB; j++) {
float dotp = 0.f;
for(int i=0; i<wA; i++) {
dotp += A[j*wA+i] * B[i*wB+k];
}
C[j*wB+k] = dotp;
}
}
}
int main(int argc, char ** argv)
{
int val = 128;
if ( argc == 2 ) {
val = atoi(argv[1]);
}
int m = val, n = val, mn = m*n;
size_t sz = size_t(mn) * sizeof(float);
srand(time(NULL));
float * A = new float[mn], * B = new float[mn], * C= new float[mn];
float * A_, * B_, * C_;
for(int i=0; i<mn; i++) {
A[i] = frand(); B[i] = frand();
}
GPUerrchk( cudaMalloc((void **)&A_, sz) );
GPUerrchk( cudaMalloc((void **)&B_, sz) );
GPUerrchk( cudaMalloc((void **)&C_, sz) );
GPUerrchk( cudaMemcpy(A_, A, sz, cudaMemcpyHostToDevice) );
GPUerrchk( cudaMemcpy(B_, B, sz, cudaMemcpyHostToDevice) );
// Launch configuration
// Note that the input matrice sizes *must* be a round
// multiple of blocksize for this code to work correctly.
const int blocksize=16;
const int shmsz = size_t(2*blocksize*blocksize) * sizeof(float);
dim3 block=dim3(blocksize,blocksize), grid = dim3(m/block.x,m/block.y);
matrixMul<<<grid,block,shmsz>>>(C_,A_,B_,m,n,blocksize);
GPUerrchk( cudaPeekAtLastError() );
GPUerrchk( cudaMemcpy(C, C_, sz, cudaMemcpyDeviceToHost) );
// Verfication on host
float * Cref = new float[mn];
matmul(Cref,A,B,m,n);
const float tol = 5e-5f;
for(int i=0; i<mn; i++) {
assert(fabs(C[i]-Cref[i])/C[i] < tol);
}
GPUerrchk( cudaThreadExit() ); // CUDA 3.2 compatible
return 0;
}
blocksize=16
:
$ nvcc -arch=sm_12 -Xcompiler="-Wall" -Xptxas="-v" -o matmul2 matmul2.cu
ptxas info : Compiling entry function '_Z9matrixMulPfS_S_iim' for 'sm_12'
ptxas info : Used 16 registers, 32+16 bytes smem, 4 bytes cmem[1]
blocksize
的情况。第一的
$ cuda-memcheck ./matmul2 4
========= CUDA-MEMCHECK
GPUassert: invalid configuration argument matmul2.cu 101
========= ERROR SUMMARY: 0 errors
dim3 block=dim3(blocksize,blocksize), grid = dim3(m/block.x,m/block.y);
m,n < blocksize
时,网格大小为 0 .
$ cuda-memcheck ./matmul2 16
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
cuda-memcheck ./matmul2 17
========= CUDA-MEMCHECK
GPUassert: unspecified launch failure matmul2.cu 103
========= Invalid __global__ read of size 4
========= at 0x000001f8 in matrixMul
========= by thread (0,2,0) in block (0,0)
========= Address 0x001009c8 is out of bounds
=========
========= ERROR SUMMARY: 1 error
$ cuda-memcheck ./matmul2 64
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$ cuda-memcheck ./matmul2 96
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$ cuda-memcheck ./matmul2 128
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$ cuda-memcheck ./matmul2 129
========= CUDA-MEMCHECK
GPUassert: unspecified launch failure matmul2.cu 103
========= Invalid __global__ read of size 4
========= at 0x000001f8 in matrixMul
========= by thread (0,1,0) in block (0,0)
========= Address 0x00120904 is out of bounds
=========
========= ERROR SUMMARY: 1 error
关于CUDA 矩阵乘法写入错误的内存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9244747/
如果矩阵A在X中,矩阵B在Y中。 进行乘法运算只是 Z = X*Y。正确假设两个数组的大小相同。 如何使用 for 循环计算它? 最佳答案 ja72 的anwser 是错误的,请查看我在其下的评论以了
我有一个 C 程序,它有 n 次乘法(单次乘法和 n 次迭代),我发现另一个逻辑有 n/2 次迭代(1 次乘法 + 2 次加法)。我知道两者都是 O(n) 的复杂性。但就 CPU 周期而言。哪个更快?
我有一个矩阵x: x <- matrix(1:8, nrow = 2, ncol = 4, byrow = 2) # [,1] [,2] [,3] [,4] #[1,] 1 2 3
我有一个矩阵x: x <- matrix(1:8, nrow = 2, ncol = 4, byrow = 2) # [,1] [,2] [,3] [,4] #[1,] 1 2 3
我正在创建一个基于电影 InTime 的 Minecraft 插件,并尝试创建代码,在玩家死亡时玩家将失去 25% 的时间。 当前代码是: String minus = itapi.getTimeSt
我正在尝试将 2 个矩阵与重载的 * 运算符相乘并打印结果。虽然看起来我不能为重载函数提供超过 1 个参数。如何将这两个矩阵传递给重载函数?请在下面查看我的实现。 #include #include
为什么在 Java 中使用 .*?例如 double probability = 1.*count/numdata; 给出相同的输出: double probability = count/numda
如果我尝试将两个值与单位相乘,则会出现意外错误。 $test: 10px; .testing{ width: $test * $test; } result: 100px*px isn't a v
我正在尝试计算库存中所有产品的总值(value)。表中的每种产品都有价格和数量。因此,我需要将每种产品的价格乘以数量,然后将所有这些加在一起以获得所有产品的总计。根据上一个问题,我现在可以使用 MyS
我正在尝试计算库存中所有产品的总值(value)。表中的每种产品都有价格和数量。因此,我需要将每种产品的价格乘以数量,然后将所有这些加在一起以获得所有产品的总计。根据上一个问题,我现在可以使用 MyS
大家好,我有以下代码行 solution first = mylist.remove((int)(Math.random() * mylist)); 这给了我一个错误说明 The operator *
我必须做很多乘法运算。如果我考虑效率,那么我应该使用位运算而不是常规的 * 运算吗?如果有差异如何进行位运算?提前致谢.. 最佳答案 不,您应该使用乘法运算符,让优化编译器决定如何最快地完成它。 您会
两个 n 位数字 A 和 B 的乘法可以理解为移位的总和: (A << i1) + (A << i2) + ... 其中 i1, i2, ... 是 B 中设置为 1 的位数。 现在让我们用 OR
我想使用 cuda 6 进行 bool 乘法,但我无法以正确的方式做到这一点。B 是一个 bool 对称矩阵,我必须进行 B^n bool 乘法。 我的 C++ 代码是: for (m=0; m
我正在编写一个定点类,但遇到了一些问题...乘法、除法部分,我不确定如何模拟。我对部门运算符(operator)进行了非常粗暴的尝试,但我确信这是错误的。到目前为止,它是这样的: class Fixe
我有TABLE_A我需要创建 TABLE_A_FINAL 规则: 在TABLE_A_FINAL中我们有包含 ID_C 的所有可能组合的行如果在 TABLE_A与 ID_C 的组合相同我们乘以 WEIG
这个问题在这里已经有了答案: Simple way to repeat a string (32 个答案) 关闭 6 年前。 我有一个任务是重复字符乘以它例如用户应该写重复输入 3 R 输出的字母和
我最近学习了C++的基础知识。我发现了一些我不明白的东西。这是让我有点困惑的程序。 #include using namespace std; int main()
我有两个列表: list_a = list_b = list(范围(2, 6)) final_list = [] 我想知道如何将两个列表中的所有值相乘。我希望我的 final_list 包含 [2*2
如何修改此代码以适用于任何基数? (二进制、十六进制、基数 10 等) int mult(int a, int b, int base){ if((a<=base)||(b<=base)){
我是一名优秀的程序员,十分优秀!