【初心者向け】 CMakeでCUDA個別コンパイルをマスター! CUDA_SEPARABLE_COMPILATIONの使い方


"CUDA_SEPARABLE_COMPILATION" プロパティは、CMake で CUDA ターゲットに対して設定できるプロパティの一つです。このプロパティを ON に設定すると、ターゲットに属するすべての CUDA ファイルに対して個別のコンパイルが有効化されます。

利点

個別のコンパイルを有効化することで、以下の利点が得られます。

  • モジュール化の促進: 個別のコンパイルは、CUDA コードをモジュール化し、再利用性を高めるのに役立ちます。
  • 依存関係の明確化: 個別のコンパイルにより、各 CUDA ファイル間の依存関係が明確になり、デバッグや保守が容易になります。

設定方法

"CUDA_SEPARABLE_COMPILATION" プロパティを設定するには、以下のコマンドを使用します。

set_property(TARGET <target_name> PROPERTY CUDA_SEPARABLE_COMPILATION <value>)

<target_name> は、プロパティを設定したいターゲットの名前です。<value> は、プロパティの値を指定します。この値は、ON または OFF のいずれかに設定できます。

以下の例は、myexe という名前のターゲットに対して "CUDA_SEPARABLE_COMPILATION" プロパティを ON に設定する方法を示します。

set_property(TARGET myexe PROPERTY CUDA_SEPARABLE_COMPILATION ON)

注意事項

"CUDA_SEPARABLE_COMPILATION" プロパティは、CMake 3.8 以降でのみ使用できます。また、このプロパティは、CUDA ツールキット 8.0 以降が必要です。

"CUDA_SEPARABLE_COMPILATION" プロパティの詳細については、CMake の公式ドキュメントを参照してください。

プログラミングへの応用

"CUDA_SEPARABLE_COMPILATION" プロパティは、以下の様なプログラミングシナリオで役立ちます。

  • パフォーマンスのチューニング: 個別のコンパイルにより、各 CUDA ファイルのパフォーマンスを個別に測定し、チューニングすることができます。
  • CUDA ライブラリの開発: CUDA ライブラリを開発する場合、個別のコンパイルにより、ライブラリの再利用性を高めることができます。
  • 大規模な CUDA アプリケーションの開発: 大規模な CUDA アプリケーションでは、多くの CUDA ファイルが使用されるため、個別のコンパイルを有効化することで、ビルド時間を大幅に短縮することができます。


cmake_minimum_required(VERSION 3.8)

project(myproject)

find_package(CUDA REQUIRED)

set(CUDA_NVCC_FLAGS "-O3")

add_executable(myexe main.cu)
set_property(TARGET myexe PROPERTY CUDA_SEPARABLE_COMPILATION ON)

target_link_libraries(myexe ${CUDA_CUDA_LIBRARY})

このコードは、以下のことを行います。

  1. CMake のバージョンを 3.8 以降に設定します。
  2. myproject という名前のプロジェクトを作成します。
  3. CUDA ツールキットを検索します。
  4. CUDA コンパイラフラグを -O3 に設定します。
  5. main.cu という名前のソースファイルから myexe という名前の実行可能ファイルを作成します。
  6. myexe ターゲットに対して "CUDA_SEPARABLE_COMPILATION" プロパティを ON に設定します。
  7. myexe 実行可能ファイルに CUDA ライブラリをリンクします。

このコードを実行すると、myexe という名前の実行可能ファイルが作成されます。この実行可能ファイルは、個別のコンパイルが有効化されているため、高速にビルドされます。

以下の例は、"CUDA_SEPARABLE_COMPILATION" プロパティをさまざまな状況で使用する方法を示しています。

例 1: 共有ライブラリの開発

cmake_minimum_required(VERSION 3.8)

project(mylib SHARED)

find_package(CUDA REQUIRED)

set(CUDA_NVCC_FLAGS "-O3")

add_library(mylib SHARED lib1.cu lib2.cu)
set_property(TARGET mylib PROPERTY CUDA_SEPARABLE_COMPILATION ON)

target_link_libraries(mylib ${CUDA_CUDA_LIBRARY})

このコードは、mylib という名前の共有ライブラリを作成します。このライブラリは、lib1.culib2.cu という名前の 2 つのソースファイルから構成されます。個別のコンパイルが有効化されているため、このライブラリは高速にビルドされます。

例 2: 静的ライブラリの開発

cmake_minimum_required(VERSION 3.8)

project(mylib STATIC)

find_package(CUDA REQUIRED)

set(CUDA_NVCC_FLAGS "-O3")

add_library(mylib STATIC lib1.cu lib2.cu)
set_property(TARGET mylib PROPERTY CUDA_SEPARABLE_COMPILATION ON)

target_link_libraries(mylib ${CUDA_CUDA_LIBRARY})

例 3: 実行可能ファイルの開発

cmake_minimum_required(VERSION 3.8)

project(myexe)

find_package(CUDA REQUIRED)

set(CUDA_NVCC_FLAGS "-O3")

add_executable(myexe main.cu lib1.cu lib2.cu)
set_property(TARGET myexe PROPERTY CUDA_SEPARABLE_COMPILATION ON)

target_link_libraries(myexe ${CUDA_CUDA_LIBRARY})

このコードは、myexe という名前の実行可能ファイルを作成します。この実行可能ファイルは、main.culib1.culib2.cu という名前の 3 つのソースファイルから構成されます。個別のコンパイルが有効化されているため、この実行可能ファイルは高速にビルドされます。



個別のコンパイラコマンドを使用する

"CUDA_SEPARABLE_COMPILATION" プロパティを使用する代わりに、個別のコンパイラコマンドを使用して各 CUDA ファイルを個別にコンパイルすることができます。これは、以下のコマンドを使用して行うことができます。

nvcc -c main.cu
nvcc -c lib1.cu
nvcc -c lib2.cu
nvcc myexe main.o lib1.o lib2.o

この方法は、"CUDA_SEPARABLE_COMPILATION" プロパティを使用するよりも柔軟性がありますが、CMake のビルドシステムを使用しないため、プロジェクトの管理が複雑になる可能性があります。

CMake の add_custom_command を使用する

"CUDA_SEPARABLE_COMPILATION" プロパティを使用する代わりに、CMake の add_custom_command マクロを使用して、個別のコンパイルコマンドを実行することができます。これは、以下のコードを使用して行うことができます。

add_custom_command(
    TARGET myexe
    COMMAND ${CMAKE_NVCC_COMPILER} -c main.cu
    COMMAND ${CMAKE_NVCC_COMPILER} -c lib1.cu
    COMMAND ${CMAKE_NVCC_COMPILER} -c lib2.cu
    COMMAND ${CMAKE_NVCC_COMPILER} myexe main.o lib1.o lib2.o
)

この方法は、"CUDA_SEPARABLE_COMPILATION" プロパティを使用するよりも詳細な制御を提供しますが、コードが冗長になる可能性があります。

Ninja ビルドシステムを使用する

"CUDA_SEPARABLE_COMPILATION" プロパティを使用する代わりに、Ninja ビルドシステムを使用することができます。Ninja は、CMake と互換性のある高速なビルドシステムであり、個別のコンパイルを自動的に実行することができます。

CMake Modules を使用する

"CUDA_SEPARABLE_COMPILATION" プロパティを使用する代わりに、CMake Modules を使用することができます。CMake Modules は、CMake の機能を拡張するために使用できるサードパーティ製のコードです。個別のコンパイルを有効にするための CMake Modules がいくつかあります。

どの方法を選択するべきか

どの方法を選択するべきかは、個々のプロジェクトの要件によって異なります。以下の点を考慮する必要があります。

  • 開発者のスキル: 開発者が CMake に精通している場合は、"CUDA_SEPARABLE_COMPILATION" プロパティを使用するか、CMake Modules を使用することをお勧めします。 開発者が CMake に慣れていない場合は、個別のコンパイラコマンドを使用することをお勧めします。
  • プロジェクトの複雑さ: プロジェクトが複雑な場合は、CMake の add_custom_command マクロを使用するか、Ninja ビルドシステムを使用することをお勧めします。
  • プロジェクトの規模: プロジェクトが大きい場合は、"CUDA_SEPARABLE_COMPILATION" プロパティを使用するか、CMake Modules を使用することをお勧めします。