Use custom struct

  • VVS0205

    VVS0205 - 2011-05-16

    Big thanks for your project, it is the best project for Net and OpenCl.
    My problem:
    I'm try use custom struct, but I did not get work solution.

    typedef struct 
        int X;
        int * Mass;
    } TestStruct;
    kernel void StructTest(
        global  TestStruct* a,
        global  int* b )
        for (int i = 0; i < 100; i++)
            b[i] = a[index].Mass[i];            


    var properties = new ComputeContextPropertyList(ComputePlatform.Platforms[0]);
                var context = new ComputeContext(ComputeDeviceTypes.Gpu, properties, null, IntPtr.Zero);
                var quene = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
                var prog = new ComputeProgram(context, Kernel);
                prog.Build(context.Devices, "", null, IntPtr.Zero);
                var testKernel = prog.CreateKernel("StructTest");
                var ints = new int[100];
                for (int index = 0; index < ints.Length; index++)
                    ints[index] = 100;
                var ints1 = new int[100];
                var triangleMesh = new TestStruct();
                fixed (int * intsPoint = ints)
                    triangleMesh.Mass = intsPoint;
                    triangleMesh.X = 888;
                    IntPtr pntToStruct = Marshal.AllocHGlobal(Marshal.SizeOf(triangleMesh));
                    Marshal.StructureToPtr(triangleMesh, pntToStruct, false);
                    ComputeErrorCode errorCode;
                    CLMemoryHandle triangleMeshDev = CL10.CreateBuffer(context.Handle,
                                                               ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer,
                                                               new IntPtr(Marshal.SizeOf(triangleMesh)), pntToStruct,
                                                               out errorCode);
                    var b = new ComputeBuffer<int>(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer,
                    ComputeErrorCode computeErrorCode = CL10.SetKernelArg(testKernel.Handle, 0, new IntPtr(sizeof(IntPtr)),
                    testKernel.SetMemoryArgument(1, b);
                    quene.Execute(testKernel, null, new long[] { 1 }, null, null);
                    quene.ReadFromBuffer(b, ref ints1, true, null);

    This is not working.
    How to pass struct?
    P.S. Sorry for my english. I hope for your help.

  • VVS0205

    VVS0205 - 2011-05-16

    Sorry, forgot to add in the kernel

    int index = get_global_id(0);
  • VVS0205

    VVS0205 - 2011-05-17

    I'm find this in the example of people say that everything works, but I do not.

  • VVS0205

    VVS0205 - 2011-05-17

    Sorry did not read to the end, bad that it is impossible to convey structure.

  • VVS0205

    VVS0205 - 2011-05-17

    I do not know the bug is or how it should be, but if you initialize an array of bool as follows:

    var bitsDev = new ComputeBuffer<bool>(_compressKernel.Context,
                                                              ComputeMemoryFlags.ReadOnly |
                                                              ComputeMemoryFlags.UseHostPointer, new bool[1000000] );

    then the large size of the array, the kernel crashes. But if you do so:

    fixed (bool* resRef = new bool[1000000])
                        var bitsDev = new ComputeBuffer<bool>(_compressKernel.Context,
                                                              ComputeMemoryFlags.ReadOnly |
                                                              ComputeMemoryFlags.UseHostPointer, bits.Count/4,
                                                              new IntPtr(resRef));

    Everything works fine. I hope something can be done.

  • nythrix

    nythrix - 2011-05-22

    Do not use ComputeMemoryFlags.UseHostPointer or AllocHostPointer, unless you're COMPLETELY sure about what they do. Replace with CopyHostPointer.
    Both pieces of code you provided contain a bug regarding the garbage collector deleting the array while the OpenCL is using them. The first one is more obvious but the second one is bad as well. Because it WILL crash sometime later.


Log in to post a comment.