Skip to content

Commit 74899e6

Browse files
Liang YuLiang Yugmgunter
authored andcommitted
CUDA interpolated geocode (#760)
* initial commit of CUDA geocode; interp mode only * test code for pybind bindings * moved to masked minmax to own files * added explicit instantiations for thrust::complex * added masked minmax to index calcuation and interpolation * made line_start class member and tweaked mask value assignment * making line_per_block adjustable * added bindings for geocoding, n_blocks+lines_per_block getters, and documentation * index and mask device vectors resized according to block size * fix max_compare and add comments * add missing cudaMalloc/Free for **interp and some reshuffling * added 1st line/pixel offsets, extra margin, and row/col index swap to interp * added projection as a class member to replace insufficient inverse call in index kernal * added class for common params and block processing testing * templated geocode and adopted templated pybind and condensed test run * Properly populated pybind docstrings * made read only data in kernel const * added wavelength getter for consistency * fixed cuda memcpy dst pointers, bicubic explicit instantiation, and clang-format * one Rdr2Geo/Geo2RdrParams to rule them all * added handle for CUDA interpolator and projection base and incorporated into CUDA geocode * add user defined invalid pixel value; default 0.0 * expose geo2rdr parameters in constructor * InterpolatorHandle constructor constructs full object * introduced dem interp method * added unit test for masked minmax * added cuda::geocode to isce3 package and updated unit test accordingly * Reset data interpolation method back to bilinear Co-authored-by: Liang Yu <[email protected]> Co-authored-by: Geoffrey M Gunter <[email protected]>
1 parent 34a1851 commit 74899e6

39 files changed

+1659
-328
lines changed

cxx/isce3/container/RadarGeometry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class RadarGeometry {
5454
/** Get radar look side */
5555
LookSide lookSide() const { return radarGrid().lookSide(); }
5656

57+
/** Get radar wavelength */
58+
double wavelength() const { return radarGrid().wavelength(); }
59+
5760
private:
5861
RadarGridParameters _radar_grid;
5962
Orbit _orbit;

cxx/isce3/cuda/Sources.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@ core/gpuPoly2d.cu
99
core/gpuProjections.cu
1010
core/gpuSinc2dInterpolator.cu
1111
core/gpuSpline2dInterpolator.cu
12+
core/InterpolatorHandle.cu
1213
core/Orbit.cu
14+
core/ProjectionBaseHandle.cu
1315
core/Stream.cu
1416
except/Error.cpp
1517
focus/Backproject.cu
1618
fft/detail/CufftWrapper.cu
19+
geocode/Geocode.cu
20+
geocode/MaskedMinMax.cu
1721
geometry/Geo2rdr.cpp
1822
geometry/gpuDEMInterpolator.cu
1923
geometry/gpuGeo2rdr.cu

cxx/isce3/cuda/container/RadarGeometry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ class RadarGeometry {
7373
/** Get radar look side */
7474
LookSide lookSide() const { return radarGrid().lookSide(); }
7575

76+
/** Get radar wavelength */
77+
double wavelength() const { return radarGrid().wavelength(); }
78+
7679
private:
7780
RadarGridParameters _radar_grid;
7881
DeviceOrbit _orbit;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include "InterpolatorHandle.h"
2+
3+
#include <isce3/cuda/except/Error.h>
4+
#include <isce3/except/Error.h>
5+
6+
#include <pyre/journal.h>
7+
8+
#include <cuda_runtime.h>
9+
#include <thrust/complex.h>
10+
#include <thrust/device_vector.h>
11+
12+
template<class T>
13+
using DeviceInterp = isce3::cuda::core::gpuInterpolator<T>;
14+
15+
namespace isce3::cuda::core {
16+
17+
template<class T>
18+
__global__ void init_interp(
19+
DeviceInterp<T>** interp, isce3::core::dataInterpMethod interp_method,
20+
bool * unsupported_interp)
21+
{
22+
if (threadIdx.x == 0 && blockIdx.x == 0) {
23+
// Choose interpolator
24+
switch(interp_method) {
25+
case isce3::core::BILINEAR_METHOD:
26+
(*interp) = new isce3::cuda::core::gpuBilinearInterpolator<T>();
27+
break;
28+
case isce3::core::BICUBIC_METHOD:
29+
(*interp) = new isce3::cuda::core::gpuBicubicInterpolator<T>();
30+
break;
31+
case isce3::core::BIQUINTIC_METHOD:
32+
{
33+
size_t order = 6;
34+
(*interp) = new isce3::cuda::core::gpuSpline2dInterpolator<T>(order);
35+
break;
36+
}
37+
default:
38+
*unsupported_interp = true;
39+
break;
40+
}
41+
}
42+
}
43+
44+
template<class T>
45+
__global__ void finalize_interp(DeviceInterp<T>** interp)
46+
{
47+
if (threadIdx.x == 0 && blockIdx.x == 0) {
48+
delete *interp;
49+
}
50+
}
51+
52+
template<class T>
53+
InterpolatorHandle<T>::InterpolatorHandle(
54+
isce3::core::dataInterpMethod interp_method)
55+
{
56+
checkCudaErrors(cudaMalloc(&_interp, sizeof(DeviceInterp<T>**)));
57+
58+
thrust::device_vector<bool> d_unsupported_interp(1, false);
59+
init_interp<<<1, 1>>>(_interp, interp_method, d_unsupported_interp.data().get());
60+
checkCudaErrors(cudaPeekAtLastError());
61+
checkCudaErrors(cudaDeviceSynchronize());
62+
63+
bool unsupported_interp = d_unsupported_interp[0];
64+
if (unsupported_interp)
65+
{
66+
pyre::journal::error_t error(
67+
"isce.cuda.core.InterpolatorHandle.InterpolatorHandle");
68+
error << "Unsupported interpolator method provided."
69+
<< pyre::journal::endl;
70+
throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
71+
"Unsupported interpolator method provided.");
72+
}
73+
}
74+
75+
template<class T>
76+
InterpolatorHandle<T>::~InterpolatorHandle()
77+
{
78+
finalize_interp<<<1, 1>>>(_interp);
79+
checkCudaErrors(cudaPeekAtLastError());
80+
checkCudaErrors(cudaDeviceSynchronize());
81+
checkCudaErrors(cudaFree(_interp));
82+
}
83+
84+
template class InterpolatorHandle<float>;
85+
template class InterpolatorHandle<thrust::complex<float>>;
86+
template class InterpolatorHandle<double>;
87+
template class InterpolatorHandle<thrust::complex<double>>;
88+
} // namespace isce3::cuda::core
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#include <isce3/core/Constants.h>
4+
#include <isce3/cuda/core/gpuInterpolator.h>
5+
6+
namespace isce3::cuda::core {
7+
8+
/** Class that handles device gpuInterpolator double pointers on device.
9+
*
10+
* This handle class ensures that pointers are properly allocated
11+
* and deallocated.
12+
*
13+
*/
14+
template<class T>
15+
class InterpolatorHandle {
16+
private:
17+
// double pointer to gpuInterpolator on device
18+
// 1st pointer is the gpuInterpolator location on device
19+
// 2nd pointer is the gpuInterpolator object on device
20+
isce3::cuda::core::gpuInterpolator<T>** _interp = nullptr;
21+
22+
public:
23+
/** Class constructor. Mallocs 1st pointer and creates gpuInterpolator
24+
* object on device.
25+
*/
26+
InterpolatorHandle(isce3::core::dataInterpMethod interp_method);
27+
28+
/** Destructor that frees and deletes pointers accordingly. */
29+
~InterpolatorHandle();
30+
31+
/** Disabling copy constructor and assignment operator to prever misuse */
32+
InterpolatorHandle(const InterpolatorHandle&) = delete;
33+
InterpolatorHandle& operator=(const InterpolatorHandle&) = delete;
34+
35+
isce3::cuda::core::gpuInterpolator<T>** getInterp() const
36+
{
37+
return _interp;
38+
};
39+
};
40+
} // namespace isce3::cuda::core
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include "ProjectionBaseHandle.h"
2+
3+
#include <isce3/cuda/except/Error.h>
4+
#include <isce3/except/Error.h>
5+
6+
#include <pyre/journal.h>
7+
8+
#include <cuda_runtime.h>
9+
#include <thrust/device_vector.h>
10+
11+
namespace isce3::cuda::core {
12+
13+
using isce3::cuda::core::ProjectionBase;
14+
15+
__global__ void init_proj(ProjectionBase** proj, int epsg_code,
16+
bool * proj_invalid)
17+
{
18+
19+
if (threadIdx.x == 0 && blockIdx.x == 0) {
20+
(*proj) = isce3::cuda::core::createProj(epsg_code);
21+
if (!*proj)
22+
*proj_invalid = true;
23+
}
24+
}
25+
26+
__global__ void finalize_proj(ProjectionBase** proj)
27+
{
28+
29+
if (threadIdx.x == 0 && blockIdx.x == 0) {
30+
delete *proj;
31+
}
32+
}
33+
34+
ProjectionBaseHandle::ProjectionBaseHandle(int epsg)
35+
{
36+
checkCudaErrors(cudaMalloc(&_proj, sizeof(ProjectionBase**)));
37+
38+
thrust::device_vector<bool> d_proj_invalid(1, false);
39+
init_proj<<<1, 1>>>(_proj, epsg, d_proj_invalid.data().get());
40+
checkCudaErrors(cudaPeekAtLastError());
41+
checkCudaErrors(cudaDeviceSynchronize());
42+
43+
bool proj_invalid = d_proj_invalid[0];
44+
if (proj_invalid)
45+
{
46+
pyre::journal::error_t error(
47+
"isce.cuda.core.ProjectionBaseHandle.ProjectionBaseHandle");
48+
error << "Unsupported EPSG provided."
49+
<< pyre::journal::endl;
50+
throw isce3::except::InvalidArgument(ISCE_SRCINFO(),
51+
"Unsupported ESPG provided.");
52+
}
53+
}
54+
55+
ProjectionBaseHandle::~ProjectionBaseHandle()
56+
{
57+
finalize_proj<<<1, 1>>>(_proj);
58+
checkCudaErrors(cudaPeekAtLastError());
59+
checkCudaErrors(cudaDeviceSynchronize());
60+
checkCudaErrors(cudaFree(_proj));
61+
}
62+
63+
} // namespace isce3::cuda::core
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <isce3/cuda/core/gpuProjections.h>
4+
5+
namespace isce3::cuda::core {
6+
7+
/** Class that handles device ProjectionBase double pointers on device.
8+
*
9+
* This handle class ensures that pointers are properly allocated
10+
* and deallocated.
11+
*
12+
*/
13+
class ProjectionBaseHandle {
14+
private:
15+
// double pointer to Projection Base on device
16+
// 1st pointer is the ProjectionBase location on device
17+
// 2nd pointer is the ProjectionBase object on device
18+
isce3::cuda::core::ProjectionBase** _proj = nullptr;
19+
20+
public:
21+
/** Class constructor. Mallocs 1st pointer and creates ProjectionBase
22+
* object on device.
23+
*
24+
* \param[in] epsg EPSG of ProjectionBase to be created
25+
*
26+
* */
27+
ProjectionBaseHandle(int epsg);
28+
29+
/** Destructor that frees and deletes pointers accordingly. */
30+
~ProjectionBaseHandle();
31+
32+
/** Disabling copy constructor and assignment operator to prever misuse */
33+
ProjectionBaseHandle(const ProjectionBaseHandle&) = delete;
34+
ProjectionBaseHandle& operator=(const ProjectionBaseHandle&) = delete;
35+
36+
isce3::cuda::core::ProjectionBase** get_proj() const { return _proj; }
37+
};
38+
} // namespace isce3::cuda::core

0 commit comments

Comments
 (0)