Search code examples
c++sortingcudathrust

Thrust sort_by_key using tiled_range - not re-ordered


I am using tiled_range with a sort_by_key() in cuda and the keys are not getting re-ordered during the sort_by_key, just the values...

For example: I have one vector representing the keys:

 Keys   0  1    2    3   4   5   

Later with the tiled_range, I have the new vector with the values duplicated.

 Keys   0  1    2    3   4   5     0    1   2   3    4     5     

And another vector representing the values:

 values 0 3382 1863 470 311 2017 3382   0  251 1394 5651  257

I was expecting with sort_by_keys to re-order the keys like this:

 Keys      0    0      1    1     2      2     3    3   4    4     5    5

 Values    0   3382   3382  0    1863   251   470  1394 311 5651  2017 257

My code re-orders the keys in this way...

 Keys      3    3      4    4     5      5     3    3   4    4     5    5 

 Values    0   3382   3382  0    1863   251   470  1394 311 5651  2017 257

I was wondering, what could be the reason is re-ordering in this way and what can I do to get the right order?

Here is the code:

#include <iterator>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>

using namespace thrust::placeholders;

template<typename Iterator>
class tiled_range
//Code of tiled_range....
// 

int main(void)
{
    thrust::device_vector<int> data(6);
    data[0] = 0; data[1] = 1; data[2] = 2; data[3] = 3; data[4] = 4; data[5] = 5;

    thrust::device_vector<float> values(12);
    values[0] = 0;          values[6] = 3382;
    values[1] = 3382;       values[7] = 0;
    values[2] = 1863;       values[8] = 251;
    values[3] = 470;        values[9] = 1394;
    values[4] = 311;        values[10] = 5651;
    values[5] = 2017;       values[11] = 257;

    tiled_range<thrust::device_vector<int>::iterator>  keys(data.begin(), data.end(), 2);

    std::cout << "Keys: " << std::endl;
    thrust::copy(keys.begin(), keys.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    thrust::sort_by_key(keys.begin(), keys.end(), values.begin());

    std::cout << "Keys: " << std::endl;
    thrust::copy(keys.begin(), keys.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    std::cout << "Values: " << std::endl;
    thrust::copy(values.begin(), values.end(), std::ostream_iterator<int>   (std::cout, " "));
    std::cout << std::endl;

return 0;

}


Solution

  • Problem solved! I was checking some code from: https://groups.google.com/forum/#!msg/thrust-users/GqufHKoaizc/qx9cv-6xCg4J

    and I noticed that they were copy the values of the tiled_range into another vector, after copying this new vector and put it in the sort_by_keys, it was sorting the keys and values perfectly. I still do not understand why by putting the iterator of the tiled_range as input for the sort_by_keys it was causing such mess above...

    Here is the code:

    #include <iterator>
    #include <thrust/device_vector.h>
    #include <thrust/host_vector.h>
    #include <thrust/sort.h>
    
    using namespace thrust::placeholders;
    
    template<typename Iterator>
    class tiled_range
    //Code of tiled_range....
    // 
    
    int main(void)
    {
        thrust::device_vector<int> data(6);
        data[0] = 0; data[1] = 1; data[2] = 2; data[3] = 3; data[4] = 4; data[5] = 5;
    
        thrust::device_vector<float> values(12);
        values[0] = 0;          values[6] = 3382;
        values[1] = 3382;       values[7] = 0;
        values[2] = 1863;       values[8] = 251;
        values[3] = 470;        values[9] = 1394;
        values[4] = 311;        values[10] = 5651;
        values[5] = 2017;       values[11] = 257;
    
        tiled_range<thrust::device_vector<int>::iterator>  keys(data.begin(), data.end(), 2);
        thrust::device_vector<int> keysN(keys.begin(), keys.end());
    
        std::cout << "Keys: " << std::endl;
        thrust::copy(keysN.begin(), keysN.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << std::endl;
    
        thrust::sort_by_key(keysN.begin(), keysN.end(), values.begin());
    
        std::cout << "Keys: " << std::endl;
        thrust::copy(keys.begin(), keys.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << std::endl;
    
        std::cout << "Values: " << std::endl;
        thrust::copy(values.begin(), values.end(), std::ostream_iterator<int>   (std::cout, " "));
        std::cout << std::endl;
    
    return 0;
    }