2013-08-25 4 views
1

나는 시뮬레이션을 쓰기 시작했고보다 객관적인 접근 방식을 사용하기로 결정했다. 따라서 CUDA 커널에서 템플릿 매개 변수를 사용하기로 결정했습니다. 이는 시뮬레이션의 공간 차원을 나타냅니다. 문제는 헤더 파일에 템플릿 함수를 구현하는 데 제한이 있기 때문에 .cpp 소스 파일에서 커널 래퍼를 호출 할 수 있도록 복잡한 접근 방식을 사용해야했습니다.CUDA 템플릿 커널 래퍼

내 접근 방식은 2 차원과 3 차원에 대한 래퍼 함수를 ​​오버로드하는 것이 었습니다. 그런 다음 초기화 및 커널 리소스 관리 래퍼 클래스에 대한 클래스가 있습니다. 제한의 내가 언급하기 때문에 불행하게도, 내가 템플릿 클래스의 두 멤버를 계속해야 즉

 

struct kernelWrapper{ 
    KernelWrapper(Simulation&lt2> *simulation): 
     d_(2), 
     simulation2d_(simulation) 
    {} 
    KernelWrapper(Simulation&lt3> *simulation): 
     d_(3), 
     simulation3d_(simulation) 
    {} 
    process(void){ //wrapper function for kernel launching 
     switch(d_){ 
     case 2: 
      kernel&lt2><<<..., ...>>>(...); 
      break; 
     } 
     case 3: 
      kernel&lt3><<<..., ...>>>(...); 
      break; 
     } 
     default: 
      break; 
    } 

    int d_; 
    union{ 
     Simulation&lt2> *simulation2d_; 
     Simulation&lt3> *simulation3d_; 
    }; 
    union{ 
     Lattice&lt2> *lattice2d_d; 
     Lattice&lt3> *lattice3d_d; 
    }; 

}; 
 
내가 할 노력하고있어 달성하기 위해 더 나은 방법을 알고 있다면 따라서 궁금

, 즉 템플릿 CUDA 커널에 대한 래퍼를 만듭니다.

업데이트 : 위 게시물을 작성한 후에 알아 낸 해결책을 하나 더 추가하고 싶습니다. C++ faq (포인트 13-15)에 표시된 바와 같이 소스 파일에 템플릿 구현을 넣고 필요한 템플릿을 명시 적으로 인스턴스화 할 수 있습니다. 즉, 2 차원 및 3 차원의 경우에 필요합니다. C++ 11을 사용하면이 단계를 더 진행하고 컴파일/링크 시간을 절약하기 위해 템플릿 정의에 extern 키워드를 도입 할 수 있습니다 (here 설명).

답변

3

문제 때문에 헤더 파일에 템플릿을 기능을 구현의 제한으로,이다, 나는 에 복잡한 방법을 사용했다가 .CPP 소스 파일에서 호출 커널 래퍼을 유지한다.

템플릿을 작성하는 법적

는 .CPP 코드를 선언

여부 kernelWrapper는 .HPP에 있거나 당신이

template<int d_> 
struct kernelWrapper 
{ 
    KernelWrapper(Simulation<d_> *simulation) : simulation_(simulation) 
    {} 

    process(void) 
    { 
      kernel<d_><<<..., ...>>>(...); 
    } 

    Simulation<d_>* simulation_; 
    Lattice<d_>* lattice2d_; 
}; 

과 같은 코드가 있어야 .CPP 또한 스위치를 사용하지 마십시오/case와 같이 커널을 선택하려면 다음과 같이 사용하십시오 :

int const max_dimension = 4; 

template<int static_dimension> 
void select_kernel(int dynamic_dimension) 
{ 
    if(dynamic_dimension == static_dimension) 
    { 
     call_kernel<static_dimension>(); 
    } 
    select_kernel<static_dimension+1>(dynamic_dimension); 
} 

template<> 
void select_kernel<max_dimension>(int dynamic_dimension) 
{ 
    // error message 
} 

void select_kernel(int dynamic_dimension) 
{ 
    select_kernel<1>(dynamic_dimension); 
} 

그런 선택이 빈번하면, 템플릿을 사용하지 않습니다.

+0

답변을 제대로 이해하지 못했다면 죄송합니다. 물론 게시 한 코드가 가장 간단하지만 커널 구현도 포함해야합니다. 그렇다면 KernelWrapper가 포함 된 파일에 .cu 확장자를 사용하고 nvcc로 컴파일해야합니다. 제 요점은 일반 .cpp 소스 파일에서 KernelWrapper를 호출 할 수있게 만드는 것입니다. – Grieverheart

+0

이제 문제를 더 잘 이해합니다. 커널 실행 구성 구문 << >>은 cpp 컴파일러에서 인식하지 못합니다. cp 컴파일 된 코드에서 커널을 호출하고 nvcc 컴파일 된 부분에서'select_kernel'을 정의하기 위해서는'select_kernel'의 템플릿이 아닌 버전을 사용해야합니다. –

+0

충분히 명확하지 않은 것에 대해 유감스럽게 생각합니다. 커널의 시작은 매우 빈번하며,'select_kernel' 버전의 성능이 얼마나 다른지 살펴 보겠습니다. – Grieverheart