OpenCL矩阵相乘求助
main.cpp
#include "stdafx.h"
#include<sstream>
#include <iostream>
#include<time.h>
#include <string>
#include<math.h>
#include <vector>
#include <CL/cl.h>
#include <fstream>
using namespace std;
#define MAX_SOURCE_SIZE (0x1000000)
int main(int argc, char **argv[])
{
FILE *fp;
char fileName[] = "./MatrixMul.cl";
char *source_str;
size_t source_size;
/* Load the source code containing the kernel*/
fp = fopen(fileName, "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);
//the size of matrixs
int A_row = 1024;
int A_col = 1024;
int B_row = A_col;
int B_col = 1024;
int A_size = A_row * A_col;
int B_size = B_row * B_col;
int C_size = A_row * B_col;
/** step 1: get platform */
int err=-1;
cl_uint num_platforms = NULL;
cl_platform_id platform_id = NULL;
int choose_num_platform = 1;
err = clGetPlatformIDs(choose_num_platform, &platform_id, &num_platforms);
if ((CL_SUCCESS != err) || (num_platforms < 1))
{
cout << "Error getting platform: " << err << endl;
return 0;
}
else
{
cout << "The number of platform is: " << num_platforms << ". And the platform id is: " << platform_id <<
". \n***If you want to change platform please modifiy the choose_num_platform variable.\n"<<endl;
}
/** step 2: get device */
cl_uint num_devices = NULL;
cl_device_id device_id = NULL;
int choose_num_device=1;
clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, choose_num_device, &device_id, &num_devices);
if ((CL_SUCCESS != err) || (num_devices < 1))
{
cout << "Error getting GPU device: " << err << endl;
return 0;
}
else {
cout << "The number of device is: " << num_devices << ". And the device id is: " << device_id <<
". \n***If you want to change device please modifiy the choose_num_device variable.\n" << endl;
}
/** step 3: create context */
cl_context_properties props[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, 0 };
cl_context context = NULL;
context = clCreateContext(props, 1, &device_id, NULL, NULL, &err);
if ((CL_SUCCESS != err) || (NULL == context))
{
cout << "Error creating context: " << err << endl;
return 0;
}
/** step 4: create command queue */
cl_command_queue command_queue = NULL;
command_queue = clCreateCommandQueue(context, device_id, CL_QUEUE_PROFILING_ENABLE, &err);
if ((CL_SUCCESS != err) || (NULL == command_queue))
{
cout << "Error creating command queue: " << err << endl;
return 0;
}
/** step 5: create memory object */
cl_mem matrixAMemObj = NULL;
cl_mem matrixBMemObj = NULL;
cl_mem matrixCMemObj = NULL;
// matrixs
int *MatrixA = NULL;;
int *MatrixB = NULL;;
int *MatrixC = NULL;;
const int BUF_SIZEa = A_size * sizeof(int);
const int BUF_SIZEb = B_size * sizeof(int);
const int BUF_SIZEc = C_size * sizeof(int);
// create and init host buffer
MatrixA = (int *)malloc(A_row * A_col * sizeof(int));
MatrixB = (int *)malloc(B_row * B_col * sizeof(int));
MatrixC = (int *)malloc(B_row * A_col * sizeof(int));
for (int i = 0; i < A_size; i++)
{
MatrixA[i] = (int)std::rand() / 10000;
}
for (int i = 0; i < B_size; i++)
{
MatrixB[i] = (int)std::rand() / 1000;
}
for (int i = 0; i < C_size; ++i)
{
MatrixC[i] = 333.0;
}
// create opencl memory object using host ptr
matrixAMemObj = clCreateBuffer(context, CL_MEM_READ_ONLY, BUF_SIZEa, NULL, NULL);
matrixBMemObj = clCreateBuffer(context, CL_MEM_READ_ONLY, BUF_SIZEb, NULL, NULL);
matrixCMemObj = clCreateBuffer(context, CL_MEM_WRITE_ONLY, BUF_SIZEc, NULL, NULL);
if ((err != CL_SUCCESS) || (NULL == matrixAMemObj) || (NULL == matrixBMemObj) || (NULL == matrixCMemObj))
{
cout << "Error creating command queue: " << err << endl;
return 0;
}
/** step 6: create program */
cl_program program;
program = clCreateProgramWithSource(context, 1, (const char**)&source_str, (const size_t *)&source_size, &err);
if ((CL_SUCCESS != err) || (NULL == program))
{
cout << "Error creating program: " << err << endl;
return 0;
}
// build program
err = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
if (CL_SUCCESS != err)
{
cout << "Error building program: " << err << endl;
return 0;
}
/** step 7: create kernel */
cl_kernel kernel;
kernel = clCreateKernel(program, "Matrixmul", &err);
if ((CL_SUCCESS != err) || (NULL == kernel))
{
cout << "Error creating kernel: " << err << endl;
return 0;
}
/** step 8: set kernel arguments */
err = clSetKernelArg(kernel, 0, sizeof(int), &B_row);
err = clSetKernelArg(kernel, 1, sizeof(int), &A_col);
err = clSetKernelArg(kernel, 2, sizeof(cl_mem), &matrixAMemObj);
err = clSetKernelArg(kernel, 3, sizeof(cl_mem), &matrixBMemObj);
err = clSetKernelArg(kernel, 4, sizeof(cl_mem), &matrixCMemObj);
err = clSetKernelArg(kernel, 5, sizeof(int)*A_col, NULL);
if (CL_SUCCESS != err)
{
cout << "Error setting kernel argument: " << err << endl;
return 0;
}
/** step 9: set work group size */
size_t globalThreads[] = { A_col };
size_t localThreads[] = { 256 };
cl_event prof_event;
//write A B into device memory
err = clEnqueueWriteBuffer(command_queue, matrixAMemObj, CL_TRUE, 0, A_row * A_col * sizeof(int), (void*)MatrixA, 0, NULL, NULL);
err = clEnqueueWriteBuffer(command_queue, matrixBMemObj, CL_TRUE, 0, B_row * B_col * sizeof(int), (void*)MatrixB, 0, NULL, NULL);
/** step 10: run kernel */
err = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, globalThreads, localThreads, 0, NULL, &prof_event);
clWaitForEvents(1, &prof_event);
/** step 11: get result */
cl_ulong ev_start_time = 0;
cl_ulong ev_end_time = 0;
int err9 = 9;
err9 = clGetEventInfo(prof_event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &ev_start_time, NULL);
cout << "ev_start_time: " << err9 << ev_start_time << endl;
int err10 = 10;
err10 = clGetEventInfo(prof_event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &ev_end_time, NULL);
cout << "ev_end_time: " << err10 << ev_end_time << endl;
int err11 = 11;
err11 = clEnqueueReadBuffer(command_queue, matrixCMemObj, CL_TRUE, 0, B_row * A_col * sizeof(int), (void*)MatrixC, 0, NULL, NULL);
cout << "readbuffer: " << err11 << endl;
float run_time = ev_end_time - ev_start_time;
cout << "runtime:" << run_time << endl;
/** step 12: release all resources */
if (NULL != kernel) clReleaseKernel(kernel);
if (NULL != program) clReleaseProgram(program);
if (NULL != matrixAMemObj) clReleaseMemObject(matrixAMemObj);
if (NULL != matrixBMemObj) clReleaseMemObject(matrixBMemObj);
if (NULL != matrixCMemObj) clReleaseMemObject(matrixCMemObj);
if (NULL != command_queue) clReleaseCommandQueue(command_queue);
if (NULL != context) clReleaseContext(context);
if (NULL != MatrixA) free(MatrixA);
if (NULL != MatrixB) free(MatrixB);
if (NULL != MatrixC) free(MatrixC);
}
Matrixmul.cl
__kernel void Matrixmul(
const int B_width,
const int A_height,
__global int* A,
__global int* B,
__global int* C,
__local int* shared)
{
int i = get_global_id(0);
int id = get_local_id(0);
int size = get_local_size(0);
float tmp = 0.0;
int tmpData[1024];
if (i<A_height)
{
for (int k = 0; k<B_width; ++k)
{
tmpData[k] = A[i*A_height + k];
}
for (int k = id; k<B_width; k += size)
shared[k] = B[k*B_width + k];
barrier(CLK_LOCAL_MEM_FENCE);
for (int j = 0; j<B_width; ++j)
{
tmp = 0.0;
for (int k = 0; k<B_width; ++k)
{
tmp += tmpData[k] * shared[k];
}
C[i*A_height + j] = tmp;
}
}
}
相关推荐
mul.zip.rar_矩阵相乘
在应用中常用矩阵相乘的定义算法对其进行计算。这个算法用到了大量的循环和相乘运算,这使得算法效率不高。而矩阵相乘的计算效率很大程度上的影响了整个程序的运行速度,所以对矩阵相乘算法进行一些改进是必要的。
OpenCL例程3-矩阵相乘
cpp文件代码 // OpenCl-3.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include using namespace std; #define MATRIX_A_ROW 8 // 矩阵A行数 #defin
openCL-矩阵相乘
这是AMD异构大赛发的书上的例子,我自己加了一些东西,实现了一下。不过还没有学会如何分析运行的时间,先贴上代码 这是第一次用amd APP KernelAnalyzer感觉还可以吧, simpleMultiply.cl // Enter your kernel in this window __kernel v
面向OpenCL的Mali GPU仿真器构建研究.pdf
面向OpenCL的Mali GPU仿真器构建研究.pdf
OpenCL编程指南
OpenCL领域公认的权威著作,由OpenCL核心设计人员亲自执笔,不仅全面而深刻地解读了OpenCL规范和编程模型,而且通过大量案例和代码演示了基于OpenCL编写并行程序和实现各种并行算法的原理、方法、流程和最佳实践,以及如何对OpenCL进行性能优化,如何对硬件进行探测和调整。, 本书分为两大部分:第一部分(1~13章),从介绍OpenCL的核心思想和编写OpenCL程序的基础知识开始,对枯燥的OpenCL规范进行了深刻而系统的解读,旨在帮助读者全面、正确地理解OpenCL规范及其编程模型;第二部分(14~22章),提供了一系列经典的案例,如图像直方图、Sobel边界检测过滤器、并行实现Dijkstra单源最短路径图算法、Bullet Physics SDK中的布模拟、用快速傅里叶变换模拟海洋、光流、OpenCL与PyOpenCL结合使用,使用OpenCL完成矩阵相乘与稀疏矩阵矢量乘法等,目的是让读者通过案例熟练掌握编写复杂并行程序的方法和技巧。本书的附录收录了OpenCL规范定义的大量函数、命名常量和类型,可供程序员开发时查阅。


