問題の概要:CUDAコードのコンパイルで頻発するnvccエラー
CUDAを用いたGPUプログラミングにおいて、カーネルコードを書いた後の最初の関門がnvcc(NVIDIA CUDA Compiler)によるコンパイルです。特に環境構築直後や、異なるマシン・CUDAバージョン間でコードを移動した際に、様々なコンパイルエラーに遭遇することがあります。これらのエラーは、単純な構文エラーから、複雑な環境設定の問題まで多岐にわたり、初心者を悩ませる原因となります。本記事では、実際の開発現場で頻繁に発生する代表的なnvccコンパイルエラーと、その体系的な解決方法を解説します。
原因の解説:なぜnvccエラーは起こるのか?
nvccエラーの根本原因は、主に以下の4つのカテゴリに分類できます。
1. 環境設定の不一致
CUDA Toolkitのバージョン、GPUアーキテクチャ(Compute Capability)、ホストコンパイラ(gcc, clang, MSVCなど)のバージョンが、コードの要求や互換性の範囲外である場合です。CUDAは特定のバージョンのホストコンパイラにしか対応していません。
2. パスとライブラリの参照エラー
nvccがCUDAのインクルードファイル(*.h)やライブラリ(libcudart.so など)を見つけられない場合です。環境変数PATHやLD_LIBRARY_PATH(Linux)、CUDA_PATH(Windows)の設定不備が原因です。
3. コードの構文・セマンティクスエラー
CUDA特有のキーワード(__global__, __shared__)の誤用、サポートされていないC++機能の使用、またはGPUアーキテクチャに対応していない組み込み関数の使用です。
4. ターゲットGPUアーキテクチャの指定ミス
コンパイル時に-archフラグで指定するCompute Capability(例:sm_61)が、実際のGPUの能力と合っていない、または全く指定されていない場合です。
解決方法:主要5エラーへのステップバイステップ対応
エラー1: 「No kernel image is available for execution on the device」または「unsupported gpu architecture」
原因: コンパイル時に指定されたGPUアーキテクチャ(-arch)と、実行環境のGPUのCompute Capabilityが一致しない。
解決手順:
1. 自身のGPUのCompute Capabilityを確認します。
# NVIDIAドライバが入っている状態で
nvidia-smi -q | grep "Compute Capability"
# または、CUDAサンプルコードを利用
deviceQuery # CUDAサンプルをビルドして実行
2. nvccコマンドに適切な-archフラグを追加します。例えば、Compute Capability 7.5のGPU(Turing世代のGeForce RTX 20シリーズ等)の場合:
# 単一アーキテクチャ向けにコンパイル
nvcc -arch=sm_75 my_kernel.cu -o my_program
# または、複数アーキテクチャ向けのFat Binaryを生成(推奨)
nvcc -arch=compute_75 -code=sm_75 my_kernel.cu -o my_program
エラー2: 「nvcc fatal : Host compiler targets unsupported OS」
原因: ホストコンパイラ(gcc等)のバージョンが、使用しているCUDA Toolkitバージョンでサポートされていない。
解決手順:
1. 現在のgccバージョンを確認します。
gcc --version
2. NVIDIA公式ドキュメント「CUDA Toolkit Release Notes」の「System Requirements」セクションで、自分のCUDAバージョンに対応するサポートされているホストコンパイラのバージョンを確認します。
3. サポートされているバージョンのコンパイラをインストールし、nvccに明示的に指定します。
# 例:gcc-9を使用する場合(Linux)
sudo apt install gcc-9 g++-9
nvcc -ccbin g++-9 my_kernel.cu -o my_program
エラー3: 「fatal error: cuda_runtime.h: No such file or directory」
原因: CUDAのインクルードディレクトリがコンパイラの検索パスに含まれていない。
解決手順:
1. CUDAインストールパスを確認します。通常は/usr/local/cuda(Linux)またはC:Program FilesNVIDIA GPU Computing ToolkitCUDAvX.Y(Windows)です。
2. コンパイル時にインクルードパスを明示的に指定します。
# Linux/macOSの場合
nvcc -I/usr/local/cuda/include my_kernel.cu -o my_program
# または、環境変数を設定して恒久的に対応(.bashrc等に記述)
export CPATH=/usr/local/cuda/include:$CPATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
:: Windows (Visual Studio Developer Command Prompt) の場合
nvcc -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.8include" my_kernel.cu
エラー4: 「identifier “__shfl_down” is undefined」などの組み込み関数エラー
原因: 関数が使用するGPUアーキテクチャ(Compute Capability)でサポートされていない。上記の__shfl_downはsm_30以降で利用可能ですが、__shfl_syncなどの新しい関数はsm_70以降など、より新しいアーキテクチャが必要です。
解決手順:
1. 使用しようとしている関数のドキュメントを確認し、必要なCompute Capabilityを調べます。
2. コンパイル時に、そのアーキテクチャを適切に指定します。古いアーキテクチャ向けにコンパイルしている場合は、コードを互換性のある方法で書き換える必要があるかもしれません。
# 例:sm_70以上のアーキテクチャ向けにコンパイル(Volta世代以降)
nvcc -arch=sm_70 my_kernel.cu -o my_program
エラー5: 「PTX JIT compilation failed: Unsupported .version …」
原因: 生成されたPTX中間コードのバージョンが、実行時のGPUドライバでサポートされていない。これは、新しいCUDA Toolkit(新しいPTXを生成)でコンパイルしたコードを、古いドライバが搭載された環境で実行しようとした場合に発生します。
解決手順:
1. 実行環境のNVIDIAドライババージョンを確認します。
nvidia-smi
2. ドライバを、使用しているCUDA Toolkitバージョンが要求する最小バージョン以上にアップデートします。あるいは、コンパイル時に古いPTXバージョンをターゲットに指定します(機能制限が発生する可能性あり)。
# 互換性の高い古い仮想アーキテクチャを指定する例
nvcc -arch=compute_50 -code=sm_50,compute_50 my_kernel.cu -o my_program
コード例・コマンド例:健全なコンパイルのベストプラクティス
以下の例は、複数の一般的なGPUアーキテクチャに対応したFat Binaryを生成し、デバッグ情報も含める推奨コンパイルコマンドです。
# 一般的なデスクトップGPU(MaxwellからAmpereまで)向けの互換性の高いコンパイル
nvcc
-arch=compute_50 # 仮想アーキテクチャ(PTX生成)
-code=sm_50,sm_52,sm_61,sm_70,sm_75,sm_80,sm_86 # 実アーキテクチャ(Cubin生成)
-O2 # 最適化レベル2
-Xcompiler "-fopenmp" # ホストコンパイラへのオプション伝達(OpenMP有効化)
--default-stream per-thread # モダンなストリーム仕様
-o my_app
my_main.cu my_kernel.cu
# CMakeLists.txtでの設定例(CMake 3.18以降、FindCUDAではなくnative CUDAサポートを利用)
cmake_minimum_required(VERSION 3.18)
project(MyCudaApp LANGUAGES CXX CUDA) # CUDAを言語として明示
set(CMAKE_CUDA_ARCHITECTURES "50;52;61;70;75;80;86") # ターゲットアーキテクチャの指定
add_executable(my_app main.cpp kernel.cu)
target_compile_options(my_app PRIVATE $<$:-O2>)
まとめ・補足情報
nvccコンパイルエラーの解決は、「エラーメッセージを正確に読む」→「原因を4つのカテゴリに当てはめて推測する」→「環境設定とコンパイルオプションを系統的に確認・修正する」というプロセスが基本です。特に、CUDA Toolkit、GPUドライバ、ホストコンパイラのバージョン互換性表は必ず参照してください。
トラブルシューティングの最終手段として、NVIDIAが提供するCUDA Installation Guideやnvccユーザーマニュアルを確認することも有効です。また、コンテナ技術(Docker, NVIDIA Container Toolkit)を利用して、再現性の高いCUDA開発環境を構築することは、環境起因のエラーを根本的に減らす現代的な解決策と言えるでしょう。
CUDAプログラミングは、並列処理のパワーをもたらす反面、環境設定という初期ハードルが存在します。本記事で紹介した手順を参考に、確実にコンパイルを通す第一歩を踏み出してください。