1 module derelict.cudnn7;
2 
3 /**
4     Translation of cudnn.h
5 */
6 
7 import derelict.cuda.runtimeapi;
8 import derelict.util.loader;
9 
10 private
11 {
12     import derelict.util.system;
13 
14     static if(Derelict_OS_Linux)
15     {
16         version(X86_64)
17             enum libNames = "libcudnn.so.7";
18         else
19             static assert(0, "Need to implement cuDNN libNames for this arch.");
20     }
21     else static if(Derelict_OS_Windows)
22     {
23         version(X86_64)
24             enum libNames = "cudnn64_7.dll";
25         else
26             static assert(0, "There are no cuDNN libNames for this arch and operating system.");
27     }
28     else static if(Derelict_OS_Mac)
29     {
30         version(X86_64)
31             enum libNames = "libcudnn.7.dylib,libcudnn.dylib";
32         else
33             static assert(0, "There are no cuDNN libNames for this arch and operating system.");
34     }
35     else
36     {
37         static assert(0, "Need to implement cuDNN libNames for this operating system.");
38     }
39 
40     enum functionTypes = [
41         ["cudnnCreate", "cudnnHandle_t *"],
42         ["cudnnDestroy", "cudnnHandle_t"],
43         ["cudnnSetStream", "cudnnHandle_t", "cudaStream_t"],
44         ["cudnnGetStream", "cudnnHandle_t", "cudaStream_t *"],
45 
46 
47         ["cudnnCreateTensorDescriptor", "cudnnTensorDescriptor_t *"],
48         ["cudnnSetTensor4dDescriptor", "cudnnTensorDescriptor_t", "cudnnTensorFormat_t", "cudnnDataType_t", "int",
49             "int", "int", "int"],
50         ["cudnnSetTensor4dDescriptorEx", "cudnnTensorDescriptor_t", "cudnnDataType_t", "int", "int", "int", "int",
51             "int", "int", "int", "int"],
52         ["cudnnGetTensor4dDescriptor", "const cudnnTensorDescriptor_t", "cudnnDataType_t *", "int *", "int *", "int *",
53             "int *", "int *", "int *", "int *", "int *"],
54         ["cudnnSetTensorNdDescriptor", "cudnnTensorDescriptor_t", "cudnnDataType_t", "int", "const int", "const int"],
55         ["cudnnGetTensorNdDescriptor", "const cudnnTensorDescriptor_t", "int", "cudnnDataType_t *", "int *", "int",
56             "int"],
57         ["cudnnDestroyTensorDescriptor", "cudnnTensorDescriptor_t"],
58         ["cudnnTransformTensor", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
59             "const void *", "const cudnnTensorDescriptor_t", "void *"],
60         ["cudnnAddTensor", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
61             "const void *", "const cudnnTensorDescriptor_t", "void *"],
62         
63 
64         ["cudnnCreateOpTensorDescriptor", "cudnnOpTensorDescriptor_t *"],
65         ["cudnnSetOpTensorDescriptor", "cudnnOpTensorDescriptor_t", "cudnnOpTensorOp_t", "cudnnDataType_t",
66             "cudnnNanPropagation_t"],
67         ["cudnnGetOpTensorDescriptor", "const cudnnOpTensorDescriptor_t", "cudnnOpTensorOp_t *", "cudnnDataType_t *",
68             "cudnnNanPropagation_t *"],
69         ["cudnnDestroyOpTensorDescriptor", "cudnnOpTensorDescriptor_t"],
70         ["cudnnOpTensor", "cudnnHandle_t", "const cudnnOpTensorDescriptor_t", "const void *",
71             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
72             "const void *", "const void *", "const cudnnTensorDescriptor_t", "void *"],
73         ["cudnnSetTensor", "cudnnHandle_t", "const cudnnTensorDescriptor_t", "void *", "const void *"],
74         ["cudnnScaleTensor", "cudnnHandle_t", "const cudnnTensorDescriptor_t", "void *", "const void *"],
75         
76 
77         ["cudnnCreateFilterDescriptor", "cudnnFilterDescriptor_t *"],
78         ["cudnnSetFilter4dDescriptor", "cudnnFilterDescriptor_t", "cudnnDataType_t", "cudnnTensorFormat_t", "int",
79 			"int", "int", "int"],
80         ["cudnnGetFilter4dDescriptor", "cudnnDataType_t *", "cudnnTensorFormat_t *", "int *", "int *", "int *",
81 			"int *"],
82         ["cudnnSetFilterNdDescriptor", "cudnnFilterDescriptor_t", "cudnnDataType_t", "cudnnTensorFormat_t", "int",
83             "const int[]"],
84         ["cudnnGetFilterNdDescriptor", "const cudnnFilterDescriptor_t", "int", "cudnnDataType_t *",
85             "cudnnTensorFormat_t *", "int *", "int[]"],
86         ["cudnnDestroyFilterDescriptor", "cudnnFilterDescriptor_t"],
87         ["cudnnCreateConvolutionDescriptor", "cudnnConvolutionDescriptor_t *"],
88         ["cudnnSetConvolution2dDescriptor", "cudnnConvolutionDescriptor_t", "int", "int", "int", "int", "int",
89             "int", "cudnnConvolutionMode_t", "cudnnDataType_t"],
90         ["cudnnGetConvolution2dDescriptor", "const cudnnConvolutionDescriptor_t", "int *", "int *", "int *",
91             "int *", "int *", "int *", "cudnnConvolutionMode_t *", "cudnnDataType_t *"],
92         ["cudnnGetConvolution2dForwardOutputDim", "const cudnnConvolutionDescriptor_t",
93             "const cudnnTensorDescriptor_t", "const cudnnFilterDescriptor_t", "int", "int", "int", "int"],
94         ["cudnnSetConvolutionNdDescriptor", "cudnnConvolutionDescriptor_t", "int", "const int[]", "const int[]",
95             "const int[]", "cudnnConvolutionMode_t", "cudnnDataType_t"],
96         ["cudnnGetConvolutionNdDescriptor", "const cudnnConvolutionDescriptor_t", "int", "int *", "int[]", "int[]",
97             "int[]", "cudnnConvolutionMode_t *", "cudnnDataType_t *"],
98         ["cudnnGetConvolutionNdForwardOutputDim", "const cudnnConvolutionDescriptor_t",
99             "const cudnnTensorDescriptor_t", "const cudnnFilterDescriptor_t", "int", "int[]"],
100         ["cudnnDestroyConvolutionDescriptor", "cudnnConvolutionDescriptor_t"],
101 
102         
103         ["cudnnFindConvolutionForwardAlgorithm", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
104             "const cudnnFilterDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
105             "const int", "int *", "cudnnConvolutionFwdAlgoPerf_t *"],
106         ["cudnnFindConvolutionForwardAlgorithmEx", "cudnnHandle_t", "const cudnnTensorDescriptor_t", "const void *",
107             "const cudnnFilterDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
108             "const cudnnTensorDescriptor_t", "void *", "const int", "int *", "cudnnConvolutionFwdAlgoPerf_t *",
109             "void *", "size_t"],
110         ["cudnnGetConvolutionForwardAlgorithm", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
111             "const cudnnFilterDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
112             "cudnnConvolutionFwdPreference_t", "size_t", "cudnnConvolutionFwdAlgo_t *"],
113         ["cudnnGetConvolutionForwardWorkspaceSize", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
114             "const cudnnFilterDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
115             "cudnnConvolutionFwdAlgo_t", "size_t *"],
116         ["cudnnConvolutionForward", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
117             "const cudnnFilterDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
118             "cudnnConvolutionFwdAlgo_t", "void *", "size_t", "const void *", "const cudnnTensorDescriptor_t",
119             "void *"],
120         ["cudnnConvolutionBackwardBias", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t",
121             "const void *", "const void *", "const cudnnTensorDescriptor_t", "void *"],
122         
123 
124         ["cudnnFindConvolutionBackwardFilterAlgorithm", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
125             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnFilterDescriptor_t",
126             "const int", "int *", "cudnnConvolutionBwdFilterAlgoPerf_t *"],
127         ["cudnnFindConvolutionBackwardFilterAlgorithmEx", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
128             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
129             "const cudnnFilterDescriptor_t", "void *", "const int", "int *", "cudnnConvolutionBwdFilterAlgoPerf_t *",
130             "void *", "size_t"],
131         ["cudnnGetConvolutionBackwardFilterAlgorithm", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
132             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnFilterDescriptor_t",
133             "cudnnConvolutionBwdFilterPreference_t", "size_t", "cudnnConvolutionBwdFilterAlgo_t *"],
134         ["cudnnGetConvolutionBackwardFilterWorkspaceSize", "cudnnHandle_t", "const cudnnTensorDescriptor_t",
135             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnFilterDescriptor_t",
136             "cudnnConvolutionBwdFilterAlgo_t", "size_t *"],
137         ["cudnnConvolutionBackwardFilter", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t",
138             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
139             "cudnnConvolutionBwdFilterAlgo_t", "void *", "size_t", "const void *", "const cudnnFilterDescriptor_t",
140             "void *"],
141         
142 
143         ["cudnnFindConvolutionBackwardDataAlgorithm", "cudnnHandle_t", "const cudnnFilterDescriptor_t",
144             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
145             "const int", "int *", "cudnnConvolutionBwdDataAlgoPerf_t *"],
146         ["cudnnFindConvolutionBackwardDataAlgorithmEx", "cudnnHandle_t", "const cudnnFilterDescriptor_t",
147             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
148             "const cudnnTensorDescriptor_t", "void *", "const int", "int *", "cudnnConvolutionBwdDataAlgoPerf_t *",
149             "void *", "size_t"],
150         ["cudnnGetConvolutionBackwardDataAlgorithm", "cudnnHandle_t", "const cudnnFilterDescriptor_t",
151             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
152             "cudnnConvolutionBwdDataPreference_t", "size_t", "cudnnConvolutionBwdDataAlgo_t *"],
153         ["cudnnGetConvolutionBackwardDataWorkspaceSize", "cudnnHandle_t", "const cudnnFilterDescriptor_t",
154             "const cudnnTensorDescriptor_t", "const cudnnConvolutionDescriptor_t", "const cudnnTensorDescriptor_t",
155             "cudnnConvolutionBwdDataAlgo_t", "size_t *"],
156         ["cudnnConvolutionBackwardData", "cudnnHandle_t", "const void *", "const cudnnFilterDescriptor_t",
157             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
158             "cudnnConvolutionBwdDataAlgo_t", "void *", "size_t", "const void *", "const cudnnTensorDescriptor_t",
159             "void *"],
160         ["cudnnIm2Col", "cudnnHandle_t", "const cudnnTensorDescriptor_t", "const void *",
161             "const cudnnFilterDescriptor_t", "const cudnnConvolutionDescriptor_t", "void *"],
162         
163 
164         ["cudnnSoftmaxForward", "cudnnHandle_t", "cudnnSoftmaxAlgorithm_t", "cudnnSoftmaxMode_t", "const void *",
165             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
166             "void *"],
167         ["cudnnSoftmaxBackward", "cudnnHandle_t", "cudnnSoftmaxAlgorithm_t", "cudnnSoftmaxMode_t", "const void *",
168             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
169             "const void *", "const cudnnTensorDescriptor_t", "void *"],
170         
171 
172         ["cudnnCreatePoolingDescriptor", "cudnnPoolingDescriptor_t *"],
173         ["cudnnSetPooling2dDescriptor", "cudnnPoolingDescriptor_t", "cudnnPoolingMode_t", "cudnnNanPropagation_t",
174             "int", "int", "int", "int", "int", "int"],
175         ["cudnnGetPooling2dDescriptor", "const cudnnPoolingDescriptor_t", "cudnnPoolingMode_t *",
176             "cudnnNanPropagation_t *", "int *", "int *", "int *", "int *", "int *", "int *"],
177         ["cudnnSetPoolingNdDescriptor", "cudnnPoolingDescriptor_t", "const cudnnPoolingMode_t",
178             "const cudnnNanPropagation_t", "int", "const int[]", "const int[]", "const int[]"],
179         ["cudnnGetPoolingNdDescriptor", "cudnnPoolingDescriptor_t", "int", "cudnnPoolingMode_t *",
180             "cudnnNanPropagation_t *", "int *", "int[]", "int[]", "int[]"],
181         ["cudnnGetPoolingNdForwardOutputDim", "const cudnnPoolingDescriptor_t", "const cudnnTensorDescriptor_t",
182             "int", "int[]"],
183         ["cudnnGetPooling2dForwardOutputDim", "const cudnnPoolingDescriptor_t", "const cudnnTensorDescriptor_t",
184             "int *", "int *", "int *", "int *"],
185         ["cudnnDestroyPoolingDescriptor", "cudnnPoolingDescriptor_t"],
186         ["cudnnPoolingForward", "cudnnHandle_t", "const cudnnPoolingDescriptor_t", "const void *",
187             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
188             "void *"],
189         ["cudnnPoolingBackward", "cudnnHandle_t", "const cudnnPoolingDescriptor_t", "const void *",
190             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
191             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
192             "void *"],
193         
194 
195         ["cudnnCreateActivationDescriptor", "cudnnActivationDescriptor_t *"],
196         ["cudnnSetActivationDescriptor", "cudnnActivationDescriptor_t", "cudnnActivationMode_t",
197             "cudnnNanPropagation_t", "double"],
198         ["cudnnGetActivationDescriptor", "const cudnnActivationDescriptor_t", "cudnnActivationMode_t *",
199             "cudnnNanPropagation_t ", "double *"],
200         ["cudnnDestroyActivationDescriptor", "cudnnActivationDescriptor_t"],
201         ["cudnnActivationForward", "cudnnHandle_t", "cudnnActivationDescriptor_t", "const void *",
202             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
203             "void *"],
204         ["cudnnActivationBackward", "cudnnHandle_t", "cudnnActivationDescriptor_t", "const void *",
205             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
206             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
207             "void *"],
208         
209 
210         ["cudnnCreateLRNDescriptor", "cudnnLRNDescriptor_t *"],
211         ["cudnnSetLRNDescriptor", "cudnnLRNDescriptor_t", "uint", "double", "double", "double"],
212         ["cudnnGetLRNDescriptor", "cudnnLRNDescriptor_t", "uint *", "double *", "double *", "double *"],
213         ["cudnnDestroyLRNDescriptor", "cudnnLRNDescriptor_t"],
214         ["cudnnLRNCrossChannelForward", "cudnnHandle_t", "cudnnLRNDescriptor_t", "cudnnLRNMode_t", "const void *",
215             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
216             "void *"],
217         ["cudnnLRNCrossChannelBackward", "cudnnHandle_t", "cudnnLRNDescriptor_t", "cudnnLRNMode_t", "const void *",
218             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
219             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t",
220             "void *"],
221         ["cudnnDivisiveNormalizationForward", "cudnnHandle_t", "cudnnLRNDescriptor_t", "cudnnDivNormMode_t",
222             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const void *", "void *", "void *",
223             "const void *", "const cudnnTensorDescriptor_t", "void *"],
224         ["cudnnDivisiveNormalizationBackward", "cudnnHandle_t", "cudnnLRNDescriptor_t", "cudnnDivNormMode_t",
225             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const void *", "const void *",
226             "void *", "void *", "const void *", "const cudnnTensorDescriptor_t", "void *", "void *"],
227         
228 
229         ["cudnnDeriveBNTensorDescriptor", "cudnnTensorDescriptor_t", "const cudnnTensorDescriptor_t",
230             "cudnnBatchNormMode_t"],
231         ["cudnnBatchNormalizationForwardTraining", "cudnnHandle_t", "cudnnBatchNormMode_t", "const void *",
232             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t",
233             "void *", "const cudnnTensorDescriptor_t", "const void *", "const void *", "double", "void *", "void *",
234             "double", "void *", "void *"],
235         ["cudnnBatchNormalizationForwardInference", "cudnnHandle_t", "cudnnBatchNormMode_t", "const void *",
236             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "void *",
237             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const void *", "const void *", "double"],
238         ["cudnnBatchNormalizationBackward", "cudnnHandle_t", "cudnnBatchNormMode_t", "const void *", "const void *",
239             "const void *", "const void *", "const cudnnTensorDescriptor_t", "const void *",
240             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "void *",
241             "const cudnnTensorDescriptor_t", "const void *", "void *", "void *", "double", "const void *",
242             "const void *"],
243         
244 
245         ["cudnnCreateSpatialTransformerDescriptor", "cudnnSpatialTransformerDescriptor_t *"],
246         ["cudnnSetSpatialTransformerNdDescriptor", "cudnnSpatialTransformerDescriptor_t", "cudnnSamplerType_t",
247             "cudnnDataType_t", "const int", "const int[]"],
248         ["cudnnDestroySpatialTransformerDescriptor", "cudnnSpatialTransformerDescriptor_t"],
249         ["cudnnSpatialTfGridGeneratorForward", "cudnnHandle_t", "const cudnnSpatialTransformerDescriptor_t",
250             "const void *", "void *"],
251         ["cudnnSpatialTfGridGeneratorBackward", "cudnnHandle_t", "const cudnnSpatialTransformerDescriptor_t",
252             "const void *", "void *"],
253         ["cudnnSpatialTfSamplerForward", "cudnnHandle_t", "cudnnSpatialTransformerDescriptor_t", "const void *",
254             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const void *", "const void *",
255             "cudnnTensorDescriptor_t", "void *"],
256         ["cudnnSpatialTfSamplerBackward", "cudnnHandle_t", "cudnnSpatialTransformerDescriptor_t", "const void *",
257             "const cudnnTensorDescriptor_t", "const void *", "const void *", "const cudnnTensorDescriptor_t", "void *",
258             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const void *", "const void *", "void *"],
259         
260 
261         ["cudnnCreateDropoutDescriptor", "cudnnDropoutDescriptor_t *"],
262         ["cudnnDestroyDropoutDescriptor", "cudnnDropoutDescriptor_t"],
263         ["cudnnDropoutGetStatesSize", "cudnnHandle_t", "size_t *"],
264         ["cudnnDropoutGetReserveSpaceSize", "cudnnTensorDescriptor_t", "size_t *"],
265         ["cudnnSetDropoutDescriptor", "cudnnDropoutDescriptor_t", "cudnnHandle_t", "float", "void *", "size_t",
266             "ulong"],
267         ["cudnnDropoutForward", "cudnnHandle_t", "const cudnnDropoutDescriptor_t", "const cudnnTensorDescriptor_t",
268             "const void *", "const cudnnTensorDescriptor_t", "void *", "void *", "size_t"],
269         ["cudnnDropoutBackward", "cudnnHandle_t", "const cudnnDropoutDescriptor_t", "const cudnnTensorDescriptor_t",
270             "const void *", "const cudnnTensorDescriptor_t", "void *", "void *", "size_t"],
271         
272 
273         ["cudnnCreateRNNDescriptor", "cudnnRNNDescriptor_t *"],
274         ["cudnnDestroyRNNDescriptor", "cudnnRNNDescriptor_t"],
275         ["cudnnSetRNNDescriptor", "cudnnRNNDescriptor_t", "int", "int", "cudnnDropoutDescriptor_t",
276             "cudnnRNNInputMode_t", "cudnnDirectionMode_t", "cudnnRNNMode_t", "cudnnDataType_t"],
277         ["cudnnGetRNNWorkspaceSize", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
278             "const cudnnTensorDescriptor_t *", "size_t *"],
279         ["cudnnGetRNNTrainingReserveSize", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
280             "const cudnnTensorDescriptor_t *", "size_t *"],
281         ["cudnnGetRNNParamsSize", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const cudnnTensorDescriptor_t",
282             "size_t *", "cudnnDataType_t"],
283         ["cudnnGetRNNLinLayerMatrixParams", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
284             "const cudnnTensorDescriptor_t", "const cudnnFilterDescriptor_t", "const void *", "const int",
285             "cudnnFilterDescriptor_t", "void **"],
286         ["cudnnGetRNNLinLayerBiasParams", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
287             "const cudnnTensorDescriptor_t", "const cudnnFilterDescriptor_t", "const void *", "const int",
288             "cudnnFilterDescriptor_t", "void **"],
289         ["cudnnRNNForwardInference", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
290             "const cudnnTensorDescriptor_t *", "const void *", "const cudnnTensorDescriptor_t", "const void *",
291             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnFilterDescriptor_t",
292             "const void *", "const cudnnTensorDescriptor_t *", "void *", "const cudnnTensorDescriptor_t", "void *",
293             "const cudnnTensorDescriptor_t", "void *", "void *", "size_t"],
294         ["cudnnRNNForwardTraining", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
295             "const cudnnTensorDescriptor_t *", "const void *", "const cudnnTensorDescriptor_t", "const void *",
296             "const cudnnTensorDescriptor_t", "const void *", "const cudnnFilterDescriptor_t", "const void *",
297             "const cudnnTensorDescriptor_t *", "void *", "const cudnnTensorDescriptor_t", "void *",
298             "const cudnnTensorDescriptor_t", "void *", "void *", "size_t", "void *", "size_t"],
299         ["cudnnRNNBackwardData", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
300             "const cudnnTensorDescriptor_t *", "const void *", "const cudnnTensorDescriptor_t *", "const void *",
301             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
302             "const cudnnFilterDescriptor_t", "const void *", "const cudnnTensorDescriptor_t", "const void *",
303             "const cudnnTensorDescriptor_t", "const void *", "const cudnnTensorDescriptor_t *", "void *",
304             "const cudnnTensorDescriptor_t", "void *", "const cudnnTensorDescriptor_t", "void *", "void *",
305             "size_t", "const void *", "size_t"],
306         ["cudnnRNNBackwardWeights", "cudnnHandle_t", "const cudnnRNNDescriptor_t", "const int",
307             "const cudnnTensorDescriptor_t *", "const void *", "const cudnnTensorDescriptor_t", "const void *",
308             "const cudnnTensorDescriptor_t *", "const void *", "const void *", "size_t",
309             "const cudnnFilterDescriptor_t", "void *", "const void *", "size_t"],
310 
311         //New in cuDNN v6
312         ["cudnnConvolutionBiasActivationForward", "cudnnHandle_t", "const void *", "const cudnnTensorDescriptor_t",
313             "const void *", "const cudnnFilterDescriptor_t", "const void *", "const cudnnConvolutionDescriptor_t",
314             "cudnnConvolutionFwdAlgo_t", "void *", "size_t", "const void *", "const cudnnTensorDescriptor_t",
315             "const void *", "const cudnnTensorDescriptor_t", "const void *", "const cudnnActivationDescriptor_t",
316             "const cudnnTensorDescriptor_t", "void *"]
317     ];
318 
319     string generateFunctionAliases()
320     {
321         import std.algorithm : joiner;
322         import std.conv : to;
323 
324         string ret;
325 
326         foreach(ft; functionTypes)
327         {
328             ret ~= "alias da_" ~ ft[0] ~ " = cudnnStatus_t function(" ~ ft[1 .. $].joiner(",").to!string ~ ");";
329         }
330 
331         return ret;
332     }
333 
334     string generateFunctionPointers()
335     {
336         string ret;
337 
338         foreach(ft; functionTypes)
339         {
340             ret ~= "da_" ~ ft[0] ~ " " ~ ft[0] ~ ";";
341         }
342 
343         return ret;
344     }
345 
346     string generateFunctionBinds()
347     {
348         string ret;
349 
350         foreach(ft; functionTypes)
351         {
352             ret ~= "bindFunc(cast(void**)&" ~ ft[0] ~ ", \"" ~ ft[0] ~ "\");";
353         }
354 
355         return ret;
356     }
357 }
358 
359 struct cudnnContext;
360 alias cudnnHandle_t = cudnnContext*;
361 
362 alias cudnnStatus_t = int;
363 enum : cudnnStatus_t
364 {
365     CUDNN_STATUS_SUCCESS          = 0,
366     CUDNN_STATUS_NOT_INITIALIZED  = 1,
367     CUDNN_STATUS_ALLOC_FAILED     = 2,
368     CUDNN_STATUS_BAD_PARAM        = 3,
369     CUDNN_STATUS_INTERNAL_ERROR   = 4,
370     CUDNN_STATUS_INVALID_VALUE    = 5,
371     CUDNN_STATUS_ARCH_MISMATCH    = 6,
372     CUDNN_STATUS_MAPPING_ERROR    = 7,
373     CUDNN_STATUS_EXECUTION_FAILED = 8,
374     CUDNN_STATUS_NOT_SUPPORTED    = 9,
375     CUDNN_STATUS_LICENSE_ERROR    = 10
376 }
377 
378 struct cudnnTensorStruct;
379 alias cudnnTensorDescriptor_t = cudnnTensorStruct*;
380 
381 struct cudnnConvolutionStruct;
382 alias cudnnConvolutionDescriptor_t = cudnnConvolutionStruct*;
383 
384 struct cudnnPoolingStruct;
385 alias cudnnPoolingDescriptor_t = cudnnPoolingStruct*;
386 
387 struct cudnnFilterStruct;
388 alias cudnnFilterDescriptor_t = cudnnFilterStruct*;
389 
390 struct cudnnLRNStruct;
391 alias cudnnLRNDescriptor_t = cudnnLRNStruct*;
392 
393 struct cudnnActivationStruct;
394 alias cudnnActivationDescriptor_t = cudnnActivationStruct*;
395 
396 struct cudnnSpatialTransformerStruct;
397 alias cudnnSpatialTransformerDescriptor_t = cudnnSpatialTransformerStruct*;
398 
399 struct cudnnOpTensorStruct;
400 alias cudnnOpTensorDescriptor_t = cudnnOpTensorStruct*;
401 
402 alias cudnnDataType_t = int;
403 enum : cudnnDataType_t
404 {
405     CUDNN_DATA_FLOAT  = 0,
406     CUDNN_DATA_DOUBLE = 1,
407     CUDNN_DATA_HALF   = 2
408 }
409 
410 alias cudnnNanPropagation_t = int;
411 enum : cudnnNanPropagation_t
412 {
413     CUDNN_NOT_PROPAGATE_NAN  = 0,
414     CUDNN_PROPAGATE_NAN      = 1
415 }
416 
417 alias cudnnTensorFormat_t = int;
418 enum : cudnnTensorFormat_t
419 {
420     CUDNN_TENSOR_NCHW = 0,   /* row major (wStride = 1, hStride = w) */
421     CUDNN_TENSOR_NHWC = 1    /* feature maps interleaved ( cStride = 1 )*/
422 }
423 
424 alias cudnnOpTensorOp_t = int;
425 enum : cudnnOpTensorOp_t
426 {
427     CUDNN_OP_TENSOR_ADD = 0,
428     CUDNN_OP_TENSOR_MUL = 1,
429     CUDNN_OP_TENSOR_MIN = 2,
430     CUDNN_OP_TENSOR_MAX = 3
431 }
432 
433 alias cudnnConvolutionMode_t = int;
434 enum : cudnnConvolutionMode_t
435 {
436     CUDNN_CONVOLUTION       = 0,
437     CUDNN_CROSS_CORRELATION = 1
438 }
439 
440 alias cudnnConvolutionFwdPreference_t = int;
441 enum : cudnnConvolutionFwdPreference_t
442 {
443     CUDNN_CONVOLUTION_FWD_NO_WORKSPACE            = 0,
444     CUDNN_CONVOLUTION_FWD_PREFER_FASTEST          = 1,
445     CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT = 2
446 }
447 
448 alias cudnnConvolutionFwdAlgo_t = int;
449 enum : cudnnConvolutionFwdAlgo_t
450 {
451     CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM         = 0,
452     CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM = 1,
453     CUDNN_CONVOLUTION_FWD_ALGO_GEMM                  = 2,
454     CUDNN_CONVOLUTION_FWD_ALGO_DIRECT                = 3,
455     CUDNN_CONVOLUTION_FWD_ALGO_FFT                   = 4,
456     CUDNN_CONVOLUTION_FWD_ALGO_FFT_TILING            = 5,
457     CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD              = 6,
458     CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED     = 7
459 }
460 
461 struct cudnnConvolutionFwdAlgoPerf_t
462 {
463     cudnnConvolutionFwdAlgo_t   algo;
464     cudnnStatus_t               status;
465     float                       time;
466     size_t                      memory;
467     int[5] reserved;
468 }
469 
470 alias cudnnConvolutionBwdFilterPreference_t = int;
471 enum : cudnnConvolutionBwdFilterPreference_t
472 {
473     CUDNN_CONVOLUTION_BWD_FILTER_NO_WORKSPACE            = 0,
474     CUDNN_CONVOLUTION_BWD_FILTER_PREFER_FASTEST          = 1,
475     CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT = 2
476 }
477 
478 alias cudnnConvolutionBwdFilterAlgo_t = int;
479 enum : cudnnConvolutionBwdFilterAlgo_t
480 {
481     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0         = 0,  // non-deterministic
482     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_1         = 1,
483     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT       = 2,
484     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_3         = 3,  // non-deterministic, algo0 with workspace
485     // CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD  = 4, // not implemented
486     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD_NONFUSED = 5
487 }
488 
489 struct cudnnConvolutionBwdFilterAlgoPerf_t
490 {
491     cudnnConvolutionBwdFilterAlgo_t algo;
492     cudnnStatus_t status;
493     float time;
494     size_t memory;
495     int[5] reserved;
496 }
497 
498 alias cudnnConvolutionBwdDataPreference_t = int;
499 enum : cudnnConvolutionBwdDataPreference_t
500 {
501     CUDNN_CONVOLUTION_BWD_DATA_NO_WORKSPACE             = 0,
502     CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST           = 1,
503     CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT  = 2
504 }
505 
506 alias cudnnConvolutionBwdDataAlgo_t = int;
507 enum : cudnnConvolutionBwdDataAlgo_t
508 {
509     CUDNN_CONVOLUTION_BWD_DATA_ALGO_0                 = 0, // non-deterministic
510     CUDNN_CONVOLUTION_BWD_DATA_ALGO_1                 = 1,
511     CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT               = 2,
512     CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT_TILING        = 3,
513     CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD          = 4,
514     CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD_NONFUSED = 5
515 }
516 
517 struct cudnnConvolutionBwdDataAlgoPerf_t
518 {
519     cudnnConvolutionBwdDataAlgo_t   algo;
520     cudnnStatus_t                   status;
521     float                           time;
522     size_t                          memory;
523     int[5] reserved;
524 }
525 
526 alias cudnnSoftmaxAlgorithm_t = int;
527 enum : cudnnSoftmaxAlgorithm_t
528 {
529     CUDNN_SOFTMAX_FAST     = 0,         /* straightforward implementation */
530     CUDNN_SOFTMAX_ACCURATE = 1,         /* subtract max from every point to avoid overflow */
531     CUDNN_SOFTMAX_LOG      = 2
532 }
533 
534 alias cudnnSoftmaxMode_t = int;
535 enum : cudnnSoftmaxMode_t
536 {
537     CUDNN_SOFTMAX_MODE_INSTANCE = 0,   /* compute the softmax over all C, H, W for each N */
538     CUDNN_SOFTMAX_MODE_CHANNEL = 1
539 }
540 
541 alias cudnnPoolingMode_t = int;
542 enum : cudnnPoolingMode_t
543 {
544     CUDNN_POOLING_MAX     = 0,
545     CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING = 1, // count for average includes padded values
546     CUDNN_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING = 2
547 }
548 
549 alias cudnnActivationMode_t = int;
550 enum : cudnnActivationMode_t
551 {
552     CUDNN_ACTIVATION_SIGMOID      = 0,
553     CUDNN_ACTIVATION_RELU         = 1,
554     CUDNN_ACTIVATION_TANH         = 2,
555     CUDNN_ACTIVATION_CLIPPED_RELU = 3
556 }
557 
558 alias cudnnLRNMode_t = int;
559 enum : cudnnLRNMode_t
560 {
561     CUDNN_LRN_CROSS_CHANNEL_DIM1 = 0
562 }
563 
564 alias cudnnDivNormMode_t = int;
565 enum : cudnnDivNormMode_t
566 {
567     CUDNN_DIVNORM_PRECOMPUTED_MEANS = 0
568 }
569 
570 alias cudnnBatchNormMode_t = int;
571 enum : cudnnBatchNormMode_t
572 {
573     // bnScale, bnBias tensor dims are 1xCxHxWx.. (one value per CHW...-slice, normalized over N slice)
574     CUDNN_BATCHNORM_PER_ACTIVATION = 0,
575 
576     //bnScale, bnBias tensor dims are 1xCx1x1 (one value per C-dim normalized over Nx1xHxW subtensors)
577     CUDNN_BATCHNORM_SPATIAL        = 1
578 }
579 
580 alias cudnnSamplerType_t = int;
581 enum : cudnnSamplerType_t
582 {
583     CUDNN_SAMPLER_BILINEAR=0
584 }
585 
586 struct cudnnDropoutStruct;
587 alias cudnnDropoutDescriptor_t = cudnnDropoutStruct*;
588 
589 alias cudnnRNNMode_t = int;
590 enum : cudnnRNNMode_t
591 {
592     CUDNN_RNN_RELU = 0, // Stock RNN with ReLu activation
593     CUDNN_RNN_TANH = 1, // Stock RNN with tanh activation
594     CUDNN_LSTM = 2,     // LSTM with no peephole connections
595     CUDNN_GRU = 3       // Using h' = tanh(r * Uh(t-1) + Wx) and h = (1 - z) * h' + z * h(t-1);
596 }
597 
598 alias cudnnDirectionMode_t = int;
599 enum : cudnnDirectionMode_t
600 {
601     CUDNN_UNIDIRECTIONAL = 0,
602     CUDNN_BIDIRECTIONAL = 1      // Using output concatination at each step. Do we also want to support output sum?
603 }
604 
605 alias cudnnRNNInputMode_t = int;
606 enum : cudnnRNNInputMode_t
607 {
608     CUDNN_LINEAR_INPUT = 0,
609     CUDNN_SKIP_INPUT = 1
610 }
611 
612 struct cudnnRNNStruct;
613 alias cudnnRNNDescriptor_t = cudnnRNNStruct*;
614 
615 extern(System) @nogc nothrow
616 {
617     alias da_cudnnGetErrorString = const char *function(cudnnStatus_t);
618 
619     mixin(generateFunctionAliases());
620 }
621 
622 __gshared
623 {
624     da_cudnnGetErrorString cudnnGetErrorString;
625 
626     mixin(generateFunctionPointers());
627 }
628 
629 class DerelictCuDNN7Loader : SharedLibLoader
630 {
631     public
632     {
633         this()
634         {
635             super(libNames);
636         }
637     }
638 
639     protected
640     {
641         override void loadSymbols()
642         {
643             bindFunc(cast(void**)&cudnnGetErrorString, "cudnnGetErrorString");
644 
645             mixin(generateFunctionBinds());
646         }
647     }
648 }
649 
650 __gshared DerelictCuDNN7Loader DerelictCuDNN7;
651 
652 shared static this()
653 {
654     DerelictCuDNN7 = new DerelictCuDNN7Loader();
655 }
656 
657 unittest
658 {
659     import std.conv : to;
660     import std.stdio : writeln;
661 
662     try
663     {
664         DerelictCuDNN7.load();
665 
666         writeln("Successfully loaded cuDNN v5");
667     }
668     catch(Exception e)
669     {
670         writeln("Could not load cuDNN v5");
671     }
672 }