This project is read-only.

Issue with Non-Nullable value

Jul 25, 2013 at 2:45 PM
Hello,

I get the error when run this code.

Error 1 The type 'FlyCapture2Managed.ManagedImage' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Cudafy.Host.GPGPU.Allocate<T>(int)' S:\FlyCapture2SimpleGUI_CSharp\Class2.cs 39
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;
using FlyCapture2Managed;
using FlyCapture2SimpleGUI_CSharp;

namespace kernel
{
   public class add_loop_gpu
        {
            //public const uint N = 10;
           public const int k_numImages = 500;
          // public ManagedImage m_rawImage;
           ManagedAVIRecorder aviRecorder = new ManagedAVIRecorder();
           FlyCapture2SimpleGUI_CSharp.Form1 obj = new FlyCapture2SimpleGUI_CSharp.Form1();


           public  void Execute()
            {
                CudafyModule km = CudafyTranslator.Cudafy();

                GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
                gpu.LoadModule(km);

               ManagedImage[] imagelist = new ManagedImage[k_numImages];
             //List<ManagedImage> imageList = new List<ManagedImage>();
               ManagedImage rawImage = new ManagedImage();
               // int[] a = new int[N];
                //int[] b = new int[N];
                //int[] c = new int[N];

                // allocate the memory on the GPU
               // ManagedImage[] imageList2 = gpu.Allocate<ManagedImage>(k_numImages);

               ManagedImage[] imageList2 = gpu.Allocate<ManagedImage>(k_numImages);
                //int[] dev_a = gpu.Allocate<int>(a);
               // int[] dev_b = gpu.Allocate<int>(b);
                //int[] dev_c = gpu.Allocate<int>(c);

                // fill the arrays 'a' and 'b' on the CPU
               for (int imageCnt = 0; imageCnt < k_numImages; imageCnt++)
              //  for (int i = 0; i < N; i++)
               {

                   obj.m_camera.RetrieveBuffer(obj.m_rawImage);
                   ManagedImage tempImage = new ManagedImage(obj.m_rawImage);
                   imagelist[imageCnt]=tempImage;

               }

                // copy the arrays 'a' and 'b' to the GPU
                gpu.CopyToDevice(imagelist, imageList2);
                //gpu.CopyToDevice(b, dev_b);

                // launch add on N threads
                gpu.Launch(k_numImages, 1).adder(imageList2);

                // copy the array 'c' back from the GPU to the CPU
              //  gpu.CopyFromDevice(dev_c, c);

                if (obj.m_grabImages == true)
                {
                    //Encoding bit
                    string aviFileName;
                    aviFileName = String.Format("SaveCSharp-h264");
                    H264Option option = new H264Option();
                    option.frameRate = 24;
                    option.bitrate = 20000000;
                    option.height = Convert.ToInt32(obj.m_rawImage.rows);
                    option.width = Convert.ToInt32(obj.m_rawImage.cols);
                    aviRecorder.AVIOpen(aviFileName, option);

                    for (int imageCnt = 0; imageCnt < k_numImages; imageCnt++)
                    {
                        aviRecorder.AVIAppend(imagelist[imageCnt]);



                    }
                    aviRecorder.AVIClose();
                }
                // free the memory allocated on the GPU
                gpu.Free(imageList2);
               // gpu.Free(dev_b);
               // gpu.Free(dev_c);
            }

            [Cudafy]
           public static void adder(GThread thread, ManagedImage[] imagelist, ManagedImage[] imagelist2)
            {
                int tid = thread.blockIdx.x;
                if (tid < k_numImages)
                    imagelist2[tid] = imagelist[tid];
                    tid += thread.gridDim.x;
            }
        }
    

}
I have tried making the value a nullable value but been unsucessful. Any ideas would help
Jul 26, 2013 at 12:34 PM
Where is the code for ManagedImage? It needs to be a simple struct and has to be explicitly Cudafied.
Jul 26, 2013 at 2:21 PM
Edited Jul 26, 2013 at 2:37 PM
Thanks Nickkopp for the reply.

The thing is ManagedImage is an already built DLL from the manufacturer of a camera I bought.!
link of picture to show what i am saying
Jul 28, 2013 at 6:16 AM
You need to Cudafy the struct you wish to use on the device.
Jul 28, 2013 at 5:33 PM
Edited Jul 28, 2013 at 5:37 PM
[Cudafy]
// [StructLayout(LayoutKind.Explicit)]
public struct Simplestruct
{
    public ManagedCameraBase m_camera;
    public ManagedImage m_rawImage;
    public ManagedImage m_processedImage;
    public bool m_grabImages;
    public ManagedAVIRecorder aviRecorder;
    public int k_numImages;
    public ManagedImage imagelist1;
    public ManagedImage imagelist2;
}
Do you mean like this?
I get the error "declaration of 'struct Simplestruct' will not be visible outside of this function"
Jul 29, 2013 at 1:05 AM
Edited Jul 29, 2013 at 1:30 AM
Any data structure that you're planning on using on the kernel must be one of:
1 - a blittable type
2 - a struct made of (1)'s
3 - an array of (1) of (2)

Your Simplestruct doesn't fit the bill. It contains classes inside, and classes aren't (1) or (2) or (3).

Edit:
From the cudafy manual:
"Placing the Cudafy attribute on classes does not work, only structs are supported. Operator overloading is also not currently supported. Be aware that all types on the GPU whether in a struct or copied between CPU and device or in a launch command, must be blittable. This means that they have to be in a standard number format – e.g. byte, int, float, double."