์ค๋ ๋ ๋ธ๋ก(์์ ๊ทธ๋ฃน)์ ์ค๋ ๋(์์ ํญ๋ชฉ) ์์ ๋ํ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ปค๋ ์ปดํ์ผ๋ฌ์ ์ ๊ณตํ๋ ๊ฒ์ด ์ข ์ข ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด HIP ์ปดํ์ผ๋ฌ์ ์ค๋ ๋ ๋ธ๋ก(์: 1024)์ ์ค๋ ๋ ์์ ๋ํ ์ํ์ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ ์ ์์ต๋๋ค.
__launch_bounds__(1024) __global__ void fooKernel(...) { ... }
์ค์ ๋ก ํ์ฌ HIP ๋ฆด๋ฆฌ์ค์ ๊ฒฝ์ฐ ๋ถํํ๋ ์ค๋ ๋ ๋ธ๋ก ํฌ๊ธฐ๊ฐ 256์ ์ด๊ณผํ ๋ ์ง์ ํด์ผ ํ๋ ๊ฒฝ์ฐ์ ๋๋ค(https://github.com/ROCm-Developer-Tools/HIP/issues/1310 ์ฐธ์กฐ).
CUDA๋ ๊ฐ์ ์์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ํ ์ต์ ์ค๋ ๋ ๋ธ๋ก ์์ ๋ํ ์คํ ๊ฒฝ๊ณ ํ์ ์์ ๋ํ ์ถ๊ฐ ์ธ์๊ฐ ์์ต๋๋ค(https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#launch-bounds).
OpenCL์ ์ปค๋ ํ์ ์๋ ์ฝ๊ฐ ๋ค๋ฆ ๋๋ค(https://www.khronos.org/registry/OpenCL/specs/2.2/pdf/OpenCL_C.pdf์ 6.7.2 ์ฐธ์กฐ).
์ ์ v1 - ์ปดํ์ผ ์๊ฐ์ ์ค๋ ๋ ๋ธ๋ก ํฌ๊ธฐ๋ฅผ ์๊ณ ์๋ ์ด์์ ์ธ ์ธ๊ณ์์ OCCA๋ ์ ์ ํ ์์ ๋ฒ์(CUDA, HIP) ๋๋ ์์ ๊ทธ๋ฃน ํฌ๊ธฐ ํํธ(OpenCL)์ ๋ํ ์ปค๋ ํ์ ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
Proposal v2 - Proposal v1์ ์ํํ๋ ๊ฒ์ด ๋๋ฌด ๋ณต์กํ ๊ฒฝ์ฐ ์์ ๋ฒ์ @qualifier("innersizes", B)์ ๋ํ okl ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ด ๊น๋ํ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์ B๋ ์ปดํ์ผ๋ฌ๊ฐ ์ ์ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ CUDA/HIP์ ๊ฒฝ์ฐ __launch_bounds__(๊ฐ B) ๋๋ OpenCL์ ๊ฒฝ์ฐ __attribute__((work_group_size_hint(๊ฐ B)))๋ก ํ์ฅ๋ฉ๋๋ค. Multi-dim ๋ณํ๋ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
์ด๊ฒ์ HIP/CUDA/OpenCL์๋ง ํด๋น๋๋ ๊ฒ์ด๋ฏ๋ก ๋น๋ ์์ฑ์ผ๋ก ์ ๋ฌํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
addVectors = device.buildKernel("addVectors.okl",
"addVectors",
"launch_bounds: 1024");
์ข์ ๊ฒ ๊ฐ์์.
๋๋ ๋ฐฉ๊ธ ์ด๊ฒ์ ๋ถ๋ช์ณค๋ค. ๊ธฐ์ฌํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ํ์ง๋ง ์ง๋ฌธ์ด ์์ต๋๋ค. OCCA๋ JIT ์๊ฐ์ ๋ด๋ถ ๋ฃจํ ์น์๋ฅผ ์๊ณ ์์ต๋๊น?
๋ฃจํ ์ฐจ์์ด ์ปค๋ ์ธ์๋ก ์ ๋ฌ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ง๋ ๋ง์ด์ง๋ง ์ ์ ์ฉํ์ง ์ดํด๊ฐ ๋์ง ์์ต๋๋ค. occa๊ฐ JIT ์๊ฐ์ __launch_bounds__
์์ฑ์ ๋ด๋ณด๋ด๋ ๋ฐฉ๋ฒ์ ๋ฌป๊ณ ์์ต๋๋ค. ๊ทธ ์ง์ ์์ ๋ฃจํ ์น์๋ฅผ ์์์ผ ํฉ๋๋ค. ์ด๊ฒ์ ์ปค๋ ์ธ์์ ์ง๊ตํ์ง ์์ต๋๊น?
๊ทธ๋ ๋ด๋ถ ๋ฃจํ์ ํฌ๋ฏธํ ๊ฐ์ด ์ธ์๋ก ์ ๋ฌ๋ ์ ์๋ค๊ณ ๋งํฉ๋๋ค. ์ฆ, JIT ์ปดํ์ผ ์๊ฐ์ ์ค๋ ๋ ๋ธ๋ก ์น์๋ฅผ ์ ํ์๋ ์์ต๋๋ค.
์ ๋ง๋ค. @tcew ์ง๊ธ ๋ฌด์จ ๋ง ํ๋์ง ์๊ฒ ์ด์. ์ข์ ์ง์ .
์ด๊ฒ์ด ๋ด๊ฐ ์ผ๋์ ๋ ๊ฒ์ ๋๋ค.
<strong i="6">@kernel</strong> void runtimeArgs(const int B,
const int T,
const int N,
const float *x,
const float *y,
float *xPy) {
for (int b=0;b<B;++b;@outer(0)){
for (int t=0;t<T;++t;@inner(0)){
if(b==0 && t==0) printf("B=%d, T=%d\n", B, T);
int n = t + T*b;
if(n<N){
xPy[n] = x[n] + y[n];
}
}
}
}
OCCA๋ ๋ถ๋ช ํ JIT ์๊ฐ์ ์์น ๋ฃจํ ๊ฒฝ๊ณ๋ฅผ ์ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ค๋ ๋ ๊ทธ๋ฆฌ๋์ ์น์๋ฅผ ์ค์ ํ๋ ๋ฐ์ฒ๋ฅผ ์์ฑํฉ๋๋ค.
extern "C" void runtimeArgs(occa::modeKernel_t * *deviceKernel,
const int & B,
const int & T,
const int & N,
occa::modeMemory_t * x,
occa::modeMemory_t * y,
occa::modeMemory_t * xPy) {
{
occa::dim outer, inner;
outer.dims = 1;
inner.dims = 1;
int b = 0;
outer[0] = B - 0;
int t = 0;
inner[0] = T - 0;
occa::kernel kernel(deviceKernel[0]);
kernel.setRunDims(outer, inner);
kernel(B, T, N, x, y, xPy);
}
}
๋ฐ๋ผ์ ์ฌ์ฉ์๋ ๋ฐํ์์ ๋ฃจํ ๊ฒฝ๊ณ์ ํฌ๊ธฐ๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
๊ต์ฐจ ๊ฒ์๋ฌผ.
SYCL์ ์ ์ฌํ ๊ตฌ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค.
sycl::range<2> global_range(Bx*Tx,By*Ty);
sycl::range<2> local_range(Tx,Ty);
sycl::nd_range<2> kernel_range(global_range, local_range);
device_queue.submit([&](sycl::handler &cgh) {
...
cgh.parallel_for(kernel_range, kernel);
});
(๋ฒํผ์๋ ์ฐ๊ด๋ ๋ฒ์๊ฐ ์์ผ๋ฏ๋ก N์ ์ ๋ฌํ ํ์๊ฐ ์์ต๋๋ค.)
SYCL sycl::range
๊ตฌ๋ฌธ์ OpenCL์์ ์ฑํ๋์์ผ๋ฉฐ ์์ฒด์ ์ผ๋ก CUDA์์ ์ฑํ๋์์ต๋๋ค.
๊ทํ์ ์์์ ์ค๋ ๋ฉ ์น์์ ์ฌ์์ ๋ณ๋ ฌ for ๋ฃจํ์ ๋ณธ๋ฌธ๊ณผ ๋ถ๋ฆฌ๋์ด ์์ต๋๋ค.
OCCA OKL ๊ตฌ๋ฌธ์ ๋ฃจํ ์ฐจ์๊ณผ ๋ณธ๋ฌธ ์ฝ๋๋ฅผ ๋ ์น์ํ ๋ณ๋ ฌ for ๋ฃจํ ๊ตฌ๋ฌธ์ผ๋ก ๊ฐ์ ธ์ค๋๋ก ํน๋ณํ ์ค๊ณ๋์์ต๋๋ค.
for (int b=0;b<B;++b;@outer(0)){ /* grid dimension defined here */
for (int t=0;t<T;++t;@inner(0)){ /* thread block dimension defined here */
if(b==0 && t==0) printf("B=%d, T=%d\n", B, T);
int n = t + T*b;
if(n<N){
xPy[n] = x[n] + y[n];
}
}
}
์ปค๋ ๋ด๋ถ์ ์ฝ๋๋ ๋ณ๋ ฌ for ๋ฃจํ ๊ฒฝ๊ณ๋ฅผ ๋ณ๋ ฌ for ๋ฃจํ์ ๋ณธ๋ฌธ์ ๋งค์ฐ ๊ฐ๊น๊ฒ ์ ์งํด์ผ ํฉ๋๋ค. ๋ํ ๋ฃจํ ๊ฒฝ๊ณ๋ ์ ๋ ฅ ๋ฐฐ์ด์ ์ํด ์ง์ ๋์ง ์์ต๋๋ค. ๋ ์ผ๋ฐ์ ์ธ ์ปค๋์ ๋ฐ์ดํฐ ๋ฐฐ์ด์ ๋ํด ๋งค์ฐ ๋ค๋ฅธ ์ค๋ ๋ ๊ทธ๋ฆฌ๋ ๊ตฌ์ฑ์ด ํ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
OKL ์ปค๋ ๊ตฌ์ฑ์ ์ฌ๋๋ค์ ๊ต์กํ ๋ CUDA/OpenCL ์ปค๋ ๊ตฌ๋ฌธ, ์ปค๋ ์คํ ๋งค๊ฐ๋ณ์ ๋ฐ ์ปค๋ ์ค๋ ๋ฉ ์ฒ ํ์ ๋ฐ๋ณต์ ์ผ๋ก ์ค๋ช ํด์ผ ํ๋ ์๋์ ์ธ ์ ํ์ด์์ต๋๋ค.
SYCL์๋ ์ฌ๊ธฐ์์ ๋
ผ์ ์ค์ธ CUDA/HIP์ __launch_bounds__
์ ๊ฐ์ ์ ์ฌํ ์ค๋ ๋ ๋ธ๋ก ํฌ๊ธฐ ํํธ๊ฐ ์์ต๋๊น?
์ข์ ์ง๋ฌธ. ์์๋ณด๊ธฐ ์ํด SYCL ํ์ค(v1.2.1)์ ๋ค์ ํ์ธํ์ต๋๋ค. OpenCL C์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์์ฑ์ด ์ง์๋๋ฉฐ cl
๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ C++ 11 ์์ฑ ์ง์ ์์ ํจ๊ป ์ ๊ณต๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด OpenCL C์ __attribute__(((reqd_work_group_size(n)))
[[cl::reqd_work_group_size(n)]]
์ ๊ฐ์ต๋๋ค.
์ค๋ ๋ ๊ทธ๋ฃน ํฌ๊ธฐ๋ฅผ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋ ๊ฐ์ง ์ ํ์ด ์์ต๋๋ค. work_group_size_hint(n)
๋ ์ํํธ ๋ฒ์ ์
๋๋ค. ์ค๋ ๋ ๊ทธ๋ฃน ํฌ๊ธฐ๋ n
๊ฐ ๋ ๊ฒ์ ์ ์ํ์ง๋ง req_work_group_size(n)
๋ ์๊ฒฉํ ์๊ตฌ ์ฌํญ์
๋๋ค. .
OCCA์ ๋ํ ๋ช ๊ฐ์ง ์ต์ :
occa::kernel ํด๋์ค์ "innerDimHint" ๋ฉค๋ฒ ํจ์๋ฅผ ์ถ๊ฐํ์ฌ CUDA/OpenCL/HIP์ ๋ํ ์ค๋ ๋ ๋ค ํํธ๋ฅผ ์ฌ์ฉํ์ฌ (์์ง ํด์์ ์๋ ๊ฒฝ์ฐ) ์ฌ์ปดํ์ผ์ ๊ฐ์ ์คํํฉ๋๋ค.
์ ์ค๋ ๋ ๋ฐฐ์ด ํฌ๊ธฐ๊ฐ ์ง์ ๋ ๋ ์ํ๋๋ ์ฌ์ปดํ์ผ์ ํธ๋ฆฌ๊ฑฐํ๊ธฐ ์ํด ์คํ๊ธฐ ๋ด๋ถ์ ์ผ๋ถ ๋ ผ๋ฆฌ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ผ๋ถ OCCA_ * ์ ์์ ์ํด ์ค์ /ํด์ ๋ ์ ์์ต๋๋ค.
์ด ๋ ๊ฐ์ง ๋ชจ๋ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋๋ ๋ฐฉ์์ผ๋ก ์ํํ ์ ์์ต๋๋ค.
๋๋ ์ค์ ๋ก ์ด๊ฒ์ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ณ๋์ ๋ฐํ์์ ์ ๋ขฐํ๊ณ ์๋ฌด ๊ฒ๋ ๋ค์ ์ปดํ์ผํ์ง ์๊ธฐ๋ก ์ ํํฉ๋๋ค. ๋ณธ์ง์ ์ผ๋ก @dmed256 ์ ์๋ ์ ์์ ์ฌ์ฉํ์ฌ ๋น๋ ์ํ์ผ๋ก ๋ง๋ ๋ค์ ๋ฐฑ์๋์์ ์ง์ํ๋ ๊ฒฝ์ฐ ๋ฒ์ญ ์ ์ปค๋์ ๊ฐ๊ฐ์ __launch_bound__
ํํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
CUDA ๋ฐ HIP์ ๊ฒฝ์ฐ __launch_bound__
๋ ์ค์ ๋ก ํํธ์ผ ๋ฟ์ด๋ฏ๋ก OpenCL์ work_group_size_hint
์ ๋ ์ ์ฌํ ์ ์์ต๋๋ค. ๋ธ๋ก์ ๊ฐ ์ค๋ ๋์์ ์ฌ์ฉํ ์ ์๋ค๊ณ ๊ฐ์ ํ ์ ์๋ ๋ ์ง์คํฐ ์๋ฅผ ์ปดํ์ผ๋ฌ์ ์๋ฆฌ๋ ๋ฐ๋ง ์ฌ์ฉ๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์์ ๋ฒ์๋ฅผ ์๋ฐํ๋๋ผ๋ ์ปค๋์ด ๋ ์ง์คํฐ๋ฅผ ๋ง์ด ์ฌ์ฉํ์ง ์์ ์ ์์ผ๋ฏ๋ก ๋ฐ๋์ ์ค๋ฅ๋ ์๋๋๋ค. ์ฌ์ฉ์๊ฐ ์์ ๋ฒ์๋ฅผ ์๋ฐํ๊ณ ์ค์ ๋ก ๋ ์ง์คํฐ๊ฐ ์ถฉ๋ถํ์ง ์์ ๊ฒฝ์ฐ ๋ฐํ์์ OCCA๊ฐ ์ก์์ผ ํ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
์๋ ํ๋๋ฅผ ์คํํ ๋ ๋๋ฌด ๋ง์ LDS ๋๋ REG๊ฐ ํ์ํ OCCA:HIP ์ปค๋์ ๋ํ ๋ถํ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ๋๋ HIP๊ฐ ์ก์๋ผ ์ค๋ฅ๋ฅผ ๋์ง ๊ฒ์ด๋ผ๊ณ ํ์์ ์ด์๋ค. ์ด์ ํด๊ฒฐ๋์๊ธธ ๋ฐ๋๋๋ค.
์ฌ์ฉ์๊ฐ ์ ๊ณตํ ํํธ๋ ๋ฐํ์์ ์ ์ค๋ ๋ ๊ตฌ์ฑ์ ๋ฐ๊ฒฌํ๋ ์คํ๊ธฐ๋ก๋ ๊ด์ฐฎ์ต๋๋ค.
์ฐธ๊ณ ๋ก ์ ๋ OKL ์ปค๋ ์ฝ๋(์: ์ธ๋ถ์ ๊ฒฝ์ฐ K_blockDim
, ๋ด๋ถ์ ๊ฒฝ์ฐ K_threadDim
)์์ ๋งคํฌ๋ก ์์ ๋์ฒด๋ฅผ ํตํด ํธ์คํธ ์ฝ๋์์ ๋ช
์์ ์ธ ๋ฐํ์ ๋ฃจํ ๊ฒฝ๊ณ๋ฅผ ์ง์ ํ๋ ๊ฒ๋ง์ผ๋ก๋ ๋ง์กฑํ์ต๋๋ค. ์ปค๋ ์ํ์ ํตํด ๋ฌผ๋ก GPU์ ํน์ฑ๊ณผ ์ํ๋ฅผ ์ฟผ๋ฆฌํ๋ ์์ฒด API ์ฝ๋๊ฐ ์์ต๋๋ค. ์ด ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฌํ ๋ฃจํ ๊ฒฝ๊ณ๋ฅผ ๊ณ์ฐํฉ๋๋ค. ์, ๊ทธ๋ฐ ์ข
๋ฅ์ ๋์ ๋ฌธ์ ๋ก ์ธํด ๋ฐํ์ ์ค์ JIT ์ฌ์ปดํ์ผ์ด ๊ฐ๋ ๋ฐ์ํ์ง๋ง ์ ๊ฒฝ์ฐ์๋ ์๊ณ๊ฐ ๋ณ๊ฒฝ์ ๋จ๊ณ์ ์ผ๋ก ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ ๋๋ฌธ ๊ฒฝ์ฐ์ด๋ฏ๋ก ์ค์ ๋ฃจํ ๊ฒฝ๊ณ๋ ์ผ๋ฐ์ ์ผ๋ก ๋์ผํ๊ฒ ์ ์ง๋๊ฑฐ๋ ์ฃผ์ด์ง ์ปค๋์ ๋ํ ์ผ๋ถ ๊ณตํต ์ธํธ์ ์ํฉ๋๋ค. ๋ํ JIT ์ฌ์ปดํ์ผ์ ์ค์ด๊ธฐ ์ํด ์ผ๋ถ ์ปค๋์ ๋ํด ์ฌ์ ์ปดํ์ผ์ ํ์ฉํฉ๋๋ค.
๋ฐํ์์ ์ด๋ฌํ ๋ฃจํ ๊ฒฝ๊ณ๋ฅผ ๋ช ์์ ์ผ๋ก ์ ์ํ๋ฉด OKL ์ฝ๋์์ GPU ๋ก์ปฌ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ๋ฐํ์ ํฌ๊ธฐ ์กฐ์ ์ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ด ์ค์ํ ๊ฒ ๊ฐ์ต๋๋ค.
https://rocmdocs.amd.com/en/latest/Current_Release_Notes/Current-Release-Notes.html#performance -impact-for-kernel-launch-bound-attribute
์ํฌ๋ฅธ ๊ตฌํ์ ๋ํ ์ฌ๊ณผ์ ํจ๊ป Np(>256) ์ค๋ ๋๊ฐ ํ์ํ libparanumal์ ์ปค๋์ ์ฌ์ฉํ๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋๋ค.
occa::properties kernelInfo;
...
if(platform.device.mode()=="HIP"){
char newflag[BUFSIZ];
sprintf(newflag, " --gpu-max-threads-per-block=%d", mesh.Np);
kernelInfo["compiler_flags"] += newflag;
}
์์ ๋ฒ์๋ฅผ ์ง์ ํ๊ธฐ ์ํด hipcc ์ปดํ์ผ๋ฌ ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด Noel Chalmers์ ์ํด ์ ์๋์์ต๋๋ค. ์ด์ฒด์ ์ธ ๊ตฌํ์ ๋ด ๊ฒ์ ๋๋ค.
์ปค๋์ด ์ต๋ ๊ฒฝ๊ณ๋ฅผ ์๋ฐํ๋ ๊ฒฝ์ฐ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ๋ถ๋ถ๋ช ํ๋ฏ๋ก ์ด ์์ ์ ์ํํ ๋ ์ฃผ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ถ์ ์ ํ ๋ฒ์๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ ์ํด ๋ค๋ฅธ ์ต๋ ์ค๋ ๋ ์๋ฅผ ์ฌ์ฉํ๋ ์ปค๋์ ๋ํด occa::properties
๊ฐ์ฒด์ ๋ณ๋ ๋ณต์ฌ๋ณธ์ ๋ง๋ญ๋๋ค.
์์ผ๋ก ์์ ๋ฒ์๋ฅผ ์๋ฐํ๋ฉด ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.