나는 이진 연관 연산자를 사용하는 쿠다 (이것은 운동입니다. 나는 다른 사람들이 더 잘 수행하고있는 것을 알고 있습니다)에 감소 함수를 작성하려고합니다. 배열을 만들고 연산자를 사용하여 배열을 줄입니다.은 쿠다에서 템플릿 매개 변수로 사용됩니다
나는 어떻게 함수를 전달하는 데 어려움을 겪고있다. hostOp()를 잘 작성한 호스트 기반 예제로 작성했습니다.
deviceOp()는 fminf()를 명시 적으로 호출하여 첫 번째 명령문에서 작동하지만 함수 매개 변수를 호출 할 때 잘못된 메모리 액세스 오류가 발생합니다.
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std; //for brevity
__device__ float g_d_a = 9, g_d_b = 5;
float g_h_a = 9, g_h_b = 5;
template<typename argT, typename funcT>
__global__
void deviceOp(funcT op){
argT result = fminf(g_d_a, g_d_b); //works fine
printf("static function result: %f\n", result);
result = op(g_d_a,g_d_b); //illegal memory access
printf("template function result: %f\n", result);
}
template<typename argT, typename funcT>
void hostOp(funcT op){
argT result = op(g_h_a, g_h_b);
printf("template function result: %f\n", result);
}
int main(int argc, char* argv[]){
hostOp<float>(min<float>); //works fine
deviceOp<float><<<1,1>>>(fminf);
cudaDeviceSynchronize();
cout<<cudaGetErrorString(cudaGetLastError())<<endl;
}
출력 :
host function result: 5.000000
static function result: 5.000000
an illegal memory access was encountered
불법적 인 메모리 액세스가되지 않도록 어떻게 deviceOp에 fminf을 통과해야한다, 내가 끔찍하게 바보 같은 일을하고 있지 않다 가정?
내가 끔찍한 짓을하고 있다면 더 좋은 방법이 무엇일까요?
흠 : 여기
는 방법 "장치 코드에 캡처 함수 주소의"를 사용하여 수정 코드의 완전한 일 예이다. 그래서 호스트에서 deviceOp를 호출하면 장치 코드로 호출되지만, 장치에서 호출하면 장치 코드가됩니다 (그리고 fminf는 어디에서 알 수 있습니까?) –
'deviceOp'는 다음과 같습니다. '__global__' 함수입니다. 호스트에서 실제로 호출되지는 않지만 (호스트 코드에서 일반 호스트 함수가 호출되는 방식으로) 실제로 커널 호출입니다 (라이브러리 호출 시퀀스를 통해 수행 됨 - 장치에서 함수를 실행 함). 디바이스 코드 (즉, 동적 병렬 처리)에서'deviceOp'를 실행했다면, 디바이스 코드에서 특정 커널을 시작하면 디바이스의 fminf 함수 주소를 직접 선택할 수 있습니다. 실제로 커널 실행 자체는 디바이스 코드로 컴파일됩니다. –
'deviceOp'에서 명시적인 직접'fminf' 호출은 사실 장치 코드입니다. '__global__' 또는'__device__' 함수 범위 한정자 안에있는 것은 디바이스 코드이며, 디바이스 코드 컴파일러에 의해 컴파일됩니다. 하지만'main' 루틴에서'deviceOp'를 ** 시작하는 것은 실제로 모든 호스트 코드입니다. –