CUDA.FourierTransform.pas 17 KB

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