#include <thrust/device_vector.h>
//#include <thrust/reduce.h>
#include <thrust/extrema.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/functional.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.\n", msg,
cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}
using namespace std;
int main(void)
{
float *cost=NULL;
cudaMalloc( (void **) &cost, 5 * sizeof(float) );
checkCUDAError("## cuda malloc cost ##");
bool *visited=NULL;
cudaMalloc( (void **) &visited, 5 * sizeof(bool) );
checkCUDAError("## cuda malloc visited ##");
/////////////////////////////////////////////////////////////////////////////////////////
thrust::device_ptr< float > dp_cost( cost );
thrust::device_ptr< bool > dp_visited( visited );
for (int i = 0; i < 5; ++i)
{
float c;
bool vs;
cin>> c >> vs;
dp_cost[i] = c;
dp_visited[i] = vs;
}
for (int i = 0; i < 5; ++i)
{
cout<< dp_cost[i] << " , " << dp_visited[i] <<endl;
}
/////////////////////////////////////////////////////////////////////////////////////////
typedef thrust::device_ptr<bool> BoolIterator;
typedef thrust::device_ptr<float> ValueIterator;
BoolIterator bools_begin = dp_visited, bools_end = dp_visited +5;
ValueIterator values_begin = dp_cost, values_end = dp_cost +5;
typedef thrust::tuple<BoolIterator, ValueIterator> IteratorTuple;
typedef thrust::tuple<bool, float> DereferencedIteratorTuple;
typedef thrust::zip_iterator<IteratorTuple> NodePropIterator;
struct nodeProp_comp : public thrust::binary_function<DereferencedIteratorTuple, DereferencedIteratorTuple, bool>
{
__host__ __device__
bool operator()( const DereferencedIteratorTuple &lhs, const DereferencedIteratorTuple &rhs ) const
{
if( !( thrust::get<0>( lhs ) ) && !( thrust::get<0>( rhs ) ) )
{
return ( thrust::get<1>( lhs ) < thrust::get<1>( rhs ) );
}
else
{
return !( thrust::get<0>( lhs ) );
}
}
};
NodePropIterator iter_begin (thrust::make_tuple(bools_begin, values_begin));
NodePropIterator iter_end (thrust::make_tuple(bools_end, values_end));
/*NodePropIterator iter_begin (thrust::make_tuple(dp_visited, dp_cost));
NodePropIterator iter_end (thrust::make_tuple(dp_visited +5, dp_cost +5));*/
NodePropIterator min_el_pos = thrust::min_element( iter_begin, iter_end, nodeProp_comp() );
/*NodePropIterator min_el_pos = thrust::min_element(
thrust::make_zip_iterator( thrust::make_tuple(dp_visited, dp_cost) ),
thrust::make_zip_iterator( thrust::make_tuple(dp_visited +5, dp_cost +5) ),
nodeProp_comp());*/
cudaThreadSynchronize();
checkCUDAError("## thrust min el ##");
/////////////////////////////////////////////////////////////////////////////////////////
DereferencedIteratorTuple tmp = *min_el_pos;
cout<< " \n#### "<< thrust::get<0>( tmp )
<< " , " << thrust::get<1>( tmp ) <<endl;
cout<< "Pos : " << min_el_pos - iter_begin <<endl;
cudaFree(cost);
cudaFree(visited);
return 0;
}
In the above simple example I tried to find the min value, which is not yet visited.
But on compilation i get this error.
thrust_min.cu(99): error: no instance of overloaded function "thrust::min_element" matches the argument list
argument types are: (NodePropIterator, NodePropIterator, nodeProp_comp)
1 error detected in the compilation of "/tmp/tmpxft_00005c67_00000000-6_thrust_min.cpp1.ii".
I just made up the sample program above. I require the above logic in a much larger (multifile) program.
Plese help.
gcc version 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC)
CUDA 5