cuda core实现两个128x128 float矩阵乘法demo

news/2024/10/20 20:16:51
#include <stdio.h>
#include <cuda_runtime.h>// 128 x 128 -> 
__global__ void mm(float* a, float* b, float* c) {// 8 x 8个方块,每个方块16x16extern __shared__ float buf[];float* a_local = buf;float* b_local = buf + 16*128;for(int i=0; i<8; i++) {a_local[threadIdx.x + i*16 + threadIdx.y*128] = a[threadIdx.x + i*16 + threadIdx.y*128 + blockIdx.y*128*16];b_local[(threadIdx.y + i*16)*16 + threadIdx.x] = b[(threadIdx.y + i*16)*128 + threadIdx.x + blockIdx.x*16];}__syncthreads();float tmp = 0.0f;for(int k=0; k<128; k++) tmp += a_local[threadIdx.y*128+k]*b_local[k*16+threadIdx.x];c[(blockIdx.y*16+threadIdx.y)*128+blockIdx.x*16+threadIdx.x] = tmp;
}#define CHECK_ERROR(expr) { \cudaError_t err = expr; \if(err != cudaSuccess) { \fprintf(stderr, "[Error] %s:%d %s\n", __FILE__, __LINE__, cudaGetErrorString(err)); \} \
}#define A(i,j) a[i*128+j]
#define B(i,j) b[i*128+j]
#define C(i,j) c[i*128+j]
#define G(i,j) golden[i*128+j]int main() {// int deviceId = 0;// CHECK_ERROR(cudaSetDevice(deviceId));constexpr size_t size = 128*128*sizeof(float);float* a = (float*)malloc(size);float* b = (float*)malloc(size);float* c = (float*)malloc(size);float* golden = (float*)malloc(size);// generate input data and goldenfor(int i=0; i<128; i++) {for(int j=0; j<128; j++) {A(i,j) = (float)(random()%1024);B(i,j) = (float)(random()%1024);}}for(int i=0; i<128; i++) {for(int j=0; j<128; j++) {G(i,j) = 0.0f;for(int k=0; k<128; k++) {G(i,j) += A(i,k)*B(k,j);}}}float *a_d, *b_d, *c_d;CHECK_ERROR(cudaMalloc((void**)&a_d, size));CHECK_ERROR(cudaMalloc((void**)&b_d, size));CHECK_ERROR(cudaMalloc((void**)&c_d, size));cudaStream_t stream;CHECK_ERROR( cudaStreamCreate(&stream) );CHECK_ERROR( cudaMemcpy(a_d, a, size, cudaMemcpyHostToDevice) );CHECK_ERROR( cudaMemcpy(b_d, b, size, cudaMemcpyHostToDevice) );mm<<<dim3(8,8,1), dim3(16, 16, 1), 16*128*2*4, stream>>>(a_d, b_d, c_d);{cudaError_t err = cudaGetLastError();if(err!=cudaSuccess) {fprintf(stderr, "[Error] %s:%d %s\n", __FILE__, __LINE__, cudaGetErrorString(err));}}CHECK_ERROR(cudaMemcpy(c, c_d, size, cudaMemcpyDeviceToHost));CHECK_ERROR( cudaStreamSynchronize(stream) );//check resultfloat res = 0.0f;for(int i=0; i<128; i++) for(int j=0; j<128; j++) res += fabs(G(i,j) - C(i,j));for(int i=0; i<10; i++) printf("golden[%d]: %f vs real[%d]: %f \n", i, golden[i], i, c[i]);if(res < 1.0e-2) printf("test pass!\n");else {printf("test fail! res = %f\n", res);}free(a); free(b); free(c); free(golden);cudaFree(a_d); cudaFree(b_d); cudaFree(c_d);return 0;
}

采用8x8的block, 每个block中完成c矩阵中16x16
编译执行结果。

$ nvcc mmad.cu -Xptxas -v 
$ ./a.out
golden[0]: 32589786.000000 vs real[0]: 32589786.000000 
golden[1]: 38473160.000000 vs real[1]: 38473160.000000 
golden[2]: 30227116.000000 vs real[2]: 30227116.000000 
golden[3]: 28977550.000000 vs real[3]: 28977550.000000 
golden[4]: 34897048.000000 vs real[4]: 34897048.000000 
golden[5]: 36245064.000000 vs real[5]: 36245064.000000 
golden[6]: 31798204.000000 vs real[6]: 31798204.000000 
golden[7]: 30707464.000000 vs real[7]: 30707464.000000 
golden[8]: 34893612.000000 vs real[8]: 34893612.000000 
golden[9]: 36354168.000000 vs real[9]: 36354168.000000 
test pass!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73926.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

如何确认Windows电脑是否支持安装苹果系统?

Windows上安装苹果系统,无论是本地磁盘多系统共存安装还是通过虚拟机安装,不是所有电脑都支持,必须得硬件支持才行,不然会出现各种问题。以下是关于如何确认电脑是否支持安装黑苹果?的主要内容,如果未能解决你的问题,请参考其他文章: https://www.cnblogs.com一、查看硬件…

使用MySQL之创建计算字段

1. 创建计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打印程序却需要把它们作为一个…

如何自动识别CAD图中所有表格数据并导出

在CAD图中自动识别并导出表格数据,是相关领域数据处理的重要需求。由于CAD图形并不像传统的电子表格那样具备明确的行列关系,表格常以线条和文本形式存在,手动提取不仅费时费力,还容易出错。如何通过自动化工具通过图形解析快速、高效地识别表格结构,提取数据并导出至Exce…

2024数据采集与融合技术实践-作业1

作业① 要求:用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020)的数据,屏幕打印爬取的大学排名信息。 代码与运行结果 代码: #导入所需要的库 import requests from bs4 import BeautifulSoup import pandas as pd#爬取…

【报告】务虚笔记

务虚笔记同学们大家好,接下来由我向大家推荐史铁生的《务虚笔记》 我的报告分为四部分。书籍简介首先是书籍简介。务虚笔记是史铁生先生的首部长篇小说,于1996年发表在《收获》杂志上。它的行文优美、凝练,情感真挚、厚重,语言平实易读,虽然理解它的内容会让第一次读此书的…

高级程序设计第三次作业

这个作业属于哪个课程:https://edu.cnblogs.com/campus/fzu/2024C 这个作业要求在哪里:https://edu.cnblogs.com/campus/fzu/2024C/homework/13284 学号:102300107 姓名:陈沁怡 4.8.2感想:学会了转义字符的使用 4.8.3感想:数字表达的转换 4.8.44.8.64.8.7理解lf和f之间的…

2024-2025-1 20241322 《计算机基础与程序设计》第四周学习总结

2024-2025-1 20241322 《计算机基础与程序设计》第四周学习总结 作业信息这个作业属于哪个课程 https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK04这个作业的目标 <门电路 组合电路,逻辑电路…

http://192.168.14.232/contest/59

A:创历史新低 dalao:d<=5,所以一个位置上只能是[i-d,i+d],考虑状压 ljxs code #include <bits/stdc++.h> using namespace std; const int maxn=505; const int mod=998244353; int read(){int ret=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch==-)f=-f;ch=ge…