2013-06-19 35 views
11

Tôi đang làm việc với CUDA và tôi đã tạo một lớp int2_ để xử lý các số nguyên phức tạp.Liên kết lớp ngoài CUDA và hàm extern chưa được giải quyết trong tệp ptxas

tờ khai Class trong file ComplexTypes.h như sau:

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. 

    }; 
} 

triển khai Class trong file ComplexTypes.cpp như sau:

#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. 

Tất cả mọi thứ hoạt động tốt. Trong số main (bao gồm ComplexTypes.h), tôi có thể xử lý các số int2_.

Trong tập tin CudaMatrix.cu, bây giờ tôi bao gồm ComplexTypes.h và xác định và instantiating đúng __global__ chức năng:

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); 

Tình hình của tập tin CudaMatrix.cu có vẻ là đối xứng với main chức năng. Tuy nhiên, trình biên dịch phàn nàn:

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

Xin vui lòng, xem xét rằng:

  1. Trước khi chuyển việc thực hiện các tập tin riêng biệt, tất cả mọi thứ đã làm việc một cách chính xác khi bao gồm cả tờ khai và triển khai trong file main.
  2. Hướng dẫn có vấn đề là data_[i] = ob[i].

Bất cứ ai cũng có ý tưởng về những gì đang diễn ra?

+0

có lẽ bạn không có tệp 'ComplexTypes.cpp', mà là tệp' ComplexTypes.cu' mà bạn đang chuyển đến nvcc, nếu không '__host__ __device__' không được biên dịch ... – talonmies

+0

Tôi đã tìm ra giải pháp cho vấn đề của mình. Tôi đã đăng nó như một câu trả lời với hy vọng rằng nó có thể hữu ích cho những người dùng khác. – JackOLantern

Trả lời

24

Các thủ tục tôi đã theo trong bài viết của tôi ở trên có hai vấn đề:

  1. Các ComplexTypes.cpp filename phải được quay sang ComplexTypes.cu để nvcc có thể đánh chặn các từ khóa CUDA __device____host__. Điều này đã được chỉ ra bởi Talonmies trong bình luận của mình. Trên thực tế, trước khi đăng, tôi đã thay đổi tên tệp từ .cpp thành .cu, nhưng trình biên dịch đã phàn nàn và hiển thị cùng một lỗi. Vì vậy, tôi đã khéo léo bước lùi lại;

  2. Trong Visual Studio 2010, người dùng phải sử dụng Chế độ xem -> Trang thuộc tính; Thuộc tính cấu hình -> CUDA C/C++ -> Chung -> Tạo mã thiết bị có thể định vị lại -> Có (-rdc = true). Điều này là cần thiết cho việc biên dịch riêng biệt. Trên thực tế, tại NVIDIA CUDA Compiler Driver NVCC, người ta nói rằng:

CUDA hoạt động bằng cách nhúng mã thiết bị vào vật chủ. Trong toàn bộ chương trình biên dịch, nó nhúng mã thiết bị thực thi vào đối tượng host. Trong trình biên dịch riêng biệt, chúng tôi nhúng mã thiết bị có thể định vị lại vào đối tượng lưu trữ và chạy trình liên kết thiết bị (nvlink) để liên kết tất cả các mã thiết bị với nhau. Đầu ra của nvlink sau đó được liên kết cùng với tất cả các đối tượng lưu trữ bởi trình liên kết máy chủ để tạo thành tệp thực thi cuối cùng.Thế hệ relocatable so với mã thiết bị thực thi được điều khiển bởi tùy chọn --relocatable-device-code = {true, false}, có thể được rút ngắn thành –rdc = {true, false}.

+4

Về cơ bản, bạn chỉ có hai lựa chọn - di chuyển tất cả mã thiết bị vào cùng một đơn vị biên dịch hoặc sử dụng trình biên dịch riêng biệt. Bạn trả lời là cái sau, và nó chỉ hoạt động với CUDA 5.0 hoặc mới hơn. Trước đây là cách duy nhất để cấu trúc các ứng dụng CUDA trước khi trình liên kết được giới thiệu. – talonmies

+0

CẢM ƠN BẠN. Tôi đã theo đuổi vấn đề này hàng giờ liền. (Cũng áp dụng cho CUDA 5.5 và VS2012) –

+4

Trong Nsight Eclipse, tùy chọn có sẵn dưới dạng nút radio "Phân tách riêng biệt" trong Project> Properties> Build> Settings> CUDA – M2X

Các vấn đề liên quan