Reputation: 13195
What is the most efficient way of converting an array of 16 bytes into a uint4 vector ? currently, I manually OR the bytes into uints, then set the vector's components with the completed uints. Is there OpenCL support for performing this task?
This is for OpenCL 1.2
Edit: here is my code:
local uchar buffer[16];
uint v[4];
for (int i = 0; i < 4; ++i) {
v[i]=0;
for (int j = 0; j < 4; ++j) {
v[i] |= (buffer[(i<<2)+j]) << (j<<3);
}
}
uint4 result = (uint4)(v[0],v[1],v[2],v[3]);
Edit 2: buffer is actually a local buffer.
Upvotes: 0
Views: 1297
Reputation: 8410
If you shape your data in a different way you have an instruction for that:
ushort[n] upsample (uchar[n] hi, uchar[n] lo){
result[i]= ((short)hi[i]<< 8) | lo[i]
}
uint[n] upsample (ushort[n] hi, ushort[n] lo){
result[i]= ((uint)hi[i]<< 8) | lo[i]
}
But you will need uchar16 buffer' = (uchar16)(buffer[0], buffer[4], buffer[8], buffer[12], buffer[1], buffer[5], buffer[9], buffer[13], ....)
(please check!)
In order to be able to just perform a simple:
uint4 result = upsample(upsample(buffer'));
This is probably the fastest way of doing it, since it does vector operations. If you have the data properly shaped of course....
But if your data is aligned, you can just cast it, and it will work.
uint4 result = *((local uint4 *)(&buffer));
For your case I think it is not, so you can do something like:
uchar16 bufferR = (uchar16)(buffer[3], buffer[2], buffer[1], buffer[0], buffer[7], buffer[6], buffer[5], buffer[4], ....)
uint4 result = *((uint4 *)(&bufferR));
Or maybe align it in the portion of code that creates that block of uchar16
Upvotes: 1
Reputation: 8494
You should be able to convert it on the fly without copying the data:
local uchar buffer[16];
if(get_local_id(0) == 0)
{
for (int x = 0; x < 4; ++x)
{
buffer[x] = x + 1;
buffer[x + 4] = x + 2;
buffer[x + 8] = x + 3;
buffer[x + 12] = x + 4;
}
local uint4 *result = (local uint4*)buffer;
printf("0x%x 0x%x 0x%x 0x%x\n", (*result).x, (*result).y, (*result).z, (*result).w);
}
Result:
0x4030201 0x5040302 0x6050403 0x7060504
If you need to copy the data though you do:
uint4 result = *(local uint4*)buffer;
Upvotes: 2