mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2026-10-23 21:28:17 +08:00
Add and update samples for cuda 11.0 support
This commit is contained in:
@@ -72,9 +72,9 @@ endif
|
||||
# architecture
|
||||
HOST_ARCH := $(shell uname -m)
|
||||
TARGET_ARCH ?= $(HOST_ARCH)
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86_64 aarch64 ppc64le armv7l))
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86_64 aarch64 sbsa ppc64le armv7l))
|
||||
ifneq ($(TARGET_ARCH),$(HOST_ARCH))
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86_64 aarch64 ppc64le))
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86_64 aarch64 sbsa ppc64le))
|
||||
TARGET_SIZE := 64
|
||||
else ifneq (,$(filter $(TARGET_ARCH),armv7l))
|
||||
TARGET_SIZE := 32
|
||||
@@ -85,8 +85,17 @@ ifneq (,$(filter $(TARGET_ARCH),x86_64 aarch64 ppc64le armv7l))
|
||||
else
|
||||
$(error ERROR - unsupported value $(TARGET_ARCH) for TARGET_ARCH!)
|
||||
endif
|
||||
|
||||
# sbsa and aarch64 systems look similar. Need to differentiate them at host level for now.
|
||||
ifeq ($(HOST_ARCH),aarch64)
|
||||
ifeq ($(CUDA_PATH)/targets/sbsa-linux,$(shell ls -1d $(CUDA_PATH)/targets/sbsa-linux))
|
||||
HOST_ARCH := sbsa
|
||||
TARGET_ARCH := sbsa
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_ARCH),$(HOST_ARCH))
|
||||
ifeq (,$(filter $(HOST_ARCH)-$(TARGET_ARCH),aarch64-armv7l x86_64-armv7l x86_64-aarch64 x86_64-ppc64le))
|
||||
ifeq (,$(filter $(HOST_ARCH)-$(TARGET_ARCH),aarch64-armv7l x86_64-armv7l x86_64-aarch64 x86_64-sbsa x86_64-ppc64le))
|
||||
$(error ERROR - cross compiling from $(HOST_ARCH) to $(TARGET_ARCH) is not supported!)
|
||||
endif
|
||||
endif
|
||||
@@ -141,6 +150,8 @@ else ifneq ($(TARGET_ARCH),$(HOST_ARCH))
|
||||
else ifeq ($(TARGET_OS), android)
|
||||
HOST_COMPILER ?= aarch64-linux-android-clang++
|
||||
endif
|
||||
else ifeq ($(TARGET_ARCH),sbsa)
|
||||
HOST_COMPILER ?= aarch64-linux-gnu-g++
|
||||
else ifeq ($(TARGET_ARCH),ppc64le)
|
||||
HOST_COMPILER ?= powerpc64le-linux-gnu-g++
|
||||
endif
|
||||
@@ -185,19 +196,27 @@ ifneq ($(TARGET_ARCH),$(HOST_ARCH))
|
||||
CCFLAGS += --sysroot=$(TARGET_FS)
|
||||
endif
|
||||
LDFLAGS += --sysroot=$(TARGET_FS)
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/lib -L $(TARGET_FS)/lib
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib -L $(TARGET_FS)/usr/lib
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib/aarch64-linux-gnu -L $(TARGET_FS)/usr/lib/aarch64-linux-gnu
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/lib -L$(TARGET_FS)/lib
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/lib/aarch64-linux-gnu -L$(TARGET_FS)/lib/aarch64-linux-gnu
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib -L$(TARGET_FS)/usr/lib
|
||||
LDFLAGS += -rpath-link=$(TARGET_FS)/usr/lib/aarch64-linux-gnu -L$(TARGET_FS)/usr/lib/aarch64-linux-gnu
|
||||
LDFLAGS += --unresolved-symbols=ignore-in-shared-libs
|
||||
CCFLAGS += -isystem=$(TARGET_FS)/usr/include
|
||||
CCFLAGS += -isystem=$(TARGET_FS)/usr/include/aarch64-linux-gnu
|
||||
CCFLAGS += -isystem=$(TARGET_FS)/usr/include -I$(TARGET_FS)/usr/include
|
||||
CCFLAGS += -isystem=$(TARGET_FS)/usr/include/aarch64-linux-gnu -I$(TARGET_FS)/usr/include/aarch64-linux-gnu
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_ARCH)-$(TARGET_OS),aarch64-qnx)
|
||||
CCFLAGS += -DWIN_INTERFACE_CUSTOM -I/usr/include/aarch64-qnx-gnu
|
||||
LDFLAGS += -lsocket
|
||||
LDFLAGS += -rpath=/usr/lib/aarch64-qnx-gnu -L/usr/lib/aarch64-qnx-gnu
|
||||
ifneq ($(TARGET_FS),)
|
||||
LDFLAGS += -rpath=$(TARGET_FS)/usr/lib -L $(TARGET_FS)/usr/lib
|
||||
LDFLAGS += -rpath=$(TARGET_FS)/usr/libnvidia -L $(TARGET_FS)/usr/libnvidia
|
||||
endif
|
||||
ifdef TARGET_OVERRIDE # cuda toolkit targets override
|
||||
NVCCFLAGS += -target-dir $(TARGET_OVERRIDE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_OS),qnx)
|
||||
CCFLAGS += -DWIN_INTERFACE_CUSTOM
|
||||
LDFLAGS += -lsocket
|
||||
endif
|
||||
|
||||
# Install directory of different arch
|
||||
@@ -206,6 +225,8 @@ ifeq ($(TARGET_ARCH)-$(TARGET_OS),armv7l-linux)
|
||||
CUDA_INSTALL_TARGET_DIR = targets/armv7-linux-gnueabihf/
|
||||
else ifeq ($(TARGET_ARCH)-$(TARGET_OS),aarch64-linux)
|
||||
CUDA_INSTALL_TARGET_DIR = targets/aarch64-linux/
|
||||
else ifeq ($(TARGET_ARCH)-$(TARGET_OS),sbsa-linux)
|
||||
CUDA_INSTALL_TARGET_DIR = targets/sbsa-linux/
|
||||
else ifeq ($(TARGET_ARCH)-$(TARGET_OS),armv7l-android)
|
||||
CUDA_INSTALL_TARGET_DIR = targets/armv7-linux-androideabi/
|
||||
else ifeq ($(TARGET_ARCH)-$(TARGET_OS),aarch64-android)
|
||||
@@ -246,12 +267,6 @@ ifeq ($(TARGET_ARCH),armv7l)
|
||||
SAMPLE_ENABLED := 0
|
||||
endif
|
||||
|
||||
# This sample is not supported on QNX
|
||||
ifeq ($(TARGET_OS),qnx)
|
||||
$(info >>> WARNING - nvJPEG is not supported on QNX - waiving sample <<<)
|
||||
SAMPLE_ENABLED := 0
|
||||
endif
|
||||
|
||||
ALL_LDFLAGS :=
|
||||
ALL_LDFLAGS += $(ALL_CCFLAGS)
|
||||
ALL_LDFLAGS += $(addprefix -Xlinker ,$(LDFLAGS))
|
||||
|
||||
@@ -31,16 +31,6 @@
|
||||
<scope>1:CUDA Basic Topics</scope>
|
||||
<scope>3:JPEG Decoding</scope>
|
||||
</scopes>
|
||||
<sm-arch>sm30</sm-arch>
|
||||
<sm-arch>sm35</sm-arch>
|
||||
<sm-arch>sm37</sm-arch>
|
||||
<sm-arch>sm50</sm-arch>
|
||||
<sm-arch>sm52</sm-arch>
|
||||
<sm-arch>sm60</sm-arch>
|
||||
<sm-arch>sm61</sm-arch>
|
||||
<sm-arch>sm70</sm-arch>
|
||||
<sm-arch>sm72</sm-arch>
|
||||
<sm-arch>sm75</sm-arch>
|
||||
<supported_envs>
|
||||
<env>
|
||||
<arch>x86_64</arch>
|
||||
|
||||
@@ -10,8 +10,6 @@ Image Decoding, NVJPEG Library
|
||||
|
||||
## Supported SM Architectures
|
||||
|
||||
[SM 3.0 ](https://developer.nvidia.com/cuda-gpus) [SM 3.5 ](https://developer.nvidia.com/cuda-gpus) [SM 3.7 ](https://developer.nvidia.com/cuda-gpus) [SM 5.0 ](https://developer.nvidia.com/cuda-gpus) [SM 5.2 ](https://developer.nvidia.com/cuda-gpus) [SM 6.0 ](https://developer.nvidia.com/cuda-gpus) [SM 6.1 ](https://developer.nvidia.com/cuda-gpus) [SM 7.0 ](https://developer.nvidia.com/cuda-gpus) [SM 7.2 ](https://developer.nvidia.com/cuda-gpus) [SM 7.5 ](https://developer.nvidia.com/cuda-gpus)
|
||||
|
||||
## Supported OSes
|
||||
|
||||
Linux, Windows
|
||||
@@ -27,7 +25,7 @@ x86_64, ppc64le, aarch64
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Download and install the [CUDA Toolkit 10.2](https://developer.nvidia.com/cuda-downloads) for your corresponding platform.
|
||||
Download and install the [CUDA Toolkit 11.0](https://developer.nvidia.com/cuda-downloads) for your corresponding platform.
|
||||
Make sure the dependencies mentioned in [Dependencies]() section above are installed.
|
||||
|
||||
## Build and Run
|
||||
|
||||
@@ -36,6 +36,10 @@ int dev_malloc(void **p, size_t s) { return (int)cudaMalloc(p, s); }
|
||||
|
||||
int dev_free(void *p) { return (int)cudaFree(p); }
|
||||
|
||||
int host_malloc(void** p, size_t s, unsigned int f) { return (int)cudaHostAlloc(p, s, f); }
|
||||
|
||||
int host_free(void* p) { return (int)cudaFreeHost(p); }
|
||||
|
||||
typedef std::vector<std::string> FileNames;
|
||||
typedef std::vector<std::vector<char> > FileData;
|
||||
|
||||
@@ -50,6 +54,14 @@ struct decode_params_t {
|
||||
nvjpegHandle_t nvjpeg_handle;
|
||||
cudaStream_t stream;
|
||||
|
||||
// used with decoupled API
|
||||
nvjpegJpegState_t nvjpeg_decoupled_state;
|
||||
nvjpegBufferPinned_t pinned_buffers[2]; // 2 buffers for pipelining
|
||||
nvjpegBufferDevice_t device_buffer;
|
||||
nvjpegJpegStream_t jpeg_streams[2]; // 2 streams for pipelining
|
||||
nvjpegDecodeParams_t nvjpeg_decode_params;
|
||||
nvjpegJpegDecoder_t nvjpeg_decoder;
|
||||
|
||||
nvjpegOutputFormat_t fmt;
|
||||
bool write_decoded;
|
||||
std::string output_dir;
|
||||
@@ -195,6 +207,33 @@ int prepare_buffers(FileData &file_data, std::vector<size_t> &file_len,
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void create_decoupled_api_handles(decode_params_t& params){
|
||||
|
||||
checkCudaErrors(nvjpegDecoderCreate(params.nvjpeg_handle, NVJPEG_BACKEND_DEFAULT, ¶ms.nvjpeg_decoder));
|
||||
checkCudaErrors(nvjpegDecoderStateCreate(params.nvjpeg_handle, params.nvjpeg_decoder, ¶ms.nvjpeg_decoupled_state));
|
||||
|
||||
checkCudaErrors(nvjpegBufferPinnedCreate(params.nvjpeg_handle, NULL, ¶ms.pinned_buffers[0]));
|
||||
checkCudaErrors(nvjpegBufferPinnedCreate(params.nvjpeg_handle, NULL, ¶ms.pinned_buffers[1]));
|
||||
checkCudaErrors(nvjpegBufferDeviceCreate(params.nvjpeg_handle, NULL, ¶ms.device_buffer));
|
||||
|
||||
checkCudaErrors(nvjpegJpegStreamCreate(params.nvjpeg_handle, ¶ms.jpeg_streams[0]));
|
||||
checkCudaErrors(nvjpegJpegStreamCreate(params.nvjpeg_handle, ¶ms.jpeg_streams[1]));
|
||||
|
||||
checkCudaErrors(nvjpegDecodeParamsCreate(params.nvjpeg_handle, ¶ms.nvjpeg_decode_params));
|
||||
}
|
||||
|
||||
void destroy_decoupled_api_handles(decode_params_t& params){
|
||||
|
||||
checkCudaErrors(nvjpegDecodeParamsDestroy(params.nvjpeg_decode_params));
|
||||
checkCudaErrors(nvjpegJpegStreamDestroy(params.jpeg_streams[0]));
|
||||
checkCudaErrors(nvjpegJpegStreamDestroy(params.jpeg_streams[1]));
|
||||
checkCudaErrors(nvjpegBufferPinnedDestroy(params.pinned_buffers[0]));
|
||||
checkCudaErrors(nvjpegBufferPinnedDestroy(params.pinned_buffers[1]));
|
||||
checkCudaErrors(nvjpegBufferDeviceDestroy(params.device_buffer));
|
||||
checkCudaErrors(nvjpegJpegStateDestroy(params.nvjpeg_decoupled_state));
|
||||
checkCudaErrors(nvjpegDecoderDestroy(params.nvjpeg_decoder));
|
||||
}
|
||||
|
||||
void release_buffers(std::vector<nvjpegImage_t> &ibuf) {
|
||||
for (int i = 0; i < ibuf.size(); i++) {
|
||||
for (int c = 0; c < NVJPEG_MAX_COMPONENT; c++)
|
||||
@@ -206,37 +245,52 @@ int decode_images(const FileData &img_data, const std::vector<size_t> &img_len,
|
||||
std::vector<nvjpegImage_t> &out, decode_params_t ¶ms,
|
||||
double &time) {
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
nvjpegStatus_t err;
|
||||
StopWatchInterface *timer = NULL;
|
||||
sdkCreateTimer(&timer);
|
||||
cudaEvent_t startEvent = NULL, stopEvent = NULL;
|
||||
float loopTime = 0;
|
||||
|
||||
checkCudaErrors(cudaEventCreate(&startEvent, cudaEventBlockingSync));
|
||||
checkCudaErrors(cudaEventCreate(&stopEvent, cudaEventBlockingSync));
|
||||
|
||||
if (!params.batched) {
|
||||
if (!params.pipelined) // decode one image at a time
|
||||
{
|
||||
int thread_idx = 0;
|
||||
sdkStartTimer(&timer);
|
||||
checkCudaErrors(cudaEventRecord(startEvent, params.stream));
|
||||
for (int i = 0; i < params.batch_size; i++) {
|
||||
checkCudaErrors(nvjpegDecode(params.nvjpeg_handle, params.nvjpeg_state,
|
||||
(const unsigned char *)img_data[i].data(),
|
||||
img_len[i], params.fmt, &out[i],
|
||||
params.stream));
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
}
|
||||
checkCudaErrors(cudaEventRecord(stopEvent, params.stream));
|
||||
} else {
|
||||
int thread_idx = 0;
|
||||
sdkStartTimer(&timer);
|
||||
// use de-coupled API in pipelined mode
|
||||
checkCudaErrors(cudaEventRecord(startEvent, params.stream));
|
||||
checkCudaErrors(nvjpegStateAttachDeviceBuffer(params.nvjpeg_decoupled_state, params.device_buffer));
|
||||
int buffer_index = 0;
|
||||
checkCudaErrors(nvjpegDecodeParamsSetOutputFormat(params.nvjpeg_decode_params, params.fmt));
|
||||
for (int i = 0; i < params.batch_size; i++) {
|
||||
checkCudaErrors(
|
||||
nvjpegDecodePhaseOne(params.nvjpeg_handle, params.nvjpeg_state,
|
||||
(const unsigned char *)img_data[i].data(),
|
||||
img_len[i], params.fmt, params.stream));
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
checkCudaErrors(nvjpegDecodePhaseTwo(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, params.stream));
|
||||
checkCudaErrors(nvjpegDecodePhaseThree(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, &out[i], params.stream));
|
||||
}
|
||||
checkCudaErrors(
|
||||
nvjpegJpegStreamParse(params.nvjpeg_handle, (const unsigned char *)img_data[i].data(), img_len[i],
|
||||
0, 0, params.jpeg_streams[buffer_index]));
|
||||
|
||||
checkCudaErrors(nvjpegStateAttachPinnedBuffer(params.nvjpeg_decoupled_state,
|
||||
params.pinned_buffers[buffer_index]));
|
||||
|
||||
checkCudaErrors(nvjpegDecodeJpegHost(params.nvjpeg_handle, params.nvjpeg_decoder, params.nvjpeg_decoupled_state,
|
||||
params.nvjpeg_decode_params, params.jpeg_streams[buffer_index]));
|
||||
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
|
||||
checkCudaErrors(nvjpegDecodeJpegTransferToDevice(params.nvjpeg_handle, params.nvjpeg_decoder, params.nvjpeg_decoupled_state,
|
||||
params.jpeg_streams[buffer_index], params.stream));
|
||||
|
||||
buffer_index = 1 - buffer_index; // switch pinned buffer in pipeline mode to avoid an extra sync
|
||||
|
||||
checkCudaErrors(nvjpegDecodeJpegDevice(params.nvjpeg_handle, params.nvjpeg_decoder, params.nvjpeg_decoupled_state,
|
||||
&out[i], params.stream));
|
||||
|
||||
}
|
||||
checkCudaErrors(cudaEventRecord(stopEvent, params.stream));
|
||||
}
|
||||
} else {
|
||||
std::vector<const unsigned char *> raw_inputs;
|
||||
@@ -244,30 +298,16 @@ int decode_images(const FileData &img_data, const std::vector<size_t> &img_len,
|
||||
raw_inputs.push_back((const unsigned char *)img_data[i].data());
|
||||
}
|
||||
|
||||
if (!params.pipelined) // decode multiple images in a single batch
|
||||
{
|
||||
sdkStartTimer(&timer);
|
||||
checkCudaErrors(nvjpegDecodeBatched(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, raw_inputs.data(),
|
||||
img_len.data(), out.data(), params.stream));
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
} else {
|
||||
int thread_idx = 0;
|
||||
for (int i = 0; i < params.batch_size; i++) {
|
||||
checkCudaErrors(nvjpegDecodeBatchedPhaseOne(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, raw_inputs[i],
|
||||
img_len[i], i, thread_idx, params.stream));
|
||||
}
|
||||
checkCudaErrors(nvjpegDecodeBatchedPhaseTwo(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, params.stream));
|
||||
checkCudaErrors(nvjpegDecodeBatchedPhaseThree(params.nvjpeg_handle,
|
||||
params.nvjpeg_state,
|
||||
out.data(), params.stream));
|
||||
checkCudaErrors(cudaStreamSynchronize(params.stream));
|
||||
}
|
||||
checkCudaErrors(cudaEventRecord(startEvent, params.stream));
|
||||
checkCudaErrors(nvjpegDecodeBatched(
|
||||
params.nvjpeg_handle, params.nvjpeg_state, raw_inputs.data(),
|
||||
img_len.data(), out.data(), params.stream));
|
||||
checkCudaErrors(cudaEventRecord(stopEvent, params.stream));
|
||||
|
||||
}
|
||||
sdkStopTimer(&timer);
|
||||
time = sdkGetAverageTimerValue(&timer)/1000.0f;
|
||||
checkCudaErrors(cudaEventSynchronize(stopEvent));
|
||||
checkCudaErrors(cudaEventElapsedTime(&loopTime, startEvent, stopEvent));
|
||||
time = static_cast<double>(loopTime);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -518,14 +558,20 @@ int main(int argc, const char *argv[]) {
|
||||
props.ECCEnabled ? "on" : "off");
|
||||
|
||||
nvjpegDevAllocator_t dev_allocator = {&dev_malloc, &dev_free};
|
||||
checkCudaErrors(nvjpegCreate(NVJPEG_BACKEND_DEFAULT, &dev_allocator,
|
||||
¶ms.nvjpeg_handle));
|
||||
nvjpegPinnedAllocator_t pinned_allocator ={&host_malloc, &host_free};
|
||||
int flags = 0;
|
||||
checkCudaErrors(nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, &dev_allocator,
|
||||
&pinned_allocator,flags, ¶ms.nvjpeg_handle));
|
||||
|
||||
checkCudaErrors(
|
||||
nvjpegJpegStateCreate(params.nvjpeg_handle, ¶ms.nvjpeg_state));
|
||||
checkCudaErrors(
|
||||
nvjpegDecodeBatchedInitialize(params.nvjpeg_handle, params.nvjpeg_state,
|
||||
params.batch_size, 1, params.fmt));
|
||||
|
||||
if(params.pipelined ){
|
||||
create_decoupled_api_handles(params);
|
||||
}
|
||||
// read source images
|
||||
FileNames image_names;
|
||||
readInput(params.input_dir, image_names);
|
||||
@@ -556,6 +602,10 @@ int main(int argc, const char *argv[]) {
|
||||
params.batch_size)
|
||||
<< std::endl;
|
||||
|
||||
if(params.pipelined ){
|
||||
destroy_decoupled_api_handles(params);
|
||||
}
|
||||
|
||||
checkCudaErrors(nvjpegJpegStateDestroy(params.nvjpeg_state));
|
||||
checkCudaErrors(nvjpegDestroy(params.nvjpeg_handle));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user