invalid device pointer

May 22, 2012 at 6:42 AM

hi,

im using EMGU CV's SURF library. i have to implement it on two GPUs in such a manner that when two images have to compared with a template , matching of one is done on one GPU and that of the other on the other GPU... for this i am creating two threads on cpu.. one thread selects gpu0 by using "_gpu0.lock()" and starts computation on it while the second thread selects gpu1 by using "_gpu1.lock()" .. however after computation is completed and the results are displayed.. i get an error that is " opencv exception :invalid device pointer " .. can anyone help??? 

thanks in advance

Coordinator
May 22, 2012 at 11:18 AM

Would be much easier to help if you can post some source code.  You indeed need to be careful with multi-gpu / multithread and if you are interoping with a 3rd party library then you are especially running the risk of issues. I'd recommend downloading source code for both projects - then you can step through and will know exactly what is going wrong.

May 22, 2012 at 3:57 PM

  void DisplayThread1()
        {

            lock (this)
            {
                _gpu0.Lock();
                watch = Stopwatch.StartNew();
                SURFDetector surfCPU = new SURFDetector(500, false);
                GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.04f);
                using (GpuImage<Gray, Byte> gpuObservedImage = new GpuImage<Gray, byte>(observedImage))
                using (GpuMat<float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null))
                {
                    pgpuObservedKeyPoints = gpuObservedKeyPoints.ToMatrix();
                    using (GpuMat<float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))
                    {
                        pgpuObservedDescriptors = gpuObservedDescriptors.ToMatrix();

                    }
                }
                watch.Stop();
                _gpu0.Unlock();
            }
        }




        void DisplayThread2()
        {

            lock (this)
            {
                _gpu1.Lock();
                watch_2 = Stopwatch.StartNew();
                SURFDetector surfCPU_2 = new SURFDetector(500, false);
                GpuSURFDetector surfGPU_2 = new GpuSURFDetector(surfCPU_2.SURFParams, 0.04f);
                using (GpuImage<Gray, Byte> gpuObservedImage_2 = new GpuImage<Gray, byte>(observedImage_2))
                using (GpuMat<float> gpuObservedKeyPoints_2 = surfGPU_2.DetectKeyPointsRaw(gpuObservedImage_2, null))
                {
                    pgpuObservedKeyPoints_2 = gpuObservedKeyPoints_2.ToMatrix();
                    using (GpuMat<float> gpuObservedDescriptors_2 = surfGPU_2.ComputeDescriptorsRaw(gpuObservedImage_2, null, gpuObservedKeyPoints_2))
                    {
                        pgpuObservedDescriptors_2 = gpuObservedDescriptors_2.ToMatrix();

                    }
                }
                watch_2.Stop();
                _gpu1.Unlock();
            }
        }
 
       
        

        private void button1_Click(object sender, EventArgs e)
        {
            watch_3 = Stopwatch.StartNew();
            _gpu0 = CudafyHost.CreateDevice(CudafyModes.Target, 0);
            _gpu1 = CudafyHost.CreateDevice(CudafyModes.Target, 1);
            _gpu0.EnableMultithreading();
            _gpu1.EnableMultithreading();
            Thread thread1 = new Thread(new ThreadStart(DisplayThread1));
            Thread thread2 = new Thread(new ThreadStart(DisplayThread2));
            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
            watch_3.Stop();
            label3.Text = string.Format("total time taken is :{0}  ", watch_3.ElapsedMilliseconds.ToString());
             this.Invoke(new MethodInvoker(delegate
               {
                  label2.Text=string.Format("thread 2 computation completed in {0} ms", watch_2.ElapsedMilliseconds.ToString());
                  label1.Text = string.Format("thread 1 computation completed in {0} ms", watch.ElapsedMilliseconds.ToString());

                   }
                      )
                       );

here is a code snippet . basically the threads launched are required to find features from two images on two gpus... this code is working perfectly however the exception is returned as soon as the elapsed milliseconds are displayed... the problem is with the "Gpumat<float>" ... any suggestions?

Coordinator
May 22, 2012 at 5:55 PM

Where do you allocate your device memory?  I can't see where you have the CUDAfy <-> SURF interop.

Sounds like it could be related to the garbage collection trying to free device memory from the wrong context.

May 22, 2012 at 9:22 PM

well in case of EMGU CV the memory is allocated itself in the SURFDETECTOR ... i dnt have to manually allocate it... i am using cudafy only to selected the gpu device .. can u please elaborate the last statement ? any proposed solution?

Coordinator
May 23, 2012 at 7:38 AM

Without knowledge of the inner workings of Surf I really can't say whether what you are doing is going to work or not.  I would be surprised if Surf does not have a means of specifying which GPU to run on.  Chances are what you are doing results in CUDAfy changing the context and then when Surf goes to clean up memory via garbage collection the context is no longer correct when freeing the device memory.

Jan 12, 2015 at 2:22 PM
I would like to use some of the OpenCV routines (2D convolve, Region Labeling, and Centroiding) in a CudaFy.net project.
  1. Is this a stupid idea?
  2. Would it be better just to implement the algorithms in C# from opensource examples?
  3. Some of inputs to the OpenCV have will already be in global GPU memory (from earlier kernels written in CudaFy.net) can you pass pointers to OpenCV GPU routines and say the matrix is already in the GPU?
  4. Are there any simple examples of doing this
I the avionics guy ran into some issues. Is there an example around of someone doing this successfully?