2014-06-09 9 views
7

Mi chiedo se v'è una differenza tra:cublasSetVector() vs cudaMemcpy()

// cumalloc.c - Create a device on the device 
HOST float * cudamath_vector(const float * h_vector, const int m) 
{ 
    float *d_vector = NULL; 
    cudaError_t cudaStatus; 
    cublasStatus_t cublasStatus; 

    cudaStatus = cudaMalloc(&d_vector, sizeof(float) * m); 

    if(cudaStatus == cudaErrorMemoryAllocation) { 
    printf("ERROR: cumalloc.cu, cudamath_vector() : cudaErrorMemoryAllocation"); 
    return NULL; 
    } 


    /* THIS: */ cublasSetVector(m, sizeof(*d_vector), h_vector, 1, d_vector, 1); 

    /* OR THAT: */ cudaMemcpy(d_vector, h_vector, sizeof(float) * m, cudaMemcpyHostToDevice); 


    return d_vector; 
} 

cublasSetVector() ha due argomenti incx e incy e documentation says:

La spaziatura stoccaggio tra elementi consecutivi è dato da incx per il vettore sorgente x e per il vettore di destinazione y.

Nel NVIDIA forum qualcuno ha detto:

iona_me: "INCX e Incy sono passi misurati in carri."

Quindi questo significa che per incx = incy = 1 tutti gli elementi di un float[] sarà sizeof(float) -allineato e per incx = incy = 2 ci sarebbe uno sizeof(float) -padding tra ogni elemento?

  • Fatta eccezione per questi due parametri e la cublasHandle - fa cublasSetVector() qualsiasi altra cosa ciò che cudaMalloc() non fa?
  • Sarebbe possibile salvare un vettore/matrice che era non creato con la rispettiva funzione cublas*() in altre funzioni CUBLAS per manipolarli?
+2

Per quanto ne so, 'cublasSetVector()' chiamerà internamente 'cudaMemcpy' o la sua versione 2D per le copie stride. Quindi penso che non ci siano problemi anche se gli array da impostare sono stati creati da un 'cudaMalloc'. In realtà, ho interscambiato le istruzioni cuBLAS e non-cuBLAS senza alcun problema nel recente passato. – JackOLantern

risposta

4

C'è un commento in un thread of the NVIDIA Forum fornito da Massimiliano Fatica conferma la mia affermazione nel commento di cui sopra (o, meglio dirlo, il mio commento originata da un richiamo di aver letto il post che ho linkato a). In particolare

cublasSetVector, cubblasGetVector, cublasSetMatrix, cublasGetMatrix sono sottili involucri attorno cudaMemcpy e cudaMemcpy2D. Pertanto, non sono previste differenze significative di prestazioni tra i due gruppi di funzioni di copia.

Di conseguenza, è possibile passare in modo sicuro gli array creati da cudaMalloc come input cublasSetVector.

riguardante i progressi, forse c'è un errore di stampa nella guida (come di CUDA 6.0), che dice che

La spaziatura stoccaggio tra elementi consecutivi è dato dalla incx per la sorgente vettore x e per il vettore di destinazione .

ma forse dovrebbe essere letta come

La spaziatura stoccaggio tra elementi consecutivi è dato dalla incx per la sorgente vettore x e incy per il vettore di destinazione y.