ISCE_INSAR/contrib/PyCuAmpcor/src/cuArraysPadding.cu

159 lines
4.9 KiB
Plaintext

/*
* cuArraysPadding.cu
* Padding Utitilies for oversampling
*/
#include "cuAmpcorUtil.h"
#include "float2.h"
//padding zeros in the middle, move quads to corners
//for raw chunk data oversampling
__global__ void cuArraysPadding_kernel(
const float2 *image1, const int height1, const int width1,
float2 *image2, const int height2, const int width2)
{
int tx = threadIdx.x + blockDim.x*blockIdx.x;
int ty = threadIdx.y + blockDim.y*blockIdx.y;
if(tx < height1/2 && ty < width1/2)
{
int tx1 = height1 - 1 - tx;
int ty1 = width1 -1 -ty;
int tx2 = height2 -1 -tx;
int ty2 = width2 -1 -ty;
//printf("%d %d %d\n", tx, height1, height2);
image2[IDX2R(tx, ty, width2)] = image1[IDX2R(tx, ty, width1)];
image2[IDX2R(tx2, ty, width2)] = image1[IDX2R(tx1, ty, width1)];
image2[IDX2R(tx, ty2, width2)] = image1[IDX2R(tx, ty1, width1)];
image2[IDX2R(tx2, ty2, width2)] = image1[IDX2R(tx1, ty1, width1)];
}
}
//tested
void cuArraysPadding(cuArrays<float2> *image1, cuArrays<float2> *image2, cudaStream_t stream)
{
int ThreadsPerBlock = NTHREADS2D;
int BlockPerGridx = IDIVUP (image1->height/2, ThreadsPerBlock);
int BlockPerGridy = IDIVUP (image1->width/2, ThreadsPerBlock);
dim3 dimBlock(ThreadsPerBlock, ThreadsPerBlock);
dim3 dimGrid(BlockPerGridx, BlockPerGridy);
checkCudaErrors(cudaMemsetAsync(image2->devData, 0, image2->getByteSize(),stream));
cuArraysPadding_kernel<<<dimGrid, dimBlock, 0, stream>>>(
image1->devData, image1->height, image1->width,
image2->devData, image2->height, image2->width);
getLastCudaError("cuArraysPadding_kernel");
}
inline __device__ float2 cmplxMul(float2 c, float a)
{
return make_float2(c.x*a, c.y*a);
}
//padding for zoomIned correlation oversampling/interpolation
__global__ void cuArraysPaddingMany_kernel(
const float2 *image1, const int height1, const int width1, const int size1,
float2 *image2, const int height2, const int width2, const int size2, const float factor )
{
int tx = threadIdx.x + blockDim.x*blockIdx.x;
int ty = threadIdx.y + blockDim.y*blockIdx.y;
if(tx < height1/2 && ty < width1/2)
{
int tx1 = height1 - 1 - tx;
int ty1 = width1 -1 -ty;
int tx2 = height2 -1 -tx;
int ty2 = width2 -1 -ty;
int stride1 = blockIdx.z*size1;
int stride2 = blockIdx.z*size2;
//printf("%d %d %d\n", tx, height1, height2);
image2[IDX2R(tx, ty, width2)+stride2] = image1[IDX2R(tx, ty, width1)+stride1]*factor;
image2[IDX2R(tx2, ty, width2)+stride2] = cmplxMul(image1[IDX2R(tx1, ty, width1)+stride1], factor);
image2[IDX2R(tx, ty2, width2)+stride2] = cmplxMul(image1[IDX2R(tx, ty1, width1)+stride1], factor);
image2[IDX2R(tx2, ty2, width2)+stride2] = cmplxMul(image1[IDX2R(tx1, ty1, width1)+stride1], factor);
}
}
void cuArraysPaddingMany(cuArrays<float2> *image1, cuArrays<float2> *image2, cudaStream_t stream)
{
int ThreadsPerBlock = NTHREADS2D;
int BlockPerGridx = IDIVUP (image1->height/2, ThreadsPerBlock);
int BlockPerGridy = IDIVUP (image1->width/2, ThreadsPerBlock);
dim3 dimBlock(ThreadsPerBlock, ThreadsPerBlock, 1);
dim3 dimGrid(BlockPerGridx, BlockPerGridy, image1->count);
checkCudaErrors(cudaMemsetAsync(image2->devData, 0, image2->getByteSize(),stream));
float factor = 1.0f/image1->size;
cuArraysPaddingMany_kernel<<<dimGrid, dimBlock, 0, stream>>>(
image1->devData, image1->height, image1->width, image1->size,
image2->devData, image2->height, image2->width, image2->size, factor);
getLastCudaError("cuArraysPadding_kernel");
}
// convert float to float2(complex)
__global__ void cuArraysR2C_kernel(float *image1, float2 *image2, int size)
{
int idx = threadIdx.x + blockDim.x*blockIdx.x;
if(idx < size)
{
image2[idx].x = image1[idx];
image2[idx].y = 0.0f;
}
}
//tested
void cuArraysR2C(cuArrays<float> *image1, cuArrays<float2> *image2, cudaStream_t stream)
{
int size = image1->getSize();
cuArraysR2C_kernel<<<IDIVUP(size, NTHREADS), NTHREADS, 0, stream>>>(image1->devData, image2->devData, size);
getLastCudaError("cuArraysR2C");
}
// take real part of float2 to float
__global__ void cuArraysC2R_kernel(float2 *image1, float *image2, int size)
{
int idx = threadIdx.x + blockDim.x*blockIdx.x;
if(idx < size)
{
image2[idx] = image1[idx].x;
}
}
//tested
void cuArraysC2R(cuArrays<float2> *image1, cuArrays<float> *image2, cudaStream_t stream)
{
int size = image1->getSize();
cuArraysC2R_kernel<<<IDIVUP(size, NTHREADS), NTHREADS, 0, stream>>>(image1->devData, image2->devData, size);
getLastCudaError("cuArraysC2R");
}
// take real part of float2 to float
__global__ void cuArraysAbs_kernel(float2 *image1, float *image2, int size)
{
int idx = threadIdx.x + blockDim.x*blockIdx.x;
if(idx < size)
{
image2[idx] = complexAbs(image1[idx]);
}
}
//tested
void cuArraysAbs(cuArrays<float2> *image1, cuArrays<float> *image2, cudaStream_t stream)
{
int size = image1->getSize();
cuArraysAbs_kernel<<<IDIVUP(size, NTHREADS), NTHREADS, 0, stream>>>(image1->devData, image2->devData, size);
getLastCudaError("cuArraysAbs_kernel");
}