2019/08/25

make時にGPUのアーキテクチャ番号を自動設定させる方法

背景


複数種類の開発環境でまたがってCUDAを利用したプログラムを開発する際、マシンに搭載されたGPUのアーキテクチャに応じて、CMakeLists.txt内のアーキテクチャ番号を毎回書き換える必要があった。メンテナンスの効率化のため、どのGPU搭載のマシンでmakeした場合でも、GPUの種類を識別して、そのGPUに最適なバイナリファイルを生成する環境を構築する。

記事の目的


makeする際に自動で搭載GPUのアーキテクチャを識別し、そのGPUに最適なバイナリーを出力するようにmake環境を構築する

仮想/実アーキテクチャの設定


ここでは、UbuntuにおけるマルチGPU対応のmake環境を構築するための方法について記載する。

nvccのコンパイルオプション

nvccのコンパイルオプションのうち、アーキテクチャに関する部分について記述する。
  • --gpu-architecture (-arch)
  • *.cuが対象にしている仮想アーキテクチャを指定する。したがって、基本的にはcompute_*の中から選択する。
  • --gpu-code (-code)
  • 仮想アーキテクチャのコード(*.ptx)から生成して出力に加えるアーキテクチャを指定する。PTXを含めたいときはcompute_*、特定のGPU向けバイナリを含めたいときはsm_*を選択する。
  • --generate-code arch=compute_*,code=\"compute_*,sm_*\"
  • 上記2つのオプションを一度に設定できる

導入方法

make環境を構築する手順は、下記の通りである。
  1. check_cuda.cuをCMakeLists.txtと同じ階層に置く
    1. // check_cuda.cu
    2. #include <stdio.h>
    3. int main(int argc, char **argv){
    4. cudaDeviceProp dP;
    5. float min_cc = 3.0;
    6. int rc = cudaGetDeviceProperties(&dP, 0);
    7. if(rc != cudaSuccess) {
    8. cudaError_t error = cudaGetLastError();
    9. printf("CUDA error: %s", cudaGetErrorString(error));
    10. return rc; /* Failure */
    11. }
    12. if((dP.major+(dP.minor/10)) < min_cc) {
    13. printf("Min Compute Capability of %2.1f required: %d.%d found",
    14. min_cc, dP.major, dP.minor);
    15. printf(" Not Building CUDA Code");
    16. return 1; /* Failure */
    17. } else {
    18. printf("%d%d", dP.major, dP.minor);
    19. return 0; /* Success */
    20. }
    21. }
  2. CMakeLists.txtを編集する
  3. 下記のコードを追加することで、$CUDA_NVCC_FLAGSにコンパイルしたマシンのアーキテクチャを自動設定できる。
    1. cmake_minimum_required(VERSION 3.0)
    2. # Find CUDA
    3. find_package(CUDA)
    4. if (CUDA_FOUND)
    5. #Get CUDA compute capability
    6. set(OUTPUTFILE ${CMAKE_CURRENT_SOURCE_DIR}/cuda_script) # No suffix required
    7. set(CUDAFILE ${CMAKE_CURRENT_SOURCE_DIR}/check_cuda.cu)
    8. execute_process(COMMAND nvcc -lcuda ${CUDAFILE} -o ${OUTPUTFILE})
    9. execute_process(COMMAND ${OUTPUTFILE}
    10. RESULT_VARIABLE CUDA_RETURN_CODE
    11. OUTPUT_VARIABLE ARCH)
    12. execute_process(COMMAND rm ${OUTPUTFILE})
    13. if(${CUDA_RETURN_CODE} EQUAL 0)
    14. set(CUDA_SUCCESS "TRUE")
    15. else()
    16. set(CUDA_SUCCESS "FALSE")
    17. endif()
    18. if (${CUDA_SUCCESS})
    19. message(STATUS "CUDA Architecture: -arch=sm_${ARCH}")
    20. message(STATUS "CUDA Version: ${CUDA_VERSION_STRING}")
    21. message(STATUS "CUDA Path: ${CUDA_TOOLKIT_ROOT_DIR}")
    22. message(STATUS "CUDA Libararies: ${CUDA_LIBRARIES}")
    23. message(STATUS "CUDA Performance Primitives: ${CUDA_npp_LIBRARY}")
    24. set(CUDA_NVCC_FLAGS "{$CUDA_NVCC_FLAGS};--generate-code arch=compute_${ARCH},code=\"compute_${ARCH},sm_${ARCH}\"")
    25. else()
    26. message(WARNING -arch=sm_${ARCH})
    27. endif()
    28. endif()

まとめ


  • 搭載GPUのアーキテクチャを識別し、そのGPUに最適なバイナリーを出力するmake環境を構築する手順について調査、記載した

参考文献



変更履歴


  1. 2019/08/25: 新規作成

0 件のコメント:

コメントを投稿

MQTTの導入

背景 IoTデバイスの接続環境構築のため、MQTT(mosquitto)の導入を行った。 記事の目的 MQTT(mosquitto)をUbuntuに導入する mosquitto ここではmosquittoについて記載する。 MQTT MQTT(Message Qu...