From 0b81d7631078484240fcbe326426f30793bc7e17 Mon Sep 17 00:00:00 2001 From: wangchaochaohu Date: Sun, 16 Aug 2020 14:11:30 +0800 Subject: [PATCH] [API2.0] add op for cudnn version query test=develop (#26180) --- paddle/fluid/platform/CMakeLists.txt | 2 +- paddle/fluid/platform/gpu_info.cc | 13 +++++-- paddle/fluid/platform/gpu_info.h | 2 + paddle/fluid/pybind/pybind.cc | 4 ++ python/paddle/__init__.py | 1 + python/paddle/device.py | 37 +++++++++++++++++++ .../fluid/tests/unittests/test_query_op.py | 32 ++++++++++++++++ 7 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 python/paddle/fluid/tests/unittests/test_query_op.py diff --git a/paddle/fluid/platform/CMakeLists.txt b/paddle/fluid/platform/CMakeLists.txt index 5a100c5746..6a28b975f8 100644 --- a/paddle/fluid/platform/CMakeLists.txt +++ b/paddle/fluid/platform/CMakeLists.txt @@ -45,7 +45,7 @@ ENDIF() cc_library(cpu_info SRCS cpu_info.cc DEPS ${CPU_INFO_DEPS}) cc_test(cpu_info_test SRCS cpu_info_test.cc DEPS cpu_info) -nv_library(gpu_info SRCS gpu_info.cc DEPS gflags glog enforce monitor) +nv_library(gpu_info SRCS gpu_info.cc DEPS gflags glog enforce monitor dynload_cuda) cc_library(place SRCS place.cc DEPS enforce boost) cc_test(place_test SRCS place_test.cc DEPS place glog gflags) diff --git a/paddle/fluid/platform/gpu_info.cc b/paddle/fluid/platform/gpu_info.cc index 5f63233d8b..ca1e5501c6 100644 --- a/paddle/fluid/platform/gpu_info.cc +++ b/paddle/fluid/platform/gpu_info.cc @@ -19,6 +19,7 @@ limitations under the License. */ #include "gflags/gflags.h" #include "paddle/fluid/platform/cuda_device_guard.h" +#include "paddle/fluid/platform/dynload/cudnn.h" #include "paddle/fluid/platform/enforce.h" #include "paddle/fluid/platform/lock_guard_ptr.h" #include "paddle/fluid/platform/macros.h" @@ -38,11 +39,11 @@ USE_GPU_MEM_STAT; namespace paddle { namespace platform { -/* Here is a very simple CUDA “pro tip”: cudaDeviceGetAttribute() is a much -faster way to query device properties. You can see details in -https://devblogs.nvidia.com/cuda-pro-tip-the-fast-way-to-query-device-properties/ -*/ +int CudnnVersion() { + if (!dynload::HasCUDNN()) return -1; + return dynload::cudnnGetVersion(); +} static int GetCUDADeviceCountImpl() { int driverVersion = 0; cudaError_t status = cudaDriverGetVersion(&driverVersion); @@ -73,6 +74,10 @@ int GetCUDADeviceCount() { return dev_cnt; } +/* Here is a very simple CUDA “pro tip”: cudaDeviceGetAttribute() is a much +faster way to query device properties. You can see details in +https://devblogs.nvidia.com/cuda-pro-tip-the-fast-way-to-query-device-properties/ +*/ int GetCUDAComputeCapability(int id) { PADDLE_ENFORCE_LT(id, GetCUDADeviceCount(), platform::errors::InvalidArgument( diff --git a/paddle/fluid/platform/gpu_info.h b/paddle/fluid/platform/gpu_info.h index 6a98936471..ec77447ef7 100644 --- a/paddle/fluid/platform/gpu_info.h +++ b/paddle/fluid/platform/gpu_info.h @@ -23,6 +23,8 @@ limitations under the License. */ namespace paddle { namespace platform { +//! Get the version of cudnn +int CudnnVersion(); //! Get the total number of GPU devices in system. int GetCUDADeviceCount(); diff --git a/paddle/fluid/pybind/pybind.cc b/paddle/fluid/pybind/pybind.cc index 7667bb50aa..f426ca8296 100644 --- a/paddle/fluid/pybind/pybind.cc +++ b/paddle/fluid/pybind/pybind.cc @@ -341,6 +341,10 @@ PYBIND11_MODULE(core_noavx, m) { m.def("set_num_threads", &platform::SetNumThreads); +#ifdef PADDLE_WITH_CUDA + m.def("cudnn_version", &platform::CudnnVersion); +#endif + m.def("from_dlpack", [](py::capsule *dltensor) { DLManagedTensor *dmt = reinterpret_cast( PyCapsule_GetPointer(dltensor->ptr(), "dltensor")); diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index d62d8c789a..6235f1c12b 100644 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -232,6 +232,7 @@ from .tensor.stat import reduce_mean #DEFINE_ALIAS from .tensor.stat import std #DEFINE_ALIAS from .tensor.stat import var #DEFINE_ALIAS from .fluid.data import data +from .device import get_cudnn_version from .device import set_device from .device import get_device # from .tensor.tensor import Tensor #DEFINE_ALIAS diff --git a/python/paddle/device.py b/python/paddle/device.py index 25b4ebe556..e2ef8e7092 100644 --- a/python/paddle/device.py +++ b/python/paddle/device.py @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +# TODO: define the functions to manipulate devices from paddle.fluid import core from paddle.fluid import framework import re + __all__ = [ + 'get_cudnn_version', 'set_device', 'get_device' # 'cpu_places', @@ -27,6 +30,40 @@ __all__ = [ # 'is_compiled_with_cuda' ] +_cudnn_version = None + + +def get_cudnn_version(): + """ + This funciton return the version of cudnn. the retuen value is int which represents the + cudnn version. For example, if it return 7600, it represents the version of cudnn is 7.6. + + Returns: + int: A int value which represents the cudnn version. If cudnn version is not installed, it return None. + + Examples: + .. code-block:: python + + import paddle + + cudnn_version = get_cudnn_version() + + + + """ + global _cudnn_version + if not core.is_compiled_with_cuda(): + return None + if _cudnn_version is None: + cudnn_version = int(core.cudnn_version()) + _cudnn_version = cudnn_version + if _cudnn_version < 0: + return None + else: + return cudnn_version + else: + return _cudnn_version + def set_device(device): """ diff --git a/python/paddle/fluid/tests/unittests/test_query_op.py b/python/paddle/fluid/tests/unittests/test_query_op.py new file mode 100644 index 0000000000..fc8ce5ad5f --- /dev/null +++ b/python/paddle/fluid/tests/unittests/test_query_op.py @@ -0,0 +1,32 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import unittest +import paddle +from paddle.fluid import core + + +class TestCudnnVersion(unittest.TestCase): + def test_no_cudnn(self): + cudnn_version = paddle.get_cudnn_version() + if not core.is_compiled_with_cuda(): + self.assertEqual((cudnn_version is None), True) + else: + self.assertEqual((isinstance(cudnn_version, int)), True) + + +if __name__ == '__main__': + unittest.main() -- GitLab