玩玩CUBLAS(2)——level1函数

转载请注明出处:http://blog.csdn.net/bendanban/article/details/8893944

/*=======================================================================

* 第二天了,打算弄完这个去吃劈柴院的灌汤包,海上起雾了,要是不冷了,去趟只听过没去过的栈桥

* 金刚狼3上映有一段时间了吧,晚上去尝尝。。

=======================================================================*/

我看过cublas的说明文档,它在讲解的时候先从总体上说明cublas的基本存储规则,所以这里,我说几点,这些内容将在实践中具体练习。


2.1 实践之前的cublas几点说明

  • cublas实现三个级别的BLAS(Basic Linear Algebra Subprograms)的函数功能,关于BLAS的说明,大家可以在这里找到。
  • 本节中讲述blas1中的某个函数的使用。
  • cublas接受的参数,按照存储地点分,有三种:设备上,主机上,设备或者主机上。按照数学类型分:标量(对应单变量,常量),向量(对应数组),矩阵(对应数组)。
  • cublas中向量,矩阵从1开始索引。这点要注意的是,cublas自己的函数这样实现,我们自己的数据还是按照自己的语言标准来做的,就是说,你用C语言的数组,还是从0开始,但是用cublas库的时候,库本身自己从1开始。


2.2 环境额外配置

上一篇中介绍了如何配置cublas的编译环境,不过要使用cublas,还需要cuda的runtime支持,所以你需要在链接器的依赖项中添加cudart.lib的额外依赖。具体添加方法,与上一篇中方法类似,不再赘述。

另外,源码中使用cuda runtime函数的文件中要添加#include “cuda_runtime.h”


2.3 实验函数说明

今天我们要实验的库函数是cublasIsamax(...),它要实现的功能是获得某个向量中第一个最大模的索引号,注意这个索引号是从1开始的。

函数原型是:cublasStatus_t cublasIsamax(cublasHandle_t handle, int n, const float *x, int incx, int *result)

参数说明:

  • 返回值,包含函数的错误代码,这是个枚举类型,值为CUBLAS_STATUS_SUCCESS时,时正常,否则说明发生了错误。
  • handle,表示是cublas的上下文句柄。由cublasStatus_t cublasCreate(cublasHandle_t *handle)函数创建,由cublasStatus_t cublasDestroy(cublasHandle_t handle)释放。
  • n,表示向量x中要索引的元素的总个数。
  • x,向量x。他的存储必须存储在GPU上
  • incx,要索引的x中元素的增量。
  • result,存放结果。他的存储可以在CPU上也可以在GPU上
数学上解释下算法:

此函数返回第一个i,使得 |Im(x[j])| + |Re(x[j])| 为最大值,其中i=1,...,n,并且,j=1 + (i-1)*incx.


2.4 基本实验

代码我贴在了下面

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "cuda_runtime.h"
#include "cublas_v2.h"
#define DATA_SIZE 1024

#define CUBLAS_ERROR_CHECK(sdata) if(CUBLAS_STATUS_SUCCESS!=sdata){printf("ERROR at:%s:%d\n",__FILE__,__LINE__);exit(-1);}

void InitVector(float *vec, int n, int down, int up)
{
	int i;
	srand((unsigned int)time(NULL));
	for (i = 0; i < n; i++)
	{
		vec[i] = (float)(rand()%(up-down+1)+down);
	}
	return ;
}
void myIsamax(int n, float *x, int incx, int *result)
{
	int i = 0;
	*result = 0;
	for (i = 1; i < n; i+=incx)
	{
		if(x[i]>x[*result]) *result=i; 
	}
}
int main(int argc, char **argv)
{
	cublasHandle_t cubhandle;
	cublasStatus_t cubStatus = CUBLAS_STATUS_SUCCESS;

	float *h_datax;
	float *d_datax;
	int    h_result;
	int    d_result;
	int    data_size = DATA_SIZE;
	
	// initialize cublas resource
	cubStatus = cublasCreate(&cubhandle); CUBLAS_ERROR_CHECK(cubStatus)

	// allocate memory CPU + GPU
	h_datax = (float*)malloc(data_size*sizeof(float));
	cudaMalloc((void**)&d_datax, data_size*sizeof(float));

	// initialize cpu memory
	InitVector(h_datax, data_size, 0, 100);

	// copy cpu value to gpu memory
	cubStatus = cublasSetVector(data_size, sizeof(float), h_datax, 1, d_datax, 1);
	CUBLAS_ERROR_CHECK(cubStatus)
	
	// execute GPU version
	cubStatus = cublasIsamax(cubhandle, data_size, d_datax, 1, &d_result); CUBLAS_ERROR_CHECK(cubStatus)
	// execute CPU version

	myIsamax(data_size, h_datax, 1, &h_result);


	printf("host   : h_datax[%d]=%.2f\n", h_result, h_datax[h_result]);
	printf("device : d_datax[%d]=%.2f\n", d_result-1, h_datax[d_result-1]);


	// Free memory
	free(h_datax);h_datax=0x0;
	cudaFree(d_datax);d_datax=0x0;

	cublasDestroy(cubhandle);
	getchar();
	return 0;
}


总结

为尽之处,欢迎大家批评指针。







你可能感兴趣的:(CUDA,VS2010,cublas)