chore: import upstream snapshot with attribution
Docker Image CI / build-ubuntu2004 (push) Waiting to run
Docker Image CI / build-ubuntu2004 (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "cudnnWrapper.h"
|
||||
#include "common/checkMacrosPlugin.h"
|
||||
#include "common/plugin.h"
|
||||
|
||||
#define CUDNN_MAJOR 8
|
||||
#if defined(_WIN32)
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
// Ensure that macros appearing in multiple files are only defined once.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif // defined(WIN32_LEAN_AND_MEAN)
|
||||
#include <windows.h>
|
||||
#define dllOpen(name) (void*) LoadLibraryA(name)
|
||||
#define dllClose(handle) FreeLibrary(static_cast<HMODULE>(handle))
|
||||
#define dllGetSym(handle, name) GetProcAddress(static_cast<HMODULE>(handle), name)
|
||||
auto const kCUDNN_PLUGIN_LIBNAME = std::string("cudnn64_") + std::to_string(CUDNN_MAJOR) + ".dll";
|
||||
#else // defined(_WIN32)
|
||||
#include <dlfcn.h>
|
||||
#define dllOpen(name) dlopen(name, RTLD_LAZY)
|
||||
#define dllClose(handle) dlclose(handle)
|
||||
#define dllGetSym(handle, name) dlsym(handle, name)
|
||||
auto const kCUDNN_PLUGIN_LIBNAME = std::string("libcudnn.so.") + std::to_string(CUDNN_MAJOR);
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
namespace nvinfer1::pluginInternal
|
||||
{
|
||||
// If tryLoadingCudnn failed, the CudnnWrapper object won't be created.
|
||||
CudnnWrapper::CudnnWrapper(bool initHandle, char const* callerPluginName)
|
||||
: mLibrary(tryLoadingCudnn(callerPluginName))
|
||||
{
|
||||
auto load_sym = [](void* handle, char const* name) {
|
||||
void* ret = dllGetSym(handle, name);
|
||||
std::string loadError = "Fail to load symbol " + std::string(name) + " from the cudnn library.";
|
||||
PLUGIN_VALIDATE(ret != nullptr, loadError.c_str());
|
||||
return ret;
|
||||
};
|
||||
|
||||
*reinterpret_cast<void**>(&_cudnnCreate) = load_sym(mLibrary, "cudnnCreate");
|
||||
*reinterpret_cast<void**>(&_cudnnDestroy) = load_sym(mLibrary, "cudnnDestroy");
|
||||
*reinterpret_cast<void**>(&_cudnnCreateTensorDescriptor) = load_sym(mLibrary, "cudnnCreateTensorDescriptor");
|
||||
*reinterpret_cast<void**>(&_cudnnDestroyTensorDescriptor) = load_sym(mLibrary, "cudnnDestroyTensorDescriptor");
|
||||
*reinterpret_cast<void**>(&_cudnnSetStream) = load_sym(mLibrary, "cudnnSetStream");
|
||||
*reinterpret_cast<void**>(&_cudnnBatchNormalizationForwardTraining)
|
||||
= load_sym(mLibrary, "cudnnBatchNormalizationForwardTraining");
|
||||
*reinterpret_cast<void**>(&_cudnnSetTensor4dDescriptor) = load_sym(mLibrary, "cudnnSetTensor4dDescriptor");
|
||||
*reinterpret_cast<void**>(&_cudnnSetTensorNdDescriptor) = load_sym(mLibrary, "cudnnSetTensorNdDescriptor");
|
||||
*reinterpret_cast<void**>(&_cudnnSetTensorNdDescriptorEx) = load_sym(mLibrary, "cudnnSetTensorNdDescriptorEx");
|
||||
*reinterpret_cast<void**>(&_cudnnDeriveBNTensorDescriptor) = load_sym(mLibrary, "cudnnDeriveBNTensorDescriptor");
|
||||
*reinterpret_cast<void**>(&_cudnnGetErrorString) = load_sym(mLibrary, "cudnnGetErrorString");
|
||||
|
||||
if (initHandle)
|
||||
{
|
||||
PLUGIN_CUDNNASSERT(cudnnCreate(&mHandle));
|
||||
PLUGIN_VALIDATE(mHandle != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
CudnnWrapper::~CudnnWrapper()
|
||||
{
|
||||
if (mHandle != nullptr)
|
||||
{
|
||||
PLUGIN_CUDNNASSERT(cudnnDestroy(mHandle));
|
||||
mHandle = nullptr;
|
||||
}
|
||||
|
||||
if (mLibrary != nullptr)
|
||||
{
|
||||
dllClose(mLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
void* CudnnWrapper::tryLoadingCudnn(char const* callerPluginName)
|
||||
{
|
||||
#if CUDART_VERSION >= 12070 && CUDNN_MAJOR == 8
|
||||
static constexpr int32_t kSM_BLACKWELL_100 = 100;
|
||||
|
||||
std::string errorMsgCudnnSupport
|
||||
= "At least one plugin (" + std::string(callerPluginName) + ") that requires cuDNN is being used. TensorRT does not provide cuDNN support for Blackwell (compute capability: 10.0) and later architectures. Detected compute capability: " + std::to_string(nvinfer1::plugin::getSmVersion() / 10) + "." + std::to_string(nvinfer1::plugin::getSmVersion() % 10) + ". Please run on a platform with compute capability < 10.0, or use an alternative to " + std::string(callerPluginName) + ".";
|
||||
PLUGIN_VALIDATE(nvinfer1::plugin::getSmVersion() < kSM_BLACKWELL_100, errorMsgCudnnSupport.c_str());
|
||||
#endif // CUDART_VERSION >= 12070 && CUDNN_MAJOR == 8
|
||||
void* cudnnLib = dllOpen(kCUDNN_PLUGIN_LIBNAME.c_str());
|
||||
std::string errorMsg = "Failed to load " + kCUDNN_PLUGIN_LIBNAME + ".";
|
||||
PLUGIN_VALIDATE(cudnnLib != nullptr, errorMsg.c_str());
|
||||
return cudnnLib;
|
||||
}
|
||||
|
||||
cudnnContext* CudnnWrapper::getCudnnHandle()
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
bool CudnnWrapper::isValid() const
|
||||
{
|
||||
return mHandle != nullptr;
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnCreate(cudnnContext** handle)
|
||||
{
|
||||
return (*_cudnnCreate)(handle);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnDestroy(cudnnContext* handle)
|
||||
{
|
||||
return (*_cudnnDestroy)(handle);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnCreateTensorDescriptor(cudnnTensorDescriptor_t* tensorDesc)
|
||||
{
|
||||
return (*_cudnnCreateTensorDescriptor)(tensorDesc);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnDestroyTensorDescriptor(cudnnTensorDescriptor_t tensorDesc)
|
||||
{
|
||||
return (*_cudnnDestroyTensorDescriptor)(tensorDesc);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnSetStream(cudnnHandle_t handle, cudaStream_t streamId)
|
||||
{
|
||||
return (*_cudnnSetStream)(handle, streamId);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnBatchNormalizationForwardTraining(cudnnHandle_t handle, cudnnBatchNormMode_t mode,
|
||||
void const* alpha, void const* beta, cudnnTensorStruct const* xDesc, void const* x, cudnnTensorStruct const* yDesc,
|
||||
void* y, cudnnTensorStruct const* bnScaleBiasMeanVarDesc, void const* bnScale, void const* bnBias,
|
||||
double exponentialAverageFactor, void* resultRunningMean, void* resultRunningVariance, double epsilon,
|
||||
void* resultSaveMean, void* resultSaveInvVariance)
|
||||
{
|
||||
return (*_cudnnBatchNormalizationForwardTraining)(handle, mode, alpha, beta, xDesc, x, yDesc, y,
|
||||
bnScaleBiasMeanVarDesc, bnScale, bnBias, exponentialAverageFactor, resultRunningMean, resultRunningVariance,
|
||||
epsilon, resultSaveMean, resultSaveInvVariance);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnSetTensor4dDescriptor(cudnnTensorDescriptor_t tensorDesc, cudnnTensorFormat_t format,
|
||||
cudnnDataType_t dataType, int n, int c, int h, int w)
|
||||
{
|
||||
return (*_cudnnSetTensor4dDescriptor)(tensorDesc, format, dataType, n, c, h, w);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnSetTensorNdDescriptor(
|
||||
cudnnTensorDescriptor_t tensorDesc, cudnnDataType_t dataType, int nbDims, int const dimA[], int const strideA[])
|
||||
{
|
||||
return (*_cudnnSetTensorNdDescriptor)(tensorDesc, dataType, nbDims, dimA, strideA);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnSetTensorNdDescriptorEx(cudnnTensorDescriptor_t tensorDesc, cudnnTensorFormat_t format,
|
||||
cudnnDataType_t dataType, int nbDims, int const dimA[])
|
||||
{
|
||||
return (*_cudnnSetTensorNdDescriptorEx)(tensorDesc, format, dataType, nbDims, dimA);
|
||||
}
|
||||
|
||||
cudnnStatus_t CudnnWrapper::cudnnDeriveBNTensorDescriptor(
|
||||
cudnnTensorDescriptor_t derivedBnDesc, cudnnTensorStruct const* xDesc, cudnnBatchNormMode_t mode)
|
||||
{
|
||||
return (*_cudnnDeriveBNTensorDescriptor)(derivedBnDesc, xDesc, mode);
|
||||
}
|
||||
|
||||
char const* CudnnWrapper::cudnnGetErrorString(cudnnStatus_t status)
|
||||
{
|
||||
return (*_cudnnGetErrorString)(status);
|
||||
}
|
||||
|
||||
CudnnWrapper& getCudnnWrapper(char const* callerPluginName)
|
||||
{
|
||||
// Initialize a global cublasWrapper instance to be used to call cudnn functions.
|
||||
static CudnnWrapper sGCudnnWrapper{/*initHandle*/ false, callerPluginName};
|
||||
return sGCudnnWrapper;
|
||||
}
|
||||
|
||||
} // namespace nvinfer1::pluginInternal
|
||||
Reference in New Issue
Block a user