CUDA, ROCm, oneAPI? — รันโค้ดบน GPU, GPU ใดๆ

Jan 02 2023
เหตุใดการรู้รูปแบบการเขียนโปรแกรม GPU ของผู้จำหน่ายหลายรายจึงเป็นสิ่งที่ชั่วร้ายที่จำเป็น...ใช่หรือไม่? บทนำ ในสองโพสต์ล่าสุดของฉันเกี่ยวกับการเขียนโปรแกรมแบบขนานและตัวเร่งความเร็ว ฉันได้พูดคุยเกี่ยวกับพื้นฐานของการเขียนโปรแกรมตัวเร่งความเร็วและแบบขนาน และแนวคิดการเขียนโปรแกรมบางอย่างที่จำเป็นเพื่อให้แน่ใจว่าโค้ดของคุณถูกต้อง คำถามที่น่าสนใจสำหรับการเขียนโปรแกรมเร่งการเรียนรู้ของโปรแกรมเมอร์คือ “ฉันจำเป็นต้องเรียนรู้ CUDA, ROCm และ SYCL เพื่อเขียนโปรแกรมสำหรับ NVIDIA, AMD และ Intel accelerators หรือไม่” เมื่อวางแผนซีรีส์นี้ ฉันคาดหวังที่จะเจาะลึกถึงความเหมือนและความแตกต่างระหว่างการทำงานของฮาร์ดแวร์และโมเดลหน่วยความจำของแต่ละสถาปัตยกรรม

เหตุใดการรู้รูปแบบการเขียนโปรแกรม GPU ของผู้จำหน่ายหลายรายจึงเป็นสิ่งที่ชั่วร้ายที่จำเป็น...ใช่หรือไม่?

ระบบทดสอบ เอื้อเฟื้อรูปภาพโดยผู้เขียน

บทนำ

ในสองโพสต์ ล่าสุดของฉัน เกี่ยวกับการเขียนโปรแกรมแบบขนานและตัวเร่งความเร็ว ฉันได้พูดคุยเกี่ยวกับพื้นฐานของการเขียนโปรแกรมตัวเร่งความเร็วและแบบขนาน และแนวคิดการเขียนโปรแกรมบางอย่างที่จำเป็นเพื่อให้แน่ใจว่าโค้ดของคุณถูกต้อง คำถามที่น่าสนใจสำหรับการเขียนโปรแกรมเร่งการเรียนรู้ของโปรแกรมเมอร์คือ “ฉันจำเป็นต้องเรียนรู้ CUDA, ROCm และ SYCL เพื่อเขียนโปรแกรมสำหรับ NVIDIA, AMD และ Intel accelerators หรือไม่”

เมื่อวางแผนซีรีส์นี้ ฉันคาดหวังที่จะเจาะลึกถึงความเหมือนและความแตกต่างระหว่างการทำงานของฮาร์ดแวร์และโมเดลหน่วยความจำของแต่ละสถาปัตยกรรม ฉันกำลังจะพูดถึง warps, wavefronts และ workgroups โครงสร้าง CUDA, ROCm และ SYCL ตามลำดับใช้เพื่อจัดกลุ่มการประมวลผลบนเธรดฮาร์ดแวร์ อย่างไรก็ตาม ยิ่งฉันคิดถึงมันมากเท่าไหร่ ก็ยิ่งดูเหมือนมากเกินไปสำหรับบล็อกโพสต์ หากคุณสนใจหัวข้อเหล่านั้น โปรดดูSYCL ที่ดีสำหรับนักพัฒนา CUDAจาก Codeplay

แต่วันนี้ฉันจะมุ่งเน้นไปที่วิธีทำให้คุณไม่ต้องเขียนโค้ด ไปจนถึงทำงานบน GPU หรือ GPU ใดๆ ก็ได้โดยเร็วที่สุด ไม่มีอะไรสนุกเท่ากับการได้เห็นประโยชน์ของคันเร่งของคุณโดยเร็วที่สุด สำหรับผม มันเป็นเรื่องสนุกเพราะมันเกิดขึ้นพร้อมกับการเปิดตัว Codeplay oneAPI สำหรับ NVIDIAและoneAPI สำหรับ AMD (เบต้า )

SYCL และ GPU ของผู้จำหน่ายหลายราย

SYCL เป็นรูปแบบการเขียนโปรแกรมที่รองรับคอมไพเลอร์สำหรับ GPU NVIDIA, AMD และ Intel คุณสามารถเขียนโค้ดของคุณใน SYCL จากนั้นสร้างและเรียกใช้บน GPU ของผู้จำหน่ายเหล่านั้น ก่อนหน้านี้จำเป็นต้องใช้คอมไพเลอร์ชุมชนต่างๆ หรือสร้างคอมไพเลอร์ Intel Open Source ขึ้นอยู่กับเป้าหมาย GPU ของคุณ ด้วยการเปิดตัว Codeplay toolchains ล่าสุด ตอนนี้คุณสามารถเรียกใช้โค้ดของคุณผ่าน toolchain เดียวที่สร้างไว้ล่วงหน้าได้อย่างรวดเร็วและง่ายดาย สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้ คุณสามารถอ่าน Ruyman Reyes, CTO ของ Codeplay, บล็อกเกี่ยวกับการเปิดตัวใหม่ของพวกเขา

คำถามหนึ่งที่คุณอาจถามคือฉันจะสร้างโค้ดของฉันเพียงครั้งเดียวจริง ๆ แล้วตัดสินใจว่าจะใช้ GPU ใดในรันไทม์ได้หรือไม่ คำตอบคือใช่ ! นี่คือข้อดีเกี่ยวกับการสนับสนุนนี้ คุณสร้างโค้ดของคุณเพียงครั้งเดียวและในขณะรันไทม์ คุณสามารถเลือกเป้าหมายด้วยตนเอง หรือปล่อยให้ไลบรารีรันไทม์เลือกให้คุณโดยอัตโนมัติ

เนื่องจากคุณมาไกลขนาดนี้แล้ว ฉันจะถือว่าสิ่งนี้เป็นที่สนใจของคุณ และเป้าหมายของฉันคือช่วยให้คุณเริ่มต้นใช้งาน GPU ที่คุณเลือกได้ สำหรับจุดประสงค์ของฉัน ฉันกำลังทดสอบ GPU ของผู้จำหน่ายทั้ง 3 รายบน Ubuntu 22.04 และทำการติดตั้งผ่าน APT

ระบบทดสอบ เอื้อเฟื้อรูปภาพโดยผู้เขียน

การติดตั้ง Codeplay toolchain

อันดับแรก เราตั้งค่าแพ็คเกจระบบพื้นฐานบางอย่าง:

sudo apt update
sudo apt -y install cmake pkg-config build-essential

# download the key to system keyring
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null

# add signed entry to apt sources and configure the APT client to use Intel repository:
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list

sudo apt-update
sudo apt install intel-basekit

ตรวจสอบให้แน่ใจว่าคุณมีไดรเวอร์พื้นฐาน/เฟรมเวิร์กที่คุณต้องการสำหรับ GPU แต่ละตัวที่คุณมี/ต้องการกำหนดเป้าหมาย ฉันจะเชื่อมโยงคำแนะนำของ Ubuntu อีกครั้ง:

ติดตั้งไดรเวอร์ Intel GPU

สามารถดูคำแนะนำสำหรับ Intel GPUs บน OS ต่างๆ ได้ที่นี่ เนื่องจากฉันใช้ Intel Arc บน Ubuntu 22.04 ฉันจึงทำตามคำแนะนำ เหล่า นี้

oneAPI สำหรับการติดตั้ง NVIDIA

คุณสามารถไปที่นี่เพื่อรับคำแนะนำอย่างเป็นทางการล่าสุดเกี่ยวกับวิธีติดตั้ง CUDA ฉันกำลังสรุปสิ่งที่ฉันใช้เพื่อเริ่มต้นใช้งาน:

  1. ติดตั้งพวงกุญแจ CUDA, CUDA และรีบูต
  2. wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb
    sudo dpkg -i cuda-keyring_1.0-1_all.deb
    
    sudo apt-get update
    sudo apt-get install cuda-11-7
    sudo apt-get install nvidia-gds
    sudo reboot
    

    export PATH=/usr/local/cuda-11.7/bin${PATH:+:${PATH}}
    export LD_LIBRARY_PATH=/usr/local/cuda-11.7/lib64\
                             ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
    

sh oneapi-for-nvidia-gpus-2023.0.0-linux.sh

. /opt/intel/oneapi/setvars.sh --include-intel-llvm
export PATH=/usr/local/cuda-11.7/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-11.7/lib64\
                         ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

คุณสามารถไปที่นี่เพื่อรับคำแนะนำอย่างเป็นทางการล่าสุดเกี่ยวกับวิธีติดตั้ง ROCm ได้ที่นี่ เพื่อให้คุณทำสิ่งต่างๆ ได้ง่ายขึ้น:

  1. ติดตั้งโปรแกรม AMD amdgpu-install ผ่าน APT
  2. sudo apt-get update
    wget https://repo.radeon.com/amdgpu-install/5.4.1/ubuntu/jammy/amdgpu-install_5.4.50401-1_all.deb
    sudo apt-get install ./amdgpu-install_5.4.50401-1_all.deb
    

    amdgpu-install --usecase="dkms,graphics,opencl,hip,hiplibsdk"
    

sh oneapi-for-amd-gpus-2023.0.0-linux.sh

. /opt/intel/oneapi/setvars.sh --include-intel-llvm

export PATH=/PATH_TO_ROCM_ROOT/bin:$PATH
export LD_LIBRARY_PATH=/PATH_TO_ROCM_ROOT/lib:$LD_LIBRARY_PATH

มีตัวอย่างโค้ดต่างๆ มากมายที่คุณสามารถลองใช้ในโอเพ่นซอร์ส ตัวอย่างที่เก็บ GitHub ของ oneAPI:

จากตัวอย่าง Codeplay คุณจะเห็นว่าพวกเขาสร้าง simple-sycl-app.cpp นี้:

#include <sycl/sycl.hpp>

int main() {
  // Creating buffer of 4 ints to be used inside the kernel code
  sycl::buffer<sycl::cl_int, 1> Buffer(4);

  // Creating SYCL queue
  sycl::queue Queue;

  // Size of index space for kernel
  sycl::range<1> NumOfWorkItems{Buffer.size()};

  // Submitting command group(work) to queue
  Queue.submit([&](sycl::handler &cgh) {
    // Getting write only access to the buffer on a device
    auto Accessor = Buffer.get_access<sycl::access::mode::write>(cgh);
    // Executing kernel
    cgh.parallel_for<class FillBuffer>(
        NumOfWorkItems, [=](sycl::id<1> WIid) {
          // Fill buffer with indexes
          Accessor[WIid] = (sycl::cl_int)WIid.get(0);
        });
  });

  // Getting read only access to the buffer on the host.
  // Implicit barrier waiting for queue to complete the work.
  const auto HostAccessor = Buffer.get_access<sycl::access::mode::read>();

  // Check the results
  bool MismatchFound = false;
  for (size_t I = 0; I < Buffer.size(); ++I) {
    if (HostAccessor[I] != I) {
      std::cout << "The result is incorrect for element: " << I
                << " , expected: " << I << " , got: " << HostAccessor[I]
                << std::endl;
      MismatchFound = true;
    }
  }

  if (!MismatchFound) {
    std::cout << "The results are correct!" << std::endl;
  }

  return MismatchFound;
}

โดยปกติแล้ว ในการสร้างสำหรับเป้าหมายต่างๆ ของเรา เราสามารถใช้บรรทัดคำสั่งที่มีลักษณะดังนี้:

NVIDIA:

clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda simple-sycl-app.cpp -o simple-sycl-app

clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend --offload-arch=<ARCH> simple-sycl-app.cpp -o simple-sycl-app

clang++ -fsycl -fsycl-targets=spir64 simple-sycl-app.cpp -o simple-sycl-app

สร้างสำหรับ GPU ของผู้จำหน่ายหลายราย

สมมติว่าฉันต้องการรัน NVIDIA และ Intel GPUs ในเวลาเดียวกัน ฉันสามารถสร้าง fat binary ที่จะรันบน NVIDIA หรือ Intel GPU ได้ เคล็ดลับที่นี่คือการตั้งค่าพารามิเตอร์บรรทัดคำสั่ง build ของคุณอย่างเหมาะสมเพื่อให้มีเป้าหมาย SYCL หลายรายการ

clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda,spir64 simple-sycl-app.cpp -o simple-sycl-app

tonym@LianLi-Linux:~/dev/2023.0Test$ clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda,spir64 simple-sycl-app.cpp -o simple-sycl-app
 
tonym@LianLi-Linux:~/dev/2023.0Test$ SYCL_DEVICE_FILTER=cuda SYCL_PI_TRACE=1 ./simple-sycl-app
SYCL_PI_TRACE[basic]: Plugin found and successfully loaded: libpi_cuda.so [ PluginVersion: 11.15.1 ]
SYCL_PI_TRACE[all]: Selected device: -> final score = 1500
SYCL_PI_TRACE[all]:   platform: NVIDIA CUDA BACKEND
SYCL_PI_TRACE[all]:   device: NVIDIA GeForce RTX 3080 Ti
The results are correct!
tonym@LianLi-Linux:~/dev/2023.0Test$
 
tonym@LianLi-Linux:~/dev/2023.0Test$ SYCL_DEVICE_FILTER=ext_oneapi_level_zero:gpu:0 SYCL_PI_TRACE=1 ./simple-sycl-app
SYCL_PI_TRACE[basic]: Plugin found and successfully loaded: libpi_level_zero.so [ PluginVersion: 11.15.1 ]
SYCL_PI_TRACE[all]: Selected device: -> final score = 1550
SYCL_PI_TRACE[all]:   platform: Intel(R) Level-Zero
SYCL_PI_TRACE[all]:   device: Intel(R) Graphics [0x56a0]
The results are correct!

งานในอนาคต

ผู้อ่านที่ชาญฉลาดบางคนอาจสังเกตเห็นว่าฉันไม่ได้ใส่ตัวอย่าง AMD ในตัวอย่าง GPU ของผู้จำหน่ายหลายราย นี่เป็นเพราะฉันเพิ่งแทนที่ด้วย AMD 6800XT GPU ด้วย AMD RX 7900XT GPU ใหม่ล่าสุด ขออภัย ขณะนี้ ROCm ไม่ได้ติดตั้งอย่างถูกต้องบนระบบ Linux ของฉัน โดยไม่คำนึงถึงเคอร์เนลที่ฉันใช้กับการ์ด RDNA3 เมื่ออัปเดตแล้ว ฉันจะกลับมาและให้คำแนะนำพร้อมตัวอย่างการทำงานบนการ์ดทั้ง 3 ใบ

โปรดทราบว่าก่อนหน้านี้เวอร์ชันของโฟลว์นี้ใช้งานได้กับ 6800XT แต่นั่นคือก่อนที่ซอฟต์แวร์ Codeplay จะเปิดตัวโดยใช้โฟลว์ DPC++ แบบโอเพ่นซอร์สที่บันทึกไว้ที่นี่:

บทสรุป

oneAPI สำหรับ NVIDIA GPUs จาก Codeplay ทำให้ฉันสามารถสร้างไบนารีสำหรับ NVIDIA หรือ Intel GPUs ได้อย่างง่ายดาย เวลาในการตั้งค่า oneAPI เพิ่มเติมสำหรับ NVIDIA GPUs ใช้เวลาประมาณ 10 นาทีในการติดตั้ง Intel oneAPI Base Toolkit ซึ่งรวมถึงการติดตั้ง CUDA และซอฟต์แวร์ Codeplay

ซอฟต์แวร์ Codeplay ใหม่จะปลดล็อกตัวเลือกใหม่ล่าสุดสำหรับบุคคลและบริษัทที่พิจารณาตัวเลือก GPU ของผู้จำหน่ายหลายราย ก่อนที่ตัวเลือกจะเป็นโอเพ่นซอร์ส คอมไพเลอร์ที่สนับสนุนโดยชุมชน นี่เป็นตัวเลือกที่ยอดเยี่ยมและเป็นสิ่งที่ฉันมักใช้กับงานประจำวัน

อย่างไรก็ตาม สำหรับคนที่พิจารณาการสนับสนุนในระยะยาว ธุรกิจต่าง ๆ ต้องพึ่งพา toolchains สำหรับการดำรงชีวิต การมีตัวเลือกที่ได้รับการสนับสนุนอย่างเป็นทางการจาก Codeplay และ Intel สามารถช่วยให้สบายใจได้

ถ้าคุณต้องการดูข่าวเทคโนโลยีแบบสุ่มที่ฉันอ่าน คุณสามารถติดตามฉันได้ที่ Twitter นอกจากนี้ ลองดูCode Togetherซึ่งเป็นพอดคาสต์ของ Intel สำหรับนักพัฒนาที่ฉันโฮสต์ไว้เพื่อพูดคุยเรื่องเทคโนโลยี

Tony เป็นสถาปนิกซอฟต์แวร์และผู้เผยแพร่ศาสนาด้านเทคนิคที่ Intel เขาเป็นสถาปนิกของ Intel VTune Profiler และเครื่องมือประสิทธิภาพอื่นๆ และล่าสุดเป็นผู้นำทีมวิศวกรรมซอฟต์แวร์ที่สร้างแพลตฟอร์มศูนย์ข้อมูลซึ่งเปิดใช้งานโซลูชัน MLPerf ที่ปรับขนาดได้ของ Habana