2017-07-27 2 views
1

Je considère le code simple suivant dans lequel je convertis thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin(); et thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin(); en pointeurs bruts. À cette fin, je passe respectivement &(h_temp_iterator[0]) et &(d_temp_iterator[0]) à une fonction et un noyau. Le premier (cas de CPU) compile, le second (cas de GPU) pas. Les deux cas doivent être symétriques principe, donc je ne comprends pas la raison du message d'erreur qui est:Conversion d'itérateurs de dispositifs Thrust en pointeurs bruts

Error 1 error : no suitable conversion function from "thrust::device_ptr<int>" to "int *" exists  

Les configurations sont:

  1. Windows 7, Visual Studio 2010, CUDA 7.5, compilation pour le 3.5 architecture.
  2. Windows 10, Visual Studio 2013, CUDA 8.0, en compilant pour l'architecture 5.2.

CODE

#include <thrust\host_vector.h> 
#include <thrust\device_vector.h> 

__global__ void testKernel(int *a, const int N) 
{ 
    int i = threadIdx.x; 

    if (i >= N) return; 

    a[i] = 2; 
} 

void testFunction(int *a, const int N) 
{ 
    for (int i = 0; i < N; i++) a[i] = 2; 
} 

int main() 
{ 
    const int N = 10; 

    thrust::host_vector<int> h_temp(N); 
    thrust::device_vector<int> d_temp(N); 

    thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin(); 
    thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin(); 

    testFunction(&(h_temp_iterator[0]), N); 
    testKernel<<<1, N>>>(&(d_temp_iterator[0]), N); 

    for (int i = 0; i < N; i++) printf("%i %i\n", i, h_temp[i]); 

    return 0; 
} 
+1

Ceci est juste une variation très légère à ce sujet, n'est ce pas? https://stackoverflow.com/q/11113485/681865 – talonmies

+1

Dans le modèle typé basé sur l'étiquette de poussée (le modèle d'origine), toute mémoire de l'appareil est représentée par un 'thrust :: device_ptr'. Cela a une sémantique de pointeur, mais n'est pas un pointeur, ce qui permet de renforcer la sécurité du type de pointeur hôte/périphérique. Dans votre code ci-dessus, l'itérateur se désintègre en un 'device_ptr' et non en un pointeur. Vous devez lancer 'device_ptr' pour obtenir un pointeur brut que vous pouvez passer au code de l'appareil – talonmies

+0

Merci, talonmies, pour votre aide inlassable. J'ai résolu le problème. Aimeriez-vous poster une réponse? – JackOLantern

Répondre

2

Après les commentaires de talonmies, la solution est de passer

thrust::raw_pointer_cast(&d_temp_iterator[0]) 

et non

&d_temp_iterator[0] 

Dans ce qui suit, le code de travail entièrement

#include <thrust\host_vector.h> 
#include <thrust\device_vector.h> 

__global__ void testKernel(int *a, const int N) 
{ 
    int i = threadIdx.x; 

    if (i >= N) return; 

    a[i] = 2; 

    printf("GPU %i %i\n", i, a[i]); 
} 

void testFunction(int *a, const int N) 
{ 
    for (int i = 0; i < N; i++) { 
     a[i] = 2; 
     printf("CPU %i %i\n", i, a[i]); 
    } 
} 

int main() 
{ 
    const int N = 10; 

    thrust::host_vector<int> h_temp(N); 
    thrust::device_vector<int> d_temp(N); 

    thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin(); 
    thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin(); 

    int *temp = thrust::raw_pointer_cast(&d_temp_iterator[0]); 

    testFunction(&(h_temp_iterator[0]), N); 
    testKernel<<<1, N>>>(temp, N); 

    return 0; 
}