Cuda 删除排序列表中的条目:在gpu中高效
我正在尝试用cuda/推力编码以下问题。我得到一个键列表和与每个键相关的三个值。我设法按字典顺序对它们进行了分类。如果具有相同键的输入具有每个值相关关系,则现在需要减少输入。在下面的示例中,V1(a)值。at(2)值。at(2)){ jt=myMap.erase(jt); } else++jt; } 否则就断了; } }Cuda 删除排序列表中的条目:在gpu中高效,cuda,thrust,Cuda,Thrust,我正在尝试用cuda/推力编码以下问题。我得到一个键列表和与每个键相关的三个值。我设法按字典顺序对它们进行了分类。如果具有相同键的输入具有每个值相关关系,则现在需要减少输入。在下面的示例中,V1(a)值。at(2)值。at(2)){ jt=myMap.erase(jt); } else++jt; } 否则就断了; } } std::cout我认为您可以将推力::unique与谓词一起使用,如中所示。 实际上,我们之所以能够做到这一点,是因为独特的具有以下特点: 对于[first,last]范围
std::cout我认为您可以将
推力::unique
与谓词一起使用,如中所示。
实际上,我们之所以能够做到这一点,是因为独特的具有以下特点:
对于[first,last]范围内具有相同值的每组连续元素,unique
删除组中除第一个元素外的所有元素
因此,您应该定义一个谓词来测试伪相等性,对于具有相同键且第一个元组中所有值都较小的元组,该谓词将返回true
:
typedef thrust::tuple<int, int, int, int> tuple_t;
// a functor which defines your *uniqueness* condition
struct tupleEqual
{
__host__ __device__
bool operator()(tuple_t x, tuple_t y)
{
return ( (x.get<0>() == y.get<0>()) // same key
&& (x.get<1>() <= y.get<1>()) // all values are smaller
&& (x.get<2>() <= y.get<2>())
&& (x.get<3>() <= y.get<3>()));
}
};
我认为您可以将推力::unique
与谓词一起使用,如中所示。
实际上,我们之所以能够做到这一点,是因为独特的具有以下特点:
对于[first,last]范围内具有相同值的每组连续元素,unique
删除组中除第一个元素外的所有元素
因此,您应该定义一个谓词来测试伪相等性,对于具有相同键且第一个元组中所有值都较小的元组,该谓词将返回true
:
typedef thrust::tuple<int, int, int, int> tuple_t;
// a functor which defines your *uniqueness* condition
struct tupleEqual
{
__host__ __device__
bool operator()(tuple_t x, tuple_t y)
{
return ( (x.get<0>() == y.get<0>()) // same key
&& (x.get<1>() <= y.get<1>()) // all values are smaller
&& (x.get<2>() <= y.get<2>())
&& (x.get<3>() <= y.get<3>()));
}
};
很难准确地识别您需要的内容,但似乎通过按键的方式完成唯一的步骤可能就是解决方案。您可以发布一个指向串行解决方案的链接吗?我认为通过按键的方式完成唯一的步骤并不容易,因为它通过查看相邻元素来完成唯一的步骤。解决方案需要查看所有可能的对。很难准确地确定您需要什么,但似乎解决方案可能是按密钥插入::unique_。您可以发布一个指向串行解决方案的链接吗?我认为插入::unique_by_key
将不容易,因为它通过查看相邻元素来执行唯一步骤。解决方案需要查看所有可能的对s
#include <iostream>
#include <tr1/array>
#include <vector>
#include <algorithm>
struct mapItem {
mapItem(int k, int v1, int v2, int v3){
key=k;
std::tr1::array<int,3> v = {v1, v2, v3};
values=v;
};
int key;
std::tr1::array<int,3> values;
};
struct sortLexiObj{
bool operator()(const mapItem& lhs, const mapItem& rhs){
return lhs.values < rhs.values;
}
};
struct sortKey{
bool operator()(const mapItem& lhs, const mapItem& rhs){
return lhs.key < rhs.key;
}
};
int main(int argc, char** argv){
std::vector<mapItem> myMap;
// Set up initial matrix:
myMap.push_back(mapItem(3, 1, 2, 4));
myMap.push_back(mapItem(1, 2, 6, 2));
myMap.push_back(mapItem(1, 2, 5, 3));
myMap.push_back(mapItem(1, 3, 6, 5));
myMap.push_back(mapItem(2, 8, 8, 8));
myMap.push_back(mapItem(1, 2, 7, 4));
std::sort(myMap.begin(), myMap.end(), sortLexiObj());
std::stable_sort(myMap.begin(), myMap.end(), sortKey());
std::cout << "\r\nOriginal sorted Map" << std::endl;
for(std::vector<mapItem>::iterator mt=myMap.begin(); mt!=myMap.end(); ++mt){
std::cout << mt->key << "\t";
for(std::tr1::array<int,3>::iterator it=(mt->values).begin(); it!=(mt->values).end(); ++it){
std::cout << *it << " ";
}
std::cout << std::endl;
}
/////////////////////////
// Reducing myMap
for(std::vector<mapItem>::iterator it=myMap.begin(); it!=myMap.end(); ++it){
std::vector<mapItem>::iterator jt=it; ++jt;
for (; jt != myMap.end();) {
if ( (it->key == jt->key)){
if ( it->values.at(0) <= jt->values.at(0) &&
it->values.at(1) <= jt->values.at(1) &&
it->values.at(2) <= jt->values.at(2) ) {
jt = myMap.erase(jt);
}
else ++jt;
}
else break;
}
}
std::cout << "\r\nReduced Map" << std::endl;
for(std::vector<mapItem>::iterator mt=myMap.begin(); mt!=myMap.end(); ++mt){
std::cout << mt->key << "\t";
for(std::tr1::array<int,3>::iterator it=(mt->values).begin(); it!=(mt->values).end(); ++it){
std::cout << *it << " ";
}
std::cout << std::endl;
}
return 0;
}
typedef thrust::tuple<int, int, int, int> tuple_t;
// a functor which defines your *uniqueness* condition
struct tupleEqual
{
__host__ __device__
bool operator()(tuple_t x, tuple_t y)
{
return ( (x.get<0>() == y.get<0>()) // same key
&& (x.get<1>() <= y.get<1>()) // all values are smaller
&& (x.get<2>() <= y.get<2>())
&& (x.get<3>() <= y.get<3>()));
}
};
typedef thrust::device_vector< int > IntVector;
typedef IntVector::iterator IntIterator;
typedef thrust::tuple< IntIterator, IntIterator, IntIterator, IntIterator > IntIteratorTuple;
typedef thrust::zip_iterator< IntIteratorTuple > ZipIterator;
IntVector keyVector;
IntVector valVector1, valVector2, valVector3;
tupleEqual predicate;
ZipIterator newEnd = thrust::unique(
thrust::make_zip_iterator(
thrust::make_tuple(
keyVector.begin(),
valVector1.begin(),
valVector2.begin(),
valVector3.begin() ) ),
thrust::make_zip_iterator(
thrust::make_tuple(
keyVector.end(),
valVector1.end(),
valVector2.end(),
valVector3.end() ) ),
predicate );
IntIteratorTuple endTuple = newEnd.get_iterator_tuple();
keyVector.erase( thrust::get<0>( endTuple ), keyVector.end() );
valVector1.erase( thrust::get<1>( endTuple ), valVector1.end() );
valVector2.erase( thrust::get<2>( endTuple ), valVector2.end() );
valVector3.erase( thrust::get<3>( endTuple ), valVector3.end() );