2013-06-19 5 views
11

Я работаю с CUDA, и я создал класс int2_ для обработки комплексных целочисленных чисел.Ссылка на внешний класс CUDA и нерешенная функция extern в файле ptxas

декларация класса в файле ComplexTypes.h следующим образом:

namespace LibraryNameSpace 
{ 
    class int2_ { 

     public: 
      int x; 
      int y; 

      // Constructors 
      __host__ __device__ int2_(const int,const int); 
      __host__ __device__ int2_(); 
      // etc. 

      // Equalities with other types  
      __host__ __device__ const int2_& operator=(const int); 
      __host__ __device__ const int2_& operator=(const float); 
      // etc. 

    }; 
} 

реализации класса в файле ComplexTypes.cpp следующим образом:

#include "ComplexTypes.h" 

__host__ __device__   LibraryNameSpace::int2_::int2_(const int x_,const int y_)   { x=x_; y=y_;} 
__host__ __device__   LibraryNameSpace::int2_::int2_() {} 
// etc. 

__host__ __device__ const LibraryNameSpace::int2_& LibraryNameSpace::int2_::operator=(const int a)      { x = a;   y = 0.;    return *this; } 
__host__ __device__ const LibraryNameSpace::int2_& LibraryNameSpace::int2_::operator=(const float a)      { x = (int)a;  y = 0.;    return *this; } 
// etc. 

Все хорошо работает. В main (который включает ComplexTypes.h) я мог бы иметь номера int2_.

В файле CudaMatrix.cu я теперь включая ComplexTypes.h и определение и правильно инстанцирование функции __global__:

template <class T1, class T2> 
__global__ void evaluation_matrix(T1* data_, T2* ob, int NumElements) 
{ 
    const int i = blockDim.x * blockIdx.x + threadIdx.x; 
    if(i < NumElements) data_[i] = ob[i]; 
} 

template __global__ void evaluation_matrix(LibraryNameSpace::int2_*,int*,int); 

Положения файла CudaMatrix.cu кажется симметричной функцией main. Тем не менее, компилятор жалуется:

Error 19 error : Unresolved extern function '_ZN16LibraryNameSpace5int2_aSEi' C:\Users\Documents\Project\Test\Testing_Files\ptxas simpleTest 

Пожалуйста, учтите, что:

  1. Перед перемещением реализации в отдельных файлах, все было правильно работать при включении обеих деклараций и реализации в файле main.
  2. Проблемная инструкция: data_[i] = ob[i].

У кого-нибудь есть идеи, что происходит?

+0

предположительно вам не имеют 'ComplexTypes.cpp' файл, а скорее' ComplexTypes.cu' файл, который вы передаете в NVCC, в противном случае '__host__ __device__' не должен составлять ... – talonmies

+0

Я нашел решение моей проблемы. Я опубликовал его как ответ, надеясь, что он может быть полезен другим пользователям. – JackOLantern

ответ

24

Процедуру я следовал в моем посте выше есть два вопроса:

  1. ComplexTypes.cpp файла должны быть превращена в ComplexTypes.cu так, что nvcc может перехватывать CUDA ключевые слова __device__ и __host__. Это было отмечено в его комментариях Talonmies. Фактически, перед публикацией я уже менял имя файла от .cpp до .cu, но компилятор жаловался и показывал ту же ошибку. Поэтому я изобретательно отступил;

  2. В Visual Studio 2010 необходимо использовать Вид -> Страницы свойств; Свойства конфигурации -> CUDA C/C++ -> Общие -> Сгенерировать код переключаемого устройства -> Да (-rdc = true). Это необходимо для отдельной компиляции. Действительно, в NVIDIA CUDA Compiler Driver NVCC, говорится, что:

CUDA работает путем встраивания кода устройства в объекты хозяевах. Во всей компиляции программы он внедряет код исполняемого устройства в объект-хост. В отдельной компиляции мы вставляем код перемещаемого устройства в объект-хост и запускаем компоновщик устройств (nvlink), чтобы связать весь код устройства вместе. Затем вывод nvlink соединяется вместе со всеми объектами хоста компоновщиком хоста для формирования окончательного исполняемого файла.Генерация relocatable vs код исполняемого устройства управляется опцией --relocatable-device-code = {true, false}, которая может быть сокращена до -rdc = {true, false}.

+4

В принципе, у вас есть только два варианта: переместите весь код устройства в один блок компиляции или используйте отдельную компиляцию. Вы отвечаете последним, и он работает только с CUDA 5.0 или новее. Первый был единственным способом структурирования приложений CUDA до введения компоновщика. – talonmies

+0

СПАСИБО. Я преследовал эту проблему часами. (Также относится к CUDA 5.5 и VS2012) –

+4

В Nsight Eclipse опция доступна в качестве переключателя «Отдельная компиляция» в разделе «Проект»> «Свойства»> «Сборка»> «Настройки»> «CUDA» – M2X