다음과 같이 나는, 생성자의 커널을 호출하는 클래스가 :문제
"ScalarField.h"
#include <iostream>
void ERROR_CHECK(cudaError_t err,const char * msg) {
if(err!=cudaSuccess) {
std::cout << msg << " : " << cudaGetErrorString(err) << std::endl;
std::exit(-1);
}
}
class ScalarField {
public:
float* array;
int dimension;
ScalarField(int dim): dimension(dim) {
std::cout << "Scalar Field" << std::endl;
ERROR_CHECK(cudaMalloc(&array, dim*sizeof(float)),"cudaMalloc");
}
};
"classA.h"
#include "ScalarField.h"
static __global__ void KernelSetScalarField(ScalarField v) {
int index = threadIdx.x + blockIdx.x * blockDim.x;
if (index < v.dimension) v.array[index] = 0.0f;
}
class A {
public:
ScalarField v;
A(): v(ScalarField(3)) {
std::cout << "Class A" << std::endl;
KernelSetScalarField<<<1, 32>>>(v);
ERROR_CHECK(cudaGetLastError(),"Kernel");
}
};
"main.cu"
#include "classA.h"
A a_object;
int main() {
std::cout << "Main" << std::endl;
return 0;
}
main (A a_object;
)에서이 클래스를 인스턴스화하면 오류가 발생하지 않습니다. 그러나 메인 (main) 외부에서 인스턴스를 생성하면 커널 정의시 (class A {...} a_object;
) 커널이 시작될 때 "invalid device function"오류가 발생합니다. 왜 그런 일이 일어날까요?
편집
업데이트 코드는보다 완전한 예제를 제공합니다. Raxvan에 의해 주석의 조언에 따라 편집 2
, 나는 내가 주요 외부 ScalarField 생성자에서 사용되는 dimensions
변수도 (다른 클래스에서) 정의를 말하고 싶었지만, 다른 모든 전에. 그것은 설명 일 수 있습니까? 디버거는 dimensions
에 대한 올바른 값을 표시하고있었습니다.
다음 질문에 대한 답변을 제공 할 수 있습니다 : 클래스 A는 자체 파일이지만 커널은 파일 확장자입니다. 다른 사람이 문제를 복제 할 수 있도록 충분한 코드를 제공해야합니다. – deathly809
@Noel Perez Gonzalez'a_Object'를 전역 변수로 정의하면 전역 데이터 초기화 중에 실행을 시작합니다. 이것은 실행 순서를 알 수있는 방법이 없으므로 매우 나쁜 관행입니다. 이를 염두에두면 모든 CUDA를 초기화하는 코드가 글로벌 데이터보다 나중에 실행될 수 있습니다. – Raxvan
더 많은 코드로 질문을 업데이트했습니다 (컴파일하지 않았 음에 유의하십시오). @Raxvan 조언을 주셔서 감사합니다, 나는 방금 런타임 순서와 컴파일 순서가 같다고 생각했습니다. – Noel