Openholo  v2.1
Open Source Digital Holographic Library
ophKernel.cuh
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
7 //
8 //
9 // License Agreement
10 // For Open Source Digital Holographic Library
11 //
12 // Openholo library is free software;
13 // you can redistribute it and/or modify it under the terms of the BSD 2-Clause license.
14 //
15 // Copyright (C) 2017-2024, Korea Electronics Technology Institute. All rights reserved.
16 // E-mail : contact.openholo@gmail.com
17 // Web : http://www.openholo.org
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // 1. Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holder or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // This software contains opensource software released under GNU Generic Public License,
41 // NVDIA Software License Agreement, or CUDA supplement to Software License Agreement.
42 // Check whether software you use contains licensed software.
43 //
44 //M*/
45 
46 #ifndef __ophKernel_cuh__
47 #define __ophKernel_cuh__
48 
49 #include <cuComplex.h>
50 #include <cufft.h>
51 #include <cuda.h>
52 #include <device_launch_parameters.h>
53 #include <device_functions.h>
54 #include <cuda_runtime.h>
55 
56 static const int kBlockThreads = 512;
57 
58 
59 __global__ void fftShift(int N, int nx, int ny, cufftDoubleComplex* input, cufftDoubleComplex* output, bool bNormalized)
60 {
61  int tid = threadIdx.x + blockIdx.x*blockDim.x;
62 
63  double normalF = 1.0;
64  if (bNormalized == true)
65  normalF = nx * ny;
66 
67  while (tid < N)
68  {
69  int i = tid % nx;
70  int j = tid / nx;
71 
72  int ti = i - nx / 2; if (ti < 0) ti += nx;
73  int tj = j - ny / 2; if (tj < 0) tj += ny;
74 
75  int oindex = tj * nx + ti;
76 
77 
78  output[tid].x = input[oindex].x / normalF;
79  output[tid].y = input[oindex].y / normalF;
80 
81  tid += blockDim.x * gridDim.x;
82  }
83 }
84 
85 __global__ void fftShiftf(int N, int nx, int ny, cuFloatComplex* input, cuFloatComplex* output, bool bNormalized)
86 {
87  int tid = threadIdx.x + blockIdx.x*blockDim.x;
88 
89  float normalF = 1.0;
90  if (bNormalized == true)
91  normalF = nx * ny;
92 
93  while (tid < N)
94  {
95  int i = tid % nx;
96  int j = tid / nx;
97 
98  int ti = i - nx / 2; if (ti < 0) ti += nx;
99  int tj = j - ny / 2; if (tj < 0) tj += ny;
100 
101  int oindex = tj * nx + ti;
102 
103 
104  output[tid].x = input[oindex].x / normalF;
105  output[tid].y = input[oindex].y / normalF;
106 
107  tid += blockDim.x * gridDim.x;
108  }
109 }
110 
111 __device__ void exponent_complex(cuDoubleComplex* val)
112 {
113  double exp_val = exp(val->x);
114  double re = val->x;
115  double im = val->y;
116 
117  val->x = exp_val * cos(im);
118  val->y = exp_val * sin(im);
119 }
120 
121 extern "C"
122 
123 void cudaFFT(CUstream_st* stream, int nx, int ny, cufftDoubleComplex* in_field, cufftDoubleComplex* output_field, int direction, bool bNormalized)
124 {
125  unsigned int nblocks = (nx*ny + kBlockThreads - 1) / kBlockThreads;
126  int N = nx * ny;
127  fftShift << <nblocks, kBlockThreads, 0, stream >> > (N, nx, ny, in_field, output_field, false);
128 
129  cufftHandle plan;
130  cufftResult result;
131  // fft
132  result = cufftPlan2d(&plan, ny, nx, CUFFT_Z2Z);
133  if (result != CUFFT_SUCCESS)
134  {
135  LOG("cufftPlan2d : Failed (%d)\n", result);
136  return;
137  };
138 
139  if (direction == -1)
140  result = cufftExecZ2Z(plan, output_field, in_field, CUFFT_FORWARD);
141  else
142  result = cufftExecZ2Z(plan, output_field, in_field, CUFFT_INVERSE);
143 
144  if (result != CUFFT_SUCCESS)
145  {
146  LOG("cufftExecZ2Z : Failed (%d)\n", result);
147  return;
148  }
149 
150  if (cudaDeviceSynchronize() != cudaSuccess) {
151  LOG("cudaDeviceSynchronize() : Failed\n");
152  return;
153  }
154 
155  fftShift << < nblocks, kBlockThreads, 0, stream >> > (N, nx, ny, in_field, output_field, bNormalized);
156 
157  cufftDestroy(plan);
158 }
159 
160 #endif // !__ophKernel_cuh__