opencl小例子

#include "CL\opencl.h"
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include<string>
#include <fstream>
#include <istream>
#include <iostream>
#include <iterator>
#pragma comment(lib,"x86/OpenCL.lib")

char *Read(const char * path) {
	FILE * fp = NULL;
	fopen_s(&fp,path,"rb");
	if (fp == NULL) return NULL;
	fseek(fp,0,SEEK_END);
	long size = ftell(fp);
	fseek(fp,0,SEEK_SET);
	void *buf = malloc(size + 2);
	if (buf == NULL) return NULL;
	memset(buf,0,size+2);

	fread(buf,1,size,fp);
	fclose(fp);

	return (char*)buf;
}

cl_program CreateProgram(cl_context context,const char * file) {
	char * Source = Read(file);
	if (Source == NULL) return NULL;

	//std::fstream fileOpen("./Kernal1.cl");
	//std::string programString(std::istreambuf_iterator<char>(fileOpen), (std::istreambuf_iterator<char>()));
	//const char *programCodeSource = programString.c_str();

	cl_program program = clCreateProgramWithSource(context, 1, (const char **)&Source, NULL, NULL);
	if (program == NULL) return program;
	cl_int err = clBuildProgram(program, 0, 0, NULL, NULL, NULL);
	//cl_int err = clBuildProgram(program,1, &IDs[0],NULL,NULL,NULL);

	free(Source);

	if (err < 0) {
		size_t len = 0;
		clGetProgramBuildInfo(program, NULL, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
		if (len > 0) {
			char *buffer = (char*)malloc(len);
			clGetProgramBuildInfo(program, NULL, CL_PROGRAM_BUILD_LOG, len, buffer, &len);
			if (len > 0) {
				printf("BuildProgram:Error:%s\n", buffer);
			}
		}
		else {
			printf("BuildProgram:Error:%d\n", err);
		}

		clReleaseProgram(program);
		return NULL;
	}
	
	return program;
}

int Process(cl_context context, std::vector<cl_device_id> IDs) {
	cl_program program = CreateProgram(context, "./Kernal1.cl");
	if (program == NULL) return -1;

#define DATA_SIZE 10
	//内存参数
	std::vector<float> a(DATA_SIZE), b(DATA_SIZE);
	for (int i = 0; i < DATA_SIZE; i++) {
		a[i] = i;
		b[i] = i;
	}

	cl_int err = 0;
	//准备参数
	cl_mem cl_a = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * DATA_SIZE, &a[0], &err);
	cl_mem cl_b = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * DATA_SIZE, &b[0], &err);
	cl_mem cl_res = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_float) * DATA_SIZE, NULL, &err);
	//关联核参数
	cl_kernel adder = clCreateKernel(program, "hello_kernel", &err);
	err = clSetKernelArg(adder, 0, sizeof(cl_mem), &cl_a);
	err = clSetKernelArg(adder, 1, sizeof(cl_mem), &cl_b);
	err = clSetKernelArg(adder, 2, sizeof(cl_mem), &cl_res);

	cl_queue_properties properties = 0;
	//创建执行队列
	cl_command_queue cqueue = clCreateCommandQueueWithProperties(context, IDs[0], &properties, &err);
	if (cqueue != NULL) {
		//执行核
		cl_uint work_dims = 2;
		size_t global_work_offset[] = { 0 , 3};
		size_t global_work_size[] = { 2 , 2 };
		size_t local_work_size[] = { 2 , 1 };
		err = clEnqueueNDRangeKernel(cqueue, adder, work_dims, global_work_offset, global_work_size, local_work_size, 0, 0, 0);
		//拷贝结果
		std::vector<float> res(DATA_SIZE);
		err = clEnqueueReadBuffer(cqueue, cl_res, CL_TRUE, 0, sizeof(float) * DATA_SIZE, &res[0], 0, 0, 0);
		err = clFinish(cqueue);
	}
	//释放核
	clReleaseCommandQueue(cqueue);
	clReleaseMemObject(cl_a);
	clReleaseMemObject(cl_b);
	clReleaseMemObject(cl_res);

	clReleaseProgram(program);

	return 0;
}

int main() {
	cl_uint num = 0;
	cl_int err = clGetPlatformIDs(0,0,&num);
	if (err < 0) {
		return -1;
	}
	std::vector<cl_platform_id> platforms(num);
	err = clGetPlatformIDs(num,&platforms[0],&num);
	if (err < 0) {
		return -1;
	}

	printf("PlatformIDs:%d \n",num);

	cl_context context = NULL;
	cl_device_id id = NULL;
	std::vector<cl_device_id> deviceIDs;

	for (cl_int i = 0; i < num; i++) {
		printf("%s %d:\n", "PLATFORM",i);
		char buf[1024] = { 0 };
		size_t size = 0;
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_PROFILE,1024, buf,&size);
		if (err < 0) continue;
		printf("	PROFILE:%s\n",buf);
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, 1024, buf, &size);
		if (err < 0) continue;
		printf("	VERSION:%s\n", buf);
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 1024, buf, &size);
		if (err < 0) continue;
		printf("	NAME:%s\n", buf);
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, 1024, buf, &size);
		if (err < 0) continue;
		printf("	VENDOR:%s\n", buf);
		/*err = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 1024, buf, &size);
		if (err < 0) continue;
		printf("	EXTENSIONS:%s\n", buf);*/
		err = clGetPlatformInfo(platforms[i], CL_PLATFORM_HOST_TIMER_RESOLUTION, 1024, buf, &size);
		if (err < 0) continue;
		printf("	TIMER:%s\n", buf);

		cl_uint deviceNum = 0;
		err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL,0,NULL,&deviceNum);
		if (err < 0) continue;

		std::vector<cl_device_id> devices(deviceNum);
		err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, deviceNum, &devices[0], &deviceNum);
		if (err < 0) continue;

		printf("	  Devices:%d\n",deviceNum);
		char deviceBuf[1024] = { 0 };
		size_t deviceSize = 0;
		for (cl_int j = 0; j < deviceNum; j++) {
			err = clGetDeviceInfo(devices[j], CL_DEVICE_TYPE, 1024, deviceBuf, &deviceSize);
			if (err < 0) continue;
			printf("		TYPE:%s\n", deviceBuf);
			err = clGetDeviceInfo(devices[j], CL_DEVICE_NAME,1024, deviceBuf,&deviceSize);
			if (err < 0) continue;
			printf("		NAME:%s\n",deviceBuf);

			if (context == NULL) {
				cl_context_properties prop[] = { CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[i]), 0 };
				context = clCreateContextFromType(prop, CL_DEVICE_TYPE_ALL, NULL, NULL, &err);
				deviceIDs = devices;
			}
		}
	}
	
	if (context != NULL) {
		Process(context, deviceIDs);
		clReleaseContext(context);
	}

	return 0;
}
__kernel void hello_kernel(__global const float *a,
                           __global const float *b,
                           __global float *result)
{
	int n = get_work_dim() - 1;
    int gid = get_global_id(n);
	result[gid] = a[gid] + b[gid];
	result[gid] = gid + 1;
	//result[gid] = n + 1;
	//result[gid] = get_local_id(n) + 1;
	//result[gid] = get_group_id(n) + 1;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值