找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3526|回复: 4

【CUDA C】矩阵的乘与加

[复制链接]
发表于 2021-3-22 21:04:42 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
好长时间没有来论坛发帖子啦!
水个帖子来冒个泡!
就是很简单的矩阵乘法与加法,就不详细阐述咯;
  1. #include "cuda_runtime.h"
  2. #include "device_launch_parameters.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <math.h>

  7. void GenerateMatrix(float *matrix, int nx, int ny)
  8. {
  9.         int i, j;
  10.         float cnt = 0;
  11.         for (i = 0; i < nx; i++)
  12.         {
  13.                 for (j = 0; j < ny; j++)
  14.                 {
  15.                         matrix[i*nx + j] = cnt++;
  16.                 }
  17.         }
  18.         printf("[*] GenerateMatrix has done!\n");
  19. }

  20. void PrintMatrix(float *matrix, int nx, int ny)
  21. {
  22.         int i, j;
  23.         for (i = 0; i < nx; i++)
  24.         {
  25.                 for (j = 0; j < ny; j++)
  26.                 {
  27.                         printf("%.2f\t", matrix[i*nx + j]);
  28.                 }
  29.                 printf("\n");
  30.         }
  31.         printf("[*] PrintMatrix has done!\n");
  32. }

  33. /************************* matrix summary begin *************************/
  34. void AddMatrixOnCPU(float *A, float *B, float *C, int nx, int ny)
  35. {
  36.         int i, j;
  37.         for (i = 0; i < nx; i++)
  38.         {
  39.                 for (j = 0; j < ny; j++)
  40.                 {
  41.                         C[i*nx + j] = A[i*nx + j] + B[i*nx + j];
  42.                 }
  43.         }
  44.         printf("[*] AddMatrix on CPU has done!\n");
  45. }

  46. __global__ void AddMatrixOnGPU(float *A, float *B, float *C, int nx, int ny)
  47. {
  48.         int i = threadIdx.x + blockIdx.x * blockDim.x;
  49.         int j = threadIdx.y + blockIdx.y * blockDim.y;
  50.         int idx = i*nx + j;
  51.         if (i <= nx && j <= ny)
  52.         {
  53.                 C[idx] = A[idx] + B[idx];
  54.         }
  55. }
  56. /************************* matrix summary done **************************/
  57. //
  58. //
  59. //
  60. /************************ matrix multiply begin *************************/
  61. void MulMatrixOnCPU(float *A, float *B, float *C, int nx, int ny)
  62. {
  63.         int i, j, k;
  64.         float sum = 0.0;
  65.         for (i = 0; i < nx; i++)
  66.         {
  67.                 for (j = 0; j < ny; j++)
  68.                 {
  69.                         sum = 0.0;
  70.                         for (k = 0; k < nx; k++)
  71.                         {
  72.                                 sum = sum + A[i*nx + k] * B[k*nx + j];
  73.                         }
  74.                         C[i*nx + j] = sum;
  75.                 }
  76.         }
  77. }

  78. __global__ void MulMatrixOnGPU(float *A, float *B, float *C, int nx, int ny)
  79. {
  80.         int i = threadIdx.x + blockIdx.x * blockDim.x;
  81.         int j = threadIdx.y + blockIdx.y * blockDim.y;
  82.         int k;
  83.         if (i < nx && j < ny)   // we should to identify the "i" and "j" scope.
  84.         {
  85.                 float sum = 0.0;
  86.                 for (k = 0; k < nx; k++)
  87.                 {
  88.                         sum += A[i*nx + k] * B[k*nx + j];
  89.                 }
  90.                 C[i*nx + j] = sum;
  91.         }
  92. }
  93. /************************ matrix multiply end ***************************/

  94. // compare the result
  95. int Compare(float *cpu_ref, float *gpu_ref, int nx, int ny)
  96. {
  97.         int i, j;
  98.         for (i = 0; i < nx; i++)
  99.         {
  100.                 for (j = 0; j < ny; j++)
  101.                 {
  102.                         if (cpu_ref[i*nx + j] != gpu_ref[i*nx + j])
  103.                         {
  104.                                 return 0;
  105.                         }
  106.                 }
  107.         }
  108.         return 1;
  109. }


  110. int main(int argc, char *argv[])
  111. {
  112.         // the size of the elements in the matrix can not be much larger....
  113.         // because of my worse GPU: nVIDIA GeForce GT710
  114.         unsigned int N = 1<<12;
  115.         int nx = (int)sqrt((float)N);
  116.         int ny = (int)sqrt((float)N);

  117.         float *A = NULL;
  118.         float *B = NULL;
  119.         float *C = NULL;
  120.         float *gpu_ref = NULL;
  121.         float *d_A = NULL;
  122.         float *d_B = NULL;
  123.         float *d_C = NULL;

  124.         // allocate the memory on CPU
  125.         A = (float *)malloc(sizeof(float)* N);
  126.         B = (float *)malloc(sizeof(float)* N);
  127.         C = (float *)malloc(sizeof(float)* N);
  128.         gpu_ref = (float *)malloc(sizeof(float)*N);
  129.         // set the memory to zero
  130.         memset(A, 0, sizeof(float)*N);
  131.         memset(B, 0, sizeof(float)*N);
  132.         memset(C, 0, sizeof(float)*N);
  133.         memset(gpu_ref, 0, sizeof(float)*N);

  134.         // allocate the memory on GPU
  135.         cudaMalloc((float **)&d_A, sizeof(float)*N);
  136.         cudaMalloc((float **)&d_B, sizeof(float)*N);
  137.         cudaMalloc((float **)&d_C, sizeof(float)*N);
  138.         // reset the memory to zero
  139.         cudaMemset(d_A, 0, sizeof(float)*N);
  140.         cudaMemset(d_B, 0, sizeof(float)*N);
  141.         cudaMemset(d_C, 0, sizeof(float)*N);

  142.         // generate the matrix on CPU
  143.         GenerateMatrix(A, nx, ny);
  144.         GenerateMatrix(B, nx, ny);

  145.         // transfer the data from CPU to GPU
  146.         cudaMemcpy(d_A, A, sizeof(float)*N, cudaMemcpyHostToDevice);
  147.         cudaMemcpy(d_B, B, sizeof(float)*N, cudaMemcpyHostToDevice);


  148.         // set the grid number and the block thread number
  149.         dim3 block(32, 32);
  150.         dim3 grid((nx + block.x - 1) / block.x, (ny + block.y - 1) / block.y);

  151.         // Add the matrix on CPU
  152.         AddMatrixOnCPU(A, B, C, nx, ny);

  153.         // Add the matrix on GPU
  154.         AddMatrixOnGPU << <grid, block >> >(d_A, d_B, d_C, nx, ny);
  155.         cudaDeviceSynchronize();  // let the CPU wait the GPU to do its calculation.

  156.         // transform the data from the GPU to CPU
  157.         cudaMemcpy(gpu_ref, d_C, sizeof(float)*N, cudaMemcpyDeviceToHost);

  158.         if (Compare(C, gpu_ref, nx, ny))
  159.         {
  160.                 printf("[*] Compare : Matrix_ADD => the result are the same!\n");
  161.         }
  162.         else
  163.         {
  164.                 printf("[*] Compare : Matrix_ADD => the result are NOT the same...\n");
  165.         }

  166.         // test the matrix multiply
  167.         MulMatrixOnCPU(A, B, C, nx, ny);

  168.         // test the matrix multiply on GPU
  169.         MulMatrixOnGPU << <grid, block >> >(d_A, d_B, d_C, nx, ny);
  170.         cudaDeviceSynchronize();

  171.         cudaMemcpy(gpu_ref, d_C, sizeof(float)*N, cudaMemcpyDeviceToHost);

  172.         // make the comparison
  173.         if (Compare(C, gpu_ref, nx, ny))
  174.         {
  175.                 printf("[*] Compare : Matrix_MUL => the result are the same!\n");
  176.         }
  177.         else
  178.         {
  179.                 printf("[*] Compare : Matrix_MUL => the result are NOT the same...\n");
  180.         }

  181.         // Debug Print
  182.         // PrintMatrix(gpu_ref, nx, ny);
  183.         // PrintMatrix(C, nx, ny);
  184.        
  185.         free(A);
  186.         free(B);
  187.         free(C);
  188.         free(gpu_ref);
  189.         cudaFree(d_A);
  190.         cudaFree(d_B);
  191.         cudaFree(d_C);

  192.         return 0;
  193. }


  194. // [*] GenerateMatrix has done!
  195. // [*] GenerateMatrix has done!
  196. // [*] AddMatrix on CPU has done!
  197. // [*] Compare : Matrix_ADD = > the result are the same!
  198. // [*] Compare : Matrix_MUL = > the result are the same!
  199. // Press any key to continue...
复制代码


有一个很困惑的bug:
QQ图片20210322210347.png

GitHub:https://github.com/XingguangZhou/CUDA_Note/blob/main/MulMatrix.cu
很期待您的star!
回复

使用道具 举报

发表于 2021-3-23 10:16:19 | 显示全部楼层
watermelon 发表于 2021-3-23 10:14
感谢A5大佬解惑!
话说A5大佬知识是真的丰富,我也怀疑是我的显卡的因素,显卡的CUDA加速器个数、寄存器 ...

其实CUDA的寄存器、加速器、共享内存等概念,和OpenGL、Direct3D的常量寄存器、VS输入输出、GS输入输出、FS输入输出、纹理材质、Buffer等东西式一一对应的。

点评

内容深度: 5.0 视角独特性: 5.0
客观性: 5.0
内容深度: 5 视角独特性: 5 客观性: 5
可以可以,学到了:)  发表于 2021-3-23 11:50
回复 赞! 1 靠! 0

使用道具 举报

发表于 2021-3-23 06:56:34 | 显示全部楼层
要知道,我当年还在使用 GTX 780 的时候,我就发现我当时创建的单张纹理的分辨率不能超过 16384 x 16384 。后来我看了DX的Caps结构体,以及OpenGL的 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &xxx); 的数值,发现当时我能创建的纹理的面积还确实只能最大是 16384 x 16384 。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2021-3-23 10:14:12 | 显示全部楼层
0xAA55 发表于 2021-3-23 06:56
要知道,我当年还在使用 GTX 780 的时候,我就发现我当时创建的单张纹理的分辨率不能超过 16384 x 16384 。 ...

感谢A5大佬解惑!
话说A5大佬知识是真的丰富,我也怀疑是我的显卡的因素,显卡的CUDA加速器个数、寄存器、共享内存等方面限制了这方面。没想到A5大佬当年就已经有过类似方面的体验了啊!
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 05:40 , Processed in 0.040158 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表