GLS.CUDAFourierTransform.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLS.CUDAFourierTransform;
  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. {$I GLScene.inc}
  42. uses
  43. Winapi.Windows,
  44. GLVectorTypes,
  45. GLS.Strings,
  46. GLS.CUDAApi,
  47. GLS.CUDARunTime
  48. {$IFDEF USE_LOGGING},GLSLog;{$ELSE};{$ENDIF}
  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 = TVector2d;
  74. PcufftComplex = ^TcufftComplex;
  75. TcufftComplex = TVector2f;
  76. TcufftResult = type Byte;
  77. const
  78. INVALID_CUFFT_HANDLE = $FFFFFFFF;
  79. CUFFT_SUCCESS: TcufftResult = $00;
  80. CUFFT_INVALID_PLAN: TcufftResult = $01;
  81. CUFFT_ALLOC_FAILED: TcufftResult = $02;
  82. CUFFT_INVALID_TYPE: TcufftResult = $03;
  83. CUFFT_INVALID_VALUE: TcufftResult = $04;
  84. CUFFT_INTERNAL_ERROR: TcufftResult = $05;
  85. CUFFT_EXEC_FAILED: TcufftResult = $06;
  86. CUFFT_SETUP_FAILED: TcufftResult = $07;
  87. CUFFT_INVALID_SIZE: TcufftResult = $08;
  88. type
  89. TcufftType = type Cardinal;
  90. TcudaRoundMode = (cudaRoundNearest, cudaRoundZero, cudaRoundPosInf,
  91. cudaRoundMinInf);
  92. /// CUFFT transform directions
  93. const
  94. CUFFT_FORWARD = -1; // Forward FFT
  95. CUFFT_INVERSE = 1; // Inverse FFT
  96. /// CUFFT supports the following transform types
  97. CUFFT_R2C: TcufftType = $2A; // Real to Complex (interleaved)
  98. CUFFT_C2R: TcufftType = $2C; // Complex (interleaved) to Real
  99. CUFFT_C2C: TcufftType = $29; // Complex to Complex, interleaved
  100. CUFFT_D2Z: TcufftType = $6A; // Double to Double-Complex
  101. CUFFT_Z2D: TcufftType = $6C; // Double-Complex to Double
  102. CUFFT_Z2Z: TcufftType = $69; // Double-Complex to Double-Complex
  103. (*
  104. Certain R2C and C2R transforms go much more slowly when FFTW memory
  105. layout and behaviour is required. The default is "best performance",
  106. which means not-compatible-with-fftw. Use the cufftSetCompatibilityMode
  107. API to enable exact FFTW-like behaviour.
  108. These flags can be ORed together to select precise FFTW compatibility
  109. behaviour. The two levels presently supported are:
  110. CUFFT_COMPATIBILITY_FFTW_PADDING
  111. Inserts extra padding between packed in-place transforms for
  112. batched transforms with power-of-2 size.
  113. CUFFT_COMPATIBILITY_FFTW_C2R_ASYMMETRIC
  114. Guarantees FFTW-compatible output for non-symmetric complex inputs
  115. for transforms with power-of-2 size. This is only useful for
  116. artificial (i.e. random) datasets as actual data will always be
  117. symmetric if it has come from the real plane. If you don't
  118. understand what this means, you probably don't have to use it.
  119. CUFFT_COMPATIBILITY_FFTW
  120. For convenience, enables all FFTW compatibility modes at once.
  121. *)
  122. type
  123. TcufftCompatibility = type Cardinal;
  124. const
  125. CUFFT_COMPATIBILITY_NORMAL: TcufftCompatibility = $00; // The default value
  126. CUFFT_COMPATIBILITY_FFTW_PADDING: TcufftCompatibility = $01;
  127. CUFFT_COMPATIBILITY_FFTW_C2R_ASYMMETRIC: TcufftCompatibility = $02;
  128. CUFFT_COMPATIBILITY_FFTW: TcufftCompatibility = $03;
  129. type
  130. TcufftPlan1d = function(out plan: TcufftHandle; nx: Integer;
  131. atype: TcufftType; batch: Integer): TcufftResult;
  132. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  133. TcufftPlan2d = function(out plan: TcufftHandle; nx: Integer; ny: Integer;
  134. atype: TcufftType): TcufftResult;
  135. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  136. TcufftPlan3d = function(out plan: TcufftHandle; nx: Integer; ny: Integer;
  137. nz: Integer; atype: TcufftType): TcufftResult;
  138. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  139. TcufftDestroy = function(plan: TcufftHandle): TcufftResult;
  140. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  141. TcufftPlanMany = function(out plan: TcufftHandle; rank: Integer;
  142. var n: Integer; var inembed: Integer; istride, idist: Integer;
  143. var onembed: Integer; ostride, odist: Integer; ctype: TcufftType;
  144. batch: Integer): TcufftResult;
  145. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  146. TcufftExecC2C = function(plan: TcufftHandle; idata: PcufftComplex;
  147. odata: PcufftComplex; direction: Integer): TcufftResult;
  148. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  149. TcufftExecR2C = function(plan: TcufftHandle; idata: PcufftReal;
  150. odata: PcufftComplex): TcufftResult;
  151. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  152. TcufftExecC2R = function(plan: TcufftHandle; idata: PcufftComplex;
  153. odata: PcufftReal): TcufftResult;
  154. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  155. TcufftExecZ2Z = function(plan: TcufftHandle; idata: PcufftDoubleComplex;
  156. odata: PcufftDoubleComplex; direction: Integer): TcufftResult;
  157. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  158. TcufftExecD2Z = function(plan: TcufftHandle; idata: PcufftDoubleReal;
  159. odata: PcufftDoubleComplex): TcufftResult;
  160. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  161. TcufftExecZ2D = function(plan: TcufftHandle; idata: PcufftDoubleComplex;
  162. odata: PcufftDoubleReal): TcufftResult;
  163. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  164. TcufftSetStream = function(p: TcufftHandle; stream: Integer): TcufftResult;
  165. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  166. TcufftSetCompatibilityMode = function(plan: TcufftHandle;
  167. mode: TcufftCompatibility): TcufftResult;
  168. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  169. var
  170. cufftPlan1d: TcufftPlan1d;
  171. cufftPlan2d: TcufftPlan2d;
  172. cufftPlan3d: TcufftPlan3d;
  173. cufftDestroy: TcufftDestroy;
  174. cufftPlanMany: TcufftPlanMany;
  175. cufftExecC2C: TcufftExecC2C;
  176. cufftExecR2C: TcufftExecR2C;
  177. cufftExecC2R: TcufftExecC2R;
  178. cufftExecZ2Z: TcufftExecZ2Z;
  179. cufftExecD2Z: TcufftExecD2Z;
  180. cufftExecZ2D: TcufftExecZ2D;
  181. cufftSetStream: TcufftSetStream;
  182. cufftSetCompatibilityMode: TcufftSetCompatibilityMode;
  183. function InitCUFFT: Boolean;
  184. procedure CloseCUFFT;
  185. function InitCUFFTFromLibrary(const LibName: WideString): Boolean;
  186. function IsCUFFTInitialized: Boolean;
  187. function Get_CUDA_FFT_Error_String(AError: TcufftResult): string;
  188. //---------------------------------------------------------
  189. implementation
  190. //---------------------------------------------------------
  191. const
  192. cufftPlan1dName = 'cufftPlan1d';
  193. cufftPlan2dName = 'cufftPlan2d';
  194. cufftPlan3dName = 'cufftPlan3d';
  195. cufftDestroyName = 'cufftDestroy';
  196. cufftPlanManyName = 'cufftPlanMany';
  197. cufftExecC2CName = 'cufftExecC2C';
  198. cufftExecR2CName = 'cufftExecR2C';
  199. cufftExecC2RName = 'cufftExecC2R';
  200. cufftExecZ2ZName = 'cufftExecZ2Z';
  201. cufftExecD2ZName = 'cufftExecD2Z';
  202. cufftExecZ2DName = 'cufftExecZ2D';
  203. cufftSetStreamName = 'cufftSetStream';
  204. cufftSetCompatibilityModeName = 'cufftSetCompatibilityMode';
  205. const
  206. INVALID_MODULEHANDLE = 0;
  207. var
  208. {$IFDEF MSWINDOWS}
  209. CUFFTHandle: HINST = INVALID_MODULEHANDLE;
  210. {$ENDIF}{$IFDEF LINUX}
  211. CUFFTHandle: TLibHandle = INVALID_MODULEHANDLE;
  212. {$ENDIF}
  213. {$IFDEF USE_CUDA_DEBUG_MODE}
  214. var
  215. cufftPlan1d_: TcufftPlan1d;
  216. cufftPlan2d_: TcufftPlan2d;
  217. cufftPlan3d_: TcufftPlan3d;
  218. cufftDestroy_: TcufftDestroy;
  219. cufftPlanMany_: TcufftPlanMany;
  220. cufftExecC2C_: TcufftExecC2C;
  221. cufftExecR2C_: TcufftExecR2C;
  222. cufftExecC2R_: TcufftExecC2R;
  223. cufftExecZ2Z_: TcufftExecZ2Z;
  224. cufftExecD2Z_: TcufftExecD2Z;
  225. cufftExecZ2D_: TcufftExecZ2D;
  226. cufftSetStream_: TcufftSetStream;
  227. cufftSetCompatibilityMode_: TcufftSetCompatibilityMode;
  228. function cufftPlan1dShell(out plan: TcufftHandle; nx: Integer;
  229. atype: TcufftType; batch: Integer): TcufftResult;
  230. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  231. begin
  232. Result := cufftPlan1d_(plan, nx, atype, batch);
  233. if Result <> CUFFT_SUCCESS then
  234. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan1dName,
  235. Get_CUDA_FFT_Error_String(Result)]);
  236. end;
  237. function cufftPlan2dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  238. atype: TcufftType): TcufftResult;
  239. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  240. begin
  241. Result := cufftPlan2d_(plan, nx, ny, atype);
  242. if Result <> CUFFT_SUCCESS then
  243. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan2dName,
  244. Get_CUDA_FFT_Error_String(Result)]);
  245. end;
  246. function cufftPlan3dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  247. nz: Integer; atype: TcufftType): TcufftResult;
  248. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  249. begin
  250. Result := cufftPlan3d_(plan, nx, ny, nz, atype);
  251. if Result <> CUFFT_SUCCESS then
  252. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan3dName,
  253. Get_CUDA_FFT_Error_String(Result)]);
  254. end;
  255. function cufftDestroyShell(plan: TcufftHandle): TcufftResult;
  256. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  257. begin
  258. Result := cufftDestroy_(plan);
  259. if Result <> CUFFT_SUCCESS then
  260. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftDestroyName,
  261. Get_CUDA_FFT_Error_String(Result)]);
  262. end;
  263. function cufftPlanManyShell(out plan: TcufftHandle; rank: Integer;
  264. var n: Integer; var inembed: Integer; istride, idist: Integer;
  265. var onembed: Integer; ostride, odist: Integer; ctype: TcufftType;
  266. batch: Integer): TcufftResult;
  267. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  268. begin
  269. Result := cufftPlanMany_(plan, rank, n, inembed, istride, idist, onembed,
  270. ostride, odist, ctype, batch);
  271. if Result <> CUFFT_SUCCESS then
  272. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlanManyName,
  273. Get_CUDA_FFT_Error_String(Result)]);
  274. end;
  275. function cufftExecC2CShell(plan: TcufftHandle; idata: PcufftComplex;
  276. odata: PcufftComplex; direction: Integer): TcufftResult;
  277. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  278. begin
  279. Result := cufftExecC2C_(plan, idata, odata, direction);
  280. if Result <> CUFFT_SUCCESS then
  281. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2CName,
  282. Get_CUDA_FFT_Error_String(Result)]);
  283. end;
  284. function cufftExecR2CShell(plan: TcufftHandle; idata: PcufftReal;
  285. odata: PcufftComplex): TcufftResult;
  286. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  287. begin
  288. Result := cufftExecR2C_(plan, idata, odata);
  289. if Result <> CUFFT_SUCCESS then
  290. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecR2CName,
  291. Get_CUDA_FFT_Error_String(Result)]);
  292. end;
  293. function cufftExecC2RShell(plan: TcufftHandle; idata: PcufftComplex;
  294. odata: PcufftReal): TcufftResult;
  295. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  296. begin
  297. Result := cufftExecC2R_(plan, idata, odata);
  298. if Result <> CUFFT_SUCCESS then
  299. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2RName,
  300. Get_CUDA_FFT_Error_String(Result)]);
  301. end;
  302. function cufftExecZ2ZShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  303. odata: PcufftDoubleComplex; direction: Integer): TcufftResult;
  304. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  305. begin
  306. Result := cufftExecZ2Z_(plan, idata, odata, direction);
  307. if Result <> CUFFT_SUCCESS then
  308. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2ZName,
  309. Get_CUDA_FFT_Error_String(Result)]);
  310. end;
  311. function cufftExecD2ZShell(plan: TcufftHandle; idata: PcufftDoubleReal;
  312. odata: PcufftDoubleComplex): TcufftResult;
  313. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  314. begin
  315. Result := cufftExecD2Z_(plan, idata, odata);
  316. if Result <> CUFFT_SUCCESS then
  317. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecD2ZName,
  318. Get_CUDA_FFT_Error_String(Result)]);
  319. end;
  320. function cufftExecZ2DShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  321. odata: PcufftDoubleReal): TcufftResult;
  322. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  323. begin
  324. Result := cufftExecZ2D_(plan, idata, odata);
  325. if Result <> CUFFT_SUCCESS then
  326. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2DName,
  327. Get_CUDA_FFT_Error_String(Result)]);
  328. end;
  329. function cufftSetStreamShell(p: TcufftHandle; stream: Integer): TcufftResult;
  330. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  331. begin
  332. Result := cufftSetStream_(p, stream);
  333. if Result <> CUFFT_SUCCESS then
  334. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetStreamName,
  335. Get_CUDA_FFT_Error_String(Result)]);
  336. end;
  337. function cufftSetCompatibilityModeShell(plan: TcufftHandle;
  338. mode: TcufftCompatibility): TcufftResult;
  339. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  340. begin
  341. Result := cufftSetCompatibilityMode_(plan, mode);
  342. if Result <> CUFFT_SUCCESS then
  343. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetCompatibilityModeName,
  344. Get_CUDA_FFT_Error_String(Result)]);
  345. end;
  346. {$ENDIF GLS_CUDA_DEBUG_MODE}
  347. function CUFFTGetProcAddress(ProcName: PAnsiChar): Pointer;
  348. begin
  349. result := GetProcAddress(CUFFTHandle, ProcName);
  350. end;
  351. function InitCUFFT: Boolean;
  352. var
  353. I: Integer;
  354. begin
  355. Result := True;
  356. if CUFFTHandle = INVALID_MODULEHANDLE then
  357. begin
  358. for I := 0 to High(CUFFTDLLNAMES) do
  359. begin
  360. if InitCUFFTFromLibrary(CUFFTDLLNAMES[I] + '.dll') then
  361. Exit;
  362. end;
  363. Result := False;
  364. end;
  365. end;
  366. procedure CloseCUFFT;
  367. begin
  368. if CUFFTHandle <> INVALID_MODULEHANDLE then
  369. begin
  370. FreeLibrary(Cardinal(CUFFTHandle));
  371. CUFFTHandle := INVALID_MODULEHANDLE;
  372. end;
  373. end;
  374. function InitCUFFTFromLibrary(const LibName: WideString): Boolean;
  375. begin
  376. CloseCUFFT;
  377. CUFFTHandle := GetModuleHandleW(PWideChar(LibName));
  378. if CUFFTHandle = INVALID_MODULEHANDLE then
  379. CUFFTHandle := LoadLibraryW(PWideChar(LibName));
  380. if CUFFTHandle = INVALID_MODULEHANDLE then
  381. Exit(False);
  382. {$IFNDEF USE_CUDA_DEBUG_MODE}
  383. cufftPlan1d := CUFFTGetProcAddress(cufftPlan1dName);
  384. cufftPlan2d := CUFFTGetProcAddress(cufftPlan2dName);
  385. cufftPlan3d := CUFFTGetProcAddress(cufftPlan3dName);
  386. cufftDestroy := CUFFTGetProcAddress(cufftDestroyName);
  387. cufftPlanMany := CUFFTGetProcAddress(cufftPlanManyName);
  388. cufftExecC2C := CUFFTGetProcAddress(cufftExecC2CName);
  389. cufftExecR2C := CUFFTGetProcAddress(cufftExecR2CName);
  390. cufftExecC2R := CUFFTGetProcAddress(cufftExecC2RName);
  391. cufftExecZ2Z := CUFFTGetProcAddress(cufftExecZ2ZName);
  392. cufftExecD2Z := CUFFTGetProcAddress(cufftExecD2ZName);
  393. cufftExecZ2D := CUFFTGetProcAddress(cufftExecZ2DName);
  394. cufftSetStream := CUFFTGetProcAddress(cufftSetStreamName);
  395. cufftSetCompatibilityMode := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  396. {$ELSE}
  397. cufftPlan1d_ := CUFFTGetProcAddress(cufftPlan1dName);
  398. cufftPlan1d := cufftPlan1dShell;
  399. cufftPlan2d_ := CUFFTGetProcAddress(cufftPlan2dName);
  400. cufftPlan2d := cufftPlan2dShell;
  401. cufftPlan3d_ := CUFFTGetProcAddress(cufftPlan3dName);
  402. cufftPlan3d := cufftPlan3dShell;
  403. cufftDestroy_ := CUFFTGetProcAddress(cufftDestroyName);
  404. cufftDestroy := cufftDestroyShell;
  405. cufftPlanMany_ := CUFFTGetProcAddress(cufftPlanManyName);
  406. cufftPlanMany := cufftPlanManyShell;
  407. cufftExecC2C_ := CUFFTGetProcAddress(cufftExecC2CName);
  408. cufftExecC2C := cufftExecC2CShell;
  409. cufftExecR2C_ := CUFFTGetProcAddress(cufftExecR2CName);
  410. cufftExecR2C := cufftExecR2CShell;
  411. cufftExecC2R_ := CUFFTGetProcAddress(cufftExecC2RName);
  412. cufftExecC2R := cufftExecC2RShell;
  413. cufftExecZ2Z_ := CUFFTGetProcAddress(cufftExecZ2ZName);
  414. cufftExecZ2Z := cufftExecZ2ZShell;
  415. cufftExecD2Z_ := CUFFTGetProcAddress(cufftExecD2ZName);
  416. cufftExecD2Z := cufftExecD2ZShell;
  417. cufftExecZ2D_ := CUFFTGetProcAddress(cufftExecZ2DName);
  418. cufftExecZ2D := cufftExecZ2DShell;
  419. cufftSetStream_ := CUFFTGetProcAddress(cufftSetStreamName);
  420. cufftSetStream := cufftSetStreamShell;
  421. cufftSetCompatibilityMode_ := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  422. cufftSetCompatibilityMode := cufftSetCompatibilityModeShell;
  423. {$ENDIF}
  424. {$IFDEF USE_LOGGING}
  425. LogInfoFmt('%s loaded...', [LibName]);
  426. {$ENDIF}
  427. Result := True;
  428. end;
  429. function IsCUFFTInitialized: Boolean;
  430. begin
  431. result := (CUFFTHandle <> INVALID_MODULEHANDLE);
  432. end;
  433. function Get_CUDA_FFT_Error_String(AError: TcufftResult): string;
  434. begin
  435. if AError = CUFFT_SUCCESS then
  436. result := 'CUFFT operation is successful.'
  437. else if AError = CUFFT_INVALID_PLAN then
  438. result := 'CUFFT is passed an invalid plan handle.'
  439. else if AError = CUFFT_ALLOC_FAILED then
  440. result := 'CUFFT failed to allocate GPU memory.'
  441. else if AError = CUFFT_INVALID_TYPE then
  442. result := 'The user requests an unsupported type.'
  443. else if AError = CUFFT_INVALID_VALUE then
  444. result := 'The user specifies a bad memory pointer.'
  445. else if AError = CUFFT_INTERNAL_ERROR then
  446. result := 'Used for all internal driver errors.'
  447. else if AError = CUFFT_EXEC_FAILED then
  448. result := 'CUFFT failed to execute an FFT on the GPU.'
  449. else if AError = CUFFT_SETUP_FAILED then
  450. result := 'The CUFFT library failed to initialize.'
  451. else if AError = CUFFT_INVALID_SIZE then
  452. result := 'The user specifies an unsupported FFT size.'
  453. else
  454. result := 'Unknown error.'
  455. end;
  456. end.