0_Simple__simpleAssert + 0_Simple__simpleAssert_nvrtc
在核函数中使用强制终止函数 assert()。并且在静态代码和运行时编译两种条件下使用。
▶ 源代码:静态使用
#include <windows.h>
#include <stdio.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <helper_functions.h>
#include <helper_cuda.h> #define WINDOWS_LEAN_AND_MEAN
#define NOMINMAX __global__ void testKernel(int N)
{
int tid = blockIdx.x*blockDim.x + threadIdx.x ; // 检查条件为“线程总编号小于 N”,即阻塞不满足该条件的线程
// 阻塞的同时向屏幕输出阻塞线程的信息,包括核函数所在文件绝对路径、行号、线程块号,线程号,没有通过的检查条件
assert(tid < N) ;
} bool runTest()
{
// 使用2个线程块各32条线程,使用 assert() 阻塞最后 4 条(即第 1 线程块的第 29、30、31、32 号线程)
int Nblocks = ;
int Nthreads = ;
cudaError_t error ; dim3 dimGrid(Nblocks);
dim3 dimBlock(Nthreads);
testKernel<<<dimGrid, dimBlock>>>(); printf("\n-- Begin assert output\n\n");
error = cudaDeviceSynchronize(); // 使用设备同步来获取错误信息
printf("\n-- End assert output\n\n"); if (error == cudaErrorAssert) // 输出错误信息种类
printf("CUDA error message is: %s\n",cudaGetErrorString(error)); return error == cudaErrorAssert;
} int main()
{
bool testResult; printf("\n\tStarted!\n"); testResult = runTest(); printf("\n\tCompleted! main function returned %s\n", testResult ? "OK!" : "ERROR!");
getchar(); return ;
}
即时编译版:
/*simpleAssert_kernel.cu*/
extern "C" __global__ void testKernel(int N)
{
int tid = blockIdx.x*blockDim.x + threadIdx.x ;
assert(tid < N) ;
}
/*simpleAssert.cpp*/
#include <windows.h>
#include <stdio.h>
#include <cuda_runtime.h>
#include <helper_functions.h>
#include "nvrtc_helper.h" #define WINDOWS_LEAN_AND_MEAN
#define NOMINMAX bool runTest()
{
int Nblocks = ;
int Nthreads = ; // 紧张的 .cu 即时编译过程
char *kernel_file = sdkFindFilePath("simpleAssert_kernel.cu", NULL); char *ptx;
size_t ptxSize;
compileFileToPTX(kernel_file, , NULL, &ptx, &ptxSize); CUmodule module = loadPTX(ptx, , NULL); CUfunction kernel_addr;
cuModuleGetFunction(&kernel_addr, module, "testKernel"); dim3 dimGrid(Nblocks);
dim3 dimBlock(Nthreads);
int count = ;
void *args[] = { (void *)&count };
cuLaunchKernel(kernel_addr,dimGrid.x, dimGrid.y, dimGrid.z,dimBlock.x, dimBlock.y, dimBlock.z,,,&args[],); printf("\n-- Begin assert output\n\n");
CUresult res = cuCtxSynchronize(); // 用的是上下文同步?
printf("\n-- End assert output\n\n"); if (res == CUDA_ERROR_ASSERT)
printf("Device assert failed as expected\n"); return res == CUDA_ERROR_ASSERT ;
} int main()
{
bool testResult; printf("\n\tStarted!\n"); testResult = runTest(); printf("\n\tCompleted! main function returned %s\n", testResult ? "OK!" : "ERROR!");
getchar(); return ;
}
▶ 输出结果:
Started! -- Begin assert output D:/Program/CUDA/Samples/0_Simple/simpleAssert/simpleAssert.cu:: block: [,,], thread: [,,] Assertion `tid < N` failed.
D:/Program/CUDA/Samples/0_Simple/simpleAssert/simpleAssert.cu:: block: [,,], thread: [,,] Assertion `tid < N` failed.
D:/Program/CUDA/Samples/0_Simple/simpleAssert/simpleAssert.cu:: block: [,,], thread: [,,] Assertion `tid < N` failed.
D:/Program/CUDA/Samples/0_Simple/simpleAssert/simpleAssert.cu:: block: [,,], thread: [,,] Assertion `tid < N` failed. -- End assert output CUDA error message is: device-side assert triggered Completed! main function returned OK!
▶ 涨姿势:
● 在核函数中使用 assert( condition ) 来检查各线程中是否满足某条件。
若不满足条件 condition,则强制终止该线程,并输出核函数所在文件绝对路径、行号、线程块号,线程号,没有通过的检查条件
返回错误种类: cudaErrorAssert,错误代码 59,信息为 device-side assert triggered
cudaErrorAssert 为定义在 driver_type.h 中的枚举类型 enum __device_builtin__ cudaError{...}; 中,记录了各种错误信息。
● 调用核函数的另一种方法。使用定义在 cuda.h 中的函数 cuLaunchKernel。使用的参数与 <<< >>> 方式基本相同。
CUresult CUDAAPI cuLaunchKernel
(
CUfunction f,
unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ,
unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ,
unsigned int sharedMemBytes,
CUstream hStream,
void **kernelParams,
void **extra
);
● 两种方法使用的同步函数
静态方法时使用的是设备同步 extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaDeviceSynchronize(void);,定义在 cuda_runtime_api.h 中
即时编译时用的是上下文同步 CUresult CUDAAPI cuCtxSynchronize(void); ,定义在 cuda.h 中
尚不清楚两者的差别,等待填坑。
0_Simple__simpleAssert + 0_Simple__simpleAssert_nvrtc的更多相关文章
随机推荐
- NameError: name 'messagebox' is not defined 错误处理
写了段代码,想在按下button的时候跳个提示框出来,调试的时候提示了messagebox未定义 from tkinter import * def test_show(): messagebox.s ...
- M方法
ThinkPHP函数详解:M方法 M方法用于实例化一个基础模型类,和D方法的区别在于:1.不需要自定义模型类,减少IO加载,性能较好:2.实例化后只能调用基础模型类(默认是Model类)中的方法:3. ...
- HDFS源码分析之NameNode(2)————Format
在Hadoop的HDFS部署好了之后并不能马上使用,而是先要对配置的文件系统进行格式化.在这里要注意两个概念,一个是文件系统,此时的文件系统在物理上还不存在,或许是网络磁盘来描述会更加合适:二就是格式 ...
- ES中const
前 言 EScript 上一次总结了,ES中let和var的区别,今天在带大家了解另一个声明关键词:const. const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改 ...
- 【技巧】datagrid锁定列后重新加载时出现错位问题的解决
[问题描述]:有时候datagrid设置了锁定列后,在重新加载datagrid数据时,出现锁定列与非锁定列数据错位的问题,如图: [问题分析]:查看css样式我们发现,锁定的列和非锁定的列属于两个不同 ...
- Linux 独立安装subversion-1.8.18
一.所需软件包 1.apr-1.4.6.tar.gz 下载地址:http://apr.apache.org/ 2.apr-util-1.4.1.tar.gz 下载地址:http://apr.apa ...
- ThinkPHP中使用PHPMailer邮件类
第一步.添加PHPMailer类库将下载后的文件解压,将PHPMail目录移动至ThinkPHP目录中的Vendor内.(请确保class.phpmailer.php文件就在ThinkPHP\Vend ...
- 电脑IP地址被占用如何释放?
回车后,关机,等待5分钟左右再开机,就释放掉了.
- javascript数组的常用方法总结
http://jingyan.baidu.com/album/86fae346bce16d3c49121af9.html?picindex=1 1. concat()方法 数组和数组的 粘结: var ...
- java程序调用存储过程和存储函数
java程序调用存储过程 jdbcUtil.java文件 package cn.itcast.oracle.utils; import java.sql.Connection; import java ...