Шаблоны функций в CUDA не связаны - PullRequest
0 голосов
/ 10 июля 2019

Я хочу создать приложение, используя CUDA 10.1 (в VisualStudio 2017, 64-битная версия) Для гибкости я хочу использовать шаблоны, поскольку типы и размеры пикселей могут различаться. Фрагменты кода ниже. Но как-то не компилируется и выдает ошибку LNK2019

неразрешенный внешний символ "__declspec (dllimport) void __cdecl CUDA_gradient (float *, unsigned int *, float *, float *) " (__imp _ ?? $ CUDA_gradient @ MM $ 02 @@ YAXPEAMPEAI00 @ Z) ссылка в функции "protected: virtual void __cdecl itk :: CudaGradientImageFilter, float, float, класс itk :: CudaImage, 3>> :: GPUGenerateData (void)" (? GPUGenerateData @? $ CudaGradientImageFilter @ V? $ CudaImage @ M $ 02 @ ITK @@ ММВ? $ CudaImage @ V? $ CovariantVector @ M $ 02 @ ITK @@ $ 02 @ 2 @@ ITK @@ MEAAXXZ)

По некоторым другим вопросам У CUDA нет проблем с шаблонами.

Каковы предостережения и главные люки для шаблонов CUDA в общем программировании?

Вызов функции в моем файле cpp:

#include "itkCudaGradientImageFilter.h"
#include "itkCudaGradientImageFilter.hcu"
// ...
template <typename TInputImage, typename TOperatorValueType, typename TOutputValueType, typename TOutputImageType>
void
CudaGradientImageFilter<TInputImage,
                       TOperatorValueType,
                       TOutputValueType,
                       TOutputImageType>
::GPUGenerateData()
{
    //...the InputPxelType and the InputImageDimension are aquired somewhere else.
    CUDA_gradient<InputPixelType, OutputValueType, InputImageDimension>(pin, outputSize, outputSpacing, pout);
    //...

}

Результат не меняется, когда я звоню:

CUDA_gradient<float, float, 3>(pin, outputSize, outputSpacing, pout);

У меня есть файл заголовка cuda (.hcu)

#include "ImageFeaturesExport.h"

    template<typename TInputPixelType,
             typename TOutputValueType,
             unsigned int TImageDimension = 3>
    void
    ImageFeatures_EXPORT
    CUDA_gradient(
        TInputPixelType* dev_in,
        unsigned int* size,
        float* spacing,
        TOutputValueType* dev_out
    );

и соответствующие функции в файле .cu:

#include "itkCudaGradientImageFilter.hcu"
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

template<typename TInputPixelType,
         typename TOutputPixelType,
         unsigned int TImageDimension>
__global__
void
gradient_kernel(cudaTextureObject_t in, TOutputPixelType* grad)
{
    //...compute gradient
}

template<typename TInputPixelType, typename TOutputValueType, unsigned int TImageDimension>
void
CUDA_gradient(
    TInputPixelType* dev_in,
    unsigned int* size,
    float* spacing,
    TOutputValueType* dev_out)
{
    // prepare texture, copy memory,...

    gradient_kernel<TInputPixelType, TOutputValueType, TImageDimension><<< dimGrid, dimBlock >>> (texObj, dev_out);
    CUDA_CHECK_ERROR;

    // Clean up [...]
}

1 Ответ

2 голосов
/ 10 июля 2019

У вас ошибка ссылки.

Сначала обратите внимание, что ваш .cpp и ваш файл .cu скомпилированы независимо.

Так что nvcc не знает, какие параметры шаблона у него естьчтобы скомпилировать функцию CUDA_gradient.

Вы можете скомпилировать ее, добавив строку в ваш файл .cu:

template void CUDA_gradient<float,float,3>(
    float* dev_in,
    unsigned int* size,
    float* spacing,
    float* dev_out);

Конечно, это позволяет использовать только точные параметры шаблона.,Но если вы знаете, что у набора возможных параметров шаблона есть хорошая копия-вставка-замена-партия, и это хорошо.

...