-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdmaa-cl.cpp
112 lines (92 loc) · 3.69 KB
/
dmaa-cl.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* dmaa-cl.cpp - Data Matrix ASCII Art encoder using OpenCL
*
* Copyright (C) 2021-2023 Piotr Fusik
*
* This file is part of DataMatrix.fu, see http://github.com/pfusik/datamatrix-fu
*
* DataMatrix.fu is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DataMatrix.fu is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DataMatrix.fu. If not, see http://www.gnu.org/licenses/
*/
#include <stdio.h>
#include <stdlib.h>
#define CL_TARGET_OPENCL_VERSION 200
#include <CL/cl.h>
#include "datamatrix.h" // DataMatrixEncoder_MAX_MESSAGE_LENGTH, DataMatrixEncoder_MAX_ROWS, DataMatrixEncoder_MAX_COLUMNS
static void check_error(cl_int err)
{
if (err != CL_SUCCESS) {
fprintf(stderr, "OpenCL error %d\n", err);
exit(1);
}
}
int main()
{
cl_platform_id platform;
cl_uint num;
check_error(clGetPlatformIDs(1, &platform, &num));
if (num == 0) {
fprintf(stderr, "No OpenCL platforms\n");
return 1;
}
cl_device_id device;
check_error(clGetDeviceIDs(platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, &num));
if (num == 0) {
fprintf(stderr, "No OpenCL device\n");
return 1;
}
size_t size;
check_error(clGetDeviceInfo(device, CL_DEVICE_NAME, 0, nullptr, &size));
char *name = static_cast<char *>(malloc(size));
check_error(clGetDeviceInfo(device, CL_DEVICE_NAME, size, name, nullptr));
fprintf(stderr, "Running on %s\n", name);
free(name);
const cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties) platform, 0
};
cl_int err;
cl_context context = clCreateContext(properties, 1, &device, nullptr, nullptr, &err);
check_error(err);
const char *source =
#include "datamatrix-cl.h"
;
cl_program program = clCreateProgramWithSource(context, 1, &source, nullptr, &err);
check_error(err);
check_error(clBuildProgram(program, 1, &device, "-cl-std=CL2.0", nullptr, nullptr));
cl_kernel kernel;
check_error(clCreateKernelsInProgram(program, 1, &kernel, nullptr));
char message[DataMatrixEncoder_MAX_MESSAGE_LENGTH];
size_t messageLength = fread(message, 1, sizeof(message) - 1, stdin);
message[messageLength] = '\0';
cl_mem messageBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR | CL_MEM_HOST_NO_ACCESS, messageLength + 1, message, &err);
check_error(err);
check_error(clSetKernelArg(kernel, 0, sizeof(messageBuffer), &messageBuffer));
char result[DataMatrixEncoder_MAX_ROWS * (DataMatrixEncoder_MAX_COLUMNS + 1) + 1];
cl_mem resultBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(result), nullptr, &err);
check_error(err);
check_error(clSetKernelArg(kernel, 1, sizeof(resultBuffer), &resultBuffer));
cl_command_queue queue = clCreateCommandQueueWithProperties(context, device, nullptr, &err);
check_error(err);
const size_t one = 1;
check_error(clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &one, nullptr, 0, nullptr, nullptr));
check_error(clEnqueueReadBuffer(queue, resultBuffer, false, 0, sizeof(result), result, 0, nullptr, nullptr));
check_error(clFinish(queue));
check_error(clReleaseCommandQueue(queue));
check_error(clReleaseMemObject(resultBuffer));
check_error(clReleaseMemObject(messageBuffer));
check_error(clReleaseKernel(kernel));
check_error(clReleaseProgram(program));
check_error(clReleaseContext(context));
fputs(result, stdout);
return 0;
}