Thanks for the answer clint3112!
i do it my dissertation and i have been confused. 8)
I think you have to define every size of the Struct members. I cant see the size of the struct inside your structs. Make shure that the full byte size of your struct is defined.
What do you mean? I suppose that you mean to check if the struct members of the host and the struct members of the device have the same size. Unfortunately, they don't. I use as device an AMD CPU, so i can use printf inside a kernel.
Let’s take it from the beginning…
I am trying to traverse a tree, so i use a contiguous memory block on host and i change the pointers using as base address the base address of the buffer object, so i have the question :
tree_d = clCreateBuffer(…); returns the base address of the buffer object? or i should do sth else?
More specifically, i do operations for changing the addresses as follows:
struct _FttOct tree_new_addresses_gpu = malloc(…);
tree_new_addresses_gpu[i].neighbors.c[j] = (struct _FttCell *)((size_t)tree_d + ((size_t)t[i].neighbors.c[j] - (size_t)tree));
and then i tranfer the tree_new_addresses_gpu to the device.
I print the addresses of the tree on the device and they are not correct.
the structs used for the traversal are:
struct _FttVector {
double x, y, z;
};
struct _FttCell {
unsigned int flags;
global void * data;
global struct _FttOct * parent, * children;
};
struct _FttCellNeighbors {
global struct _FttCell * c[FTT_NEIGHBORS];
};
struct _FttCellChildren {
global struct _FttCell * c[FTT_CELLS];
};
struct _FttRootCell {
struct _FttCell cell;
struct _FttCellNeighbors neighbors;
struct _FttVector pos;
unsigned int level;
global void * parent;
};
struct _FttOct {
unsigned int level;
global struct _FttCell * parent;
struct _FttCellNeighbors neighbors;
struct _FttVector pos;
struct _FttCell cell[FTT_CELLS];
};
struct _FttCellFace {
global struct _FttCell * cell, * neighbor;
FttDirection d;
};
struct _GfsFaceStateVector {
double un;
double v;
};
struct _GfsStateVector {
/* temporary face variables */
struct _GfsFaceStateVector f[FTT_NEIGHBORS];
/* solid boundaries */
global struct _GfsSolidVector * solid;
double place_holder;
};
struct _GfsSolidVector {
double s[FTT_NEIGHBORS];
double a, fv;
global struct _FttCell * merged;
struct _FttVector cm, ca, v;
};
struct _GfsGradient {
double a, b;
};
I find differences at sizes of structs:
host : sizeof(struct _GfsStateVector) = 80) and device : sizeof(struct _GfsStateVector) = 112
host : sizeof(struct _FttCellNeighbors) = 32 and device : sizeof(struct _FttCellNeighbors) = 48
host : sizeof(struct FttCell) = 32 and device : sizeof(struct FttCell) = 32 are the same…
So, i am confused!!! :roll:
i found :
The compiler should handle data alignment for you. As for the structure’s size, if you put a pointer in it, it’s size will be implementation dependent. That being said, using pointers and expecting them to persist across kernels is dangerous.
On AMD GPUs, memory addresses can map differently across kernel calls which will screw up your data structures. I would recommend using integer offsets instead of pointers, as integers have a predictable size and you can reindex into the buffer they were allocated in at runtime and get the real address.
and also i found at a lecture :
OpenCL does not allow device pointer arithmetic on the host:
Must use integer offsets
i do not understand… :?
So, i cannot use pointers as members of structs?? :?: It is not convenient for me to use integer offsets instead.
P.S I found at OpenCL Progamming Guide that global and __global are the same.