import six

import cupy

try:
    import cupy.cuda.cudnn as cudnn
except ImportError:
    cudnn = None

try:
    import cupy.cuda.nccl as nccl
except ImportError:
    nccl = None


def _eval_or_error(func, errors):
    # Evaluates `func` and return the result.
    # If an error specified by `errors` occured, it returns a string
    # representing the error.
    try:
        return func()
    except errors as e:
        return repr(e)


class _RuntimeInfo(object):

    cupy_version = None
    cuda_path = None
    cuda_build_version = None
    cuda_driver_version = None
    cuda_runtime_version = None
    cudnn_build_version = None
    cudnn_version = None
    nccl_build_version = None
    nccl_runtime_version = None

    def __init__(self):
        self.cupy_version = cupy.__version__

        self.cuda_path = cupy.cuda.get_cuda_path()
        self.cuda_build_version = cupy.cuda.driver.get_build_version()
        self.cuda_driver_version = _eval_or_error(
            cupy.cuda.runtime.driverGetVersion,
            cupy.cuda.runtime.CUDARuntimeError)
        self.cuda_runtime_version = _eval_or_error(
            cupy.cuda.runtime.runtimeGetVersion,
            cupy.cuda.runtime.CUDARuntimeError)

        if cudnn is not None:
            self.cudnn_build_version = cudnn.get_build_version()
            self.cudnn_version = _eval_or_error(
                cudnn.getVersion, cudnn.CuDNNError)

        if nccl is not None:
            self.nccl_build_version = nccl.get_build_version()
            nccl_runtime_version = nccl.get_version()
            if nccl_runtime_version == 0:
                nccl_runtime_version = '(unknown)'
            self.nccl_runtime_version = nccl_runtime_version

    def __str__(self):
        records = [
            ('CuPy Version', self.cupy_version),
            ('CUDA Root', self.cuda_path),
            ('CUDA Build Version', self.cuda_build_version),
            ('CUDA Driver Version', self.cuda_driver_version),
            ('CUDA Runtime Version', self.cuda_runtime_version),
            ('cuDNN Build Version', self.cudnn_build_version),
            ('cuDNN Version', self.cudnn_version),
            ('NCCL Build Version', self.nccl_build_version),
            ('NCCL Runtime Version', self.nccl_runtime_version),
        ]
        width = max([len(r[0]) for r in records]) + 2
        fmt = '{:' + str(width) + '}: {}\n'
        s = six.StringIO()
        for k, v in records:
            s.write(fmt.format(k, v))

        return s.getvalue()


def get_runtime_info():
    return _RuntimeInfo()

@@ -1,12 +1,37 @@
+import inspect%0Aimport os%0A
 import six%0A%0A
@@ -458,16 +458,1068 @@
 pr(e)%0A%0A%0A
+class _InstallInfo(object):%0A%0A    # TODO(niboshi): Add is_binary_distribution%0A%0A    def __init__(self):%0A        cupy_package_root = self._get_cupy_package_root()%0A        if cupy_package_root is not None:%0A            data_root = os.path.join(cupy_package_root, '.data')%0A            data_paths = %7B%0A                'lib': _dir_or_none(os.path.join(data_root, 'lib')),%0A                'include': _dir_or_none(os.path.join(data_root, 'include')),%0A            %7D%0A        else:%0A            data_paths = %7B%0A                'lib': None,%0A                'include': None,%0A            %7D%0A%0A        self.cupy_package_root = cupy_package_root%0A        self.data_paths = data_paths%0A%0A    def get_data_path(self, data_type):%0A        if data_type not in self.data_paths:%0A            raise ValueError('Invalid data type: %7B%7D'.format(data_type))%0A        return self.data_paths%5Bdata_type%5D%0A%0A    def _get_cupy_package_root(self):%0A        try:%0A            cupy_path = inspect.getfile(cupy)%0A        except TypeError:%0A            return None%0A        return os.path.dirname(cupy_path)%0A%0A%0A
 class _R
@@ -3630,8 +3630,197 @@
 eInfo()%0A
+%0A%0Adef get_install_info():%0A    return _InstallInfo()%0A%0A%0Adef _dir_or_none(path):%0A    %22%22%22Returns None if path does not exist.%22%22%22%0A    if os.path.isdir(path):%0A        return path%0A    return None%0A

Add API to retrieve installation info