編譯運(yùn)行Hello!
Hello!
編譯運(yùn)行Vadd表悬!
實(shí)驗(yàn)于虛擬機(jī)上運(yùn)行,因此OpenCL運(yùn)行時(shí)間實(shí)際不如CPU串行快丧靡。
Vadd(Vecsize=6)
Vadd(Vecsize=10)
可通過定義print_vec來輸出向量查看
編寫矩陣乘法并運(yùn)行
基本思想:
暴力三重循環(huán)
C++
for ( i = 0; i < VECSIZE; i++)
{
for ( j = 0; j < VECSIZE; j++)
{
buf[i][j]=0;
for (int k = 0; k < VECSIZE; k++)
{
buf[i][j]+=buf1[i][k]*buf2[k][j];
}
}
}
OpenCL實(shí)現(xiàn)
繼續(xù)采集kernel的維數(shù)(這里為2)蟆沫,然后將兩個(gè)變量作為row和col放到原來的三重循環(huán)中并在函數(shù)調(diào)用中加入新參數(shù)W叉讥。在設(shè)置kernel參數(shù)時(shí)自然也要加上這個(gè)參數(shù)的設(shè)置。
__kernel void matrix(
__global float* c, __global const float* a, __global const float* b, int VECSIZE) {
int id0 = get_global_id(1);
int id1 = get_global_id(0);
printf("[%d , %d ]",get_global_id(1),get_global_id(0));
float tmp=0;
for (int k = 0;k<VECSIZE;k++)
{
tmp+=a[id0*VECSIZE+k]*b[k*VECSIZE+id1];
}
c[id0*VECSIZE+id1]=tmp;
//printf("OK\n");
}
數(shù)組升級(jí)到二維數(shù)組后對(duì)源代碼的調(diào)整
總的來講就是指針的加次
void showVec(const char* name , float** vec)
float** const buf1 = (float**)malloc(VECSIZE * sizeof(float*));
for(i=0;i<VECSIZE;i++) buf1[i]=(float*)malloc(VECSIZE * sizeof(float*));
與數(shù)量相關(guān)的由1變成2
//Set local and global workgroup sizes
size_t global_work_size[2] = {VECSIZE,VECSIZE};
//執(zhí)行kernel
status=clEnqueueNDRangeKernel(
queue , kernel,
2, 0, global_work_size,NULL,
0, NULL, &prof_event);
與空間有關(guān)的由W變成W*W饥追。
//創(chuàng)建三個(gè)OpenCL內(nèi)存對(duì)象
cl_mem clbuf1 = clCreateBuffer(context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
VECSIZE * VECSIZE * sizeof(cl_float), buf1,
NULL );
//設(shè)置Kernel參數(shù)
cl_int length = VECSIZE*VECSIZE;
//數(shù)據(jù)拷回host內(nèi)存
float* op_data = 0;
op_data = (cl_float*) clEnqueueMapBuffer( queue,
cloutbuf,
CL_TRUE,
CL_MAP_READ,
0,
VECSIZE * VECSIZE * sizeof(cl_float),
0, NULL, NULL, NULL );
結(jié)果
結(jié)果不盡人意图仓。C++的運(yùn)算結(jié)果應(yīng)該正確,然而GPU的結(jié)果不禁數(shù)據(jù)有問題但绕,而且有缺失救崔,具體情況為WW的數(shù)組中只有(W-2)(W-2)個(gè)數(shù)據(jù),即W=4時(shí)只采集到4個(gè)數(shù)據(jù)捏顺,W=6時(shí)只采集到16個(gè)數(shù)據(jù)六孵,等等。
實(shí)驗(yàn)結(jié)果1
后來我試著在kernel函數(shù)中輸出了get_global_id()幅骄,可以看出get_global_id(0)一直是0劫窒,而它理應(yīng)也有變化才能實(shí)現(xiàn)循環(huán),這是導(dǎo)致結(jié)果出錯(cuò)的原因拆座。我會(huì)早日解決之主巍。
實(shí)驗(yàn)結(jié)果2
實(shí)驗(yàn)結(jié)果3