Hi,
I have the following C++ structure :
struct plXYZ { float x,y,z; }
typedef struct
{
float turbidity;
float thetaSun, phiSun;
float Zenith_x, Zenith_y, Zenith_Y;
float zenithL_A, zenithL_B, zenithL_C, zenithL_D, zenithL_E;
float zenithX_A, zenithX_B, zenithX_C, zenithX_D, zenithX_E;
float zenithY_A, zenithY_B, zenithY_C, zenithY_D, zenithY_E;
plXYZ sunDirection;
plXYZ sunSpectralRadiance;
float sunSolidAngle;
cl_float8 riS0Spectrum;
cl_float8 riS1Spectrum;
cl_float8 riS2Spectrum;
cl_float8 Y;
float yint;
} CLPhysicalSkyLight;
And the following OpenCL structure :
typedef struct
{
float turbidity;
float thetaSun, phiSun;
float Zenith_x, Zenith_y, Zenith_Y;
float zenithL_A, zenithL_B, zenithL_C, zenithL_D, zenithL_E;
float zenithX_A, zenithX_B, zenithX_C, zenithX_D, zenithX_E;
float zenithY_A, zenithY_B, zenithY_C, zenithY_D, zenithY_E;
float sunDirectionX, sunDirectionY, sunDirectionZ;
float sunSpectralRadianceX,sunSpectralRadianceY,sunSpectralRadianceZ;
float sunSolidAngle;
// Constants for 'chromacity to spectrum'
float8 riS0Spectrum;
float8 riS1Spectrum;
float8 riS2Spectrum;
float8 Y;
float yint;
} PhysicalSkyLight;
struct size must be multiples of maximum datatype size. In your case, it should be multiples of float8 size.
typedef struct { float turbidity; float thetaSun, phiSun; float Zenith_x, Zenith_y, Zenith_Y; float zenithL_A, zenithL_B, zenithL_C, zenithL_D, zenithL_E; float zenithX_A, zenithX_B, zenithX_C, zenithX_D, zenithX_E; float zenithY_A, zenithY_B, zenithY_C, zenithY_D, zenithY_E; float sunDirectionX, sunDirectionY, sunDirectionZ; float sunSpectralRadianceX,sunSpectralRadianceY,sunSpectralRadianceZ; float sunSolidAngle; // Add four dummy floats to make 32 floats which is equal to 4 * float8's float dummy1, dummy2, dummy3, dummy4; // Constants for 'chromacity to spectrum' float8 riS0Spectrum; float8 riS1Spectrum; float8 riS2Spectrum; float8 Y; float yint; //Add 7 floats to make alignment float4 d1; float f1, f2, f3; } PhysicalSkyLight;
try change native types like float8 to cl_float8. you should get proper aligment.
Thanks,
I have already try this... to align to 8, but I got some wrong values on the OpenCL side !
There is only one way I've found to fix this is to use __attribute__ ((packed)) !! But it is not very beautiful !
In my C++ structure, I use plXYZ ... maybe the problem come from there ?
typedef struct { float x, y, z; } plXYZ;
Should I align to 8 before/after each plXYZ ?
Originally posted by: viewon01 Thanks,
I have already try this... to align to 8, but I got some wrong values on the OpenCL side !
There is only one way I've found to fix this is to use __attribute__ ((packed)) !! But it is not very beautiful !
In my C++ structure, I use plXYZ ... maybe the problem come from there ?
typedef struct { float x, y, z; } plXYZ;
Should I align to 8 before/after each plXYZ ?
I feel it should not affect. You should add similar padding in your C++ structure also. If you don't add padding to C++ structure, you should get error from clSetKernelArg() function.
it depent on which boundary compiler align that struct. if it align to a 4 byte then it is not a problem. but on 64bit it can align onto 8 byte. packged align is IMHO only solution.
Thanks,
I'm on a Windows 7 - 64 bits machine. But compile in 32 bits !
The alignment is only done on the C++ level... I have nothing to do on the OpenCL side ! Right ?
Originally posted by: viewon01 Thanks,
I'm on a Windows 7 - 64 bits machine. But compile in 32 bits !
The alignment is only done on the C++ level... I have nothing to do on the OpenCL side ! Right ?
You have to do same thing on both sides.
Thanks,
It works, the problem was in another structure :
typedef struct
{
enum SkyType type;
union
{
PhysicalSkyLight physical;
EnvironmentLight environment;
} sky;
} Sky;
Now transformed to :
typedef struct
{
union
{
PhysicalSkyLight physical;
EnvironmentLight environment;
} sky;
enum SkyType type;
} Sky;
Another problem...
Now I have added some fields to the structure and I got a crash when I try to access to "sky.physical.riS1Spectrum.s0" (But no problem for "sky.physical.riS0Spectrum.s7") !!
So, why I got an "access violation" when I try to access riS1Spectrum !!
Do you have any idea ?
Thanks
Here is the OpenCL structure :
typedef struct __attribute__ ((packed))
{
float turbidity;
float thetaSun, phiSun;
float Zenith_x, Zenith_y, Zenith_Y; //xyY color
float zenithL_A, zenithL_B, zenithL_C, zenithL_D, zenithL_E;
float zenithX_A, zenithX_B, zenithX_C, zenithX_D, zenithX_E;
float zenithY_A, zenithY_B, zenithY_C, zenithY_D, zenithY_E;
plXYZ sunDirection;
plXYZ sunSpectralRadiance;
float sunSolidAngle;
float a1, a2, a3, a4;
// Constants for 'chromacity to spectrum'
float8 riS0Spectrum;
float8 riS1Spectrum;
float8 riS2Spectrum;
float8 X;
float8 Y;
float8 Z;
float yint;
float b1, b2, b3, b4, b5, b6, b7;
} PhysicalSkyLight;
typedef struct
{
float shiftU;
float shiftV;
plXYZ gain;
int textMapId;
} EnvironmentLight;
enum SkyType
{
T_NO_SKY, T_ENVIRONMENT_SKY, T_PHYSICAL_SKY
};
typedef struct
{
union
{
PhysicalSkyLight physical;
EnvironmentLight environment;
} sky;
enum SkyType type;
} Sky;
And the C++ structure
typedef struct
{
float turbidity;
float thetaSun, phiSun;
float Zenith_x, Zenith_y, Zenith_Y; //xyY color
float zenithL_A, zenithL_B, zenithL_C, zenithL_D, zenithL_E;
float zenithX_A, zenithX_B, zenithX_C, zenithX_D, zenithX_E;
float zenithY_A, zenithY_B, zenithY_C, zenithY_D, zenithY_E;
plXYZ sunDirection;
plXYZ sunSpectralRadiance;
float sunSolidAngle;
// Align : 28->32
float a1, a2, a3, a4;
// Constants for 'chromacity to spectrum'
cl_float8 riS0Spectrum;
cl_float8 riS1Spectrum;
cl_float8 riS2Spectrum;
cl_float8 X;
cl_float8 Y;
cl_float8 Z;
float yint;
// Align : 1->8
float b1, b2, b3, b4, b5, b6, b7;
} CLPhysicalSkyLight;
typedef struct
{
float shiftU;
float shiftV;
plXYZ gain;
int textMapId;
} CLEnvironmentLight;
enum CLSkyType
{
T_NO_SKY, T_ENVIRONMENT_SKY, T_PHYSICAL_SKY
};
typedef struct
{
union
{
CLPhysicalSkyLight physical;
CLEnvironmentLight environment;
} sky;
enum CLSkyType type;
} CLSky;
Hi,
I have added this to CLSky (on both side)
float b1, b2, b3, b4, b5, b6, b7;
and added __attribute__ ((packed)) on the OpenCL side !
But why should I also "align" by hand the OpenCL version ?
you can check proper aligment with something like this. extend it for every var in your struct. and remove that attribute from OpenCL side. run this kernel on OpenCL and on C++ side too. and add padding elements to achive same aligment on C++ and OpenCL side.
CLPhysicalSkyLight c; printf("%d ", sizeof(CLPhysicalSkyLight)); printf("%d ", ((size_t)&c.sunSolidAngle)-((size_t)&c)); printf("%d ", ((size_t)&c.riS0Spectrum)-((size_t)&c));
Thanks,
I will try this. Just a question... how can I run a kernel in C++ side ? What does it mean ? (For now I only run on CPU).
Thx
no you just run kernel in OpenCl. with global size 1. and normal run it as normal C++ code. so you get starting offset of elements from OpenCL and C++. and you must make them match.
Originally posted by: nou it depent on which boundary compiler align that struct. if it align to a 4 byte then it is not a problem. but on 64bit it can align onto 8 byte. packged align is IMHO only solution.
structure alignment should depend on size of data types, not on address bus size.