SYCL 입문 시리즈의 첫 번째 글입니다. 이번 글에서는 SYCL이란 무엇이며, 왜 SYCL을 사용할 때 NVIDIA GPU나 Qualcomm GPU에서도 동일한 코드를 실행할 수 있는지 기본 개념을 소개합니다. 또한 개발 환경 설정, CMake 빌드 시스템 활용, 그리고 가장 기본적인 “Hello SYCL!” 예제를 통해, 독자가 실제로 코드를 컴파일하고 실행해보는 과정을 안내하겠습니다.
이 글은 SYCL에 완전히 처음 입문하는 독자를 대상으로 하며, 모든 단계에 대해 가능한 한 자세히 설명하여, 글을 따라만 해도 실제 코드를 실행할 수 있도록 하였습니다.
왜 SYCL인가?
SYCL은 Khronos 그룹에서 정의한, C++ 기반의 이식성 높은 병렬 프로그래밍 모델입니다. CUDA는 NVIDIA GPU 전용이고, OpenCL은 다양한 디바이스를 지원하지만 C 스타일 API를 사용합니다. SYCL은 C++17 이상을 활용한 모던한 API를 제공하며, 다양한 벤더의 GPU(예: NVIDIA, Qualcomm)에서 동일한 코드를 컴파일하고 실행할 수 있는 잠재력을 가지고 있습니다.
- NVIDIA GPU: CUDA 백엔드(hipSYCL나 oneAPI DPC++를 통한) 활용
- Qualcomm GPU: OpenCL 백엔드 혹은 Level Zero, 또는 oneAPI 기반 구현체 사용 가능성
이렇게 SYCL을 통해 특정 벤더 종속성에서 벗어나 좀 더 이식성 높은 GPU 코드를 작성할 수 있습니다.
목표
- SYCL 기본 개념 이해: 호스트 코드(C++), 디바이스 코드(커널), 큐(queue), 버퍼(buffer) 등
- 간단한 “Hello SYCL!” 예제 실행: CPU 또는 GPU 중 하나에서 돌려보며 환경 점검
- CMake 빌드 시스템으로 SYCL 코드 빌드
- 다음 글에서는 NVIDIA 및 Qualcomm GPU에서 동일 코드 실행하기 위한 세부 설정을 소개할 예정
오늘은 일단 SYCL 구현체 중 하나(예: oneAPI DPC++ 또는 hipSYCL)를 설치하고, CPU 또는 NVIDIA GPU를 대상으로 하는 간단한 예제를 실행해보겠습니다. Qualcomm GPU에 대한 설정은 다음 글에서 자세히 다룰 예정입니다.
준비 사항
- 운영체제: Linux(우분투 20.04 이상 권장)
- C++17 이상 지원하는 컴파일러(gcc 9 이상)
- CMake(3.10 이상)
- SYCL 구현체(예: Intel oneAPI DPC++ Compiler, hipSYCL)
SYCL 구현체 선택 (초보자용 가이드)
- oneAPI DPC++: Intel에서 주도하는 SYCL 구현체. CPU, Intel GPU, 일부 백엔드를 통해 NVIDIA GPU 지원(시험적) 가능.
- hipSYCL: LLVM/Clang 기반 SYCL 구현으로, CUDA 백엔드나 ROCm 백엔드 등을 통해 NVIDIA GPU 지원이 잘 이루어짐.
- NVIDIA GPU 사용 시 hipSYCL + CUDA 백엔드 권장
- Qualcomm GPU 지원은 OpenCL 백엔드가 필요할 수 있음. 이 부분은 차후 글에서 추가 설명
초심자라면 일단 hipSYCL 또는 oneAPI DPC++를 설치하고 CPU/Intel/NVIDIA GPU에서 코드가 돌아가는지 확인하는 단계를 거치는 것이 좋습니다.
hipSYCL 설치 예시(Ubuntu)
# 패키지 리포지토리 추가 (hipSYCL 공식 문서 참고)
# 예: https://gitlab.com/hipSYCL/hipSYCL/-/wikis/Installation
# 아래는 예시이며, 실제 설치 지침은 hipSYCL 깃랩 위키 참고
sudo apt install hipsycl-base hipsycl-dev
# 설치 완료 후 syclcc, syclcc-clang 명령 등이 제공
oneAPI DPC++ 설치 예시
# Intel oneAPI Base Toolkit 설치(공식 문서 참고)
# 설치 후 dpcpp 명령어 사용 가능
둘 중 하나 구현체만 준비해도 됩니다. 일단 CPU 타겟으로 “Hello SYCL!” 돌려보는 것이 1단계 목표입니다.
CMake 프로젝트 구조
my_sycl_hello/
├─ CMakeLists.txt
└─ src/
└─ main.cpp
main.cpp
에 간단한 SYCL 코드를 작성하고, CMake를 통해 빌드합니다.
Hello SYCL 코드 (main.cpp)
이 예제는 SYCL 큐(queue)를 하나 만들고, 디바이스 정보(이 큐가 타겟하는 디바이스의 이름)를 출력한 뒤, 간단히 1차원 배열을 SYCL 커널로 처리하는 예제입니다. 초반에는 CPU 디바이스나 NVIDIA GPU 디바이스를 SYCL 구현체가 자동으로 선택할 수도 있습니다.
#include <CL/sycl.hpp>
#include <iostream>
#include <vector>
int main() {
try {
// SYCL 큐 생성: 기본 device_selector 사용 (CPU 또는 GPU 중 하나 선택)
sycl::queue q;
std::cout << "Running on: " << q.get_device().get_info<sycl::info::device::name>() << "\n";
size_t N = 1024;
std::vector<float> data(N, 1.0f);
{
// 버퍼 생성: data 벡터를 감싸서 디바이스 접근 가능
sycl::buffer<float,1> buf(data.data(), sycl::range<1>(N));
// 커맨드 그룹 제출
q.submit([&](sycl::handler& cgh) {
auto acc = buf.get_access<sycl::access::mode::read_write>(cgh);
cgh.parallel_for<class simple_kernel>(sycl::range<1>(N), [=](sycl::id<1> i) {
// 각 원소를 2배로 만듦
acc[i] *= 2.0f;
});
});
} // 스코프 끝나면 buf가 언맵되어 Host 메모리에 결과 반영
// 결과 확인
std::cout << "data[0] = " << data[0] << ", data[100] = " << data[100] << "\n";
std::cout << "All elements should now be 2.0\n";
} catch (sycl::exception const &e) {
std::cerr << "SYCL Exception: " << e.what() << "\n";
return 1;
}
return 0;
}
이 코드에서는 sycl::queue q;
로 기본 디바이스를 선택합니다. CPU나 GPU 중 SYCL 구현체가 고를 것입니다. NVIDIA GPU 또는 Qualcomm GPU에서 실행하려면 다음 글에서 디바이스 셀렉터를 조정하는 방법을 다룰 예정입니다. 일단 CPU나 Intel/NVIDIA 중 가능한 디바이스가 선택될 수 있습니다.
CMakeLists.txt 예제
SYCL 구현체에 따라 컴파일러 명령어가 다를 수 있습니다. oneAPI DPC++ 사용 시 dpcpp
, hipSYCL 사용 시 syclcc
또는 clang++ -fsycl
등을 사용해야 합니다. 이 예제에서는 환경 변수나 CMake 옵션으로 SYCL 컴파일러를 지정했다고 가정합니다.
cmake_minimum_required(VERSION 3.10)
project(hello_sycl CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# SYCL 컴파일러 설정 (예: dpcpp)
# 실제 환경에 맞게 설정 필요
# 예: cmake -D SYCL_COMPILER=dpcpp ..
if(NOT DEFINED SYCL_COMPILER)
set(SYCL_COMPILER "dpcpp")
endif()
set(CMAKE_CXX_COMPILER ${SYCL_COMPILER})
add_executable(hello_sycl src/main.cpp)
빌드 시 다음처럼 컴파일러를 지정할 수 있습니다.
mkdir build
cd build
cmake -D SYCL_COMPILER=dpcpp ..
make
./hello_sycl
만약 hipSYCL을 사용한다면 cmake -D SYCL_COMPILER=syclcc ..
와 같이 명령어를 변경할 수 있습니다.
실행 결과
프로그램을 실행하면 다음과 같이 출력될 수 있습니다.
Running on: Intel(R) UHD Graphics [0x3ea0] # 예: Intel GPU
data[0] = 2, data[100] = 2
All elements should now be 2.0
만약 NVIDIA GPU를 사용할 수 있는 환경이라면 Running on: NVIDIA ... GPU
와 같은 문구가 나올 수도 있습니다. Qualcomm GPU는 추후 글에서 디바이스 셀렉터와 백엔드 설정을 통해 접근하는 방법을 다룰 것입니다.
정리 및 다음 글 예고
이번 글에서는 SYCL과 C++ 기반 GPGPU 프로그래밍 개념을 소개하고, 최소한의 “Hello SYCL!” 예제를 통해 CPU 또는 GPU 디바이스에서 코드를 실행해보는 과정을 살펴봤습니다. CMake 빌드 시스템 설정 방법과 SYCL 구현체 선택, 기본 실행 환경 구성을 확인했습니다.
다음 글(#2)에서는 NVIDIA GPU를 대상으로 SYCL 코드를 실행하기 위한 설정 방법, Qualcomm GPU 접근을 위한 백엔드 선택 전략 등을 다루며, 실제로 여러 벤더 GPU에서 동일한 SYCL 코드를 실행하는 목표에 한 걸음 더 다가갈 것입니다.
'개발 이야기 > SYCL (시클)' 카테고리의 다른 글
[SYCL 입문 #4] ND-Range 활용과 메모리 최적화 기법 소개 (0) | 2024.12.19 |
---|---|
[SYCL 입문 #3] 메모리 모델 & 커널 작성 패턴 이해하기 (0) | 2024.12.19 |
[SYCL 입문 #2] NVIDIA와 Qualcomm GPU에서 SYCL 코드 실행하기 (1) | 2024.12.19 |