2012-01-31 66 views
4

編輯:根據PlasmaHH的建議增加了帶有內存位置的調試輸出。cl :: vector vs std :: vector:不同的迭代器行爲

我不明白cl :: vector <>在OpenCL的C++綁定中的不同行爲。考慮下面的代碼:

部首Top.hpp

class Top { 
public: 
    void setBool(bool b); 
    bool getBool(); 
private: 
    bool status; 
}; 

Top.cpp

#include "Top.hpp" 

void Top::setBool(bool b) { 
    std::cout << (void*)this << " setBool("<< b<< ")\n"; 
    status = b; 
} 

bool Top::getBool() { 
    std::cout << (void*)this << " getBool() returns " << status << std::endl; 
    return status; 
} 

使用以上:

#define __NO_STD_VECTOR 

#include <iostream> 
#include "CL/cl.hpp" 
#include "Top.hpp" 

using namespace cl; 
using namespace std; 

cl::vector<Top> js; 

int main() { 
    js.push_back(Top()); 
    js[0].setBool(true); 
    cout << js[0].getBool() << endl; 
    for(cl::vector<Top>::iterator i = js.begin(); i != js.end(); ++i) { 
     (*i).setBool(false); 
    } 
    cout << js[0].getBool() << endl; 
} 

隨着__NO_STD_VECTOR在std ::矢量被覆蓋。輸出是

0x6021c0 setBool(1) 
0x6021c0 getBool() returns 1 
0x7fffae671d60 setBool(0) 
0x6021c0 getBool() returns 1 

所以迭代器返回的位置肯定是錯誤的。

使用上述與std::vector(並更改命名空間,當然std),但是給人的預期輸出:

0x1be0010 setBool(1) 
0x1be0010 getBool() returns 1 
0x1be0010 setBool(0) 
0x1be0010 getBool() returns 0 

這個迭代器作用不同,但它應該更換的std ::向量避免兼容性問題。我錯過了什麼嗎?

+1

嘗試添加類似'std :: cout <<(void *)this <<「setBool(」<< b <<「)\ n」;'到你的setBool函數(類似於getBool)來看看正在進行,以及在哪裏設置,如果有的話。這樣你可以看到它是否迭代,或者東西是「指向」錯誤的元素等。 – PlasmaHH 2012-01-31 15:20:19

+0

在任何情況下,'std :: vector'行爲都是我所期望的。我無法想象爲什麼'cl :: vector'會做一些奇怪的事情...... – Xeo 2012-01-31 15:31:16

+0

@Xeo:是的,預計是'std :: vector'。 @PlasmaHH:的確,由迭代器返回的對象具有不同的內存地址,所以它不會返回我的對象​​並在其他地方設置「false」。 – rdoubleui 2012-01-31 15:34:56

回答

4

不是任何想象力的OpenCL專家,但我很感興趣,所以我去了CUDA/OpenCL Computing。我似乎他們的*符返回一個副本,而不是參考:

00706   T operator *() 
00707   { 
00708    return vec_[index_]; 
00709   } 

鑑於(第一,非const)載體[]操作返回一個參考:

00621  T& operator[](int index) 
00622  { 
00623   return data_[index]; 
00624  } 
00625 
00626  T operator[](int index) const 
00627  { 
00628   return data_[index]; 
00629  } 

嘗試通過矢量迭代直接(使用舊的「int i = 0,...」),看看是否給出了不同的結果。如果是這樣,您可能需要輸入一個錯誤報告(首先檢查),因爲這是*運算符的意外行爲。

+0

我可以證實類似數組的方法(原諒缺乏適當的術語)有效(正如上面的例子'js [0] .setBool(false)')。 – rdoubleui 2012-01-31 17:13:36

+0

Erp!我應該注意到了!那麼,我會說要聯繫AMD(或者你的圖書館的任何人)並詢問是否有意。這當然不是我期望它行動的方式。 – 2012-01-31 19:17:14

+0

不幸的是它是一個Nvidia芯片,所以我打賭他們只是在等待我的錯誤報告......但我會看看。 – rdoubleui 2012-01-31 20:18:39

1

從地址判斷我懷疑這是一個64位版本,並且cl向量的迭代器的operator*正在通過值返回而不是通過引用返回,而不允許訪問原始元素。作爲一個實驗,你可以嘗試使用->運營商,而不是i->setBool(false);,看看它是否健全。

+0

' - >'運算符不起作用,編譯器抱怨:' - >'的基本操作數具有非指針類型'cl :: vector :: iterator'。我有點遺憾解釋這一點。 – rdoubleui 2012-01-31 16:10:18

+1

@rdoubleui:這意味着迭代器似乎沒有重載'operator->'。 – Xeo 2012-01-31 16:46:15