Ok, das war ein bisschen komplizierter als ich erwartet hatte :)
Hier sind die Ergebnisse meiner Untersuchungen:
Ihr Problem liegt in der Umsetzung von Thrust. Thrust verwendet einen Typ namens device_reference
die, wie es in der Dokumentation heißt: http://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html
device_reference
fungiert als referenzähnliches Objekt auf ein Objekt das im Gerätespeicher gespeichert ist. device_reference
ist nicht dazu bestimmt direkt verwendet werden; vielmehr ist dieser Typ das Ergebnis der Zurückstellung einer device_ptr
. Ähnlich verhält es sich, wenn man die Adresse einer device_reference
ergibt sich ein device_ptr
.
Es gibt jedoch einige Fälle, in denen wir es implizit mit device_reference
. Wenn z.B. eine device_reference als Parameter an Funktionen übergeben wird, die auf POD warten (mehr oder weniger das, was Sie versuchen, mit operator<<
), stellt sich das folgende Problem:
Ein weiterer häufiger Fall, in dem ein device_reference
nicht direkt sein anstelle des referenzierten Objekts verwendet werden tritt auf, wenn sie als Parameter übergeben werden an Funktionen wie printf
die über varargs-Parameter haben. Da varargs Parameter Plain Old Data sein müssen, muss ein device_reference
zu einem POD-Typ erfordert einen Cast wenn sie an printf übergeben wird:
Alles, was Sie tun müssen, ist, Ihre device_reference
zu dem POD, den Sie bearbeiten. In Ihrem Fall würden Sie das tun:
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++) {
std::cout << (static_cast<point>(*iter)).x << " " << (static_cast<point>(*iter)).y << std::endl;
}
Meiner Meinung nach ist dies nicht die eleganteste Lösung, ich würde lieber die std::copy
Algorithmus zum Drucken des Inhalts Ihrer point
Klasse. Deshalb habe ich eine kleine Beispieldatei geschrieben, die Ihre point
Klasse und druckt sie auf drei verschiedene Arten aus:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <cstdlib>
#include <algorithm>
#include <iostream>
struct point
{
unsigned int x;
unsigned int y;
};
__host__
point getRandomPoint() {
point p;
p.x = rand();
p.y = rand();
return p;
}
__host__
std::ostream& operator<< (std::ostream& os, const point& p) {
os << "[ " << p.x << " ; " << p.y << " ]";
return os;
}
int main() {
// fill the host_vector with random points
thrust::host_vector<point> hPoints(512);
thrust::generate(hPoints.begin(), hPoints.end(), getRandomPoint);
// copy hPoints content to device memory
thrust::device_vector<point> devPoints(hPoints.begin(), hPoints.end());
// first way
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++) {
std::cout << (static_cast<point>(*iter)).x << " " << (static_cast<point>(*iter)).y << std::endl;
}
// second way
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++)
{
std::cout << *iter << std::endl;
}
// third way
std::copy(devPoints.begin(), devPoints.end(), std::ostream_iterator< point >(std::cout, " $ ") );
return 0;
}
Nun liegt es an Ihnen, sich für eine davon zu entscheiden!