How to pass a matrix to Image2D in OpenCLTemplate?

I'm trying to implement a parallel Gauss-Seidel algorithm. Here is my kernel function

#define dx (float2)(1,0)
#define dy (float2)(0,1)

__kernel void rbgs(read_only image2d_t fh, read_only image2d_t vh, 
  global float *vvh, __global float* hx, __global float* hy,__global int* red)
{
    float2 id = (float2)(get_global_id(0) << 1,get_global_id(1));
    const float2 sz = (float2)(1,get_global_size(0));
    const sampler_t sampler = CLK_ADDRESS_CLAMP_TO_EDGE;
    id.x += ((int)(id.y + *red) & 1);
    const float s = ((read_imagef(vh,sampler,id-dx).x + read_imagef(vh,sampler,id+dx).x)/(*hy* *hy) + (read_imagef(vh,sampler,id-dy).x + 
    read_imagef(vh,sampler,id+dy).x)/(*hx* *hx) - read_imagef(fh,    sampler,id).x)/(2/(*hx**hx)+2/(*hy**hy));
    vvh[(int)dot(id,sz)] = s;
}

It does compile good, but I have problems with passing an Image to kernel

Here's what I try

var rows = u.GetLength(0);
var cols = u.GetLength(1);
var array1d = new float[rows * cols];
var current = 0;
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        array1d[current++] = u[i, j];
    }
}

rows = fh.GetLength(0);
cols = fh.GetLength(1);
var array1df= new float[rows * cols];
current = 0;
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        array1df[current++] = fh[i, j];
    }
}
CLCalc.Program.Image2D CLfh = new CLCalc.Program.Image2D(array1df, M, N);
CLCalc.Program.Image2D CLvh = new CLCalc.Program.Image2D(array1d, M, N);
CLfh.WriteToDevice(array1df);
CLvh.WriteToDevice(array1d);

float[] solution = new float[(N+1)*(M+1)];


CLCalc.Program.Variable Stepx = new CLCalc.Program.Variable(new float[] { hx });
CLCalc.Program.Variable Stepy = new CLCalc.Program.Variable(new float[] { hy });
CLCalc.Program.Variable Red = new CLCalc.Program.Variable(new float[] { 1.0f });
CLCalc.Program.Variable Result = new CLCalc.Program.Variable(solution);

CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] {CLfh, CLvh, Result, Stepx, Stepy, Red} ;
gs.Execute(args, new int[] { 2, 4 });
Result.ReadFromDeviceTo(solution);
CLvh.WriteToDevice(solution);
Red.WriteToDevice(new float[] { 0.0f });
gs.Execute(args, new int[] { 2, 4 });
Result.ReadFromDeviceTo(solution);
for (int m = 0; m < (M + 1) * (N + 1); m++)
    u[m / (N+1), m % (N+1)] = solution[m];
return u;

The program fails with Runtime Exception: Vector Length should be 4*width*height. I know that exception was supposed to be thrown because an Image stores data in RGBA format but I do not really understand how I should overcome this problem.

Any help would be appreciated.

Upvotes: 1

Views: 181

Answers (0)

Related Questions