CUDA.FourierTransform.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. //
  2. // The graphics platform GLScene https://github.com/glscene
  3. //
  4. unit CUDA.FourierTransform;
  5. (* CUDA Fourier Transform *)
  6. /// *
  7. // * Copyright 1993-2009 NVIDIA Corporation. All rights reserved.
  8. // *
  9. // * NOTICE TO USER:
  10. // *
  11. // * This source code is subject to NVIDIA ownership rights under U.S. and
  12. // * international Copyright laws. Users and possessors of this source code
  13. // * are hereby granted a nonexclusive, royalty-free license to use this code
  14. // * in individual and commercial software.
  15. // *
  16. // * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
  17. // * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
  18. // * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
  19. // * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
  20. // * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
  21. // * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
  22. // * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  23. // * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  24. // * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  25. // * OR PERFORMANCE OF THIS SOURCE CODE.
  26. // *
  27. // * U.S. Government End Users. This source code is a "commercial item" as
  28. // * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
  29. // * "commercial computer software" and "commercial computer software
  30. // * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
  31. // * and is provided to the U.S. Government only as a commercial end item.
  32. // * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
  33. // * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
  34. // * source code with only those rights set forth herein.
  35. // *
  36. // * Any use of this source code in individual and commercial software must
  37. // * include, in the user documentation and internal comments to the code,
  38. // * the above Disclaimer and U.S. Government End Users Notice.
  39. // */
  40. interface
  41. uses
  42. {$IFDEF MSWINDOWS}
  43. Winapi.Windows,
  44. {$ELSE}
  45. Windows,
  46. {$ENDIF}
  47. CUDA.Import,
  48. CUDA.RunTime;
  49. const
  50. {$IFDEF WIN32}
  51. CUFFTDLLNAMES: array [0 .. 9] of string = (
  52. 'cufft32_42_9', 'cufft32_41_28',
  53. 'cufft32_40_10', 'cufft32_32_16', 'cufft32_31_4', 'cufft32_30_14',
  54. 'cufft32_30_9', 'cufft32_30_8', 'cufft32', 'cufft');
  55. {$ENDIF}
  56. {$IFDEF WIN64}
  57. CUFFTDLLNAMES: array [0 .. 7] of string = (
  58. 'cufft64_42_9', 'cufft64_41_28',
  59. 'cufft64_40_10', 'cufft64_32_16', 'cufft64_31_4', 'cufft64_30_14',
  60. 'cufft64_30_9', 'cufft64_30_8');
  61. {$ENDIF}
  62. /// CUFFT API function return values
  63. type
  64. /// CUFFT defines and supports the following data types
  65. /// cufftHandle is a handle type used to store and access CUFFT plans.
  66. TcufftHandle = type Cardinal;
  67. TcufftReal = Single;
  68. PcufftReal = ^TcufftReal;
  69. TcufftRealfloat = Single;
  70. PcufftDoubleReal = ^TcufftDoubleReal;
  71. TcufftDoubleReal = Double;
  72. PcufftDoubleComplex = ^TcufftDoubleComplex;
  73. TcufftDoubleComplex = record
  74. case Integer of
  75. 0 : (V: array[0..1] of Double);
  76. 1 : (X: Double;
  77. Y: Double);
  78. end;
  79. PcufftComplex = ^TcufftComplex;
  80. TcufftComplex = record
  81. case Integer of
  82. 0 : (V: array[0..1] of Single);
  83. 1 : (X,Y: Single);
  84. end;
  85. TcufftResult = type Byte;
  86. const
  87. INVALID_CUFFT_HANDLE = $FFFFFFFF;
  88. CUFFT_SUCCESS: TcufftResult = $00;
  89. CUFFT_INVALID_PLAN: TcufftResult = $01;
  90. CUFFT_ALLOC_FAILED: TcufftResult = $02;
  91. CUFFT_INVALID_TYPE: TcufftResult = $03;
  92. CUFFT_INVALID_VALUE: TcufftResult = $04;
  93. CUFFT_INTERNAL_ERROR: TcufftResult = $05;
  94. CUFFT_EXEC_FAILED: TcufftResult = $06;
  95. CUFFT_SETUP_FAILED: TcufftResult = $07;
  96. CUFFT_INVALID_SIZE: TcufftResult = $08;
  97. type
  98. TcufftType = type Cardinal;
  99. TcudaRoundMode = (cudaRoundNearest, cudaRoundZero, cudaRoundPosInf,
  100. cudaRoundMinInf);
  101. /// CUFFT transform directions
  102. const
  103. CUFFT_FORWARD = -1; // Forward FFT
  104. CUFFT_INVERSE = 1; // Inverse FFT
  105. /// CUFFT supports the following transform types
  106. CUFFT_R2C: TcufftType = $2A; // Real to Complex (interleaved)
  107. CUFFT_C2R: TcufftType = $2C; // Complex (interleaved) to Real
  108. CUFFT_C2C: TcufftType = $29; // Complex to Complex, interleaved
  109. CUFFT_D2Z: TcufftType = $6A; // Double to Double-Complex
  110. CUFFT_Z2D: TcufftType = $6C; // Double-Complex to Double
  111. CUFFT_Z2Z: TcufftType = $69; // Double-Complex to Double-Complex
  112. (*
  113. Certain R2C and C2R transforms go much more slowly when FFTW memory
  114. layout and behaviour is required. The default is "best performance",
  115. which means not-compatible-with-fftw. Use the cufftSetCompatibilityMode
  116. API to enable exact FFTW-like behaviour.
  117. These flags can be ORed together to select precise FFTW compatibility
  118. behaviour. The two levels presently supported are:
  119. CUFFT_COMPATIBILITY_FFTW_PADDING
  120. Inserts extra padding between packed in-place transforms for
  121. batched transforms with power-of-2 size.
  122. CUFFT_COMPATIBILITY_FFTW_C2R_ASYMMETRIC
  123. Guarantees FFTW-compatible output for non-symmetric complex inputs
  124. for transforms with power-of-2 size. This is only useful for
  125. artificial (i.e. random) datasets as actual data will always be
  126. symmetric if it has come from the real plane. If you don't
  127. understand what this means, you probably don't have to use it.
  128. CUFFT_COMPATIBILITY_FFTW
  129. For convenience, enables all FFTW compatibility modes at once.
  130. *)
  131. type
  132. TcufftCompatibility = type Cardinal;
  133. const
  134. CUFFT_COMPATIBILITY_NORMAL: TcufftCompatibility = $00; // The default value
  135. CUFFT_COMPATIBILITY_FFTW_PADDING: TcufftCompatibility = $01;
  136. CUFFT_COMPATIBILITY_FFTW_C2R_ASYMMETRIC: TcufftCompatibility = $02;
  137. CUFFT_COMPATIBILITY_FFTW: TcufftCompatibility = $03;
  138. type
  139. TcufftPlan1d = function(out plan: TcufftHandle; nx: Integer;
  140. atype: TcufftType; batch: Integer): TcufftResult;stdcall;
  141. TcufftPlan2d = function(out plan: TcufftHandle; nx: Integer; ny: Integer;
  142. atype: TcufftType): TcufftResult;stdcall;
  143. TcufftPlan3d = function(out plan: TcufftHandle; nx: Integer; ny: Integer;
  144. nz: Integer; atype: TcufftType): TcufftResult;stdcall;
  145. TcufftDestroy = function(plan: TcufftHandle): TcufftResult;stdcall;
  146. TcufftPlanMany = function(out plan: TcufftHandle; rank: Integer;
  147. var n: Integer; var inembed: Integer; istride, idist: Integer;
  148. var onembed: Integer; ostride, odist: Integer; ctype: TcufftType;
  149. batch: Integer): TcufftResult;stdcall;
  150. TcufftExecC2C = function(plan: TcufftHandle; idata: PcufftComplex;
  151. odata: PcufftComplex; direction: Integer): TcufftResult;stdcall;
  152. TcufftExecR2C = function(plan: TcufftHandle; idata: PcufftReal;
  153. odata: PcufftComplex): TcufftResult;stdcall;
  154. TcufftExecC2R = function(plan: TcufftHandle; idata: PcufftComplex;
  155. odata: PcufftReal): TcufftResult;stdcall;
  156. TcufftExecZ2Z = function(plan: TcufftHandle; idata: PcufftDoubleComplex;
  157. odata: PcufftDoubleComplex; direction: Integer): TcufftResult;stdcall;
  158. TcufftExecD2Z = function(plan: TcufftHandle; idata: PcufftDoubleReal;
  159. odata: PcufftDoubleComplex): TcufftResult;stdcall;
  160. TcufftExecZ2D = function(plan: TcufftHandle; idata: PcufftDoubleComplex;
  161. odata: PcufftDoubleReal): TcufftResult;stdcall;
  162. TcufftSetStream = function(p: TcufftHandle; stream: Integer): TcufftResult;stdcall;
  163. TcufftSetCompatibilityMode = function(plan: TcufftHandle;
  164. mode: TcufftCompatibility): TcufftResult;stdcall;
  165. var
  166. cufftPlan1d: TcufftPlan1d;
  167. cufftPlan2d: TcufftPlan2d;
  168. cufftPlan3d: TcufftPlan3d;
  169. cufftDestroy: TcufftDestroy;
  170. cufftPlanMany: TcufftPlanMany;
  171. cufftExecC2C: TcufftExecC2C;
  172. cufftExecR2C: TcufftExecR2C;
  173. cufftExecC2R: TcufftExecC2R;
  174. cufftExecZ2Z: TcufftExecZ2Z;
  175. cufftExecD2Z: TcufftExecD2Z;
  176. cufftExecZ2D: TcufftExecZ2D;
  177. cufftSetStream: TcufftSetStream;
  178. cufftSetCompatibilityMode: TcufftSetCompatibilityMode;
  179. function InitCUFFT: Boolean;
  180. procedure CloseCUFFT;
  181. function InitCUFFTFromLibrary(const LibName: WideString): Boolean;
  182. function IsCUFFTInitialized: Boolean;
  183. function Get_CUDA_FFT_Error_String(AError: TcufftResult): string;
  184. //---------------------------------------------------------
  185. implementation
  186. //---------------------------------------------------------
  187. const
  188. cufftPlan1dName = 'cufftPlan1d';
  189. cufftPlan2dName = 'cufftPlan2d';
  190. cufftPlan3dName = 'cufftPlan3d';
  191. cufftDestroyName = 'cufftDestroy';
  192. cufftPlanManyName = 'cufftPlanMany';
  193. cufftExecC2CName = 'cufftExecC2C';
  194. cufftExecR2CName = 'cufftExecR2C';
  195. cufftExecC2RName = 'cufftExecC2R';
  196. cufftExecZ2ZName = 'cufftExecZ2Z';
  197. cufftExecD2ZName = 'cufftExecD2Z';
  198. cufftExecZ2DName = 'cufftExecZ2D';
  199. cufftSetStreamName = 'cufftSetStream';
  200. cufftSetCompatibilityModeName = 'cufftSetCompatibilityMode';
  201. const
  202. INVALID_MODULEHANDLE = 0;
  203. var
  204. {$IFDEF MSWINDOWS}
  205. CUFFTHandle: HINST = INVALID_MODULEHANDLE;
  206. {$ENDIF}{$IFDEF LINUX}
  207. CUFFTHandle: TLibHandle = INVALID_MODULEHANDLE;
  208. {$ENDIF}
  209. {$IFDEF USE_CUDA_DEBUG_MODE}
  210. var
  211. cufftPlan1d_: TcufftPlan1d;
  212. cufftPlan2d_: TcufftPlan2d;
  213. cufftPlan3d_: TcufftPlan3d;
  214. cufftDestroy_: TcufftDestroy;
  215. cufftPlanMany_: TcufftPlanMany;
  216. cufftExecC2C_: TcufftExecC2C;
  217. cufftExecR2C_: TcufftExecR2C;
  218. cufftExecC2R_: TcufftExecC2R;
  219. cufftExecZ2Z_: TcufftExecZ2Z;
  220. cufftExecD2Z_: TcufftExecD2Z;
  221. cufftExecZ2D_: TcufftExecZ2D;
  222. cufftSetStream_: TcufftSetStream;
  223. cufftSetCompatibilityMode_: TcufftSetCompatibilityMode;
  224. function cufftPlan1dShell(out plan: TcufftHandle; nx: Integer;
  225. atype: TcufftType; batch: Integer): TcufftResult;stdcall;
  226. begin
  227. Result := cufftPlan1d_(plan, nx, atype, batch);
  228. if Result <> CUFFT_SUCCESS then
  229. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan1dName,
  230. Get_CUDA_FFT_Error_String(Result)]);
  231. end;
  232. function cufftPlan2dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  233. atype: TcufftType): TcufftResult;stdcall;
  234. begin
  235. Result := cufftPlan2d_(plan, nx, ny, atype);
  236. if Result <> CUFFT_SUCCESS then
  237. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan2dName,
  238. Get_CUDA_FFT_Error_String(Result)]);
  239. end;
  240. function cufftPlan3dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  241. nz: Integer; atype: TcufftType): TcufftResult;stdcall;
  242. begin
  243. Result := cufftPlan3d_(plan, nx, ny, nz, atype);
  244. if Result <> CUFFT_SUCCESS then
  245. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan3dName,
  246. Get_CUDA_FFT_Error_String(Result)]);
  247. end;
  248. function cufftDestroyShell(plan: TcufftHandle): TcufftResult;stdcall;
  249. begin
  250. Result := cufftDestroy_(plan);
  251. if Result <> CUFFT_SUCCESS then
  252. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftDestroyName,
  253. Get_CUDA_FFT_Error_String(Result)]);
  254. end;
  255. function cufftPlanManyShell(out plan: TcufftHandle; rank: Integer;
  256. var n: Integer; var inembed: Integer; istride, idist: Integer;
  257. var onembed: Integer; ostride, odist: Integer; ctype: TcufftType;
  258. batch: Integer): TcufftResult;stdcall;
  259. begin
  260. Result := cufftPlanMany_(plan, rank, n, inembed, istride, idist, onembed,
  261. ostride, odist, ctype, batch);
  262. if Result <> CUFFT_SUCCESS then
  263. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlanManyName,
  264. Get_CUDA_FFT_Error_String(Result)]);
  265. end;
  266. function cufftExecC2CShell(plan: TcufftHandle; idata: PcufftComplex;
  267. odata: PcufftComplex; direction: Integer): TcufftResult;stdcall;
  268. begin
  269. Result := cufftExecC2C_(plan, idata, odata, direction);
  270. if Result <> CUFFT_SUCCESS then
  271. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2CName,
  272. Get_CUDA_FFT_Error_String(Result)]);
  273. end;
  274. function cufftExecR2CShell(plan: TcufftHandle; idata: PcufftReal;
  275. odata: PcufftComplex): TcufftResult;stdcall;
  276. begin
  277. Result := cufftExecR2C_(plan, idata, odata);
  278. if Result <> CUFFT_SUCCESS then
  279. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecR2CName,
  280. Get_CUDA_FFT_Error_String(Result)]);
  281. end;
  282. function cufftExecC2RShell(plan: TcufftHandle; idata: PcufftComplex;
  283. odata: PcufftReal): TcufftResult;stdcall;
  284. begin
  285. Result := cufftExecC2R_(plan, idata, odata);
  286. if Result <> CUFFT_SUCCESS then
  287. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2RName,
  288. Get_CUDA_FFT_Error_String(Result)]);
  289. end;
  290. function cufftExecZ2ZShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  291. odata: PcufftDoubleComplex; direction: Integer): TcufftResult;stdcall;
  292. begin
  293. Result := cufftExecZ2Z_(plan, idata, odata, direction);
  294. if Result <> CUFFT_SUCCESS then
  295. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2ZName,
  296. Get_CUDA_FFT_Error_String(Result)]);
  297. end;
  298. function cufftExecD2ZShell(plan: TcufftHandle; idata: PcufftDoubleReal;
  299. odata: PcufftDoubleComplex): TcufftResult;stdcall;
  300. begin
  301. Result := cufftExecD2Z_(plan, idata, odata);
  302. if Result <> CUFFT_SUCCESS then
  303. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecD2ZName,
  304. Get_CUDA_FFT_Error_String(Result)]);
  305. end;
  306. function cufftExecZ2DShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  307. odata: PcufftDoubleReal): TcufftResult;stdcall;
  308. begin
  309. Result := cufftExecZ2D_(plan, idata, odata);
  310. if Result <> CUFFT_SUCCESS then
  311. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2DName,
  312. Get_CUDA_FFT_Error_String(Result)]);
  313. end;
  314. function cufftSetStreamShell(p: TcufftHandle; stream: Integer): TcufftResult;stdcall;
  315. begin
  316. Result := cufftSetStream_(p, stream);
  317. if Result <> CUFFT_SUCCESS then
  318. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetStreamName,
  319. Get_CUDA_FFT_Error_String(Result)]);
  320. end;
  321. function cufftSetCompatibilityModeShell(plan: TcufftHandle;
  322. mode: TcufftCompatibility): TcufftResult;stdcall;
  323. begin
  324. Result := cufftSetCompatibilityMode_(plan, mode);
  325. if Result <> CUFFT_SUCCESS then
  326. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetCompatibilityModeName,
  327. Get_CUDA_FFT_Error_String(Result)]);
  328. end;
  329. {$ENDIF GLS_CUDA_DEBUG_MODE}
  330. function CUFFTGetProcAddress(ProcName: PAnsiChar): Pointer;
  331. begin
  332. result := GetProcAddress(CUFFTHandle, ProcName);
  333. end;
  334. function InitCUFFT: Boolean;
  335. var
  336. I: Integer;
  337. begin
  338. Result := True;
  339. if CUFFTHandle = INVALID_MODULEHANDLE then
  340. begin
  341. for I := 0 to High(CUFFTDLLNAMES) do
  342. begin
  343. if InitCUFFTFromLibrary(CUFFTDLLNAMES[I] + '.dll') then
  344. Exit;
  345. end;
  346. Result := False;
  347. end;
  348. end;
  349. procedure CloseCUFFT;
  350. begin
  351. if CUFFTHandle <> INVALID_MODULEHANDLE then
  352. begin
  353. FreeLibrary(Cardinal(CUFFTHandle));
  354. CUFFTHandle := INVALID_MODULEHANDLE;
  355. end;
  356. end;
  357. function InitCUFFTFromLibrary(const LibName: WideString): Boolean;
  358. begin
  359. CloseCUFFT;
  360. CUFFTHandle := GetModuleHandleW(PWideChar(LibName));
  361. if CUFFTHandle = INVALID_MODULEHANDLE then
  362. CUFFTHandle := LoadLibraryW(PWideChar(LibName));
  363. if CUFFTHandle = INVALID_MODULEHANDLE then
  364. Exit(False);
  365. {$IFNDEF USE_CUDA_DEBUG_MODE}
  366. cufftPlan1d := CUFFTGetProcAddress(cufftPlan1dName);
  367. cufftPlan2d := CUFFTGetProcAddress(cufftPlan2dName);
  368. cufftPlan3d := CUFFTGetProcAddress(cufftPlan3dName);
  369. cufftDestroy := CUFFTGetProcAddress(cufftDestroyName);
  370. cufftPlanMany := CUFFTGetProcAddress(cufftPlanManyName);
  371. cufftExecC2C := CUFFTGetProcAddress(cufftExecC2CName);
  372. cufftExecR2C := CUFFTGetProcAddress(cufftExecR2CName);
  373. cufftExecC2R := CUFFTGetProcAddress(cufftExecC2RName);
  374. cufftExecZ2Z := CUFFTGetProcAddress(cufftExecZ2ZName);
  375. cufftExecD2Z := CUFFTGetProcAddress(cufftExecD2ZName);
  376. cufftExecZ2D := CUFFTGetProcAddress(cufftExecZ2DName);
  377. cufftSetStream := CUFFTGetProcAddress(cufftSetStreamName);
  378. cufftSetCompatibilityMode := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  379. {$ELSE}
  380. cufftPlan1d_ := CUFFTGetProcAddress(cufftPlan1dName);
  381. cufftPlan1d := cufftPlan1dShell;
  382. cufftPlan2d_ := CUFFTGetProcAddress(cufftPlan2dName);
  383. cufftPlan2d := cufftPlan2dShell;
  384. cufftPlan3d_ := CUFFTGetProcAddress(cufftPlan3dName);
  385. cufftPlan3d := cufftPlan3dShell;
  386. cufftDestroy_ := CUFFTGetProcAddress(cufftDestroyName);
  387. cufftDestroy := cufftDestroyShell;
  388. cufftPlanMany_ := CUFFTGetProcAddress(cufftPlanManyName);
  389. cufftPlanMany := cufftPlanManyShell;
  390. cufftExecC2C_ := CUFFTGetProcAddress(cufftExecC2CName);
  391. cufftExecC2C := cufftExecC2CShell;
  392. cufftExecR2C_ := CUFFTGetProcAddress(cufftExecR2CName);
  393. cufftExecR2C := cufftExecR2CShell;
  394. cufftExecC2R_ := CUFFTGetProcAddress(cufftExecC2RName);
  395. cufftExecC2R := cufftExecC2RShell;
  396. cufftExecZ2Z_ := CUFFTGetProcAddress(cufftExecZ2ZName);
  397. cufftExecZ2Z := cufftExecZ2ZShell;
  398. cufftExecD2Z_ := CUFFTGetProcAddress(cufftExecD2ZName);
  399. cufftExecD2Z := cufftExecD2ZShell;
  400. cufftExecZ2D_ := CUFFTGetProcAddress(cufftExecZ2DName);
  401. cufftExecZ2D := cufftExecZ2DShell;
  402. cufftSetStream_ := CUFFTGetProcAddress(cufftSetStreamName);
  403. cufftSetStream := cufftSetStreamShell;
  404. cufftSetCompatibilityMode_ := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  405. cufftSetCompatibilityMode := cufftSetCompatibilityModeShell;
  406. {$ENDIF}
  407. {$IFDEF USE_LOGGING}
  408. LogInfoFmt('%s loaded...', [LibName]);
  409. {$ENDIF}
  410. Result := True;
  411. end;
  412. function IsCUFFTInitialized: Boolean;
  413. begin
  414. result := (CUFFTHandle <> INVALID_MODULEHANDLE);
  415. end;
  416. function Get_CUDA_FFT_Error_String(AError: TcufftResult): string;
  417. begin
  418. if AError = CUFFT_SUCCESS then
  419. result := 'CUFFT operation is successful.'
  420. else if AError = CUFFT_INVALID_PLAN then
  421. result := 'CUFFT is passed an invalid plan handle.'
  422. else if AError = CUFFT_ALLOC_FAILED then
  423. result := 'CUFFT failed to allocate GPU memory.'
  424. else if AError = CUFFT_INVALID_TYPE then
  425. result := 'The user requests an unsupported type.'
  426. else if AError = CUFFT_INVALID_VALUE then
  427. result := 'The user specifies a bad memory pointer.'
  428. else if AError = CUFFT_INTERNAL_ERROR then
  429. result := 'Used for all internal driver errors.'
  430. else if AError = CUFFT_EXEC_FAILED then
  431. result := 'CUFFT failed to execute an FFT on the GPU.'
  432. else if AError = CUFFT_SETUP_FAILED then
  433. result := 'The CUFFT library failed to initialize.'
  434. else if AError = CUFFT_INVALID_SIZE then
  435. result := 'The user specifies an unsupported FFT size.'
  436. else
  437. result := 'Unknown error.'
  438. end;
  439. end.