CMake CUDA: статическая ссылка с cublas

Я хочу скомпилировать CUDALibrarySamples. cuFFT использует cmake, и я хочу скомпилировать и связать приложение 1d_c2c со статической версией cufft lib (-lcufft_static). Использование Makefiles тривиально, я добавил -lcufft_static в

nvcc -x cu $(FLAGS) $(INC) 1d_c2c_example.cpp -o 1d_c2c_example $(LIBS)

Однако я не уверен, как я могу сделать то же самое с помощью cmake. Я заметил, что cmake имеет статические флаги: CUDA_cublasLt_static_LIBRARY, CUDA_cufft_static_LIBRARY и т. д. Итак, мой вопрос: как их включить? Заранее спасибо!

я пытался

target_link_libraries(${ROUTINE}_example PRIVATE ${CUDA_cufft_static_LIBRARY})

но, похоже, это не работает.

Согласно предложению @paleonix, я сделал следующее:

target_link_libraries(${ROUTINE}_example PRIVATE CUDA::cufft_static CUDA::cudart). 

НО я получаю следующую ошибку:

/usr/bin/ld: /opt/cuda/lib64/libcufft_static.a(cbdouble_32bit_prime_callback_RT_SM35_plus.o): in function __sti____cudaRegisterAll()': cbdouble_32bit_prime_callback_RT_SM35_plus.compute_86.cudafe1.cpp:(.text.startup+0x1d): undefined reference to __cudaRegisterLinkedBinary_61_cbdouble_32bit_prime_callback_RT_SM35_plus_compute_86_cpp1_ii_dc5d5345

Я пытаюсь создать следующий пример для примеров библиотеки CUDA:

1d_c2c_example.cpp

#include <complex>
#include <iostream>
#include <random>
#include <vector>    
#include <cuda_runtime.h>
#include <cufftXt.h>
#include "cufft_utils.h"
int main(int argc, char *argv[]) {
    cufftHandle plan;
    cudaStream_t stream = NULL;
    
    int n = 8;
    int batch_size = 2;
    int fft_size = batch_size * n;
    
    using scalar_type = float;
    using data_type = std::complex<scalar_type>;
    std::vector<data_type> data(fft_size);
    for (int i = 0; i < fft_size; i++) {
        data[i] = data_type(i, -i);
    }
    
    std::printf("Input array:\n");
    for (auto &i : data) {
        std::printf("%f + %fj\n", i.real(), i.imag());
    }
    std::printf("=====\n");
    
    cufftComplex *d_data = nullptr;
    
    CUFFT_CALL(cufftCreate(&plan));
    CUFFT_CALL(cufftPlan1d(&plan, data.size(), CUFFT_C2C, batch_size));
    
    CUDA_RT_CALL(cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking));
    CUFFT_CALL(cufftSetStream(plan, stream));
    
    // Create device data arrays
    CUDA_RT_CALL(cudaMalloc(reinterpret_cast<void **>(&d_data), sizeof(data_type) * data.size()));
    CUDA_RT_CALL(cudaMemcpyAsync(d_data, data.data(), sizeof(data_type) * data.size(), cudaMemcpyHostToDevice, stream));
    
    CUFFT_CALL(cufftExecC2C(plan, d_data, d_data, CUFFT_FORWARD));
    CUFFT_CALL(cufftExecC2C(plan, d_data, d_data, CUFFT_INVERSE));
    
    CUDA_RT_CALL(cudaMemcpyAsync(data.data(), d_data, sizeof(data_type) * data.size(), cudaMemcpyDeviceToHost, stream));
    
    CUDA_RT_CALL(cudaStreamSynchronize(stream));
    
    /* free resources */
    CUDA_RT_CALL(cudaFree(d_data))
    CUFFT_CALL(cufftDestroy(plan));
    CUDA_RT_CALL(cudaStreamDestroy(stream));
    CUDA_RT_CALL(cudaDeviceReset());
    return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)

set(ROUTINE 1d_c2c)

project(
  "${ROUTINE}_example"
  DESCRIPTION "GPU-Accelerated Fast Fourier Transforms"
  HOMEPAGE_URL "https://docs.nvidia.com/cuda/cufft/index.html"
  LANGUAGES CXX CUDA)

set(CMAKE_CUDA_ARCHITECTURES 80)
find_package(CUDAToolkit REQUIRED)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
  set(CMAKE_BUILD_TYPE Release)
endif ()

set(CMAKE_CUDA_ARCHITECTURES 80)
#if (CMAKE_CUDA_ARCHITECTURES LESS 60)
    #set(CMAKE_CUDA_ARCHITECTURES 60 70 75 80 86)
    #endif ()
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CUFFT_LIBRARIES ${CUDA_cufft_LIBRARY} ${CUDA_culibos_LIBRARY} ${CUDA_cudart_LIBRARY})


add_executable(${ROUTINE}_example)

target_include_directories(${ROUTINE}_example
                           PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} 
                           ${CMAKE_SOURCE_DIR}/../utils)

target_sources(${ROUTINE}_example
               PRIVATE ${PROJECT_SOURCE_DIR}/${ROUTINE}_example.cpp)

set(CMAKE_CUDA_ARCHITECTURES 80)
#target_link_libraries(${ROUTINE}_example PRIVATE ${CUDA_cufft_static_LIBRARY} CUDA::cufft CUDA::cudart)
target_link_libraries(${ROUTINE}_example PRIVATE CUDA::cufft_static CUDA::cudart)

Когда я удалил

find_package(CUDAToolkit REQUIRED)

cmake показывает мне следующую ошибку:

CMake Error at CMakeLists.txt:82 (target_link_libraries):
   Target "1d_c2c_example" links to:

     CUDA::cufft_static

   but the target was not found.
target_link_libraries(${ROUTINE}_example PRIVATE cufft_static) при использовании FindCUDAToolkit() вместо языка добавьте CUDA:: перед целевой библиотекой. См. связанные документы.
paleonix 20.04.2023 10:17

Вы пытаетесь использовать устаревшую функциональность из старого FindCUDA. Я бы рекомендовал не использовать версию CMake, которая поддерживает более новый API, 3.18 — хорошее начало.

paleonix 20.04.2023 10:35

Я удалю find_package и повторю попытку. Что касается .cu, я не думаю, что это проблема, потому что с Makefile он компилируется. Как вы думаете, есть проблема с .cu и cmake?

MANOS 20.04.2023 14:31

Я исправил свой ответ для работы с исходным файлом .cpp.

paleonix 21.04.2023 01:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Основная причина, по которой у вас все еще были проблемы с компоновщиком после использования CUDA::cufft_static, заключалась в том, что для статического cuFFT требуется включенный код перемещаемого устройства. Хотя это делается в CMake с помощью свойства CUDA_SEPARABLE_COMPILATION для компиляции, нам это нужно для связывания, которое достигается с помощью свойства CUDA_RESOLVE_DEVICE_SYMBOLS.

Я откажусь от своего заявления о том, что нельзя использовать одновременно язык CUDA и find_package(CUDAToolkit REQUIRED). Хотя цель cufft_static доступна при использовании только языка, она не связывается автоматически с culibos. Таким образом, более элегантным решением является использование CUDA::cufft_static из пакета.

Архитектура CUDA и тип сборки должны быть установлены во время первой настройки либо с помощью аргументов командной строки cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=80, либо с помощью ccmake, чтобы получить приятный интерфейс консоли.

cmake_minimum_required(VERSION 3.18)

set(ROUTINE 1d_c2c)

project(
  "${ROUTINE}_example"
  DESCRIPTION "GPU-Accelerated Fast Fourier Transforms"
  HOMEPAGE_URL "https://docs.nvidia.com/cuda/cufft/index.html"
  LANGUAGES CXX CUDA)

find_package(CUDAToolkit REQUIRED)

add_executable(${ROUTINE}_example)

set_target_properties(${ROUTINE}_example
  PROPERTIES
    CUDA_RESOLVE_DEVICE_SYMBOLS ON
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

target_compile_features(${ROUTINE}_example
  PRIVATE cxx_std_11)

target_sources(${ROUTINE}_example
  PRIVATE ${PROJECT_SOURCE_DIR}/${ROUTINE}_example.cpp)

target_include_directories(${ROUTINE}_example
  PRIVATE ${CMAKE_SOURCE_DIR}/../utils)

target_link_libraries(${ROUTINE}_example PRIVATE
  PRIVATE
    CUDA::cufft_static
    CUDA::cudart_static)

Спасибо @RobertJMaynard, который помог мне понять, как правильно сделать ссылку, не меняя исходный файл на .cu (т. е. использовать CUDA_RESOLVE_DEVICE_SYMBOLS и добавить CUDA::cudart_static) на CMake Discourse.

У меня такая же проблема с bazel и tensorflow. Что эквивалентно CUDA_RESOLVE_DEVICE_SYMBOLS в базеле?

MANOS 25.04.2023 14:59

Я не знаю Базеля. Пожалуйста, откройте новый вопрос. Погуглив проблему, этот образец bazel кажется, что он может помочь, то есть rdc = 1.

paleonix 25.04.2023 15:12

Другие вопросы по теме