CUDA.FourierTransform.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. //
  2. // The graphics engine 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. implementation //---------------------------------------------------------
  185. const
  186. cufftPlan1dName = 'cufftPlan1d';
  187. cufftPlan2dName = 'cufftPlan2d';
  188. cufftPlan3dName = 'cufftPlan3d';
  189. cufftDestroyName = 'cufftDestroy';
  190. cufftPlanManyName = 'cufftPlanMany';
  191. cufftExecC2CName = 'cufftExecC2C';
  192. cufftExecR2CName = 'cufftExecR2C';
  193. cufftExecC2RName = 'cufftExecC2R';
  194. cufftExecZ2ZName = 'cufftExecZ2Z';
  195. cufftExecD2ZName = 'cufftExecD2Z';
  196. cufftExecZ2DName = 'cufftExecZ2D';
  197. cufftSetStreamName = 'cufftSetStream';
  198. cufftSetCompatibilityModeName = 'cufftSetCompatibilityMode';
  199. const
  200. INVALID_MODULEHANDLE = 0;
  201. var
  202. {$IFDEF MSWINDOWS}
  203. CUFFTHandle: HINST = INVALID_MODULEHANDLE;
  204. {$ENDIF}{$IFDEF LINUX}
  205. CUFFTHandle: TLibHandle = INVALID_MODULEHANDLE;
  206. {$ENDIF}
  207. {$IFDEF USE_CUDA_DEBUG_MODE}
  208. var
  209. cufftPlan1d_: TcufftPlan1d;
  210. cufftPlan2d_: TcufftPlan2d;
  211. cufftPlan3d_: TcufftPlan3d;
  212. cufftDestroy_: TcufftDestroy;
  213. cufftPlanMany_: TcufftPlanMany;
  214. cufftExecC2C_: TcufftExecC2C;
  215. cufftExecR2C_: TcufftExecR2C;
  216. cufftExecC2R_: TcufftExecC2R;
  217. cufftExecZ2Z_: TcufftExecZ2Z;
  218. cufftExecD2Z_: TcufftExecD2Z;
  219. cufftExecZ2D_: TcufftExecZ2D;
  220. cufftSetStream_: TcufftSetStream;
  221. cufftSetCompatibilityMode_: TcufftSetCompatibilityMode;
  222. function cufftPlan1dShell(out plan: TcufftHandle; nx: Integer;
  223. atype: TcufftType; batch: Integer): TcufftResult;stdcall;
  224. begin
  225. Result := cufftPlan1d_(plan, nx, atype, batch);
  226. if Result <> CUFFT_SUCCESS then
  227. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan1dName,
  228. Get_CUDA_FFT_Error_String(Result)]);
  229. end;
  230. function cufftPlan2dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  231. atype: TcufftType): TcufftResult;stdcall;
  232. begin
  233. Result := cufftPlan2d_(plan, nx, ny, atype);
  234. if Result <> CUFFT_SUCCESS then
  235. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan2dName,
  236. Get_CUDA_FFT_Error_String(Result)]);
  237. end;
  238. function cufftPlan3dShell(out plan: TcufftHandle; nx: Integer; ny: Integer;
  239. nz: Integer; atype: TcufftType): TcufftResult;stdcall;
  240. begin
  241. Result := cufftPlan3d_(plan, nx, ny, nz, atype);
  242. if Result <> CUFFT_SUCCESS then
  243. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlan3dName,
  244. Get_CUDA_FFT_Error_String(Result)]);
  245. end;
  246. function cufftDestroyShell(plan: TcufftHandle): TcufftResult;stdcall;
  247. begin
  248. Result := cufftDestroy_(plan);
  249. if Result <> CUFFT_SUCCESS then
  250. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftDestroyName,
  251. Get_CUDA_FFT_Error_String(Result)]);
  252. end;
  253. function cufftPlanManyShell(out plan: TcufftHandle; rank: Integer;
  254. var n: Integer; var inembed: Integer; istride, idist: Integer;
  255. var onembed: Integer; ostride, odist: Integer; ctype: TcufftType;
  256. batch: Integer): TcufftResult;stdcall;
  257. begin
  258. Result := cufftPlanMany_(plan, rank, n, inembed, istride, idist, onembed,
  259. ostride, odist, ctype, batch);
  260. if Result <> CUFFT_SUCCESS then
  261. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftPlanManyName,
  262. Get_CUDA_FFT_Error_String(Result)]);
  263. end;
  264. function cufftExecC2CShell(plan: TcufftHandle; idata: PcufftComplex;
  265. odata: PcufftComplex; direction: Integer): TcufftResult;stdcall;
  266. begin
  267. Result := cufftExecC2C_(plan, idata, odata, direction);
  268. if Result <> CUFFT_SUCCESS then
  269. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2CName,
  270. Get_CUDA_FFT_Error_String(Result)]);
  271. end;
  272. function cufftExecR2CShell(plan: TcufftHandle; idata: PcufftReal;
  273. odata: PcufftComplex): TcufftResult;stdcall;
  274. begin
  275. Result := cufftExecR2C_(plan, idata, odata);
  276. if Result <> CUFFT_SUCCESS then
  277. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecR2CName,
  278. Get_CUDA_FFT_Error_String(Result)]);
  279. end;
  280. function cufftExecC2RShell(plan: TcufftHandle; idata: PcufftComplex;
  281. odata: PcufftReal): TcufftResult;stdcall;
  282. begin
  283. Result := cufftExecC2R_(plan, idata, odata);
  284. if Result <> CUFFT_SUCCESS then
  285. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecC2RName,
  286. Get_CUDA_FFT_Error_String(Result)]);
  287. end;
  288. function cufftExecZ2ZShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  289. odata: PcufftDoubleComplex; direction: Integer): TcufftResult;stdcall;
  290. begin
  291. Result := cufftExecZ2Z_(plan, idata, odata, direction);
  292. if Result <> CUFFT_SUCCESS then
  293. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2ZName,
  294. Get_CUDA_FFT_Error_String(Result)]);
  295. end;
  296. function cufftExecD2ZShell(plan: TcufftHandle; idata: PcufftDoubleReal;
  297. odata: PcufftDoubleComplex): TcufftResult;stdcall;
  298. begin
  299. Result := cufftExecD2Z_(plan, idata, odata);
  300. if Result <> CUFFT_SUCCESS then
  301. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecD2ZName,
  302. Get_CUDA_FFT_Error_String(Result)]);
  303. end;
  304. function cufftExecZ2DShell(plan: TcufftHandle; idata: PcufftDoubleComplex;
  305. odata: PcufftDoubleReal): TcufftResult;stdcall;
  306. begin
  307. Result := cufftExecZ2D_(plan, idata, odata);
  308. if Result <> CUFFT_SUCCESS then
  309. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftExecZ2DName,
  310. Get_CUDA_FFT_Error_String(Result)]);
  311. end;
  312. function cufftSetStreamShell(p: TcufftHandle; stream: Integer): TcufftResult;stdcall;
  313. begin
  314. Result := cufftSetStream_(p, stream);
  315. if Result <> CUFFT_SUCCESS then
  316. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetStreamName,
  317. Get_CUDA_FFT_Error_String(Result)]);
  318. end;
  319. function cufftSetCompatibilityModeShell(plan: TcufftHandle;
  320. mode: TcufftCompatibility): TcufftResult;stdcall;
  321. begin
  322. Result := cufftSetCompatibilityMode_(plan, mode);
  323. if Result <> CUFFT_SUCCESS then
  324. GLSLogger.LogErrorFmt(strFFTFuncRetErr, [cufftSetCompatibilityModeName,
  325. Get_CUDA_FFT_Error_String(Result)]);
  326. end;
  327. {$ENDIF GLS_CUDA_DEBUG_MODE}
  328. function CUFFTGetProcAddress(ProcName: PAnsiChar): Pointer;
  329. begin
  330. result := GetProcAddress(CUFFTHandle, ProcName);
  331. end;
  332. function InitCUFFT: Boolean;
  333. var
  334. I: Integer;
  335. begin
  336. Result := True;
  337. if CUFFTHandle = INVALID_MODULEHANDLE then
  338. begin
  339. for I := 0 to High(CUFFTDLLNAMES) do
  340. begin
  341. if InitCUFFTFromLibrary(CUFFTDLLNAMES[I] + '.dll') then
  342. Exit;
  343. end;
  344. Result := False;
  345. end;
  346. end;
  347. procedure CloseCUFFT;
  348. begin
  349. if CUFFTHandle <> INVALID_MODULEHANDLE then
  350. begin
  351. FreeLibrary(Cardinal(CUFFTHandle));
  352. CUFFTHandle := INVALID_MODULEHANDLE;
  353. end;
  354. end;
  355. function InitCUFFTFromLibrary(const LibName: WideString): Boolean;
  356. begin
  357. CloseCUFFT;
  358. CUFFTHandle := GetModuleHandleW(PWideChar(LibName));
  359. if CUFFTHandle = INVALID_MODULEHANDLE then
  360. CUFFTHandle := LoadLibraryW(PWideChar(LibName));
  361. if CUFFTHandle = INVALID_MODULEHANDLE then
  362. Exit(False);
  363. {$IFNDEF USE_CUDA_DEBUG_MODE}
  364. cufftPlan1d := CUFFTGetProcAddress(cufftPlan1dName);
  365. cufftPlan2d := CUFFTGetProcAddress(cufftPlan2dName);
  366. cufftPlan3d := CUFFTGetProcAddress(cufftPlan3dName);
  367. cufftDestroy := CUFFTGetProcAddress(cufftDestroyName);
  368. cufftPlanMany := CUFFTGetProcAddress(cufftPlanManyName);
  369. cufftExecC2C := CUFFTGetProcAddress(cufftExecC2CName);
  370. cufftExecR2C := CUFFTGetProcAddress(cufftExecR2CName);
  371. cufftExecC2R := CUFFTGetProcAddress(cufftExecC2RName);
  372. cufftExecZ2Z := CUFFTGetProcAddress(cufftExecZ2ZName);
  373. cufftExecD2Z := CUFFTGetProcAddress(cufftExecD2ZName);
  374. cufftExecZ2D := CUFFTGetProcAddress(cufftExecZ2DName);
  375. cufftSetStream := CUFFTGetProcAddress(cufftSetStreamName);
  376. cufftSetCompatibilityMode := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  377. {$ELSE}
  378. cufftPlan1d_ := CUFFTGetProcAddress(cufftPlan1dName);
  379. cufftPlan1d := cufftPlan1dShell;
  380. cufftPlan2d_ := CUFFTGetProcAddress(cufftPlan2dName);
  381. cufftPlan2d := cufftPlan2dShell;
  382. cufftPlan3d_ := CUFFTGetProcAddress(cufftPlan3dName);
  383. cufftPlan3d := cufftPlan3dShell;
  384. cufftDestroy_ := CUFFTGetProcAddress(cufftDestroyName);
  385. cufftDestroy := cufftDestroyShell;
  386. cufftPlanMany_ := CUFFTGetProcAddress(cufftPlanManyName);
  387. cufftPlanMany := cufftPlanManyShell;
  388. cufftExecC2C_ := CUFFTGetProcAddress(cufftExecC2CName);
  389. cufftExecC2C := cufftExecC2CShell;
  390. cufftExecR2C_ := CUFFTGetProcAddress(cufftExecR2CName);
  391. cufftExecR2C := cufftExecR2CShell;
  392. cufftExecC2R_ := CUFFTGetProcAddress(cufftExecC2RName);
  393. cufftExecC2R := cufftExecC2RShell;
  394. cufftExecZ2Z_ := CUFFTGetProcAddress(cufftExecZ2ZName);
  395. cufftExecZ2Z := cufftExecZ2ZShell;
  396. cufftExecD2Z_ := CUFFTGetProcAddress(cufftExecD2ZName);
  397. cufftExecD2Z := cufftExecD2ZShell;
  398. cufftExecZ2D_ := CUFFTGetProcAddress(cufftExecZ2DName);
  399. cufftExecZ2D := cufftExecZ2DShell;
  400. cufftSetStream_ := CUFFTGetProcAddress(cufftSetStreamName);
  401. cufftSetStream := cufftSetStreamShell;
  402. cufftSetCompatibilityMode_ := CUFFTGetProcAddress(cufftSetCompatibilityModeName);
  403. cufftSetCompatibilityMode := cufftSetCompatibilityModeShell;
  404. {$ENDIF}
  405. {$IFDEF USE_LOGGING}
  406. LogInfoFmt('%s loaded...', [LibName]);
  407. {$ENDIF}
  408. Result := True;
  409. end;
  410. function IsCUFFTInitialized: Boolean;
  411. begin
  412. result := (CUFFTHandle <> INVALID_MODULEHANDLE);
  413. end;
  414. function Get_CUDA_FFT_Error_String(AError: TcufftResult): string;
  415. begin
  416. if AError = CUFFT_SUCCESS then
  417. result := 'CUFFT operation is successful.'
  418. else if AError = CUFFT_INVALID_PLAN then
  419. result := 'CUFFT is passed an invalid plan handle.'
  420. else if AError = CUFFT_ALLOC_FAILED then
  421. result := 'CUFFT failed to allocate GPU memory.'
  422. else if AError = CUFFT_INVALID_TYPE then
  423. result := 'The user requests an unsupported type.'
  424. else if AError = CUFFT_INVALID_VALUE then
  425. result := 'The user specifies a bad memory pointer.'
  426. else if AError = CUFFT_INTERNAL_ERROR then
  427. result := 'Used for all internal driver errors.'
  428. else if AError = CUFFT_EXEC_FAILED then
  429. result := 'CUFFT failed to execute an FFT on the GPU.'
  430. else if AError = CUFFT_SETUP_FAILED then
  431. result := 'The CUFFT library failed to initialize.'
  432. else if AError = CUFFT_INVALID_SIZE then
  433. result := 'The user specifies an unsupported FFT size.'
  434. else
  435. result := 'Unknown error.'
  436. end;
  437. end.