2017-05-15 2 views
0

J'ai testé un code de test minimum pour remplir tableau « c » à chaque élément du tableau « a »poussée imbriquée :: remplissage ne fonctionne pas pour l'entrée des valeurs variées

Il montre que lorsque la poussée est imbriqué :: fill appelé avec une entrée constante, il remplit correctement le tableau d'entrée de cette valeur d'entrée.

Cependant, si la valeur d'entrée est une valeur variée dire que chaque élément d'un tableau de valeurs, il peut remplir la matrice d'entrée avec un seul (premier ou dernier) Valeur

#include <thrust/inner_product.h> 
#include <thrust/functional.h> 
#include <thrust/device_vector.h> 
#include <thrust/random.h> 

#include <thrust/execution_policy.h> 

#include <iostream> 
#include <cmath> 
#include <boost/concept_check.hpp> 

struct bFuntor 
{ 
    bFuntor(int* av__, int* cv__, const int& N__) : av_(av__), cv_(cv__), N_(N__) {}; 

    __host__ __device__ 
    int operator()(const int& idx) 
    { 
     thrust::device_ptr<int> cv_dpt = thrust::device_pointer_cast(cv_); 
     thrust::device_ptr<int> cv_dpt1 = thrust::device_pointer_cast(cv_+N_); 

     thrust::detail::normal_iterator<thrust::device_ptr<int>> c0 = thrust::detail::make_normal_iterator<thrust::device_ptr<int>>(cv_dpt); 
     thrust::detail::normal_iterator<thrust::device_ptr<int>> c1 = thrust::detail::make_normal_iterator<thrust::device_ptr<int>>(cv_dpt1); 

     // ** this thrust::fill with varied values does not work 
     thrust::fill(thrust::device,c0,c1,av_[idx]); 

     // ** this thrust::fill with constant works 
//  thrust::fill(thrust::device,c0,c1,10); 

     printf("fill result:\n"); 
     for (int i=0; i<N_; i++) 
     printf("fill value: %d -> return value: %d \n",av_[idx],cv_[i]); 
     printf("\n"); 

     return cv_dpt[idx]; 
    } 

    int* av_; 
    int* cv_; 
    int N_; 
}; 

int main(void) 
{ 
     int N = 2; 
     std::vector<int> av = {0,1}; 
     std::vector<int> cv = {-1,-2}; 

     thrust::device_vector<int> av_d(N); 
     thrust::device_vector<int> cv_d(N); 
     av_d = av; cv_d = cv; 

     // call with nested manner 
     thrust::transform(thrust::counting_iterator<int>(0), 
      thrust::counting_iterator<int>(N), 
      cv_d.begin(), 
      bFuntor(thrust::raw_pointer_cast(av_d.data()), 
      thrust::raw_pointer_cast(cv_d.data()), 
        N));  

     return 0; 
} 

cas de sortie de l'entrée variée valeur:

fill result: 
fill value: 0 -> return value: 1 
fill value: 1 -> return value: 1 
fill value: 0 -> return value: 1 
fill value: 1 -> return value: 1 

sortie cas de la valeur d'entrée constante:

fill result: 
fill value: 10 -> return value: 10 
fill value: 10 -> return value: 10 
fill value: 10 -> return value: 10 
fill value: 10 -> return value: 10 

est de cette poussée problème? ou il n'est pas censé utiliser comme ça?

+0

C'est exactement le même problème qui vous a été expliqué dans votre dernière question. – talonmies

+0

Je n'utilise pas "thrust :: transform" et écris son foncteur dans ce cas. Cela élimine le risque d'initialisation incorrecte des variables dans le foncteur (qui n'existe pas dans ce cas). Quant à l'interface thrust :: fill, sa 4ème entrée est une "const T & value", elle est supposée fonctionner tant que je respecte cette interface, n'est-ce pas? –

+2

Vous demandez deux opérations de données parallèles différentes pour remplir le même tableau avec des valeurs différentes. Qu'attendez-vous devrait arriver? – talonmies

Répondre

1

Voici un exemple d'une course de données:

int operator()(const int& idx) 
{ 
    thrust::device_ptr<int> cv_dpt = thrust::device_pointer_cast(cv_); 
    thrust::device_ptr<int> cv_dpt1 = thrust::device_pointer_cast(cv_+N_); 

    thrust::detail::normal_iterator<thrust::device_ptr<int>> c0 = thrust::detail::make_normal_iterator<thrust::device_ptr<int>>(cv_dpt); 
    thrust::detail::normal_iterator<thrust::device_ptr<int>> c1 = thrust::detail::make_normal_iterator<thrust::device_ptr<int>>(cv_dpt1); 


    thrust::fill(thrust::device,c0,c1,av_[idx]); 

    //..... 
} 

Ici, chaque appel à la foncteur va tenter de remplir la même gamme de iterator (c0 c1) avec des valeurs différentes. Évidemment, cela produira des problèmes lorsque plusieurs appels de foncteurs se produisent en parallèle.