cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

spectral
Adept II

OpenCL alignment

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;

 

0 Likes
14 Replies
genaganna
Journeyman III

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;

0 Likes

try change native types like float8 to cl_float8. you should get proper aligment.

0 Likes

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 ?

0 Likes

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.

0 Likes

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.

0 Likes

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 ?

0 Likes

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.

0 Likes

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;



0 Likes

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;



 

 



 

0 Likes

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 ?

0 Likes

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

0 Likes

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

0 Likes

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.

0 Likes

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.

0 Likes