CUDA学习之一:二维矩阵加法

  今天忙活了3个小时,竟然被一个苦恼的CUDA小例程给困住了,本来是参照Rachal zhang大神的CUDA学习笔记来一个模仿,结果却自己给自己糊里糊涂,最后还是弄明白了一些。

  RZ大神对CUDA关于kernel,memory的介绍还是蛮清楚,看完决定写一个二维数组的加法。如果是C++里的加法,那就简单了,用C[i][j] = A[i][j] +B[i][j]就可以。

1 void CppMatAdd(int A[M][N],int B[M][N],int C[M][N]){
2     for(int i=0;i<M;i++)
3         for(int j=0;j<N;j++)
4             C[i][j] = A[i][j] + B[i][j];
5 }
1 int main()
2 {
3     int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
4     int b[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
5     int c[M][N] ;
6         CppMatAdd(a,b,c);
7     std::cout<<c[0][0];
8 } 

运行上面代码,就可以实现二维矩阵(也就是数组)的加法运算。

但是CUDA计算是在GPU上实现的,要划分出专门的内存区域给GPU做运算,结果就是,我们必须划分出主机内存、设备内存分别供CPU、GPU访问。

对于一维的情况,我们设置好主机变量,设备变量即可。具体可以参找RZ的博客。

但是二维的情况麻烦就来了,最一开始我也是设置出主机变量,设备变量,一一对应的分配内存,拷贝数据,GPU运算,最后考出结果。但是发现怎么调试结果都不对,最主要的原因是c++的二维数组实际上是一维数组的指针,所以,无法按照一位数组的模式去拷贝数据,结果相映的写法就麻烦许多,其实说到底还是还原成一维数组的方法去做的加法运算,代码如下,具体就不想赘述了,代码能力有限,慢慢来吧,今天算是把指针弄的更清楚了。

/*--------------------------------------------
* Date:2015-3-18
* Author:李根
* FileName:.cpp
* Description:CUDA二维数组加法
------------------------------------------------*/
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h>

static const int M = 4;
static const int N = 3;

//矩阵加法的kernel
__global__ void addMat(int **A,int **B,int **C)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    int j = blockIdx.y * blockDim.y + threadIdx.y;
    if(i < M && j < N)
        C[i][j] = A[i][j] + B[i][j];
}

int main()
{int **A = (int **)malloc(M*sizeof(int *));  //host memory
    int **B = (int **)malloc(M*sizeof(int *));  //host memory
    int **C = (int **)malloc(M*sizeof(int *));  //host memory
    int *dataA =(int *)malloc(M*N*sizeof(int )); //host memory data
    int *dataB = (int *)malloc(M*N*sizeof(int )); //host memory data
    int *dataC =(int *)malloc(M*N*sizeof(int )); //host memory data

    int **dev_A ;  //device memory
    int **dev_B ;  //device memory
    int **dev_C ;  //device memory
    int *dev_dataA ;  //device memory  data
    int *dev_dataB ;  //device memory  data
    int *dev_dataC ;  //device memory  data

    cudaMalloc((void**)(&dev_A), M*sizeof(int*));
    cudaMalloc((void**)(&dev_dataA), M*N*sizeof(int));
    cudaMalloc((void**)(&dev_B), M*sizeof(int*));
    cudaMalloc((void**)(&dev_dataB), M*N*sizeof(int));
    cudaMalloc((void**)(&dev_C), M*sizeof(int*));
    cudaMalloc((void**)(&dev_dataC), M*N*sizeof(int));

    for(int i=0;i<M*N;i++)
    {
        dataA[i] = i;
        dataB[i] = i+1;
        dataC[i] =0;
    }

    cudaMemcpy((void*)(dev_dataA), (void*)(dataA), M*N*sizeof(int*), cudaMemcpyHostToDevice);
    cudaMemcpy((void*)(dev_dataB), (void*)(dataB), M*N*sizeof(int*), cudaMemcpyHostToDevice);

    for(int i=0;i<M;i++)
    {
        A[i] = dev_dataA + N*i;
        B[i] = dev_dataB + N*i;
        C[i] = dev_dataC + N*i;
    }

    cudaMemcpy((void*)(dev_A), (void*)(A), M*sizeof(int*), cudaMemcpyHostToDevice);
    cudaMemcpy((void*)(dev_B), (void*)(B), M*sizeof(int*), cudaMemcpyHostToDevice);
    cudaMemcpy((void*)(dev_C), (void*)(C), M*sizeof(int*), cudaMemcpyHostToDevice);

    dim3 threadPerBlock(16,16);
    dim3 numBlocks((N+threadPerBlock.x-1)/(threadPerBlock.x), (M+threadPerBlock.y-1)/(threadPerBlock.y));
    addMat<<<numBlocks,threadPerBlock>>>(dev_A,dev_B,dev_C);
    cudaMemcpy((void*)(dataC), (void*)(dev_dataC), M*N*sizeof(int), cudaMemcpyDeviceToHost);
    for(int i=0;i<M*N;i++)
        std::cout<<dataC[i]<<" ";
    cudaFree((void*)dev_dataC);
    cudaFree((void*)dev_C);
    free(C);
    free(dataC);
    cudaFree((void*)dev_dataB);
    cudaFree((void*)dev_B);
    free(B);
    free(dataB);
    cudaFree((void*)dev_dataA);
    cudaFree((void*)dev_A);
    free(A);
    free(dataA);
    getchar();
}

博客恢复更新,慢慢的积累吧

时间: 2024-10-27 16:57:29

CUDA学习之一:二维矩阵加法的相关文章

【LeetCode-面试算法经典-Java实现】【074-Search a 2D Matrix(搜索二维矩阵)】

[074-Search a 2D Matrix(搜索二维矩阵)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right. The first

lintcode 容易题:Search a 2D Matrix 搜索二维矩阵

题目: 搜索二维矩阵 写出一个高效的算法来搜索 m × n矩阵中的值. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每行的第一个数大于上一行的最后一个整数. 样例 考虑下列矩阵: [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] 给出 target = 3,返回 true 挑战 O(log(n) + log(m)) 时间复杂度 解题: 1.最简单的方法就是遍历整个矩阵,时间复杂度:O(log(mn)),这个应该等于O(long(

二维矩阵卷积运算实现

http://z.download.csdn.net/detail/wangfei0117/4408649 http://download.csdn.net/detail/wanwenliang2008/1767686 二维矩阵卷积运算实现,布布扣,bubuko.com

lintcode 中等题:search a 2d matrix II 搜索二维矩阵II

题目 搜索二维矩阵 II 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每一列的整数从上到下是排序的. 在每一行或每一列中没有重复的整数. 样例 考虑下列矩阵: [     [1, 3, 5, 7],     [2, 4, 7, 8],     [3, 5, 9, 10] ] 给出target = 3,返回 2 挑战 要求O(m+n) 时间复杂度和O(1) 额外空间 解题 直接遍历,时间复杂度是O(MN) public

20140920百度笔试题一道之二维矩阵查找

题目: 有这样一个二维矩阵A[N][N],满足j < k时, 1)a[i][j] < a[i][k]; 2)a[j][i] < a[k][i](其实就数据从左上角到右下角纵横方向上都递减),给定一个数target,如何快速搜索是否在这个矩阵中,是的话输出二维坐标,否则输出Null:(不妨假设数据不重复) 比如  12  34  56  78  90  96 13  35  57  79  91  97 14  36  58  80  93  98 15  37  59  81  94  

search-a-2d-matrix——二维矩阵找数

题目描述 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right. The first integer of each row is greater than the last integer of the previo

关于有序二维矩阵查找和字符串替换的两道算法题

最近看一本书上写到的两个面试题 于是实现了一下 感觉思路很好,大牛略过 : 1.对于一个二维矩阵,从左到右  从上到下 都是递增的,如何判断一个值是否在矩阵内部?(C实现  实现复杂度 O(n)) bool FindInTwoDimensionalMatrix(int*pMatrix,int iRows,int iCols,int iFindVal) { bool bFind=false ; if(pMatrix==0||iRows<=0||iCols<=0) return bFind ; i

[LeetCode] Search a 2D Matrix II 搜索一个二维矩阵之二

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted in ascending from left to right. Integers in each column are sorted in ascending from top to bottom.

lintcode 搜索二维矩阵

题目:搜索二维矩阵 描述: 写出一个高效的算法来搜索 m × n矩阵中的值. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每行的第一个数大于上一行的最后一个整数. 样例 考虑下列矩阵: [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] 给出 target = 3,返回 true ------------------------------------------- 开始用两个二分搜索,先找列,再找行.运行后提示超时... 1 c