Ho una classe che chiama un kernel nel suo costruttore, come segue:Problemi lanciare i kernel CUDA dal codice di inizializzazione statica
"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;
}
Se istanzio questa classe su main (A a_object;
) non ottengo errori. Tuttavia, se lo istanziamo all'esterno del main, appena dopo averlo definito (class A {...} a_object;
), ricevo un errore di "funzione dispositivo non valida" all'avvio del kernel. Perché succede?
EDIT
Aggiornato codice per fornire un esempio più completo.
EDIT 2
Seguendo i consigli nel commento di Raxvan, volevo dire che ho la variabile dimensions
utilizzato nel costruttore ScalarField anche definito (in un'altra classe) al di fuori principale, ma prima di tutto il resto. Potrebbe essere questa la spiegazione? Il debugger stava mostrando il giusto valore per dimensions
.
Potete fornire più aiuto per il codice per rispondere a queste domande: La classe A è nel proprio file ma il kernel è in un altro, quali sono l'estensione del file, ecc. Dovreste fornire abbastanza codice affinché altri possano replicare il vostro problema. – deathly809
@Noel Perez Gonzalez se hai definito 'a_Object' come variabile globale, inizia l'esecuzione durante l'inizializzazione dei dati globali. Questa è una pessima pratica in quanto non c'è modo di conoscere l'ordine di esecuzione. Tenendo presente questo, è possibile che il codice che inizializza tutta la roba CUDA venga eseguito successivamente rispetto ai dati globali. – Raxvan
Aggiornata la domanda con altro codice (si prega di notare che non l'ho compilato). @Raxvan Grazie per il consiglio, ho pensato che l'ordine di runtime fosse lo stesso dell'ordine di compilazione. – Noel