Skip to content

gpuResampSlc.cu: fix out of bounds reading bug in transformTile#214

Open
scottstanie wants to merge 1 commit intoisce-framework:developfrom
scottstanie:fix-gpu-LUT2d-bounds
Open

gpuResampSlc.cu: fix out of bounds reading bug in transformTile#214
scottstanie wants to merge 1 commit intoisce-framework:developfrom
scottstanie:fix-gpu-LUT2d-bounds

Conversation

@scottstanie
Copy link
Member

@scottstanie scottstanie commented Feb 9, 2026

(note: have not been able to recompile this on the GPU machine to fully test. just makes logical sense now)

I was getting the following error sporadically when running CUDA versions of geo2rdr + gpuResampleSlc

  Reading in image data for tile 38 of 39
  Interpolating  tile 38 of 39
  terminate called after throwing an instance of 'isce3::cuda::except::CudaError<cudaError>'
    what():  Error in file .../cxx/isce3/cuda/core/gpuLUT1d.cu, line 77, function isce3::cuda::core::gpuLUT1d< <template-parameter-1-1>
  >::~gpuLUT1d() [with T = double]: cudaError 700 (an illegal memory access was encountered)
  zsh: IOT instruction (core dumped)

I thought it was a "my image is too big problem", since shrinking the linesPerBlock worked (sometimes). Other times, shrinking it didnt work, but just changing it did.

The CPU version in cxx/isce3/image/ResampSlc.cpp:322-327 has the correct bounds check:

      if ((iRowResampled < chipHalf) ||
              (iRowResampled >= (inLength - chipHalf)))
          continue;
      if ((iColResampled < chipHalf) || (
                  iColResampled >= (inWidth - chipHalf)))
          continue;
``
However, the GPU version has only `>`.
The chip reading loop iterates iChipRow from 0 to chipSize - 1 (0 to 8), accessing row:
```c++
    iTileRow = iRowResamp + iChipRow - chipHalf

The maximum iTileRow is iRowResamp + 8 - 4 = iRowResamp + 4. With the current bounds check (iRowResamp + 4 > inReadableLength, it will skip), the kernel proceeds when iRowResamp = inReadableLength - 4. That gives:

    max iTileRow = (inReadableLength - 4) + 4 = inReadableLength  // out of bounds

The valid row indices are 0 to inReadableLength - 1, so this reads one row past the end of the tile buffer.

I was getting the following error sporadicall when running CUDA-versions
of geo2rdr and gpuResampleSlc

  Reading in image data for tile 38 of 39
  Interpolating  tile 38 of 39
  terminate called after throwing an instance of 'isce3::cuda::except::CudaError<cudaError>'
    what():  Error in file .../cxx/isce3/cuda/core/gpuLUT1d.cu, line 77, function isce3::cuda::core::gpuLUT1d< <template-parameter-1-1>
  >::~gpuLUT1d() [with T = double]: cudaError 700 (an illegal memory access was encountered)
  zsh: IOT instruction (core dumped)

The CPU version in cxx/isce3/image/ResampSlc.cpp:322-327 has the correct bounds check:

      if ((iRowResampled < chipHalf) ||
              (iRowResampled >= (inLength - chipHalf)))
          continue;
      if ((iColResampled < chipHalf) || (
                  iColResampled >= (inWidth - chipHalf)))
          continue;

However, the GPU version has only `>`.
The chip reading loop iterates iChipRow from 0 to chipSize - 1 (0 to 8), accessing row:
    iTileRow = iRowResamp + iChipRow - chipHalf

The maximum iTileRow is iRowResamp + 8 - 4 = iRowResamp + 4.
With the current bounds check (iRowResamp + 4 > inReadableLength → skip), the kernel proceeds when iRowResamp = inReadableLength - 4. That gives:

    max iTileRow = (inReadableLength - 4) + 4 = inReadableLength  ← OUT OF BOUNDS

The valid row indices are 0 to inReadableLength - 1, so this reads one row past the end of the tile buffer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments