diff --git a/paddle/fluid/platform/CMakeLists.txt b/paddle/fluid/platform/CMakeLists.txt index 5a100c5746e616e860811dd47da27036ea7355d5..6a28b975f8e3fc7c7bd56f3a88464cbe4b4c9a72 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 5f63233d8bee4beefd6e1695d8bc3d6e5e4ae7fb..ca1e5501c6a84e6136c28f564a78a7e63f0ee8d4 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 6a9893647172e2c63f4749fdb0ae1cb0fdfaaf04..ec77447ef77dbb1cd7ee180176f95a9ab8f7c03a 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 7667bb50aa49fc9fbe32612695fd93e8676cacf4..f426ca82966d3ec39e5504660c394c4539a39d5e 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 d62d8c789a71ee4ccc12542164c4ebe416500d81..6235f1c12ba7e9b624d905dcc0de46a794afe6d2 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 25b4ebe55609ddd36a22678fc2689886b231050f..e2ef8e7092ad3f6af91c8d5d3c0b1deaed025514 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 0000000000000000000000000000000000000000..fc8ce5ad5f6b89b28fb2ddddd15d5b315fe4c0e4 --- /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()