1 module derelict.cudnn6;
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.6";
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_6.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.6.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 }
468 
469 alias cudnnConvolutionBwdFilterPreference_t = int;
470 enum : cudnnConvolutionBwdFilterPreference_t
471 {
472     CUDNN_CONVOLUTION_BWD_FILTER_NO_WORKSPACE            = 0,
473     CUDNN_CONVOLUTION_BWD_FILTER_PREFER_FASTEST          = 1,
474     CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT = 2
475 }
476 
477 alias cudnnConvolutionBwdFilterAlgo_t = int;
478 enum : cudnnConvolutionBwdFilterAlgo_t
479 {
480     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0         = 0,  // non-deterministic
481     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_1         = 1,
482     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT       = 2,
483     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_3         = 3,  // non-deterministic, algo0 with workspace
484     // CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD  = 4, // not implemented
485     CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD_NONFUSED = 5
486 }
487 
488 struct cudnnConvolutionBwdFilterAlgoPerf_t
489 {
490     cudnnConvolutionBwdFilterAlgo_t algo;
491     cudnnStatus_t status;
492     float time;
493     size_t memory;
494 }
495 
496 alias cudnnConvolutionBwdDataPreference_t = int;
497 enum : cudnnConvolutionBwdDataPreference_t
498 {
499     CUDNN_CONVOLUTION_BWD_DATA_NO_WORKSPACE             = 0,
500     CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST           = 1,
501     CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT  = 2
502 }
503 
504 alias cudnnConvolutionBwdDataAlgo_t = int;
505 enum : cudnnConvolutionBwdDataAlgo_t
506 {
507     CUDNN_CONVOLUTION_BWD_DATA_ALGO_0                 = 0, // non-deterministic
508     CUDNN_CONVOLUTION_BWD_DATA_ALGO_1                 = 1,
509     CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT               = 2,
510     CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT_TILING        = 3,
511     CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD          = 4,
512     CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD_NONFUSED = 5
513 }
514 
515 struct cudnnConvolutionBwdDataAlgoPerf_t
516 {
517     cudnnConvolutionBwdDataAlgo_t   algo;
518     cudnnStatus_t                   status;
519     float                           time;
520     size_t                          memory;
521 }
522 
523 alias cudnnSoftmaxAlgorithm_t = int;
524 enum : cudnnSoftmaxAlgorithm_t
525 {
526     CUDNN_SOFTMAX_FAST     = 0,         /* straightforward implementation */
527     CUDNN_SOFTMAX_ACCURATE = 1,         /* subtract max from every point to avoid overflow */
528     CUDNN_SOFTMAX_LOG      = 2
529 }
530 
531 alias cudnnSoftmaxMode_t = int;
532 enum : cudnnSoftmaxMode_t
533 {
534     CUDNN_SOFTMAX_MODE_INSTANCE = 0,   /* compute the softmax over all C, H, W for each N */
535     CUDNN_SOFTMAX_MODE_CHANNEL = 1
536 }
537 
538 alias cudnnPoolingMode_t = int;
539 enum : cudnnPoolingMode_t
540 {
541     CUDNN_POOLING_MAX     = 0,
542     CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING = 1, // count for average includes padded values
543     CUDNN_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING = 2
544 }
545 
546 alias cudnnActivationMode_t = int;
547 enum : cudnnActivationMode_t
548 {
549     CUDNN_ACTIVATION_SIGMOID      = 0,
550     CUDNN_ACTIVATION_RELU         = 1,
551     CUDNN_ACTIVATION_TANH         = 2,
552     CUDNN_ACTIVATION_CLIPPED_RELU = 3
553 }
554 
555 alias cudnnLRNMode_t = int;
556 enum : cudnnLRNMode_t
557 {
558     CUDNN_LRN_CROSS_CHANNEL_DIM1 = 0
559 }
560 
561 alias cudnnDivNormMode_t = int;
562 enum : cudnnDivNormMode_t
563 {
564     CUDNN_DIVNORM_PRECOMPUTED_MEANS = 0
565 }
566 
567 alias cudnnBatchNormMode_t = int;
568 enum : cudnnBatchNormMode_t
569 {
570     // bnScale, bnBias tensor dims are 1xCxHxWx.. (one value per CHW...-slice, normalized over N slice)
571     CUDNN_BATCHNORM_PER_ACTIVATION = 0,
572 
573     //bnScale, bnBias tensor dims are 1xCx1x1 (one value per C-dim normalized over Nx1xHxW subtensors)
574     CUDNN_BATCHNORM_SPATIAL        = 1
575 }
576 
577 alias cudnnSamplerType_t = int;
578 enum : cudnnSamplerType_t
579 {
580     CUDNN_SAMPLER_BILINEAR=0
581 }
582 
583 struct cudnnDropoutStruct;
584 alias cudnnDropoutDescriptor_t = cudnnDropoutStruct*;
585 
586 alias cudnnRNNMode_t = int;
587 enum : cudnnRNNMode_t
588 {
589     CUDNN_RNN_RELU = 0, // Stock RNN with ReLu activation
590     CUDNN_RNN_TANH = 1, // Stock RNN with tanh activation
591     CUDNN_LSTM = 2,     // LSTM with no peephole connections
592     CUDNN_GRU = 3       // Using h' = tanh(r * Uh(t-1) + Wx) and h = (1 - z) * h' + z * h(t-1);
593 }
594 
595 alias cudnnDirectionMode_t = int;
596 enum : cudnnDirectionMode_t
597 {
598     CUDNN_UNIDIRECTIONAL = 0,
599     CUDNN_BIDIRECTIONAL = 1      // Using output concatination at each step. Do we also want to support output sum?
600 }
601 
602 alias cudnnRNNInputMode_t = int;
603 enum : cudnnRNNInputMode_t
604 {
605     CUDNN_LINEAR_INPUT = 0,
606     CUDNN_SKIP_INPUT = 1
607 }
608 
609 struct cudnnRNNStruct;
610 alias cudnnRNNDescriptor_t = cudnnRNNStruct*;
611 
612 extern(System) @nogc nothrow
613 {
614     alias da_cudnnGetErrorString = const char *function(cudnnStatus_t);
615 
616     mixin(generateFunctionAliases());
617 }
618 
619 __gshared
620 {
621     da_cudnnGetErrorString cudnnGetErrorString;
622 
623     mixin(generateFunctionPointers());
624 }
625 
626 class DerelictCuDNN6Loader : SharedLibLoader
627 {
628     public
629     {
630         this()
631         {
632             super(libNames);
633         }
634     }
635 
636     protected
637     {
638         override void loadSymbols()
639         {
640             bindFunc(cast(void**)&cudnnGetErrorString, "cudnnGetErrorString");
641 
642             mixin(generateFunctionBinds());
643         }
644     }
645 }
646 
647 __gshared DerelictCuDNN6Loader DerelictCuDNN6;
648 
649 shared static this()
650 {
651     DerelictCuDNN6 = new DerelictCuDNN6Loader();
652 }
653 
654 unittest
655 {
656     import std.conv : to;
657     import std.stdio : writeln;
658 
659     try
660     {
661         DerelictCuDNN6.load();
662 
663         writeln("Successfully loaded cuDNN v5");
664     }
665     catch(Exception e)
666     {
667         writeln("Could not load cuDNN v5");
668     }
669 }