boostorg / compute

A C++ GPU Computing Library for OpenCL
http://boostorg.github.io/compute/
Boost Software License 1.0
1.52k stars 333 forks source link

Error sorting int2 vector #835

Closed ymhsieh closed 5 years ago

ymhsieh commented 5 years ago

Hello, I've gotten wrong results doing sorting with the following code using NVIDIA or Intel GPU. I've tried both the master branch or develop branch and they both give me incorrect results.
Would you please look into this issue? Thanks.

#include <iostream>
using namespace std;
#include <boost/compute.hpp>
namespace compute = boost::compute;
using compute::uint2_;

BOOST_COMPUTE_FUNCTION(uint2_, myGen, (), {
  uint2 out;
  out.x = get_global_id(0);
  out.y = out.x * 4;
  return out;
});

BOOST_COMPUTE_FUNCTION(bool, myComp, (uint2_ a, uint2_ b), {
  return a.x > b.x;
});

int main() {
  cout << "\nBoost compute version: "
    << BOOST_COMPUTE_VERSION_MAJOR << "."
    << BOOST_COMPUTE_VERSION_MINOR << "."
    << BOOST_COMPUTE_VERSION_PATCH << endl;
  auto device = compute::system::default_device();
  cout << "\nDevice: " << device.name();
  compute::vector<uint2_> array(64);
  compute::generate(array.begin(), array.end(), myGen);

  for(const auto& i: array) {
    cout << i << " ";
  }
  compute::sort( array.begin(), array.end(), myComp);

  cout << endl;
  for(const auto& i: array) {
    cout << i << " ";
  }

  return 0;
}
jszuppe commented 5 years ago

Try replacing

 for(const auto& i: array) {
    cout << i << " ";
  }

with

for(auto i = array.begin; i != array.end(); i++)
{
    cout << i.read(compute::system::default_queue()) << " ";
}

Alternatively, you can also add compute::system::default_queue().finish() after sorting.

I'm not 100% sure, but the problem might be that

 for(const auto& i: array) {
    cout << i << " ";
  }

uses different queue to read values than sorting operations, therefore they are not synchronised.

ymhsieh commented 5 years ago

Thank you for your quick advise, and it did solve the problem...