CUDA

最終更新日:2020年10月29日

CUDA(Compute Unified Device Architecture)は、NVIDIA社が開発したGPUプログラム開発環境です。 C/C++言語を拡張した言語仕様とAPI関数が提供されており、 これらを用いることでGPUに様々な処理を行わせることができます。 (アーキテクチャと区別するために「CUDA C」と呼ぶこともありますが、ここでは「CUDA」とだけ表記します。) このページでは、CUDAで記述されたプログラムのコンパイルおよび実行方法を説明します。 CUDAの詳細な仕様や提供されているAPI関数等については以下のページをご参照ください。

また、以下のページから様々なサンプルプログラムを入手できます。(CUDA Toolkitにも多数のサンプルが含まれています。)


利用環境

システム・バージョン・利用範囲

  • サブシステムB
  • バージョン 九州大学構成員 学術研究機関構成員 民間利用の方
    8.0
    9.1
    10.1
    11.0
  • 基本フロントエンド
  • バージョン 九州大学構成員 学術研究機関構成員 民間利用の方
    8.0
    9.1
    10.1
    11.0
  • 大容量フロントエンド
  • バージョン 九州大学構成員 学術研究機関構成員 民間利用の方
    8.0
    9.1
    10.1
    11.0

利用方法

環境設定(moduleコマンド)

CUDAプログラムのコンパイル、および実行時には、利用を希望するバージョンとともに、 moduleコマンドを実行してください。実行時の CUDAのバージョンには、コンパイル時と同じものを選択してください。

CUDA 8.0を使用する場合の例)

$ module load cuda/8.0

CUDA 9.1を使用する場合の例)

$ module load cuda/9.1

CUDA 10.1を使用する場合の例)

$ module load cuda/10.1

CUDA 11.0を使用する場合の例)

$ module load cuda/11.0

プログラムの作成とコンパイル

CUDAのプログラムを格納するファイル名の拡張子には .cu を使用してください。

CUDAプログラムのコンパイルはnvccコマンドで行います。 CUDA プログラムのコンパイルは以下のように行います。(ソースプログラム: test.cu, 実行ファイル: test)

$ nvcc -gencode arch=compute_60,code=sm_60 -o test test.cu

nvccは与えられたプログラムからCPU向けに書かれた部分(ホストコード)とGPU向けに書かれた部分(GPUカーネル)を分離し、それぞれコンパイルして一つの実行 ファイルを作成します。 GPUカーネル以外のCPU上で実行されるコードは、特に指定しない限りgccによってコンパイルされます。 インテルコンパイラ(icc)を用いてコンパイルしたい場合やCPU向けの最適化オプションを指定したい場合は -ccbinや-Xcompilerオプションを適切に指定してください。(本ページ下部、「主なコンパイルオプション」を参照。)
以下は「CPU上で実行されるコードのコンパイルにはiccを使いOpenMPによる並列化も行う」という設定の一例です。

$ nvcc -O3 -ccbin icc -Xcompiler="-O3 -no-prec-div -fp-model fast=2 -xHost -qopenmp" -gencode arch=compute_60,code=sm_60 -o test test.cu

ライブラリ等利用時の補足

moduleコマンドによって 環境変数PATHと環境変数LD_LIBRARY_PATHに、 それぞれ CUDAのコマンドとライブラリのパスが追加されます。
プロファイラやデバッガの機能を使う一部のCUDAプログラムを利用する場合には、 さらにヘッダファイルやライブラリの探索パスとして別のディレクトリを追加する必要があります。
コンパイル/リンク時のエラーメッセージにcuptiや cudacoreの文字列が出てくる場合には環境変数やコンパイル時オプションの追加を検討してください。

CUDA 8.0でプロファイラとデバッガの機能を使う場合の例: 
nvcc \
 -I/usr/local/cuda-8.0/extras/CUPTI/include -L/usr/local/cuda-8.0/extras/CUPTI/lib64 \
 -I/usr/local/cuda-8.0/extras/Debugger/include -L/usr/local/cuda-8.0/extras/Debugger/lib64 \
 -lcupti -lcudacore source.cu

GPUカーネルを含まないコードをコンパイルする場合 (ライブラリを呼び出すだけの場合や分割コンパイルを行う場合など)には、 ソースコードのコンパイルにはiccやgccを使用し、 使用するCUDAのバージョンに合わせてヘッダーファイルのインクルードやライブラリファイルのリンクを行ってください。


バッチジョブでのプログラム利用方法

コンパイルされたプログラムは、通常のコマンドと同様にジョブスクリプトに記述して実行できます。 コンパイル時と同様にmoduleコマンドの実行を行っておく必要があります。

CUDA 8.0を使用する場合の例)

#!/bin/bash
#PJM -L "vnode=1"
#PJM -L "vnode-core=36"
#PJM -L "rscunit=ito-b"
#PJM -L "rscgrp=ito-g-4"
#PJM -L "elapse=1:00"

module load cuda/11.0
./test

主なコンパイルオプション

nvccの主なコンパイルオプションは以下のとおりです。

コンパイルオプション 説明
-ccbin compiler ホストCPU向けのプログラムをコンパイルするコンパイラを指定する。未指定時はgccが使われるため、インテルコンパイラを使う場合には明示する必要がある。
-O[0,1..] ホストコードの最適化レベルを指定する。与えられたパラメタは-ccbinにて指定されたコンパイラに渡される。
-Xcompiler options -ccbinオプションで指定したコンパイラに与えるオプション。推奨オプション等については各コンパイラの説明を参照。
-gencode options 動作対象とするGPUの指定。
サブシステムBには
-gencode arch=compute_60,code=sm_60
基本フロントエンドには
-gencode arch=compute_61,code=sm_61
大容量フロントエンドには
-gencode arch=compute_53,code=sm_53
が対応する。 下位互換性があるため、例えば大容量フロントエンド向けにコンパイルしたプログラムをサブシステムBで実行することは可能だが、その逆は不可能。
-gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61
のように複数の-gencodeオプションを組み合わせて指定しても良く、実行時には最適なものが自動的に選択される。 コンパイル時間やバイナリファイルサイズは組み合わせの数だけ増加する。
--help (-h) 利用可能なオプションの一覧(説明)を表示する。
--version (-V) バージョン情報を表示する。

CUDAに関連するツールとライブラリ

CUDAプログラミングをサポートする多数のツールやライブラリが提供されています。 ここではそれらの幾つかについて紹介します。


デバッガ・プロファイラ

GPUカーネルのデバッガとしてはNVIDIAからcuda-gdbが提供されています。 基本的な使い方はgdbと同様ですが、コンパイル時に-Gオプションを付けておく必要があります。 詳細はCUDA-GDB :: CUDA Toolkit Documentationをご参照ください。
プロファイラとしては、GUIベースのプロファイラやCUIベースのプロファイラがNVIDIAから提供されています。 詳細はProfiler :: CUDA Toolkit Documentationをご参照ください。


様々なGPU向けライブラリ

GPUを用いて高速な処理を行う様々なライブラリが様々な開発者によって作られており、 すでに NVIDIAのWebサイト(NVIDIA Developer) には多くの情報が集約されています。
特に数値計算ライブラリについてはCUDA Toolkitに同梱されているものが数多くあります。 例えば、密行列計算向けのcuBLAS/NVBLAS、FFTを行うcuFFT、疎行列計算向けのcuSPARSE、グラフ処理向けのnvGRAPHなどは CUDA Toolkitの一部として配布されているため、 ヘッダファイルやライブラリをリンクすればすぐに利用可能です。 使い方などの有益な情報はCUDA Toolkitのドキュメントからリンクされています。 CUDA Toolkit Documentation
Deep Learningに関するツール/ライブラリも以下から参照できます。 Deep Learning Software | NVIDIA Developer


CUDA-Aware MPIおよびNVLinkの活用について

GPU上のメモリを直接MPI通信することができるCUDA-Aware MPIや、 NVLinkを用いてGPU間での直接通信を行うためのライブラリが用意されています。 これらの利用方法については今後情報を追加していく予定です。