def nvmlInit():
    r"""
    /**
     * Initialize NVML, but don't initialize any GPUs yet.
     *
     * \note nvmlInit_v3 introduces a "flags" argument, that allows passing boolean values
     *       modifying the behaviour of nvmlInit().
     * \note In NVML 5.319 new nvmlInit_v2 has replaced nvmlInit"_v1" (default in NVML 4.304 and older) that
     *       did initialize all GPU devices in the system.
     *
     * This allows NVML to communicate with a GPU
     * when other GPUs in the system are unstable or in a bad state.  When using this API, GPUs are
     * discovered and initialized in nvmlDeviceGetHandleBy* functions instead.
     *
     * \note To contrast nvmlInit_v2 with nvmlInit"_v1", NVML 4.304 nvmlInit"_v1" will fail when any detected GPU is in
     *       a bad or unstable state.
     *
     * For all products.
     *
     * This method, should be called once before invoking any other methods in the library.
     * A reference count of the number of initializations is maintained.  Shutdown only occurs
     * when the reference count reaches zero.
     *
     * @return
     *         - \ref NVML_SUCCESS                   if NVML has been properly initialized
     *         - \ref NVML_ERROR_DRIVER_NOT_LOADED   if NVIDIA driver is not running
     *         - \ref NVML_ERROR_NO_PERMISSION       if NVML does not have permission to talk to the driver
     *         - \ref NVML_ERROR_UNKNOWN             on any unexpected error
     */
    nvmlReturn_t DECLDIR nvmlInit
    """
    _LoadNvmlLibrary()

    #
    # Initialize the library
    #
    fn = _nvmlGetFunctionPointer("nvmlInit_v2")
    ret = fn()
    _nvmlCheckReturn(ret)

    # Atomically update refcount
    global _nvmlLib_refcount
    libLoadLock.acquire()
    _nvmlLib_refcount += 1
    libLoadLock.release()
    global nvmlLib
    return nvmlLib