0_Simple__simpleTemplates + 0_Simple__simpleTemplates_nvrtc
使用 C++ 的模板
▶ 源代码:静态使用
// sharedmem.cuh
#ifndef _SHAREDMEM_H_
#define _SHAREDMEM_H_ // SharedMemory 的封装
template <typename T> struct SharedMemory
{
__device__ T *getPointer()
{
extern __device__ void error(void);
error();
return NULL;
}
}; // SharedMemory 的各种数据类型的实现
template <> struct SharedMemory <int>
{
__device__ int *getPointer()
{
extern __shared__ int s_int[];
return s_int;
}
}; template <> struct SharedMemory <unsigned int>
{
__device__ unsigned int *getPointer()
{
extern __shared__ unsigned int s_uint[];
return s_uint;
}
}; template <> struct SharedMemory <char>
{
__device__ char *getPointer()
{
extern __shared__ char s_char[];
return s_char;
}
}; template <> struct SharedMemory <unsigned char>
{
__device__ unsigned char *getPointer()
{
extern __shared__ unsigned char s_uchar[];
return s_uchar;
}
}; template <> struct SharedMemory <short>
{
__device__ short *getPointer()
{
extern __shared__ short s_short[];
return s_short;
}
}; template <> struct SharedMemory <unsigned short>
{
__device__ unsigned short *getPointer()
{
extern __shared__ unsigned short s_ushort[];
return s_ushort;
}
}; template <> struct SharedMemory <long>
{
__device__ long *getPointer()
{
extern __shared__ long s_long[];
return s_long;
}
}; template <> struct SharedMemory <unsigned long>
{
__device__ unsigned long *getPointer()
{
extern __shared__ unsigned long s_ulong[];
return s_ulong;
}
}; template <> struct SharedMemory <bool>
{
__device__ bool *getPointer()
{
extern __shared__ bool s_bool[];
return s_bool;
}
}; template <> struct SharedMemory <float>
{
__device__ float *getPointer()
{
extern __shared__ float s_float[];
return s_float;
}
}; template <> struct SharedMemory <double>
{
__device__ double *getPointer()
{
extern __shared__ double s_double[];
return s_double;
}
}; #endif
// simpleTemplates.cu
#include <stdio.h>
#include <timer.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <helper_functions.h>
#include <helper_cuda.h>
#include "sharedmem.cuh" template<class T> __global__ void testKernel(T *g_idata, T *g_odata)
{
SharedMemory<T> smem;
T *sdata = smem.getPointer();
// 以上两行结合,等效于 extern __shared__ T sdata[];
const unsigned int tid = threadIdx.x; sdata[tid] = g_idata[tid];
__syncthreads();
sdata[tid] = (T) blockDim.x * sdata[tid];
__syncthreads();
g_odata[tid] = sdata[tid];
} template<class T> void computeGold(T *reference, T *idata, const unsigned int len)// 生成理论结果数据
{
const T T_len = static_cast<T>(len);// 强制类型转换(const unsigned int -> T),并加上 const 限定
for (unsigned int i = ; i < len; ++i)
reference[i] = idata[i] * T_len;
} // ArrayComparator 的封装
template<class T> class ArrayComparator
{
public:
bool compare(const T *reference, T *data, unsigned int len)
{
fprintf(stderr, "Error: no comparison function implemented for this type\n");
return false;
}
};
// int 和 flaot 的实现,其中的函数 compareData() 定义于 helper_image.h
template<> class ArrayComparator<int>
{
public:
bool compare(const int *reference, int *data, unsigned int len) { return compareData(reference, data, len, 0.15f, 0.0f); }
}; template<> class ArrayComparator<float>
{
public:
bool compare(const float *reference, float *data, unsigned int len) { return compareData(reference, data, len, 0.15f, 0.15f); }
}; // ArrayFileWriter 的封装
template<class T> class ArrayFileWriter
{
public:
bool write(const char *filename, T *data, unsigned int len, float epsilon)
{
fprintf(stderr, "Error: no file write function implemented for this type\n");
return false;
}
};
// int 和 flaot 的实现,其中的函数 sdkWriteFile() 定义于 helper_image.h
template<> class ArrayFileWriter<int>
{
public:
bool write(const char *filename, int *data, unsigned int len, float epsilon) { return sdkWriteFile(filename, data, len, epsilon, false); }
}; template<> class ArrayFileWriter<float>
{
public:
bool write(const char *filename, float *data, unsigned int len, float epsilon) { return sdkWriteFile(filename, data, len, epsilon, false); }
}; template<class T> bool test(int len)
{
unsigned int mem_size = sizeof(T) * len;
dim3 grid(, , );
dim3 threads(len, , );
ArrayComparator<T> comparator;
ArrayFileWriter<T> writer;
cudaSetDevice();
StartTimer(); // 申请内存
T *h_idata, *h_odata, *d_idata, *d_odata;
h_idata = (T *)malloc(mem_size);
h_odata = (T *)malloc(mem_size);
cudaMalloc((void **)&d_idata, mem_size);
cudaMalloc((void **)&d_odata, mem_size);
for (unsigned int i = ; i < len; ++i)
h_idata[i] = (T) i;
cudaMemcpy(d_idata, h_idata, mem_size, cudaMemcpyHostToDevice); // 计算和计时
testKernel<T> << < grid, threads, mem_size >> > (d_idata, d_odata);
cudaMemcpy(h_odata, d_odata, sizeof(T) * len, cudaMemcpyDeviceToHost);
printf("\n\tProcessing time: %f ms\n", GetTimer()); // 检查结果
computeGold<T>(h_idata, h_idata, len);// 生成理论结果数据
bool result = comparator.compare(h_idata, h_odata, len);
//writer.write("./data/regression.dat", h_odata, num_threads, 0.0f);// 写入文件的部分 free(h_idata);
free(h_odata);
cudaFree(d_idata);
cudaFree(d_odata);
return result;
} int main()
{
printf("\n\tStart.\n");
printf("\n\t> test<float, 32>, result: %s.\n", test<float>() ? "Passed" : "Failed");
printf("\n\t> test<float, 64>, result: %s.\n", test<float>() ? "Passed" : "Failed"); getchar();
return ;
}
▶ 输出结果:
Start.
Processing time: 107.394216 ms
> test<float, >, result: Passed.
Processing time: 3.153182 ms
> test<float, >, result: Passed.
▶ 源代码:使用运行时编译
// sharedmem.cuh,与静态完全相同
// simpleTemplates_kernel.cu
#include "sharedmem.cuh" template<class T> __global__ void testKernel(T *g_idata, T *g_odata)
{
SharedMemory<T> smem;
T *sdata = smem.getPointer();
// 以上两行结合,等效于 extern __shared__ T sdata[];
const unsigned int tid = threadIdx.x; sdata[tid] = g_idata[tid];
__syncthreads();
sdata[tid] = (T)blockDim.x * sdata[tid];
__syncthreads();
g_odata[tid] = sdata[tid];
} extern "C" __global__ void testFloat(float *p1, float *p2) { testKernel<float>(p1, p2); } extern "C" __global__ void testInt(int *p1, int *p2) { testKernel<int>(p1, p2); }
// simpleTemplates.cpp
#include <stdio.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <helper_functions.h>
#include <nvrtc_helper.h>
#include <timer.h> template<class T> void computeGold(T *reference, T *idata, const unsigned int len)// 生成理论结果数据
{
const T T_len = static_cast<T>(len);// 强制类型转换(const unsigned int -> T),并加上 const 限定
for (unsigned int i = ; i < len; ++i)
reference[i] = idata[i] * T_len;
} // ArrayComparator 的封装
template<class T> class ArrayComparator
{
public:
bool compare(const T *reference, T *data, unsigned int len)
{
fprintf(stderr, "Error: no comparison function implemented for this type\n");
return false;
}
};
// int 和 flaot 的实现,其中的函数 compareData() 定义于 helper_image.h
template<> class ArrayComparator<int>
{
public:
bool compare(const int *reference, int *data, unsigned int len) { return compareData(reference, data, len, 0.15f, 0.0f); }
}; template<> class ArrayComparator<float>
{
public:
bool compare(const float *reference, float *data, unsigned int len) { return compareData(reference, data, len, 0.15f, 0.15f); }
}; // ArrayFileWriter 的封装
template<class T> class ArrayFileWriter
{
public:
bool write(const char *filename, T *data, unsigned int len, float epsilon)
{
fprintf(stderr, "Error: no file write function implemented for this type\n");
return false;
}
};
// int 和 flaot 的实现,其中的函数 sdkWriteFile() 定义于 helper_image.h
template<> class ArrayFileWriter<int>
{
public:
bool write(const char *filename, int *data, unsigned int len, float epsilon) { return sdkWriteFile(filename, data, len, epsilon, false); }
}; template<> class ArrayFileWriter<float>
{
public:
bool write(const char *filename, float *data, unsigned int len, float epsilon) { return sdkWriteFile(filename, data, len, epsilon, false); }
}; // getKernel 的模板
template <typename T> CUfunction getKernel(CUmodule in); template<> CUfunction getKernel<int>(CUmodule in)
{
CUfunction kernel_addr;
cuModuleGetFunction(&kernel_addr, in, "testInt");
return kernel_addr;
} template<> CUfunction getKernel<float>(CUmodule in)
{
CUfunction kernel_addr;
cuModuleGetFunction(&kernel_addr, in, "testFloat");
return kernel_addr;
} template<class T> bool test(int len)
{
// 与静态不同,编译 PTX
char *kernel_file = "D:\\Program\\CUDA9.0\\Samples\\0_Simple\\simpleTemplates_nvrtc\\simpleTemplates_kernel.cu";
char *ptx;
size_t ptxSize;
compileFileToPTX(kernel_file, , NULL, &ptx, &ptxSize, ); // 1, NULL 分别为 argc 和 argv
CUmodule module = loadPTX(ptx, , NULL); // 1, NULL 分别为 argc 和 argv,有关于 GPU的输出 unsigned int mem_size = sizeof(T) * len;
dim3 grid(, , );
dim3 threads(len, , );
ArrayComparator<T> comparator;
ArrayFileWriter<T> writer;
StartTimer(); // 申请内存
T *h_idata, *h_odata;
CUdeviceptr d_idata, d_odata; // 与静态不同
h_idata = (T *)malloc(mem_size);
h_odata = (T *)malloc(mem_size);
cuMemAlloc(&d_idata, mem_size); // 与静态不同
cuMemAlloc(&d_odata, mem_size);
for (unsigned int i = ; i < len; ++i)
h_idata[i] = (T)i;
cuMemcpyHtoD(d_idata, h_idata, mem_size); // 与静态不同 // 计算和计时
CUfunction kernel_addr = getKernel<T>(module); void *arr[] = { (void *)&d_idata, (void *)&d_odata };
cuLaunchKernel(kernel_addr, grid.x, grid.y, grid.z, threads.x, threads.y, threads.z, mem_size, , &arr[], );
cuCtxSynchronize(); // 上下文同步
cuMemcpyDtoH(h_odata, d_odata, sizeof(T) * len);// 与静态不同
printf("\n\tProcessing time: %f ms\n", GetTimer()); // 检查结果
computeGold<T>(h_idata, h_idata, len);// 生成理论结果数据
bool result = comparator.compare(h_idata, h_odata, len);
//writer.write("./data/regression.dat", h_odata, len, 0.0f);// 写入文件的部分 free(h_idata);
free(h_odata);
cuMemFree(d_idata); // 与静态不同
cuMemFree(d_odata);
return result;
} int main()
{
printf("\n\tStart.\n");
printf("\n\t> test<float, 32>, result: %s.\n", test<float>() ? "Passed" : "Failed");
printf("\n\t> test<int, 64>, result: %s.\n", test<int>() ? "Passed" : "Failed"); getchar();
return ;
}
▶ 输出结果:
Start.
> Using CUDA Device []: GeForce GTX
> GPU Device has SM 6.1 compute capability Processing time: 0.699976 ms > test<float, >, result: Passed.
> Using CUDA Device []: GeForce GTX
> GPU Device has SM 6.1 compute capability Processing time: 0.665355 ms > test<int, >, result: Passed.
▶ 涨姿势
● 封装了 SharedMemory,ArrayComparator,ArrayFileWriter 三个模板,并定义了其在不同的数据类型下的实现。
0_Simple__simpleTemplates + 0_Simple__simpleTemplates_nvrtc的更多相关文章
随机推荐
- Codeforces gym101955 A【树形dp】
LINK 有n个大号和m个小号 然后需要对这些号进行匹配,一个大号最多匹配2个小号 匹配条件是大号和小号构成了前缀关系 字符串长度不超过10 问方案数 思路 因为要构成前缀关系 所以就考虑在trie树 ...
- 通过torodb && hasura graphql 让mongodb 快速支持graphql api
torodb 可以方便的将mongo 数据实时同步到pg,hasura graphql 可以方便的将pg 数据暴露为graphql api,集成在一起真的很方便 环境准备 docker-compose ...
- statik golang 静态资源嵌入二进制文件工具使用(docker 构建)
将静态资源打包进二进制文件有好多方便的地方 方便客户演示 代码简单加密 运行方便 statik 就是一款在golang 中用的比较多,nodejs 有一款pkg (oclif 就推荐使用此工具) ...
- HTML图片热区map area的用法
<area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: < ...
- tomcat源码阅读之SingleThreadModel
一.接口简介: 实现了SingleThreadModel接口的servlet类只能保证在同一时刻,只有一个线程执行该servlet实例的service方法,在tomcat实现中会创建多个servlet ...
- Mybatis连接Oracle实现增删改查实践
1. 首先要在项目中增加Mybatis和Oracle的Jar文件 这里我使用的版本为ojdbc7 Mybatis版本为:3.2.4 2. 在Oracle中创建User表 create table T_ ...
- JZ2440 裸机驱动 第14章 ADC和触摸屏接口
本章目标: 了解S3C2410/S3C2440和触摸屏的结构: 了解电阻触摸屏的工作原理和等效电路图: 了解S3C2410/S3C2440触摸屏控制器的多种工作模式: ...
- ML(5):KNN算法
K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,可以简单的理解为由那离自己最近的K个点来投票决定待分类数据归为哪一类.这个算法是机器学习里面一个比较经典的算法, ...
- C# 教程
http://www.runoob.com/csharp/csharp-tutorial.html
- charles只获取指定的请求的设置方法
过滤网络请求 通常情况下,需要对网络请求进行过滤,只监控指定服务器的请求.有3种办法: 方法一:在主界面的中部的 Filter 栏中输入需要过滤出来的关键字.例如我们的服务器的地址(host)是:ww ...