OpenCL: 2D Array: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 16: | Line 16: | ||
idx = 1 * 4 + 2 | idx = 1 * 4 + 2 | ||
idx = 6 | idx = 6 | ||
</syntaxhighlight> | |||
=== Code === | |||
Contoh buat data. Vector a, b, c di sini semuanya tetap 1D. Tapi untuk menentukan dimensinya ditentukan ketika kita mengkonfigurasi kernel. | |||
<syntaxhighlight lang=cpp> | |||
const int W = 4; | |||
const int H = 3; | |||
std::vector<float> a(W * H); | |||
std::vector<float> b(W * H); | |||
std::vector<float> c(W * H); | |||
// isi data | |||
for (int y = 0; y < H; y++) { | |||
for (int x = 0; x < W; x++) { | |||
a[y * W + x] = y * 10 + x; | |||
b[y * W + x] = 1.0f; | |||
} | |||
} | |||
</syntaxhighlight> | |||
Lalu buat buffer, yang ini sama aja. Perhatikan ketika kita menentukan sizenya | |||
<syntaxhighlight lang=cpp> | |||
cl_mem bufA = clCreateBuffer( | |||
context, | |||
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, | |||
sizeof(float) * W * H, | |||
a.data(), | |||
nullptr | |||
); | |||
cl_mem bufB = clCreateBuffer( | |||
context, | |||
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, | |||
sizeof(float) * W * H, | |||
b.data(), | |||
nullptr | |||
); | |||
cl_mem bufC = clCreateBuffer( | |||
context, | |||
CL_MEM_WRITE_ONLY, | |||
sizeof(float) * W * H, | |||
nullptr, | |||
nullptr | |||
); | |||
</syntaxhighlight> | |||
code kernel: | |||
<syntaxhighlight lang=c> | |||
__kernel void mat_add(__global const float* A, | |||
__global const float* B, | |||
__global float* C, | |||
int width) { | |||
int x = get_global_id(0); | |||
int y = get_global_id(1); | |||
int idx = y * width + x; | |||
C[idx] = A[idx] + B[idx]; | |||
printf("x=%d, y=%d, idx=%d, a=%f, b=%f, c=%f\n", | |||
x, y, idx, A[idx], B[idx], C[idx]); | |||
} | |||
</syntaxhighlight> | |||
Lalu untuk execute | |||
<syntaxhighlight lang=cpp> | |||
size_t global[2] = { (size_t)W, (size_t)H }; | |||
clEnqueueNDRangeKernel( | |||
queue, | |||
kernel, | |||
2, // DIMENSI | |||
nullptr, | |||
global, | |||
nullptr, | |||
0, | |||
nullptr, | |||
nullptr | |||
); | |||
</syntaxhighlight> | |||
Lalu read result | |||
<syntaxhighlight lang=cpp> | |||
clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(float) * W * H, c.data(), 0, nullptr, nullptr); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 07:56, 8 January 2026
Untuk memproses array 2D di OpenCL, kita perlu nge-flatten array 2D itu jadi 1D. Bahkan mau sampai 100D tetap perlu di-flatten ke 1D. Jadi teknik untuk memproses data yang lebih dari 1D adalah dengan cara Indexing
Maka kita perlu flatten ke 1D. Kira-kira gini:
Lalu untuk indexing 2D Array, formula sakti nya adalah
idx = y * width + xMisal kita mau ambil y=1, x=2, dan kita punya 4 kolom (width=4). elemen array yang nilainya 6.
idx = y * width + x
idx = 1 * 4 + 2
idx = 6Code
Contoh buat data. Vector a, b, c di sini semuanya tetap 1D. Tapi untuk menentukan dimensinya ditentukan ketika kita mengkonfigurasi kernel.
const int W = 4;
const int H = 3;
std::vector<float> a(W * H);
std::vector<float> b(W * H);
std::vector<float> c(W * H);
// isi data
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
a[y * W + x] = y * 10 + x;
b[y * W + x] = 1.0f;
}
}
Lalu buat buffer, yang ini sama aja. Perhatikan ketika kita menentukan sizenya
cl_mem bufA = clCreateBuffer(
context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
sizeof(float) * W * H,
a.data(),
nullptr
);
cl_mem bufB = clCreateBuffer(
context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
sizeof(float) * W * H,
b.data(),
nullptr
);
cl_mem bufC = clCreateBuffer(
context,
CL_MEM_WRITE_ONLY,
sizeof(float) * W * H,
nullptr,
nullptr
);
code kernel:
__kernel void mat_add(__global const float* A,
__global const float* B,
__global float* C,
int width) {
int x = get_global_id(0);
int y = get_global_id(1);
int idx = y * width + x;
C[idx] = A[idx] + B[idx];
printf("x=%d, y=%d, idx=%d, a=%f, b=%f, c=%f\n",
x, y, idx, A[idx], B[idx], C[idx]);
}
Lalu untuk execute
size_t global[2] = { (size_t)W, (size_t)H };
clEnqueueNDRangeKernel(
queue,
kernel,
2, // DIMENSI
nullptr,
global,
nullptr,
0,
nullptr,
nullptr
);
Lalu read result
clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(float) * W * H, c.data(), 0, nullptr, nullptr);
