cuEGLStreamConsumerReleaseFrame : illegal access : CUresult 700

So, i’m trying to make a camera class a bit like cv::VideoCapture that uses libArgus to map a cuda buffer to a GpuMat. The important bits of my code are

A capture method, that returns a unique_ptr to a Frame, which wraps a mapped buffer.

std::unique_ptr<Frame> NvCvCam::capture() {
  CUgraphicsResource tmp_res = nullptr;

... checks that the producer thread is ok here ...

  DEBUG << "nvcvcam:Getting an image from the EGLStream.";
  auto err = cuEGLStreamConsumerAcquireFrame(&_cuda_conn, &tmp_res, &_cuda_stream, -1)
  if (err) {
    ERROR << "nvcvcam:Could not get image from the EglStream becuase: "
          << error_string(err) << ".";
    return nullptr;
  }

  DEBUG << "nvcvcam:Returning Frame.";
  return std::make_unique<Frame>(tmp_res, _cuda_conn, _cuda_stream);
}

The frame ctor:

Frame::Frame(CUgraphicsResource resource,
             CUeglStreamConnection conn,
             cudaStream_t stream)
    : _resource(resource), _conn(conn), _stream(stream), _raw_frame{}, _mat() {
  CUresult cu_err;

  DEBUG << "frame:Mapping from resource.";
  cu_err = cuGraphicsResourceGetMappedEglFrame(&_raw_frame, resource, 0, 0);
  if (cu_err) {
    ERROR << "frame:Could not map CUgraphicsResource to CUeglFrame becuase: "
          << error_string(cu_err) << ".";
    return;
  }

... debug and stream syncronize here ...

  // map the data to a GpuMat
  _mat = cv::cuda::GpuMat(_raw_frame.height, _raw_frame.width, CV_16SC1,
                          _raw_frame.frame.pPitch[0], _raw_frame.pitch);
}

The frame dtor:

Frame::~Frame() {
  CUresult cu_err;

  DEBUG << "frame:releasing resource in stream " << (size_t)_stream;
  cu_err = cuEGLStreamConsumerReleaseFrame(&_conn, _resource, &_stream);
  if (cu_err) {
    ERROR << "frame:Could not release resource because: "
          << error_string(cu_err) << "(" << cu_err << ").";
    std::terminate();
  }
}

So, the capture works, ctor works, GpuMat is !empty(), but when I release the frame, i get:

[2021-02-23 11:45:34.124095][debug]: frame:releasing resource in stream 368095401344
[2021-02-23 11:45:34.124573][error]: frame:Could not release resource because: an illegal memory access was encountered(700).
terminate called without an active exception
Aborted (core dumped)

Few other notes: the EGL stream is set to EGL_STREAM_MODE_MAILBOX. Requests are made continuously in the producer’s main loop with icapturesession->capture(request.get()).

Any clues as to what I am doing wrong? My C++ is not as good as my Python, so it’s entirely possible i’m missing something basic. I’d appreciate any help at all. Full source code for this WIP is here for anybody curious. Feedback welcome.

I do need the raw bayer and lowest latency possible, otherwise I would just use narguscamerasrc. A full gstreamer pipeline through cv::VideoCapture with the conversion that implies is way too slow for my client’s purposes.

So, i’m just gonna post my notes here in case it helps anybody else. CUresult error 700 says:

While executing a kernel, the device encountered a load or store instruction on an invalid memory address. This leaves the process in an inconsistent state and any further CUDA work will return the same error. To continue using CUDA, the process must be terminated and relaunched.

I’m aquiring a CUgraphicsResource from an EGL stream, mapping it to a CUeglFrame, all of that seems to work, but when I try to touch the mapped data or release the underlying resource, boom, i get result 700.

Going to see if this has something to do with using a dedicated cuda stream for aquiring and releasing. The Argus examples do not use this, and it’s entirely possible i’m trying to be too smart here or i need to sync the stream someplace i’m not.

edit: same issue with default stream, so it doesn’t look like it’s the stream

Hi,
Could you check if the data type is supported:
CUDA Runtime API :: CUDA Toolkit Documentation

And do you hit the issue if you remove the code:

  // map the data to a GpuMat
  _mat = cv::cuda::GpuMat(_raw_frame.height, _raw_frame.width, CV_16SC1,
                          _raw_frame.frame.pPitch[0], _raw_frame.pitch);

Would like to know if it works without mapping to GpuMat.

@DaneLLL

Thanks for the suggestion. It seems commenting out that section indeed fixes it, so it’s definately related. According to the docs, it should support i16 (CV_16SC1). There is no OpenCV bayer format for i16 but my plan was to use GpuMat::convertTo() to convert to a supported data type.

Some more testing and it seems I can actually access the data without an issue. I can convert it to CV_16UC1, download() it to cpu, and imwrite the packed bayer data to file. It’s just the release that was failing.

I removed some cudaStreamSyncronize and now it works. I’m not sure why. In any case, thanks for pointing me to the right solution. I’ll post the project in Jetson Projects when it’s done and @ you.