求矩阵每行的和?

  可以把每行放入一个不同线程块,这样行与行之间进行粗粒度的并行。而对于每行,其对应的线程块中分配n个线程(对应行宽),使用共享存储器,让每个线程从显存中读取一个数至shared memory中,然后使用规约算法计算和。

代码如下:

#include "cuda_runtime.h" //CUDA运行时API
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h> cudaError_t addWithCuda(int mat[][], int *ans, dim3 d); __global__ void addKernel(int *mat, int *ans, size_t pitch)
{
int bid = blockIdx.x;
int tid = threadIdx.x;
__shared__ int data[];
int *row = (int*)((char*)mat + bid*pitch);
data[tid] = row[tid];
__syncthreads();
for (int i = ; i > ; i /= ) {
if (tid < i)
data[tid] = data[tid] + data[tid + i];
__syncthreads();
}
if (tid == )
ans[bid] = data[];
} int main()
{
const int row = ;
const int col = ;
dim3 d(col, row);
int mat[row][col] = { ,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,, };
int ans[row];
// Add vectors in parallel.
cudaError_t cudaStatus = addWithCuda(mat, ans, d);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "addWithCuda failed!\n");
return ;
}
// cudaThreadExit must be called before exiting in order for profiling and
// tracing tools such as Nsight and Visual Profiler to show complete traces.
cudaStatus = cudaThreadExit();
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaThreadExit failed!");
return ;
}
for (int i = ; i < d.y; i++)
{
std::cout << ans[i] << " ";
}
return ;
} // 重点理解这个函数
cudaError_t addWithCuda(int mat[][], int *ans, dim3 d)
{
int *dev_mat = ; //GPU设备端数据指针
int *dev_ans = ;
int pitch;
cudaError_t cudaStatus; //状态指示
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(); //选择运行平台
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
goto Error;
}
// 分配GPU设备端内存
cudaStatus = cudaMallocPitch((void**)&dev_mat, (size_t *)&pitch, d.x * sizeof(int), d.y);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMalloc failed!\n");
goto Error;
}
cudaStatus = cudaMalloc((void**)&dev_ans, d.y * sizeof(int));
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMalloc failed!\n");
goto Error;
}
// 拷贝数据到GPU
cudaStatus = cudaMemcpy2D(dev_mat, pitch, mat, d.x*sizeof(int), d.x*sizeof(int), d.y, cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy for dev_mat failed!\n");
goto Error;
}
cudaStatus = cudaMemcpy(dev_ans, ans, d.y * sizeof(int), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy for dev_ans failed!\n");
goto Error;
}
// 运行核函数
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, );
addKernel<<<d.y,d.x>>>(dev_mat, dev_ans, pitch);
//addKernel_thd << <1, size >> >(dev_c, dev_a, dev_b); cudaEventRecord(stop, );
cudaEventSynchronize(stop);
float tm;
cudaEventElapsedTime(&tm, start, stop);
printf("GPU Elapsed time:%.6f ms.\n", tm);
// cudaThreadSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaThreadSynchronize(); //同步线程
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaThreadSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
goto Error;
}
// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(ans, dev_ans, d.y * sizeof(int), cudaMemcpyDeviceToHost); //拷贝结果回主机
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}
Error:
cudaFree(dev_mat); //释放GPU设备端内存
cudaFree(dev_ans);
return cudaStatus;
}

CUDA -- 规约求矩阵的行和的更多相关文章

  1. POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)

    求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...

  2. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)

    做这道题之前,建议先做POJ 1151  Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...

  3. MATLAB中求矩阵非零元的坐标

    MATLAB中求矩阵非零元的坐标: 方法1: index=find(a); [i,j]=ind2sub(size(a),index); disp([i,j]) 方法2: [i,j]=find(a> ...

  4. POJ 1151 Atlantis 求矩阵面积并 扫描线 具体解释

    题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092 ...

  5. 求矩阵中各列数字的和 Exercise08_01

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵中各列数字的和 * */ public class Exercise ...

  6. 求矩阵主对角线元素的和 Exercise08_02

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵主对角线元素的和 * */ public class Exercis ...

  7. matlab求矩阵、向量的模

    求矩阵的模: function count = juZhenDeMo(a,b) [r,c] = size(a);%求a的行列 [r1,c1] = size(b);%求b的行列 count = 0; f ...

  8. JAVA 基础编程练习题29 【程序 29 求矩阵对角线之和】

    29 [程序 29 求矩阵对角线之和] 题目:求一个 3*3 矩阵对角线元素之和 程序分析:利用双重 for 循环控制输入二维数组,再将 a[i][i]累加后输出. package cskaoyan; ...

  9. 市场清仓价格算法 python求矩阵不同行不同列元素和的最大值

    问题描述 求矩阵不同行不同列元素和的最大值(最小值) 问题求解 1.通过scipy库求解 scipy.optimize库中的linear_sum_assignment方法可以求解 输入一个矩阵,参数m ...

随机推荐

  1. Rewrite基本概述

    Rewrite基本概述 什么是rewrite Rewrite主要实现url地址重写,以及重定向,就是把传入web的请求重定向到其他url的过程. rewrite使用场景 1.地址跳转,用户访问www. ...

  2. Linux数据库的创建 导入导出 以及一些基本指令

    首先linux 下查看mysql相关目录 查看 mysql 的安装路径 执行查询 SQL mysql>show variables like '%dir%'; datadir 就是数据路径 确定 ...

  3. Python对MySql增删改查

    pip install pymysql import pymysql db_config = { 'host': '127.0.0.1(ip)', 'port': 3306, 'user': '账号' ...

  4. Educational Codeforces Round 71 (Rated for Div. 2)

    传送门 A.There Are Two Types Of Burgers 签到. B.Square Filling 签到 C.Gas Pipeline 每个位置只有"高.低"两种状 ...

  5. 201871010123-吴丽丽《面向对象程序设计(Java)》第一周学习总结

                                                                            201871010123-吴丽丽<面向对象程序设计 ...

  6. mysql导出数据的几种形式-待更新

    1.导出某个数据库的某张表,添加where条件 mysqldump -u [用户名] -p  -h [ip地址]  --default-character-set=utf8 [数据库名] [表名] - ...

  7. Linux 的 Crond(二)

    最近由于工作中用到了crond,之前对crond不是很了解,只知道咋用,但是这次需要考虑好多情况,所以又深入了解了一下crond,下面就以下几个问题来谈谈crond. crond 中指定的job,如果 ...

  8. CF732D Exams

    这题可以用二分答案来做 那么为什么可以用二分答案呢? 答案当然是满足了单调性. 假设用\(x\)天能够考完所有试,那么用大于$x $天必定也能够考完所有试,所以满足了单调性,我们就可以二分答案 那么如 ...

  9. 曾Python培训讲师-2年Python开发无包装简历-20191217-可公开

    目录 个人介绍 技能介绍 项目经历 自我评价 简历非完整版,需要完整版看下述信息,禁止任何一切私人用途.转发 我生日是27号,那就27元一份,有需求的来购买!只会涨价不会降价,大概卖10份涨1元:曾P ...

  10. NumPy 学习 第二篇:索引和切片

    数组索引是指使用中括号 [] 来定位数据元素,不仅可以定位到单个元素,也可以定位到多个元素.索引基于0,并接受从数组末尾开始索引的负索引. 举个例子,正向索引从0开始,从数组开始向末尾依次加1递增:负 ...