download - Errore "argomento di configurazione non valido" per la chiamata del kernel CUDA?




toolkit nvidia (3)

Ecco il mio codice:

int threadNum = BLOCKDIM/8;
dim3 dimBlock(threadNum,threadNum);
int blocks1 = nWidth/threadNum + (nWidth%threadNum == 0 ? 0 : 1);
int blocks2 = nHeight/threadNum + (nHeight%threadNum == 0 ? 0 : 1);
dim3 dimGrid;
dimGrid.x = blocks1;
dimGrid.y = blocks2;

//  dim3 numThreads2(BLOCKDIM);
//  dim3 numBlocks2(numPixels/BLOCKDIM + (numPixels%BLOCKDIM == 0 ? 0 : 1) );
perform_scaling<<<dimGrid,dimBlock>>>(imageDevice,imageDevice_new,min,max,nWidth, nHeight);
cudaError_t err = cudaGetLastError();
cudasafe(err,"Kernel2");

Questa è l'esecuzione del mio secondo kernel ed è completamente indipendente in termini di utilizzo dei dati. BLOCKDIM è 512, nWidth and nHeight sono anch'essi 512 e cudasafe stampa semplicemente il corrispondente messaggio di stringa del codice di errore. Questa sezione del codice fornisce un errore di configurazione subito dopo la chiamata del kernel.

Cosa potrebbe dare questo errore, qualche idea?


Answers

Solo per aggiungere alle risposte precedenti, puoi trovare anche i max thread consentiti nel tuo codice, in modo che possa essere eseguito su altri dispositivi senza codificare il numero di thread che utilizzerai:

struct cudaDeviceProp properties;
cudaGetDeviceProperties(&properties, device);
cout<<"using "<<properties.multiProcessorCount<<" multiprocessors"<<endl;
cout<<"max threads per processor: "<<properties.maxThreadsPerMultiProcessor<<endl;

Questo tipo di messaggio di errore fa spesso riferimento ai parametri di configurazione di avvio (in questo caso le dimensioni della griglia / del threadblock potrebbero anche essere la memoria condivisa, ecc. In altri casi). Quando vedi un messaggio come questo è una buona idea solo stampare i parametri di configurazione attuali prima di avviare il kernel, per vedere se hai commesso degli errori.

Hai detto BLOCKDIM = 512. Hai threadNum = BLOCKDIM/8 quindi threadNum = 64. La configurazione del threadblock è:

dim3 dimBlock(threadNum,threadNum);

Quindi stai chiedendo di avviare blocchi di 64 x 64 thread, ovvero 4096 thread per blocco. Questo non funzionerà su nessuna generazione di dispositivi CUDA.


Il comando __syncthreads() è una barriera di sincronizzazione a livello di blocco . Ciò significa che è sicuro da usare quando tutti i fili in un blocco raggiungono la barriera. È anche possibile usare __syncthreads() nel codice condizionale ma solo quando tutti i thread valutano identicamente tale codice, altrimenti l'esecuzione potrebbe bloccarsi o produrre effetti collaterali indesiderati [4] .

Esempio di utilizzo di __syncthreads() : ( source )

__global__ void globFunction(int *arr, int N) 
{
    __shared__ int local_array[THREADS_PER_BLOCK];  //local block memory cache           
    int idx = blockIdx.x* blockDim.x+ threadIdx.x;

    //...calculate results
    local_array[threadIdx.x] = results;

    //synchronize the local threads writing to the local memory cache
    __syncthreads();

    // read the results of another thread in the current thread
    int val = local_array[(threadIdx.x + 1) % THREADS_PER_BLOCK];

    //write back the value to global memory
    arr[idx] = val;        
}

Per sincronizzare tutti i thread in una griglia al momento non esiste una chiamata API nativa. Un modo per sincronizzare i thread a livello di griglia consiste nell'utilizzare chiamate kernel successive, in quanto a quel punto tutti i thread terminano e ricominciano dallo stesso punto. È anche comunemente chiamato sincronizzazione della CPU o sincronizzazione implicita. Quindi sono tutti sincronizzati.

Esempio di utilizzo di questa tecnica ( source ):

Per quanto riguarda la seconda domanda. , dichiara la quantità di memoria condivisa specificata per blocco. Tenere presente che la quantità di memoria condivisa disponibile viene misurata per SM . Quindi si dovrebbe fare molta attenzione a come viene usata la memoria condivisa insieme alla configurazione di avvio .





cuda