Repository: pytorch/pytorch

Issue:
better error messages on compiling with cudnn v5 (which is not supported anymore)
Hi All --

I'm getting the following error when I try to build:

```
   if (perfResults.status == CUDNN_STATUS_SUCCESS && !(deterministic && perfResults.determinism != CUDNN_DETERMINISTIC)) {
                                                                                                ^
torch/csrc/cudnn/Conv.cpp: In instantiation of ‘void torch::cudnn::{anonymous}::findAlgorithm(THCState*, cudnnHandle_t, const torch::cudnn::Convolution&, bool, bool, void*, void*, void*, algo_t*) [with algo_t = cudnnConvolutionBwdDataAlgo_t; THCState = THCState; cudnnHandle_t = cudnnContext*]’:
torch/csrc/cudnn/Conv.cpp:465:83:   required from ‘torch::cudnn::{anonymous}::Workspace torch::cudnn::{anonymous}::chooseAlgorithm(THCState*, cudnnHandle_t, const torch::cudnn::Convolution&, bool, bool, void*, void*, void*, algo_t*) [with algo_t = cudnnConvolutionBwdDataAlgo_t; THCState = THCState; cudnnHandle_t = cudnnContext*]’
torch/csrc/cudnn/Conv.cpp:726:18:   required from here
torch/csrc/cudnn/Conv.cpp:448:96: error: ‘struct cudnnConvolutionBwdDataAlgoPerf_t’ has no member named ‘determinism’
torch/csrc/cudnn/Conv.cpp: In instantiation of ‘void torch::cudnn::{anonymous}::findAlgorithm(THCState*, cudnnHandle_t, const torch::cudnn::Convolution&, bool, bool, void*, void*, void*, algo_t*) [with algo_t = cudnnConvolutionBwdFilterAlgo_t; THCState = THCState; cudnnHandle_t = cudnnContext*]’:
torch/csrc/cudnn/Conv.cpp:465:83:   required from ‘torch::cudnn::{anonymous}::Workspace torch::cudnn::{anonymous}::chooseAlgorithm(THCState*, cudnnHandle_t, const torch::cudnn::Convolution&, bool, bool, void*, void*, void*, algo_t*) [with algo_t = cudnnConvolutionBwdFilterAlgo_t; THCState = THCState; cudnnHandle_t = cudnnContext*]’
torch/csrc/cudnn/Conv.cpp:766:20:   required from here
torch/csrc/cudnn/Conv.cpp:448:96: error: ‘struct cudnnConvolutionBwdFilterAlgoPerf_t’ has no member named ‘determinism’
```

Seems like the `deterministic` flags were added within the past couple of weeks, and I can't find anything Googling the errors.

I have CUDNNV5 and CUDA 8.0 on an Ubuntu16.04 box.  Can provide more details as needed.

Thanks



Discussion:
we are ending support for cudnn v5, i will push some patches to have better error messages. NVIDIA already released CuDNN v7, so we are going for supporting cudnn v6 and v7
Roger that.  Should change README as well. 

Thanks

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,8 @@
 
 from tools.setup_helpers.env import check_env_flag
 from tools.setup_helpers.cuda import WITH_CUDA, CUDA_HOME, CUDA_VERSION
-from tools.setup_helpers.cudnn import WITH_CUDNN, CUDNN_LIB_DIR, CUDNN_INCLUDE_DIR
+from tools.setup_helpers.cudnn import WITH_CUDNN, CUDNN_LIB_DIR, CUDNN_INCLUDE_DIR, \
+    CUDNN_VERSION
 from tools.setup_helpers.nccl import WITH_NCCL, WITH_SYSTEM_NCCL, NCCL_LIB_DIR, \
     NCCL_INCLUDE_DIR, NCCL_ROOT_DIR, NCCL_SYSTEM_LIB
 from tools.setup_helpers.nnpack import WITH_NNPACK, NNPACK_LIB_DIR, NNPACK_INCLUDE_DIRS
@@ -173,6 +174,7 @@ def create_version_file():
             # this would claim to be a release build when it's not.)
             f.write("debug = {}\n".format(repr(DEBUG)))
             f.write("cuda = {}\n".format(repr(CUDA_VERSION)))
+            f.write("cudnn = {}\n".format(repr(CUDNN_VERSION)))
 
 
 class develop(setuptools.command.develop.develop):
diff --git a/tools/setup_helpers/cudnn.py b/tools/setup_helpers/cudnn.py
--- a/tools/setup_helpers/cudnn.py
+++ b/tools/setup_helpers/cudnn.py
@@ -2,6 +2,7 @@
 import sys
 import glob
 from itertools import chain
+import re
 
 from .env import check_env_flag
 from .cuda import WITH_CUDA, CUDA_HOME
@@ -10,12 +11,54 @@
 def gather_paths(env_vars):
     return list(chain(*(os.getenv(v, '').split(':') for v in env_vars)))
 
+
+def find_cudnn_version(cudnn_lib_dir):
+    candidate_names = list(glob.glob(os.path.join(cudnn_lib_dir, 'libcudnn*')))
+    candidate_names = [os.path.basename(c) for c in candidate_names]
+
+    # suppose version is MAJOR.MINOR.PATCH, all numbers
+    version_regex = re.compile('\d+\.\d+\.\d+')
+    candidates = [c.group() for c in map(version_regex.search, candidate_names) if c]
+    if len(candidates) > 0:
+        # normally only one will be retrieved, take the first result
+        return candidates[0]
+
+    # if no candidates were found, try MAJOR.MINOR
+    version_regex = re.compile('\d+\.\d+')
+    candidates = [c.group() for c in map(version_regex.search, candidate_names) if c]
+    if len(candidates) > 0:
+        return candidates[0]
+
+    # if no candidates were found, try MAJOR
+    version_regex = re.compile('\d+')
+    candidates = [c.group() for c in map(version_regex.search, candidate_names) if c]
+    if len(candidates) > 0:
+        return candidates[0]
+
+    return 'unknown'
+
+
+def check_cudnn_version(cudnn_version_string):
+    if cudnn_version_string is 'unknown':
+        return  # Assume version is OK and let compilation continue
+
+    cudnn_min_version = 6
+    cudnn_version = int(cudnn_version_string.split('.')[0])
+    if cudnn_version < cudnn_min_version:
+        raise RuntimeError(
+            'CuDNN v%s found, but need at least CuDNN v%s. '
+            'You can get the latest version of CuDNN from '
+            'https://developer.nvidia.com/cudnn' %
+            (cudnn_version_string, cudnn_min_version))
+
+
 is_conda = 'conda' in sys.version or 'Continuum' in sys.version
 conda_dir = os.path.join(os.path.dirname(sys.executable), '..')
 
 WITH_CUDNN = False
 CUDNN_LIB_DIR = None
 CUDNN_INCLUDE_DIR = None
+CUDNN_VERSION = None
 if WITH_CUDA and not check_env_flag('NO_CUDNN'):
     lib_paths = list(filter(bool, [
         os.getenv('CUDNN_LIB_DIR'),
@@ -56,4 +99,6 @@ def gather_paths(env_vars):
     if not CUDNN_LIB_DIR or not CUDNN_INCLUDE_DIR:
         CUDNN_LIB_DIR = CUDNN_INCLUDE_DIR = None
     else:
+        CUDNN_VERSION = find_cudnn_version(CUDNN_LIB_DIR)
+        check_cudnn_version(CUDNN_VERSION)
         WITH_CUDNN = True


Test patch: