批改娘 10092. OpenCL Build Program Debug

contents

  1. 1. 題目描述
    1. 1.1. err1.cl
  2. 2. 輸入格式
  3. 3. 輸出格式
  4. 4. 範例輸入 1
  5. 5. 範例輸出 1
  6. 6. Solution

題目描述

為 OpenCL 中的 clBuildProgram() Debug 鋪路。請嘗試從標準輸入得到要編譯的檔案名稱,並把編譯的錯誤訊息輸出。

err1.cl

1
2
3
4
5
typedef unsigned int uint32_t;
__kernel void mul(__global uint32_t A[], __global uint32_t C[], const int N)
{
opencl;
}

輸入格式

輸入只有一行,字串長度不大於 30 的檔案名稱。

輸出格式

將錯誤訊息印出,如 printf("%s", program_log);

範例輸入 1

1
err1.cl

範例輸出 1

1
2
3
<kernel>:4:2: error: use of undeclared identifier 'opencl'
opencl;
^

Solution

盡量使用較少的 device,減少建立文本的 overhead,反正都是錯誤的代碼要找編譯錯誤資訊,那麼就直接用其中一個 device 編譯即可,除非牽涉到 compute version 問題,原則上都會是一樣的。

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
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <CL/cl.h>
#define MAXGPU 1
#define MAXN 2048
int N = MAXN;
char clSrc[1024] = "";
char clSrcMain[1024] = "notused";
// -- start working with OpenCL
cl_context clCtx;
cl_program clPrg;
#define clCallFunc &clCtx, &clPrg
#define clFuncArgs cl_context *clCtx, cl_program *clPrg
#define CheckFailAndExit(status) \
if (status != CL_SUCCESS) { \
fprintf(stderr, "Error: Line %u in file %s\n\n", __LINE__, __FILE__), \
destroyGPU(clCtx, clPrg); \
}
#define clPrint(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
void destroyGPU(clFuncArgs) {
fprintf(stderr, "Starting Cleanup ...\n\n");
if (*clCtx) clReleaseContext(*clCtx);
if (*clPrg) clReleaseProgram(*clPrg);
exit(0);
}
void clCompile(char fileName[], clFuncArgs) {
FILE *codefin = fopen(fileName, "r");
assert(codefin != NULL);
size_t clSrcLen = fread(clSrc, 1, 1024, codefin);
fclose(codefin);
cl_int clStat;
cl_uint clPlatN, clGPUN;
cl_platform_id clPlatID;
cl_device_id clGPUID[MAXGPU];
const char *clSrcPtr = clSrc;
// -- basic OpenCL setup
clGetPlatformIDs(1, &clPlatID, &clPlatN);
clGetDeviceIDs(clPlatID, CL_DEVICE_TYPE_GPU, MAXGPU, clGPUID, &clGPUN);
*clCtx = clCreateContext(NULL, 1, clGPUID, NULL, NULL, &clStat);
CheckFailAndExit(clStat);
*clPrg = clCreateProgramWithSource(*clCtx, 1, &clSrcPtr, &clSrcLen, &clStat);
CheckFailAndExit(clStat);
clStat = clBuildProgram(*clPrg, 1, clGPUID, NULL, NULL, NULL);
if (clStat != CL_SUCCESS) {
static char program_log[32767];
clGetProgramBuildInfo(*clPrg, clGPUID[0],
CL_PROGRAM_BUILD_LOG, sizeof(program_log), program_log, NULL);
printf("%s", program_log);
CheckFailAndExit(CL_BUILD_PROGRAM_FAILURE);
}
}
int main() {
char fileName[128];
assert(scanf("%s", fileName) == 1);
clCompile(fileName, clCallFunc);
// Compile Success
destroyGPU(clCallFunc);
return 0;
}