1 /* ************************************************************************
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * ************************************************************************/
16
17
18 #ifndef CLARGS_H_
19 #define CLARGS_H_
20
21 #if defined(__APPLE__) || defined(__MACOSX)
22 #include <OpenCL/cl.h>
23 #else
24 #include <CL/cl.h>
25 #endif
26
27 #include <string.h>
28 #include <dis_warning.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #define INIT_KARG(karg, val) \
35 do { \
36 memcpy((karg)->arg.data, &(val), sizeof(val)); \
37 (karg)->typeSize = sizeof(val); \
38 } while (0)
39
40 enum {
41 MAX_KERNEL_ARGS = 32,
42 MAX_ARG_SIZE = sizeof(cl_double2),
43 MAX_WORK_DIM = 3
44 };
45
46 // memory object data transfer direction
47 typedef enum MemobjDir {
48 MEMOBJ_READ = 0x1,
49 MEMOBJ_WRITE = 0x2
50 } MemobjDir;
51
52 typedef enum KernelLaunchPhase {
53 PHASE_SET_ARGS,
54 PHASE_ENQUEUE_WRITE,
55 PHASE_ENQUEUE_KERNEL,
56 PHASE_PROFILING,
57 PHASE_ENQUEUE_READ
58 } KernelLaunchPhase;
59
60 typedef union KernelArgValue {
61 cl_mem mem;
62 int ival;
63 unsigned char data[MAX_ARG_SIZE];
64 } KernelArgValue;
65
66 /*
67 * Structure describing an argument to be passed to a kernel
68 *
69 * @arg: pointer to the argument
70 * @ardIdx: argument index in the kernel argument list
71 * @hostBuf: buffer to copy data to/from from/to GPU memory
72 * @enqType: buffer enqueue type
73 * @sync: blocking I/O
74 * @event: event for I/O
75 */
76 typedef struct KernelArg {
77 KernelArgValue arg;
78 unsigned int typeSize; // argument type size, ignored for mem objects
79 void *hostBuf; // host buffer for using with OpenCL memory objects
80 size_t hostBufLen;
81 MemobjDir dir;
82 } KernelArg;
83
84 typedef struct KernelDesc {
85 cl_kernel kernel;
86 size_t globalThreads[MAX_WORK_DIM];
87 size_t localThreads[MAX_WORK_DIM];
88 size_t workDim;
89 const cl_event *eventWaitList;
90 size_t waitListSize;
91 cl_event *event;
92 int nowait;
93 int needExecTime;
94 KernelArg args[MAX_KERNEL_ARGS];
95 unsigned long execTime;
96 } KernelDesc;
97
98 typedef struct KernelErrorInfo {
99 unsigned int wrongArg;
100 KernelLaunchPhase phase;
101 } KernelErrorInfo;
102
103 /*
104 * store kernel arguments launch the kernel and read its results
105 *
106 * @kernDesc: descriptor of the kernel to be launched
107 * @queue: command queue associated with the device
108 * @errInfo: location to store info about occurred error,
109 * ignored if NULL
110 *
111 * The function gets itself number of arguments to the kernel
112 * usging the OpenCL API
113 */
114 cl_int launchClKernel(
115 KernelDesc *kernDesc,
116 cl_command_queue queue,
117 KernelErrorInfo *errInfo);
118
119 /*
120 * build a program from source
121 *
122 * @source: program source
123 * @buildOpts: options to the opencl program builder
124 * @DevID: ID of device to create program for
125 * @logBuf: buffer to store build log at error
126 * @status: location to store OpenCL status at error
127 *
128 * On success returns a build program object.
129 * On error returns <NULL>, and stores to the 'status' location
130 * opencl status; if <NULL> result is returned, but 'status'
131 * cointains 'CL_SUCCESS', it means an file I/O or memory allocation
132 * failure is occurred. If 'status' is set to NULL, it is ignored
133 */
134 cl_program
135 buildClProgram(
136 const char *source,
137 const char *buildOpts,
138 cl_context ctx,
139 cl_device_id devID,
140 char *logBuf,
141 size_t logBufSize,
142 cl_int *status);
143
144 /*
145 * TODO: Doxygen-style comments
146 */
147 cl_program
148 createClProgramWithBinary(
149 cl_context ctx,
150 cl_device_id devID,
151 unsigned char *binary,
152 size_t binSize,
153 cl_int *status);
154
155 /*
156 * TODO: Doxygen-style comments
157 */
158 size_t
159 getProgramBinarySize(cl_program program);
160
161 /*
162 * TODO: Doxygen-style comments
163 */
164 unsigned char
165 *getProgramBinary(cl_program program);
166
167 /*
168 * set a kernel argument of the size_t type
169 */
170 static __inline void
initSizeKarg(KernelArg * arg,size_t value)171 initSizeKarg(KernelArg *arg, size_t value)
172 {
173 memcpy(arg->arg.data, &value, sizeof(cl_uint));
174 arg->typeSize = sizeof(cl_uint);
175 }
176
177 /*
178 * @inOut: memory object data transfer direction
179 */
180 static __inline void
initMemobjKarg(KernelArg * karg,cl_mem memobj,void * hostBuf,size_t hostBufLen,MemobjDir dir)181 initMemobjKarg(
182 KernelArg *karg,
183 cl_mem memobj,
184 void *hostBuf,
185 size_t hostBufLen,
186 MemobjDir dir)
187 {
188 karg->arg.mem = memobj;
189 karg->typeSize = sizeof(cl_mem);
190 karg->hostBuf = hostBuf;
191 karg->hostBufLen = hostBufLen;
192 karg->dir = dir;
193 }
194
195 #ifdef __cplusplus
196 }
197 #endif
198
199 #endif /* CLARGS_H_ */
200