OpenCL/CUDAのスレッド間通信めも

CUDAとOpenCLでスレッド同士の通信でどうするんだっけ?と思って調べたことを自分用にメモ。

AMD(OpenCL)はshuffleがなさそう

  • retval = sub_group_broadcast(value, thread_id)がある
  • 特定の1つのthread_idからWavefront全体に値をわたせる
  • 隣のスレッドと値を交換するshuffleみたいなのは無さそう

参考(StackOverflow "Can we use shuffle() instruction for reg-to-reg data-exchange between items (threads) in WaveFront?")

CUDAはshuffleがある

  • __shfl_down()でスレッドIDの若番側へデータを送れる
  • __shfl_up()でスレッドIDの大きな方へデータを送れる
  • __shfl_xor()で2スレッド同士でデータ交換できる

参考("CSE 599 I Accelerated Computing - Programming GPUS Warp Shuffle and Warp Vote Instructions" 16/43ページ、17/43ページ、26/43ページ)

__shfl_xorを使えばbitonic sort実装できそう、と思っていたらすでにあった

  • facebook/fbcuda @ github
  • とはいえ、Warpサイズを超えるデータ数だとShared Memory使ったりする必要がありそう

あとついでにメモ

ROCm Docker内でfind_package(OpenCL)に失敗した

  • 使ったイメージはrocm2.9_ubuntu18.04_py3.6
  • cmake v3.6.3(古いなぁ・・・)
  • cmake AMDAPPSDKROOT=/opt/rocm/opencl ..だとエラー
    • exportしても同じ
  • CMakeLists.txtで直接上書きしたら(当然だけど)OK
cmake_minimum_required(VERSION 3.6)
set(OpenCL_INCLUDE_DIR /opt/rocm/opencl/include)
set(OpenCL_LIBRARY /opt/rocm/opencl/lib/x86_64)
find_package(OpenCL REQUIRED)

/usr/local/share/cmake-3.6/Modules/FindOpenCL.cmakeはこうなってた。AMDAPPSDKROOTを見に行くように見えるのだが・・・

find_path(OpenCL_INCLUDE_DIR
  NAMES
    CL/cl.h OpenCL/cl.h
  PATHS
    ENV "PROGRAMFILES(X86)"
    ENV AMDAPPSDKROOT
    ENV INTELOCLSDKROOT
    ENV NVSDKCOMPUTE_ROOT
    ENV CUDA_PATH
    ENV ATISTREAMSDKROOT
  PATH_SUFFIXES
    include
    OpenCL/common/inc
    "AMD APP/include")