Last active
April 25, 2017 18:51
-
-
Save blrB/bcaf4bc80feae6c75d114c718b011545 to your computer and use it in GitHub Desktop.
open cl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 25. Посчитать массив общих элементов двух отсортированных массивов (13) | |
#include <iostream> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <CL/opencl.h> | |
#define PROCESS_ERROR(msg,stateCondition) if (stateCondition != CL_SUCCESS) { \ | |
printf(msg, stateCondition); \ | |
return stateCondition; \ | |
} | |
using namespace std; | |
void serialRelease(int pA[], int pB[], const int countA, const int countB) | |
{ | |
int *pC = new int[countB]; | |
clock_t startP = clock(); | |
for (int i = 0; i < countB; i++){ | |
pC[i] = -1; | |
for (int j = 0; j < countA; j++){ | |
if (pB[i] == pA[j]) pC[i] = pB[i]; | |
} | |
} | |
cout << " - > " << clock() - startP << endl; | |
for (int i = 0; i < countB; i++){ | |
cout << pC[i] << " "; | |
} | |
cout << endl << endl; | |
} | |
void init(int pV[], const int cnDimention){ | |
int i; | |
for (i = 0; i < cnDimention; i++){ | |
cout << "Введите элемент " << i << " "; | |
cin >> pV[i]; | |
} | |
cout << endl; | |
} | |
void initT(int pV[], const int cnDimention){ | |
int i; | |
for (i = 0; i < cnDimention; i++){ | |
pV[i] = i; | |
} | |
cout << endl; | |
} | |
void dump(int pV[], const int cnDimention) { | |
for (int i = 0; i < cnDimention; i++) { | |
cout << pV[i]<< " "; | |
} | |
cout << endl; | |
} | |
int main() { | |
const char * sProgramSource[] = {"\ | |
__kernel void intersection (__global const int * a, __global const int * b, __global int * c, __global int * countA)\ | |
{\ | |
int nIndex = get_global_id(0);\ | |
c[nIndex] = -1;\ | |
for (int i = 0 ; i < *countA ;i++)\ | |
{\ | |
if (b[nIndex] == a[i]) c[nIndex] = b[nIndex];\ | |
}\ | |
}" | |
}; | |
int countA; | |
int countB; | |
cout << "Введите количество элементов в первом массиве : "; | |
cin >> countA; | |
int *pA = new int[countA]; | |
init(pA,countA); | |
cout << "Введите количество элементов во втором массиве : "; | |
cin >> countB; | |
int *pB = new int[countB]; | |
init(pB,countB); | |
cout << "Массив общих элементов :" << endl; | |
cout << "Последовательный алгоритм :" << endl; | |
serialRelease(pA, pB, countA, countB); | |
// Выбор платформы --------------------------------------------------------------------------------------------------- | |
cl_int stateCondition; | |
cl_uint numberOfPlatforms; | |
cl_platform_id platform; | |
stateCondition = clGetPlatformIDs(0, NULL, &numberOfPlatforms); // нахождение количества платформ | |
if (stateCondition == CL_SUCCESS) { // проверка на успешность подсчета кол-ва платформ | |
cl_platform_id* platforms = new cl_platform_id[numberOfPlatforms]; // выделяется память для объектов платформы | |
stateCondition = clGetPlatformIDs(numberOfPlatforms, platforms, NULL); // получения объектов платформы | |
if (stateCondition == CL_SUCCESS) { // проверка на успешность выбора платформы | |
platform = platforms[0]; // взятие (первой попавшейся) платформы из массива | |
} | |
PROCESS_ERROR("Platform detection faults. Error Code: %d.", stateCondition); | |
} | |
PROCESS_ERROR("Platform detection faults. Error Code: %d.", stateCondition); | |
// Выбор устройств --------------------------------------------------------------------------------------------------- | |
cl_device_id device_id; | |
cl_uint numberOfDevices; | |
stateCondition = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numberOfDevices); // определяет число устройств | |
PROCESS_ERROR("Device detection faults. Error Code: %d.", stateCondition); | |
stateCondition = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, numberOfDevices, &device_id, NULL); // обнаруживает объекты устройств | |
PROCESS_ERROR("Device detection faults. Error Code: %d.", stateCondition); | |
// Контекст ---------------------------------------------------------------------------------------------------------- | |
cl_context context; | |
context = clCreateContext(NULL, numberOfDevices, &device_id, NULL, NULL, &stateCondition); // создаёт контекст | |
PROCESS_ERROR("Context creation faults. Error Code: %d.", stateCondition); | |
// Очереди команд ---------------------------------------------------------------------------------------------------- | |
cl_command_queue commandQueue; | |
commandQueue = clCreateCommandQueue(context, device_id, 0, 0); // очереди команд связывают контекст с устройством | |
// Создание буферов -------------------------------------------------------------------------------------------------- | |
int *pC = new int[countB]; | |
cl_mem deviceMemoryA; | |
cl_mem deviceMemoryB; | |
cl_mem deviceMemoryC; | |
cl_mem deviceCountA; | |
deviceMemoryA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, countA * sizeof(cl_int), pA, NULL); | |
deviceMemoryB = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, countB * sizeof(cl_int), pB, NULL); | |
deviceMemoryC = clCreateBuffer(context, CL_MEM_WRITE_ONLY, countB * sizeof(cl_int), NULL, NULL); | |
deviceCountA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_int), &countA, NULL); | |
// Создание программ ------------------------------------------------------------------------------------------------- | |
cl_program hProgram; | |
hProgram = clCreateProgramWithSource(context, 1, sProgramSource, 0, 0); // создаёт программный объект из строк исходного кода | |
stateCondition = clBuildProgram(hProgram, 0, 0, 0, 0, 0); // компилирует исполняемый файл для каждого устройства | |
PROCESS_ERROR("Program building faults. Error Code: %d.", stateCondition); | |
// Создания ядра ----------------------------------------------------------------------------------------------------- | |
cl_kernel kernel; | |
kernel = clCreateKernel(hProgram, "intersection", 0); // создаёт ядро из заданной программы | |
// Установка аргументов ядра ----------------------------------------------------------------------------------------- | |
stateCondition = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&deviceMemoryA); | |
PROCESS_ERROR("First argument failure. Error Code: %d.",stateCondition); | |
stateCondition = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&deviceMemoryB); | |
PROCESS_ERROR("Second argument failure. Error Code: %d.",stateCondition); | |
stateCondition = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&deviceMemoryC); | |
PROCESS_ERROR("Third argument failure. Error Code: %d.",stateCondition); | |
stateCondition = clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&deviceCountA); | |
PROCESS_ERROR("Fourth argument failure. Error Code: %d.",stateCondition); | |
size_t co = countB; | |
clock_t startP = clock(); | |
// Говорим устройству, связанному с очередью команд, начать исполнение указанного ядра | |
stateCondition = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, &co, NULL, 0, 0, 0); | |
PROCESS_ERROR("clEnqueueNDRangeKernel failure. Error Code: %d.", stateCondition); | |
cout << " - > " << clock() - startP << endl; | |
// Копирование данных с устройства на хост | |
stateCondition = clEnqueueReadBuffer(commandQueue, deviceMemoryC, CL_TRUE, 0, countB * sizeof(cl_int), pC, 0, 0, 0); | |
PROCESS_ERROR("clEnqueueReadBuffer failure. Error Code: %d.", stateCondition); | |
cout << "Параллельный алгоритм :" << endl; | |
dump(pC, countB); | |
// Очистка памяти ---------------------------------------------------------------------------------------------------- | |
delete[] pA; | |
delete[] pB; | |
delete[] pC; | |
stateCondition = clReleaseMemObject(deviceMemoryA); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseMemObject(deviceMemoryB); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseMemObject(deviceMemoryC); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseKernel(kernel); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseProgram(hProgram); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseCommandQueue(commandQueue); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
stateCondition = clReleaseContext(context); | |
PROCESS_ERROR("Release failure. Error Code: %d.", stateCondition); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment