2011-08-27 37 views
1

我想在cuda/thrust中編碼以下問題。我給出了一個關鍵字列表和三個與每個鍵關聯的值。我已經設法按字典順序對它們進行排序。如果具有相同鍵的輸入具有每個數值關係,那麼現在需要減少輸入。在下面的例子中,V1(a)和V1(c)和V2(a)是V2(c)和V3(a),這意味着Input a <輸入c,因此輸入c從輸出中刪除。刪除排序列表中的條目:在gpu中有效

示例輸入:

 Key  V1  V2  V3 
a.  1  2  5  3 
b.  1  2  6  2 
c.  1  2  7  4   
d.  1  3  6  5   
e.  2  8  8  8 
f.  3  1  2  4 

示例輸出:

  Key V1 V2 V3 
a.  1 2 5 3 
b.  1 2 6 2 
e.  2 8 8 8 
f.  3 1 2 4 
  • 輸入一個<輸入的C ==>℃下除去
  • 輸入一個<輸入d ==> d除去

我已經能夠使用for-loops和if語句解決上述問題。我目前正在嘗試使用基於GPU的cuda/thrust來解決這個問題。這是否可以在GPU上完成(最好是推力)或者一個單獨的內核必須用cuda編寫?

我沒有制定使用獨特的這個問題,因爲在Thrust: Removing duplicates in key-value arrays

編輯討論包括程序「STL/C++」的程序來生成上述方案:部分「減少MYMAP」使用for循環我的實現和if語句。

#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; 
} 
+0

難以確切地確定您需要什麼,但它似乎像推力:: unique_by_key可能是解決方案。你可以發佈一個鏈接到你的串行解決方案嗎? –

+0

在原始文章中添加代碼。 – waqy

+0

我不'想'推力:: unique_by_key'將以一種簡單的方式工作,因爲它通過查看相鄰元素來執行獨特的步驟。解決方案需要查看所有可能的配對。 –

回答

1

我認爲你可以使用thrust::unique有謂語,因爲它在Thrust: Removing duplicates in key-value arrays顯示真實。 實際上,我們可以這樣做是因爲的unique以下特徵的:具有相同值的

對於每個組在範圍[第一連續元素,最後一個),unique移除所有,但第一元件羣組。

所以,你應該定義一個謂詞來測試 -equality將返回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>())); 
     } 
    }; 

而且您必須將其應用於排序的集合。這樣,只有第一個元組(最小)不會被刪除。 具有相同鍵和V1,V2或V3中較大值的元組將產生false,因此它不會被刪除。

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());