diff --git a/CMakeLists.txt b/CMakeLists.txt index 22d02d04..e7c4a169 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,6 @@ set(VERSION "0.6.0") # Set Project Version and Language project(rocpydecode VERSION ${VERSION} LANGUAGES CXX) set(TARGET_NAME rocpydecode) -set(TARGET_NAME_JPEG rocpyjpegdecode) set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE STRING "Include install directory") @@ -149,7 +148,6 @@ set(CMAKE_SKIP_BUILD_RPATH true) # Find dependencies find_package(HIP REQUIRED) find_package(rocdecode 1.0.0 REQUIRED) -find_package(rocjpeg 1.0.0 REQUIRED) find_package(pybind11 REQUIRED) find_package(dlpack REQUIRED) find_package(FFmpeg REQUIRED) @@ -200,17 +198,8 @@ include_directories(src) file(GLOB pyfiles pyRocVideoDecode/*.py pyRocVideoDecode/*.pyi) file(GLOB include src/rocdecode/*.h src/common/*.h ${ROCM_PATH}/share/rocdecode/utils/rocvideodecode/*.h ${ROCM_PATH}/share/rocdecode/utils/ffmpegvideodecode/*.h) file(GLOB sources src/rocdecode/*.cpp src/common/*.cpp ${ROCM_PATH}/share/rocdecode/utils/*.cpp ${ROCM_PATH}/share/rocdecode/utils/rocvideodecode/*.cpp ${ROCM_PATH}/share/rocdecode/utils/ffmpegvideodecode/*.cpp) -# rocJPEG -include_directories(${rocjpeg_INCLUDE_DIR} ${ROCM_PATH}/share/rocjpeg/samples) -set(LINK_LIBRARY_LIST_JPEG ${LINK_LIBRARY_LIST_JPEG} hip::device rocjpeg::rocjpeg) - -file(GLOB pyfiles_jpeg pyRocJpegDecode/*.py pyRocJpegDecode/*.pyi) -file(GLOB include_jpeg src/rocjpeg/*.h src/common/*.h) -file(GLOB sources_jpeg src/rocjpeg/*.cpp src/common/*.cpp) - message("-- ${White}rocPyDecode -- Link Libraries: ${LINK_LIBRARY_LIST}${ColourReset}") -message("-- ${White}rocPyJPEG -- Link Libraries: ${LINK_LIBRARY_LIST_JPEG}${ColourReset}") -message("-- ${White}rocPyDecode/rocPyJPEG -- CMAKE_CXX_FLAGS:${CMAKE_CXX_FLAGS}${ColourReset}") +message("-- ${White}rocPyDecode -- CMAKE_CXX_FLAGS:${CMAKE_CXX_FLAGS}${ColourReset}") # set license information set(CPACK_RPM_PACKAGE_LICENSE "MIT") @@ -221,7 +210,6 @@ install(FILES ${CPACK_RESOURCE_FILE_LICENSE} DESTINATION ${CMAKE_INSTALL_DOCDIR} # Detect Conda Installation execute_process(COMMAND which conda OUTPUT_VARIABLE CONDA_EXECUTABLE OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) set(CONDA_PYTHON_VERSIONS "") - if(CONDA_EXECUTABLE) message(STATUS "Conda detected at: ${CONDA_EXECUTABLE}") @@ -305,28 +293,6 @@ if(NOT PYTHON_EXECUTABLES_LIST STREQUAL "") set(ROCPYDECODE_INSTALLED TRUE) message(STATUS "Building and installing rocPyDecode for ${PYTHON_VERSION}") install(FILES ${NAME_DST_VIDEO} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime) - - - set(TARGET_NAME_JPEG_VERSIONED "${TARGET_NAME_JPEG}.${PYTHON_INDEX}") - #add-rocpyjpegdecode-pybind11-module - pybind11_add_module(${TARGET_NAME_JPEG_VERSIONED} MODULE ${sources_jpeg}) - target_link_libraries(${TARGET_NAME_JPEG_VERSIONED} PRIVATE ${LINK_LIBRARY_LIST_JPEG}) - - #include - target_include_directories(${TARGET_NAME_JPEG_VERSIONED} PRIVATE ${pybind11_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIR}) - foreach(filename ${pyfiles_jpeg}) - get_filename_component(target "${filename}" REALPATH) - #to maintain folder structure - file(RELATIVE_PATH ITEM_PATH_REL ${CMAKE_CURRENT_SOURCE_DIR} ${filename}) - message(STATUS "Copying ${filename} to ${TARGET_NAME_JPEG_VERSIONED}/${ITEM_PATH_REL}") - configure_file("${filename}" "${CMAKE_BINARY_DIR}/${TARGET_NAME_JPEG_VERSIONED}/${ITEM_PATH_REL}" COPYONLY) - endforeach(filename) - set_target_properties(${TARGET_NAME_JPEG_VERSIONED} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_EXTENSION}" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${TARGET_NAME_JPEG}/${CMAKE_INSTALL_LIBDIR}") - set(NAME_SRC_JPEG ${CMAKE_BINARY_DIR}/${TARGET_NAME_JPEG}/${CMAKE_INSTALL_LIBDIR}/${PYTHON_MODULE_PREFIX}${TARGET_NAME_JPEG_VERSIONED}${PYTHON_MODULE_EXTENSION}) - set(NAME_DST_JPEG ${CMAKE_BINARY_DIR}/${TARGET_NAME_JPEG}/${CMAKE_INSTALL_LIBDIR}/${PYTHON_MODULE_PREFIX}${TARGET_NAME_JPEG}${PYTHON_MODULE_EXTENSION}) - add_custom_command(TARGET ${TARGET_NAME_JPEG_VERSIONED} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${NAME_SRC_JPEG} ${NAME_DST_JPEG} COMMENT "Renaming shared library after build: ${NAME_SRC_JPEG} -> ${NAME_DST_JPEG}" VERBATIM) - message(STATUS "Building and installing rocpyjpegdecode for ${PYTHON_VERSION}") - install(FILES ${NAME_DST_JPEG} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime) else() message(STATUS "[Python Version DOES NOT EXIST] :${PYTHON_VERSION}") endif() # (EXISTS ${CURRENT_PY_EXECUTABLE}) @@ -345,10 +311,6 @@ endif() #install rocPyDecode API folder -and- samples folder install(DIRECTORY pyRocVideoDecode DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime) install(DIRECTORY samples/rocdecode DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyRocVideoDecode/samples COMPONENT runtime) -#install rocpyjpegdecode API folder -and- samples folder -install(DIRECTORY pyRocJpegDecode DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime) -install(DIRECTORY samples/rocjpeg DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyRocJpegDecode/samples COMPONENT runtime) - # Test - Installed -rocpydecode install(DIRECTORY ${CMAKE_SOURCE_DIR}/tests DESTINATION ${CMAKE_INSTALL_DATADIR}/rocpydecode COMPONENT test) install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/rocpydecode COMPONENT test) @@ -392,9 +354,9 @@ if(DEFINED ENV{ROCM_LIBPATCH_VERSION}) endif() # Set the dependent packages -set(ROCPYDECODE_DEBIAN_PACKAGE_LIST "rocdecode-dev, rocjpeg-dev, libdlpack-dev, python3-dev, python3-pip") +set(ROCPYDECODE_DEBIAN_PACKAGE_LIST "rocdecode-dev, libdlpack-dev, python3-dev, python3-pip") # TBD: libdlpack-devel not available -set(ROCPYDECODE_RPM_PACKAGE_LIST "rocdecode-devel, rocjpeg-devel, python3-devel, python3-pip") +set(ROCPYDECODE_RPM_PACKAGE_LIST "rocdecode-devel, python3-devel, python3-pip") # '%{?dist}' breaks manual builds on debian systems due to empty Provides execute_process( diff --git a/pyRocJpegDecode/__init__.py b/pyRocJpegDecode/__init__.py deleted file mode 100644 index ee005576..00000000 --- a/pyRocJpegDecode/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. \ No newline at end of file diff --git a/pyRocJpegDecode/decoder.py b/pyRocJpegDecode/decoder.py deleted file mode 100644 index 5f7550bd..00000000 --- a/pyRocJpegDecode/decoder.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -import rocpyjpegdecode as rocpyjpeg -import rocpyjpegdecode.jpegTypes as jpegt - -def initialize_hip(device_id = 0, display_prop = True): - hip = rocpyjpeg.PyRocJpegUtils() - num_devices, ret = hip.init_hip_device(device_id, display_prop) - return num_devices, ret - -class decoder(object): - def __init__( - self, - device_id = 0, - backend = 0, - output_format = jpegt.ROCJPEG_OUTPUT_RGB): - self.device_id = device_id - self.backend = backend - self.output_format = output_format - self.jpegdec = rocpyjpeg.Decoder(self.device_id, self.backend, self.output_format) - - # read image or batch of images - def read(self, jpeg_item_to_decode): - elapsed_time_in_msec, img = self.jpegdec.read(jpeg_item_to_decode) # elapsed_time_in_msec back in milliseconds - return elapsed_time_in_msec, img - - # decode image or batch of images - def decode(self, jpeg_item_to_decode): - elapsed_time_in_msec, img = self.jpegdec.decode(jpeg_item_to_decode) # elapsed_time_in_msec back in milliseconds - return elapsed_time_in_msec, img - - def set_output_image_format(self, output_format): - self.output_format = jpegt.RocJpegOutputFormat(output_format) - self.jpegdec.SetOutputFormat(self.output_format) - return diff --git a/pyRocJpegDecode/types.py b/pyRocJpegDecode/types.py deleted file mode 100644 index ec24c1b8..00000000 --- a/pyRocJpegDecode/types.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# RocJpegChromaSubsampling -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_444 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_440 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_422 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_420 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_411 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_400 -from rocpyjpegdecode.jpegTypes import ROCJPEG_CSS_UNKNOWN - -# RocJpegBackend -from rocpyjpegdecode.jpegTypes import ROCJPEG_BACKEND_HARDWARE -from rocpyjpegdecode.jpegTypes import ROCJPEG_BACKEND_HYBRID - -# RocJpegOutputFormat -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_NATIVE -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_YUV_PLANAR -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_Y -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_RGB -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_RGB_PLANAR -from rocpyjpegdecode.jpegTypes import ROCJPEG_OUTPUT_FORMAT_MAX - -# RocJpegStatus -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_SUCCESS -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_NOT_INITIALIZED -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_INVALID_PARAMETER -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_BAD_JPEG -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_JPEG_NOT_SUPPORTED -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_OUTOF_MEMORY -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_EXECUTION_FAILED -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_ARCH_MISMATCH -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_INTERNAL_ERROR -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_RUNTIME_ERROR -from rocpyjpegdecode.jpegTypes import ROCJPEG_STATUS_NOT_IMPLEMENTED - -from rocpyjpegdecode.jpegTypes import ROCJPEG_MAX_COMPONENT - -_known_types = { - # RocJpegChromaSubsampling - ROCJPEG_CSS_400:("ROCJPEG_CSS_444",ROCJPEG_CSS_444), - ROCJPEG_CSS_411:("ROCJPEG_CSS_440",ROCJPEG_CSS_440), - ROCJPEG_CSS_420:("ROCJPEG_CSS_422",ROCJPEG_CSS_422), - ROCJPEG_CSS_422:("ROCJPEG_CSS_420",ROCJPEG_CSS_420), - ROCJPEG_CSS_440:("ROCJPEG_CSS_411",ROCJPEG_CSS_411), - ROCJPEG_CSS_444:("ROCJPEG_CSS_400",ROCJPEG_CSS_400), - ROCJPEG_CSS_UNKNOWN:("ROCJPEG_CSS_UNKNOWN",ROCJPEG_CSS_UNKNOWN), - - # RocJpegBackend - ROCJPEG_BACKEND_HARDWARE:("ROCJPEG_BACKEND_HARDWARE",ROCJPEG_BACKEND_HARDWARE), - ROCJPEG_BACKEND_HYBRID:("ROCJPEG_BACKEND_HYBRID",ROCJPEG_BACKEND_HYBRID), - - # RocJpegOutputFormat - ROCJPEG_OUTPUT_NATIVE:("ROCJPEG_OUTPUT_NATIVE",ROCJPEG_OUTPUT_NATIVE), - ROCJPEG_OUTPUT_YUV_PLANAR:("ROCJPEG_OUTPUT_YUV_PLANAR",ROCJPEG_OUTPUT_YUV_PLANAR), - ROCJPEG_OUTPUT_Y:("ROCJPEG_OUTPUT_Y",ROCJPEG_OUTPUT_Y), - ROCJPEG_OUTPUT_RGB:("ROCJPEG_OUTPUT_RGB",ROCJPEG_OUTPUT_RGB), - ROCJPEG_OUTPUT_RGB_PLANAR:("ROCJPEG_OUTPUT_RGB_PLANAR",ROCJPEG_OUTPUT_RGB_PLANAR), - ROCJPEG_OUTPUT_FORMAT_MAX:("ROCJPEG_OUTPUT_FORMAT_MAX",ROCJPEG_OUTPUT_FORMAT_MAX), - - # RocJpegStatus - ROCJPEG_STATUS_SUCCESS:("ROCJPEG_STATUS_SUCCESS",ROCJPEG_STATUS_SUCCESS), - ROCJPEG_STATUS_NOT_INITIALIZED:("ROCJPEG_STATUS_NOT_INITIALIZED",ROCJPEG_STATUS_NOT_INITIALIZED), - ROCJPEG_STATUS_INVALID_PARAMETER:("ROCJPEG_STATUS_INVALID_PARAMETER",ROCJPEG_STATUS_INVALID_PARAMETER), - ROCJPEG_STATUS_BAD_JPEG:("ROCJPEG_STATUS_BAD_JPEG",ROCJPEG_STATUS_BAD_JPEG), - ROCJPEG_STATUS_JPEG_NOT_SUPPORTED:("ROCJPEG_STATUS_JPEG_NOT_SUPPORTED",ROCJPEG_STATUS_JPEG_NOT_SUPPORTED), - ROCJPEG_STATUS_OUTOF_MEMORY:("ROCJPEG_STATUS_OUTOF_MEMORY",ROCJPEG_STATUS_OUTOF_MEMORY), - ROCJPEG_STATUS_EXECUTION_FAILED:("ROCJPEG_STATUS_EXECUTION_FAILED",ROCJPEG_STATUS_EXECUTION_FAILED), - ROCJPEG_STATUS_ARCH_MISMATCH:("ROCJPEG_STATUS_ARCH_MISMATCH",ROCJPEG_STATUS_ARCH_MISMATCH), - ROCJPEG_STATUS_INTERNAL_ERROR:("ROCJPEG_STATUS_INTERNAL_ERROR",ROCJPEG_STATUS_INTERNAL_ERROR), - ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED:("ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED",ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED), - ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED:("ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED",ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED), - ROCJPEG_STATUS_RUNTIME_ERROR:("ROCJPEG_STATUS_RUNTIME_ERROR",ROCJPEG_STATUS_RUNTIME_ERROR), - ROCJPEG_STATUS_NOT_IMPLEMENTED:("ROCJPEG_STATUS_NOT_IMPLEMENTED",ROCJPEG_STATUS_NOT_IMPLEMENTED), - - ROCJPEG_MAX_COMPONENT:("ROCJPEG_MAX_COMPONENT",ROCJPEG_MAX_COMPONENT), -} - -def data_type_function(dtype): - if dtype in _known_types: - ret = _known_types[dtype][0] - return ret - else: - raise RuntimeError( - str(dtype) + - " does not correspond to a known type.") \ No newline at end of file diff --git a/rocPyDecode-requirements.py b/rocPyDecode-requirements.py index afc95efa..240f6930 100755 --- a/rocPyDecode-requirements.py +++ b/rocPyDecode-requirements.py @@ -154,7 +154,6 @@ def ERROR_CHECK(waitval): # Debian packages coreDebianPackages = [ 'rocdecode-dev', - 'rocjpeg-dev', 'python3-dev', 'python3-pip', 'python3-pybind11', @@ -165,7 +164,6 @@ def ERROR_CHECK(waitval): # TODO: dlpack package missing in RPM coreRPMPackages = [ 'rocdecode-devel', - 'rocjpeg-devel', 'python3-devel', 'python3-pybind11', 'python3-pip' diff --git a/samples/README.md b/samples/README.md index 064a3d75..d910e86a 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,5 +1,3 @@ # rocPyDecode Samples - [rocPyDecode](./rocdecode/README.md) -- [rocPyJpegDecode](./rocjpeg/README.md) - diff --git a/samples/rocjpeg/README.md b/samples/rocjpeg/README.md deleted file mode 100644 index 781a9800..00000000 --- a/samples/rocjpeg/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# rocPyJpegDecode samples - -## Prerequisites -* [rocJPEG C/C++ Library](https://github.com/ROCm/rocJPEG) -* [rocPyJpegDecode installed](https://github.com/ROCm/rocPyDecode/tree/develop/samples/rocjpeg) -* [DLPack](https://pypi.org/project/dlpack/) - -## jpegdecode.py - -This sample decodes single JPEG images, and optionally saves the decoded images. \ -To run this python sample script, you need to provide input JPEG file full path name, other arguments are optional. - -### Arguments - -The following are full list of arguments that can be passed to the sample. - -```bash --h, --help : Show detail help message and exit --i INPUT, --input INPUT : Input File Path - required --d DEVICE, --device DEVICE : GPU device ID - optional, default - 0 --fmt {3,4}, --output_format {3,4} : Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3 --bk {0,1}, --backend {0,1} : Set backend choice 0:GPU and 1:CPU, Optional, default is 0 --o OUTPUT, --output OUTPUT : Output File Name Path - optional -``` - -## jpegdecodebatched.py - -This sample decodes batch of JPEG images. \ -The user specifies the root folder full path with the -i argument for multiple JPEG images with any number of files and/or subfolders. - -### Arguments - -The following are full list of arguments that can be passed to the sample. - -```bash --h, --help : Show this help message and exit --i INPUT, --input INPUT : Input Files FULL Path - required --b BATCH, --batch BATCH : batch size > 0 process the batch of files with this batch size, if 0 means do not process as batch, optional, default is 2 --fmt {3,4}, --output_format {3,4} : Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3 --bk {0,1}, --backend {0,1} : Set backend choice 0:GPU and 1:CPU, Optional, default is 0 --d DEVICE, --device DEVICE : GPU device ID - optional, default 0 -``` - -## jpegdecodeperf.py - -This sample decodes batch of JPEG images on multiple processes. \ -The user can define the number of parallel jobs to observe performance scaling. \ -The user specifies the root folder full path with the -i argument for multiple JPEG images with any number of files and/or subfolders. \ -This sample distributes the workload on the available GPU devices if more than one was available. - -### Arguments - -The following are full list of arguments that can be passed to the sample. - -```bash --h, --help : Show this help message and exit --i INPUT, --input INPUT : Input Files FULL Path - required --b BATCH, --batch BATCH : batch size > 0 process the batch of files with this batch size, if 0 means do not process as batch, optional, default is 2 --fmt {3,4}, --output_format {3,4} : Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3 --bk {0,1}, --backend {0,1} : Set backend choice 0:GPU and 1:CPU, Optional, default is 0 --d DEVICE, --device DEVICE : GPU device ID - optional, default 0 --t NUM_PROCESS, --num_process NUM_PROCESS : Num of parallel runs - optional, default 4 -``` - -# Samples Notebook - -The following list shows the provided notebooks samples that visually demonstrate the use of rocPyJpegDecode: - -| Notebook File | Description | -|---------------------------|-------------| -| `batch_sample.ipynb` | This sample decodes a batch of multiple JPEG images, passing all the images full path as a list, or loading their data and passes it as a list of memory buffers. | -| `decode_rgb_planar.ipynb` | This sample decodes a JPEG image into 3 planes, red, green and blue, then it views each of those planes as a separate image and combines them in one RGB image in one row. | -| `decode_source.ipynb` | This sample decodes one JPEG image, passing the image full path, or loading its data and passing it as memory buffer, and as a NumPy array. | diff --git a/samples/rocjpeg/batch_sample.ipynb b/samples/rocjpeg/batch_sample.ipynb deleted file mode 100644 index ade4870e..00000000 --- a/samples/rocjpeg/batch_sample.ipynb +++ /dev/null @@ -1,132 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n", - "### rocPyJpegDecode\n", - "##### Copyright © Advanced Micro Devices, Inc., or its affiliates.\n", - "##### SPDX-License-Identifier: MIT License\n", - "#### Python Sample - Batch decode" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This sample decodes a batch of multiple JPEG images, passing all the images full path as a list, or loading their data and pass it as a list of memory buffer(s). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pyRocJpegDecode.decoder as jdec\n", - "import sys" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Load images" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "image_paths = [\"/opt/rocm/share/rocjpeg/images/mug_400.jpg\", \"/opt/rocm/share/rocjpeg/images/mug_420.jpg\", \"/opt/rocm/share/rocjpeg/images/mug_422.jpg\"]\n", - "batch_size = len(image_paths)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create decoder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "device_id = 0\n", - "backend = 0\n", - "\n", - "devices_count, ret = jdec.initialize_hip(device_id)\n", - "if(ret == False):\n", - " print(f\"Device#: {device_id} not found.\")\n", - " sys.exit(1)\n", - "\n", - "decoder = jdec.decoder(device_id, backend)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Decode data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data_list = []\n", - "for p in image_paths:\n", - " with open(p, 'rb') as in_file:\n", - " data = in_file.read()\n", - " data_list.append(data)\n", - " \n", - "dec_time_msec, image_list = decoder.decode(data_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Decode files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "images = decoder.decode(image_paths)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/samples/rocjpeg/decode_rgb_planar.ipynb b/samples/rocjpeg/decode_rgb_planar.ipynb deleted file mode 100644 index e1176bde..00000000 --- a/samples/rocjpeg/decode_rgb_planar.ipynb +++ /dev/null @@ -1,157 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n", - "### rocPyJpegDecode\n", - "##### Copyright © Advanced Micro Devices, Inc., or its affiliates.\n", - "##### SPDX-License-Identifier: MIT License\n", - "#### Python Sample - RGB Planar image" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This sample decodes a JPEG image into 3 planes, red, green and blue, then it views each of those planes as a separate image and combine them in one RGB image in one row." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import pyRocJpegDecode.decoder as jdec\n", - "import pyRocJpegDecode.types as tdec\n", - "from PIL import Image\n", - "from IPython.display import display\n", - "import cv2\n", - "import numpy as np\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def display_rgb_row(tensor_red, tensor_green, tensor_blue):\n", - " def to_uint8_2d(t):\n", - " arr = np.squeeze(t.detach().cpu().numpy())\n", - " return arr.astype(np.uint8)\n", - " def tint_and_resize(arr, channel_index):\n", - " h, w = arr.shape\n", - " resized = cv2.resize(arr, (max(1, w // 16), max(1, h // 16)), interpolation=cv2.INTER_LINEAR)\n", - " out = np.zeros((resized.shape[0], resized.shape[1], 3), dtype=np.uint8)\n", - " out[:, :, channel_index] = resized\n", - " return out\n", - " def rgb_composite(r, g, b):\n", - " rgb = np.stack([r, g, b], axis=-1)\n", - " h, w, _ = rgb.shape\n", - " return cv2.resize(rgb, (max(1, w // 16), max(1, h // 16)), interpolation=cv2.INTER_LINEAR)\n", - " def add_label(img, label):\n", - " labeled = img.copy()\n", - " cv2.putText(labeled, label, (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1, cv2.LINE_AA)\n", - " return labeled\n", - " # Convert tensors and generate tinted images\n", - " r, g, b = map(to_uint8_2d, (tensor_red, tensor_green, tensor_blue))\n", - " red_img, green_img, blue_img, rgb_img = [*map(tint_and_resize, (r, g, b), (0, 1, 2)), rgb_composite(r, g, b)]\n", - " # Add labels to each image\n", - " labels = [\"Red\", \"Green\", \"Blue\", \"RGB\"]\n", - " images = [red_img, green_img, blue_img, rgb_img]\n", - " labeled_images = [add_label(img, lbl) for img, lbl in zip(images, labels)]\n", - " # Combine and display\n", - " combined = np.concatenate(labeled_images, axis=1)\n", - " display(Image.fromarray(combined))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create decoder, Load the image & Set the output format" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "device_id = 0 # change to the appropriate device id\n", - "backend = 0 # 0 for GPU 1 for CPU, change to the appropriate one\n", - "img_full_path = \"/opt/rocm/share/rocjpeg/images/mug_420.jpg\" # change it to the your JPEG image full path on your system \n", - "\n", - "devices_count, ret = jdec.initialize_hip(device_id)\n", - "if(ret == False):\n", - " print(f\"Device#: {device_id} not found.\")\n", - " sys.exit(1)\n", - "\n", - "decoder = jdec.decoder(device_id, backend)\n", - "decoder.set_output_image_format(tdec.ROCJPEG_OUTPUT_RGB_PLANAR) # set the output format to ROCJPEG_OUTPUT_RGB_PLANAR (the default is ROCJPEG_OUTPUT_RGB)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Decode Image as PLANAR RGB" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dec_time_msec, image = decoder.decode(img_full_path)\n", - "\n", - "tensor_red = torch.from_numpy(image.to_numpy(0))\n", - "tensor_green = torch.from_numpy(image.to_numpy(1))\n", - "tensor_blue = torch.from_numpy(image.to_numpy(2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Display the Image(s), each plane separately and combined" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "display_rgb_row(tensor_red, tensor_green, tensor_blue)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/samples/rocjpeg/decode_source.ipynb b/samples/rocjpeg/decode_source.ipynb deleted file mode 100644 index 65cfa292..00000000 --- a/samples/rocjpeg/decode_source.ipynb +++ /dev/null @@ -1,144 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n", - "### rocPyJpegDecode\n", - "##### Copyright © Advanced Micro Devices, Inc., or its affiliates.\n", - "##### SPDX-License-Identifier: MIT License\n", - "#### Python Sample - Single file, data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This sample decodes one JPEG images, passing the image full path, or loading its data and pass it as memory buffer, and as a numpy array." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import pyRocJpegDecode.decoder as jdec\n", - "from PIL import Image\n", - "from IPython.display import display\n", - "import cv2\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def display_tensor(tensor):\n", - " arr = tensor.cpu().numpy()\n", - " small_arr = cv2.resize(arr, (arr.shape[1] // 8, arr.shape[0] // 8), interpolation=cv2.INTER_LINEAR)\n", - " img_resized = Image.fromarray(small_arr)\n", - " display(img_resized)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using the rocPyJpeg **`read`** API to read and decode from a file path:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "device_id = 0 # change to the appropriate device id\n", - "backend = 0 # 0 for GPU 1 for CPU, change to the appropriate one\n", - "\n", - "# change it to the JPEG image full path on your system\n", - "# \"/opt/rocm\" the ROCm path might be different on your system\n", - "img_full_path = \"/opt/rocm/share/rocjpeg/images/mug_420.jpg\" \n", - "\n", - "devices_count, ret = jdec.initialize_hip(device_id)\n", - "if(ret == False):\n", - " print(f\"Device#: {device_id} not found.\")\n", - " sys.exit(1)\n", - "\n", - "decoder = jdec.decoder(device_id, backend)\n", - "\n", - "image1 = decoder.read(img_full_path)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tensor1 = torch.from_numpy(image1.to_numpy())\n", - "display_tensor(tensor1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or the rocPyJpeg **`decode`** API to decode from an in-memory encoded stream: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try:\n", - " with open(img_full_path, 'rb') as in_file:\n", - " data = in_file.read()\n", - " if not data:\n", - " raise ValueError(\"File is empty.\")\n", - "except Exception as e:\n", - " print(f\"Failed to read file: {e}\")\n", - "\n", - "dec_time_msec, image2 = decoder.decode(data)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tensor2 = torch.from_numpy(image2.to_numpy())\n", - "display_tensor(tensor2)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/samples/rocjpeg/jpegdecode.py b/samples/rocjpeg/jpegdecode.py deleted file mode 100644 index 178ef92c..00000000 --- a/samples/rocjpeg/jpegdecode.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -import torch -import pyRocJpegDecode.decoder as jdec -import rocpyjpegdecode.jpegTypes as jpegt -import argparse -import os -import sys -from PIL import Image -import numpy as np - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of decoding jpeg image -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def jpeg_decode( - input_file_path, - output_format, - device_id, - backend, - output_file_path): - - # initialize hip - devices_count, ret = jdec.initialize_hip(device_id) - if(ret == False): - print(f"Exiting jpegdecode application, Device#: {device_id} not found.") - sys.exit() - - # create the decode instance - decoder = jdec.decoder(device_id, backend) - decoder.set_output_image_format(output_format) # set the output image to the desired format - - print(f"Image output format set to: {jpegt.RocJpegOutputFormat(output_format)}") - print(f"\nDecoding file: {input_file_path} on Device: {'CPU' if backend else 'GPU'} with Device ID: {device_id}") - - dec_time_msec, img_tensor = decoder.decode(input_file_path) - - print(f"Decoding file: {input_file_path} is complete.\n") - - # example how to save the decoded image as a file - if (output_file_path is not None): - filename = output_file_path.strip() + ".png" - img1 = torch.from_numpy(img_tensor.to_numpy()) - arr = img1.cpu().numpy() - img = Image.fromarray(arr.astype(np.uint8)) - img.save(filename) - print(f"Image saved as: {filename}") - - -if __name__ == "__main__": - - # get passed arguments - parser = argparse.ArgumentParser( - description='Jpeg decode example Arguments') - parser.add_argument( - '-i', - '--input', - type=str, - help='Input File-FULL-Path - required', - required=True) - parser.add_argument( - '-fmt', - '--output_format', - type=int, - choices=[3, 4], - default=3, - help='Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3.', - required=False) - parser.add_argument( - '-bk', - '--backend', - type=int, - choices=[0, 1], - default=0, - help='Set backend choice 0:GPU and 1:CPU, Optional, default is 0', - required=False) - parser.add_argument( - '-d', - '--device', - type=int, - default=0, - help='GPU device ID - optional, default 0', - required=False) - parser.add_argument( - '-o', - '--output', - type=str, - help='Output File Name Path - optional', - required=False) - - try: - args = parser.parse_args() - except BaseException: - sys.exit() - - # get params - input_file_path = args.input - output_format = args.output_format - device_id = args.device - backend = args.backend - output_file_path = args.output - - if not os.path.isfile(input_file_path): # Input must be a file - print("ERROR: input passed with -i must be an existing file.") - exit() - - jpeg_decode(input_file_path, output_format, device_id, backend, output_file_path) \ No newline at end of file diff --git a/samples/rocjpeg/jpegdecodebatched.py b/samples/rocjpeg/jpegdecodebatched.py deleted file mode 100644 index 80b836f7..00000000 --- a/samples/rocjpeg/jpegdecodebatched.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -import pyRocJpegDecode.decoder as jdec -import rocpyjpegdecode.jpegTypes as jpegt -import argparse -import os -import sys - - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Example of decoding whole folder and sub-folders containing jpeg images -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def jpeg_decode_batch( - input_file_path, - batch_size, - output_format, - device_id, - backend): - - # initialize hip - print("") - devices_count, ret = jdec.initialize_hip(device_id) - if(ret == False): - print(f"Exiting jpegdecodebatched application, Device#: {device_id} not found.") - sys.exit() - - # create the decoder instance - decoder = jdec.decoder(device_id, backend) - decoder.set_output_image_format(output_format) # set the output image to the desired format - - print(f"Decoding whole folder of images: {input_file_path} on Device: {'CPU' if backend else 'GPU'} with Device ID: {device_id}") - - files_full_path_list = [os.path.join(root, f) for root, _, files in os.walk(input_file_path) for f in files] - total = len(files_full_path_list) - total_decode_time_in_milli_sec = 0.0 - total_valid_images_processed = 0 - - print(f"Decoding Starting for {total} files with batch size = {batch_size}.") - for i in range(0, total, batch_size): - current_batch = files_full_path_list[i:i + batch_size] - batch_time_msec, img_list = decoder.decode(current_batch) - total_decode_time_in_milli_sec += batch_time_msec - total_valid_images_processed += len(img_list) - - print(f"Total files processed : {total_valid_images_processed}") - print(f"Total Bad files found : {total-total_valid_images_processed}") - if (total_valid_images_processed > 0): - avg_time_per_image = total_decode_time_in_milli_sec / float(total) - ips = 1000.0 / avg_time_per_image - print("info: Average processing time per image (ms): " + str(round(avg_time_per_image, 3))) - print("info: Average decoded images per sec (Images/Sec): " + str(round(ips, 3)) + "\n") - - -if __name__ == "__main__": - - # get passed arguments - parser = argparse.ArgumentParser( - description='Batch decode example Arguments') - parser.add_argument( - '-i', - '--input', - type=str, - help='Input Files FULL Path - required', - required=True) - parser.add_argument( - '-b', - '--batch', - type=int, - default=2, - help='batch size > 0 process the batch of files with this batch size, if 0 means do not process as batch, optional, default is 2', - required=False) - parser.add_argument( - '-fmt', - '--output_format', - type=int, - choices=[3, 4], - default=3, - help='Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3.', - required=False) - parser.add_argument( - '-bk', - '--backend', - type=int, - choices=[0, 1], - default=0, - help='Set backend choice 0:GPU and 1:CPU, Optional, default is 0', - required=False) - parser.add_argument( - '-d', - '--device', - type=int, - default=0, - help='GPU device ID - optional, default 0', - required=False) - - try: - args = parser.parse_args() - except BaseException: - sys.exit() - - # get params - input_file_path = args.input - batch_size = args.batch - output_format = args.output_format - device_id = args.device - backend = args.backend - - if not isinstance(batch_size, int) or batch_size <= 0: - print(f"Args Error: batch_size must be a positive integer, got {batch_size}\n") - exit() - if not os.path.isdir(input_file_path): - print(f"Args Error: '{input_file_path}' is not a directory.\n") - exit() - if not os.path.exists(input_file_path): # Input file or folder (must exist) - print("ERROR: input folder doesn't exist.") - exit() - - jpeg_decode_batch(input_file_path, batch_size, output_format, device_id, backend) diff --git a/samples/rocjpeg/jpegdecodeperf.py b/samples/rocjpeg/jpegdecodeperf.py deleted file mode 100644 index fbd7f3b8..00000000 --- a/samples/rocjpeg/jpegdecodeperf.py +++ /dev/null @@ -1,200 +0,0 @@ -# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -import pyRocJpegDecode.decoder as jdec -import argparse -import os -import sys -import multiprocessing -from multiprocessing import Process, Value - -# decoding batch of jpeg images -def jpeg_decode_batch_process(files_batch_full_path_list, batch_size, output_format, device_id, backend, imgs_total, bad_images, ips, init_hip): - - # each process on diff GPU device - if(init_hip): - _, ret = jdec.initialize_hip(device_id, False) - if(ret == False): - print(f"Exiting, Device#: {device_id} not found.") - sys.exit() - - # create the decoder instance - decoder = jdec.decoder(device_id, backend) - decoder.set_output_image_format(output_format) - - # init variables/containers - total = len(files_batch_full_path_list) - total_decode_time_in_milli_sec = 0.0 - total_valid_images_processed = 0 - ips.value = 0.0 - - for i in range(0, total, batch_size): - current_batch = files_batch_full_path_list[i:i + batch_size] - batch_time_msec, img_list = decoder.decode(current_batch) # batch_time_msec elapsed time in milliseconds for 'current' batch - total_decode_time_in_milli_sec += batch_time_msec - total_valid_images_processed += len(img_list) - - imgs_total.value = total_valid_images_processed - bad_images.value = total-total_valid_images_processed - - if (total_valid_images_processed > 0): - avg_time_per_image = total_decode_time_in_milli_sec / float(total) - ips.value = 1000.0 / avg_time_per_image - - -if __name__ == "__main__": - - # get passed arguments - parser = argparse.ArgumentParser( - description='Batch decode example Arguments') - parser.add_argument( - '-i', - '--input', - type=str, - help='Input Files FULL Path - required', - required=True) - parser.add_argument( - '-b', - '--batch', - type=int, - default=2, - help='batch size > 0 process the batch of files with this batch size, if 0 means do not process as batch, optional, default is 2', - required=False) - parser.add_argument( - '-fmt', - '--output_format', - type=int, - choices=[3, 4], - default=3, - help='Set output image format: 3 for ROCJPEG_OUTPUT_RGB (interleaved), 4 for ROCJPEG_OUTPUT_RGB_PLANAR. Optional, default is 3.', - required=False) - parser.add_argument( - '-bk', - '--backend', - type=int, - choices=[0, 1], - default=0, - help='Set backend choice 0:GPU and 1:CPU, Optional, default is 0', - required=False) - parser.add_argument( - '-d', - '--device', - type=int, - default=0, - help='GPU device ID - optional, default 0', - required=False) - parser.add_argument( - '-t', - '--num_process', - type=int, - default=4, - help='Num of parallel runs - optional, default 4', - required=False) - - try: - args = parser.parse_args() - except BaseException: - sys.exit() - - # get params - input_file_path = args.input - batch_size = args.batch - output_format = args.output_format - device_id = 0 if args.device <= 0 else args.device - backend = args.backend - num_process = 4 if args.num_process <= 0 else args.num_process - - # parse/process params - if not isinstance(batch_size, int) or batch_size <= 0: - print(f"Args Error: batch_size must be a positive integer, got {batch_size}\n") - exit() - if not os.path.isdir(input_file_path): - print(f"Args Error: '{input_file_path}' is not a directory.\n") - exit() - if not os.path.exists(input_file_path): # Input file or folder (must exist) - print("ERROR: input folder doesn't exist.") - exit() - - # not initializing hip if many GPUs, just get count of devices back - init_hip = False # init hip ONE time here as we have only 1 GPU - devices_count, ret = jdec.initialize_hip(-1) - if(ret == False): - print(f"Exiting jpegdecodeperf application, Device#: {device_id} not found.") - sys.exit() - if(devices_count>1): - init_hip = True # init hip in every process to distribute workload - else: - # init hip ONE time here as we have only 1 GPU - _, ret = jdec.initialize_hip(device_id) - if(ret == False): - print(f"Exiting, Device#: {device_id} not found.") - sys.exit() - - # prepare data collecting containers - print(f"Info: Number of processes: {num_process}") - total_ips = 0.0 - total_images = 0 - total_bad_images = 0 - total_ims = 0.0 - - # processes init - try: - multiprocessing.set_start_method('spawn') - except RuntimeError: - print('ERROR: Could not create processes') - exit() - - # prepare shared containers - images_totals = [Value('i', 0) for _ in range(num_process)] - bad_images_list = [Value('i', 0) for _ in range(num_process)] - ips_list = [Value('f', 0.0) for _ in range(num_process)] - - # device_id list distributed over available devices (for best HW performance):Essam Aly - device_ids = [i % devices_count for i in range(num_process)] - - # Distribute files into num_process lists as equally as possible - all_files_full_path = [os.path.join(root, f) for root, _, files in os.walk(input_file_path) for f in files] - files_batch_full_path_list = [[] for _ in range(num_process)] - for i, filepath in enumerate(all_files_full_path): - files_batch_full_path_list[i % num_process].append(filepath) - - # create count of processes required by args.num_process - processes = [] - for i in range(num_process): - p = Process(target=jpeg_decode_batch_process, args=(files_batch_full_path_list[i], batch_size, output_format, device_ids[i], backend, images_totals[i], bad_images_list[i], ips_list[i], init_hip)) - p.start() - processes.append(p) - - # launch the processes and synchronize collecting its data - for p in processes: - p.join() - - # aggregate results from all processes - total_images = sum(v.value for v in images_totals) - total_bad_images = sum(v.value for v in bad_images_list) - total_ips = sum(v.value for v in ips_list) - - # printout results - print("info: Total decoded images: " + str(total_images)) - print("info: Total bad files found : " + str(total_bad_images)) - print("info: Average processing time per image (ms): " + str(round(1000.0/total_ips, 3))) - print("info: Average decoded images per sec (Images/Sec): " + str(round(total_ips, 3))) - print(f"info: GPU Devices Used: {device_ids}") - print(f"info: Batch Size Used: {batch_size}\n") \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg.cpp b/src/rocjpeg/roc_pyjpeg.cpp deleted file mode 100644 index baa1d4d8..00000000 --- a/src/rocjpeg/roc_pyjpeg.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "roc_pyjpeg.h" -#include "common/roc_pybuffer.h" -#include "roc_pyjpeg_decoder.h" -#include "roc_pyjpeg_codestream.h" -#include "roc_pyjpeg_decode_source.h" -#include "roc_pyjpeg_images.h" - -using namespace std; - -namespace py = pybind11; -using namespace py::literals; - -PYBIND11_MODULE(rocpyjpegdecode, m) { - - m.doc() = "Python bindings for the C++ portions of rocJPEG .."; - - // Types: - py::module types_m = m.def_submodule("jpegTypes"); - types_m.doc() = R"pbdoc( - - rocPyJpegDecode Python API reference - - This is the Python API reference for the AMD ROCm rocJPEG library. - )pbdoc"; - - // current version - // TODO: match version on CMakeLists for future version update - m.attr("__version__") = py::str("0.6.0"); - - types_m.attr("ROCJPEG_MAX_COMPONENT") = ROCJPEG_MAX_COMPONENT; - - // RocJpegChromaSubsampling - py::enum_(types_m, "RocJpegChromaSubsampling") - .value("ROCJPEG_CSS_444",ROCJPEG_CSS_444) - .value("ROCJPEG_CSS_440",ROCJPEG_CSS_440) - .value("ROCJPEG_CSS_422",ROCJPEG_CSS_422) - .value("ROCJPEG_CSS_420",ROCJPEG_CSS_420) - .value("ROCJPEG_CSS_411",ROCJPEG_CSS_411) - .value("ROCJPEG_CSS_400",ROCJPEG_CSS_400) - .value("ROCJPEG_CSS_UNKNOWN",ROCJPEG_CSS_UNKNOWN) - .export_values(); - - // RocJpegBackend - py::enum_(types_m,"RocJpegBackend") - .value("ROCJPEG_BACKEND_HARDWARE",ROCJPEG_BACKEND_HARDWARE) - .value("ROCJPEG_BACKEND_HYBRID",ROCJPEG_BACKEND_HYBRID) - .export_values(); - - // RocJpegOutputFormat - py::enum_(types_m, "RocJpegOutputFormat") - .value("ROCJPEG_OUTPUT_NATIVE",ROCJPEG_OUTPUT_NATIVE) - .value("ROCJPEG_OUTPUT_YUV_PLANAR",ROCJPEG_OUTPUT_YUV_PLANAR) - .value("ROCJPEG_OUTPUT_Y",ROCJPEG_OUTPUT_Y) - .value("ROCJPEG_OUTPUT_RGB",ROCJPEG_OUTPUT_RGB) - .value("ROCJPEG_OUTPUT_RGB_PLANAR",ROCJPEG_OUTPUT_RGB_PLANAR) - .value("ROCJPEG_OUTPUT_FORMAT_MAX",ROCJPEG_OUTPUT_FORMAT_MAX) - .export_values(); - - // RocJpegStatus - py::enum_(types_m, "RocJpegStatus") - .value("ROCJPEG_STATUS_SUCCESS",ROCJPEG_STATUS_SUCCESS) - .value("ROCJPEG_STATUS_NOT_INITIALIZED",ROCJPEG_STATUS_NOT_INITIALIZED) - .value("ROCJPEG_STATUS_INVALID_PARAMETER",ROCJPEG_STATUS_INVALID_PARAMETER) - .value("ROCJPEG_STATUS_BAD_JPEG",ROCJPEG_STATUS_BAD_JPEG) - .value("ROCJPEG_STATUS_JPEG_NOT_SUPPORTED",ROCJPEG_STATUS_JPEG_NOT_SUPPORTED) - .value("ROCJPEG_STATUS_OUTOF_MEMORY",ROCJPEG_STATUS_OUTOF_MEMORY) - .value("ROCJPEG_STATUS_EXECUTION_FAILED",ROCJPEG_STATUS_EXECUTION_FAILED) - .value("ROCJPEG_STATUS_ARCH_MISMATCH",ROCJPEG_STATUS_ARCH_MISMATCH) - .value("ROCJPEG_STATUS_INTERNAL_ERROR",ROCJPEG_STATUS_INTERNAL_ERROR) - .value("ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED",ROCJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED) - .value("ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED",ROCJPEG_STATUS_HW_JPEG_DECODER_NOT_SUPPORTED) - .value("ROCJPEG_STATUS_RUNTIME_ERROR",ROCJPEG_STATUS_RUNTIME_ERROR) - .value("ROCJPEG_STATUS_NOT_IMPLEMENTED",ROCJPEG_STATUS_NOT_IMPLEMENTED) - .export_values(); - - // AMD JPEG Decoder exported classes - Decoder::ExportToPython(m); - CodeStream::ExportToPython(m); - DecodeSource::ExportToPython(m); - BufferInterface::ExportToPython(m); - PyJpegImages::ExportToPython(m); - - // PyJpegUtils for HIP Call - py::class_(m, "PyRocJpegUtils") - .def(py::init<>()) - .def("init_hip_device",&PyRocJpegUtils::InitHipDevice); - -} diff --git a/src/rocjpeg/roc_pyjpeg.h b/src/rocjpeg/roc_pyjpeg.h deleted file mode 100644 index d61a8f87..00000000 --- a/src/rocjpeg/roc_pyjpeg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef PY_ROC_JPEG_PYBIND11_HEADER -#define PY_ROC_JPEG_PYBIND11_HEADER -#pragma once - -#include -#include "rocjpeg/rocjpeg.h" -#include "common/roc_pybuffer.h" - -#include -#include -#include -#include -#include -#include - -namespace py = pybind11; -using namespace py::literals; - - -#endif // PY_ROC_JPEG_PYBIND11_HEADER \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg_codestream.cpp b/src/rocjpeg/roc_pyjpeg_codestream.cpp deleted file mode 100644 index 5ec2b6b9..00000000 --- a/src/rocjpeg/roc_pyjpeg_codestream.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "roc_pyjpeg_decoder.h" -#include "common/roc_pybuffer.h" -#include "roc_pyjpeg_codestream.h" -#include -#include -#include - -using namespace std; - -void CodeStream::ExportToPython(py::module& m) { - py::class_(m, "CodeStream", - R"pbdoc( - Class representing a coded stream of image data. - - This class provides access to image information such as dimensions. - It supports initialization from bytes, numpy arrays, or file path. - )pbdoc") - .def(py::init([](py::bytes bytes) { - return new CodeStream(bytes); - }), - "bytes"_a, - R"pbdoc( - Initialize a CodeStream using bytes as input. - - Args: - bytes: The byte data representing the encoded stream. - )pbdoc") - .def(py::init([](py::array_t arr) { - return new CodeStream(arr); - }), - "array"_a, - R"pbdoc( - Initialize a CodeStream using a numpy array of uint8 as input. - - Args: - array: The numpy array containing the encoded stream. - )pbdoc") - .def(py::init([](const std::filesystem::path& filename) { - return new CodeStream(filename); - }), - "filename"_a, - R"pbdoc( - Initialize a CodeStream using a file path as input. - - Args: - filename: The file path to the encoded stream data. - )pbdoc"); -} - -int CodeStream::ReadFromFile(const std::filesystem::path& filename, std::shared_ptr>& file_data, int& file_size) { - // Open image file in binary mode and go to the end to get file size - std::ifstream input(filename, std::ios::in | std::ios::binary | std::ios::ate); - if (!input.is_open()) { - std::cerr << "ERROR: Cannot open image: " << filename << std::endl; - return EXIT_FAILURE; - } - // Get the size - file_size = static_cast(input.tellg()); - input.seekg(0, std::ios::beg); - // Allocate shared buffer if not already allocated or too small - if (!file_data || file_data->size() < static_cast(file_size)) { - file_data = std::make_shared>(file_size); - } - // Read the file into the buffer - if (!input.read(file_data->data(), file_size)) { - std::cerr << "ERROR: Cannot read from file: " << filename << std::endl; - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - -// Use the dat and its size if valid, otherwise use the file to load the data -int CodeStream::InitializeSingleImage(const std::filesystem::path& filename, const unsigned char* data, int data_size) { - // File sanity check - if(!filename.empty()) { - if(!std::filesystem::exists(filename)) { - std::cerr << "Invalid or missing file: " << filename << std::endl; - return EXIT_FAILURE; - } - } - // Read file data, if no data sent - if (data != nullptr && data_size > 0) { - file_data = std::make_shared>(reinterpret_cast(data), reinterpret_cast(data) + data_size); - } else if(data == nullptr) { - int ret = EXIT_SUCCESS; - if((ret = ReadFromFile(filename, file_data, data_size)) != EXIT_SUCCESS) { - return ret; - } - } - RocJpegStatus rocjpeg_status = ROCJPEG_STATUS_NOT_INITIALIZED; - rocjpeg_status = rocJpegStreamCreate(&stream_handle); - if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "ERROR: Failed to create stream with " << rocJpegGetErrorName(rocjpeg_status) << std::endl; - return EXIT_FAILURE; - } - // Stream Parse - rocjpeg_status = rocJpegStreamParse(reinterpret_cast(file_data->data()), data_size, stream_handle); - if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "ERROR: Failed to parse the input jpeg stream with " << rocJpegGetErrorName(rocjpeg_status) << ": Input File : " << (!filename.empty() ? filename : "") << std::endl; - Release(); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - -void CodeStream::Release() { - if(stream_handle) { - RocJpegStatus rocjpeg_status = rocJpegStreamDestroy(stream_handle); - stream_handle = nullptr; - } -} - -CodeStream::CodeStream(const std::filesystem::path& filename) { - py::gil_scoped_release release; - InitializeSingleImage(filename, nullptr, 0); -} - -CodeStream::CodeStream(const unsigned char* data, size_t length) { - py::gil_scoped_release release; - InitializeSingleImage(static_cast(""), data, length); -} - -CodeStream::CodeStream(py::bytes data) { - data_ref_bytes_ = data; - std::string data_str = static_cast(data_ref_bytes_); // Convert py::bytes to std::string - std::string_view data_view(data_str); - py::gil_scoped_release release; - InitializeSingleImage(static_cast(""), reinterpret_cast(data_view.data()), data_view.size()); -} - -CodeStream::CodeStream(py::array_t arr) { - data_ref_arr_ = arr; - auto data = data_ref_arr_.unchecked<1>(); - py::gil_scoped_release release; - InitializeSingleImage(static_cast(""), data.data(0), data.size()); -} - -CodeStream::CodeStream() { -} - -CodeStream::~CodeStream() { - Release(); -} diff --git a/src/rocjpeg/roc_pyjpeg_codestream.h b/src/rocjpeg/roc_pyjpeg_codestream.h deleted file mode 100644 index b9b7e787..00000000 --- a/src/rocjpeg/roc_pyjpeg_codestream.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef PY_ROC_JPEG_CODE_STREAM_HEADER -#define PY_ROC_JPEG_CODE_STREAM_HEADER - -#pragma once - -#include -#include "common/roc_pybuffer.h" -#include "rocjpeg/rocjpeg.h" - -class CodeStream { - -public: - CodeStream(const std::filesystem::path&); - CodeStream(const unsigned char*, size_t); - CodeStream(py::bytes); - CodeStream(py::array_t); - ~CodeStream(); - CodeStream(); - - static void ExportToPython(py::module& m); - - // 'this' image info - RocJpegStreamHandle stream_handle = nullptr; - std::shared_ptr> file_data; - -private: - py::bytes data_ref_bytes_; - py::array_t data_ref_arr_; - void Release(); - int ReadFromFile(const std::filesystem::path& filename, std::shared_ptr>& file_data, int& file_size); - int InitializeSingleImage(const std::filesystem::path& filename, const unsigned char* data, int data_size); -}; - -#endif // PY_ROC_JPEG_CODE_STREAM_HEADER \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg_decode_source.cpp b/src/rocjpeg/roc_pyjpeg_decode_source.cpp deleted file mode 100644 index e6b37baf..00000000 --- a/src/rocjpeg/roc_pyjpeg_decode_source.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include -#include "roc_pyjpeg_decode_source.h" - -DecodeSource::DecodeSource(const CodeStream* code_stream_ptr) - : code_stream_(std::make_unique(*code_stream_ptr)) // make a copy - , code_stream_ptr_(code_stream_.get()) { -} - -DecodeSource::DecodeSource(std::unique_ptr code_stream) - : code_stream_(std::move(code_stream)) - , code_stream_ptr_(code_stream_.get()) { -} - -const CodeStream* DecodeSource::CodeStreamInstance() const { - return code_stream_ptr_; -} - -DecodeSource::~DecodeSource() { -} - -void DecodeSource::ExportToPython(py::module& m) { - py::class_(m, "DecodeSource", - "Class representing a source for decoding, which includes the image code stream to decode.") - .def(py::init([](const CodeStream* code_stream) { - return new DecodeSource(code_stream); - }), - "Constructor initializing DecodeSource with a code stream of the image to decode.", - "code_stream"_a) - .def(py::init([](const py::array_t arr) { - return new DecodeSource(std::make_unique(arr)); - }), - "Constructor initializing DecodeSource with a numpy array.", - "array"_a) - .def(py::init([](const py::bytes bytes) { - return new DecodeSource(std::make_unique(bytes)); - }), - "Constructor initializing DecodeSource with byte data.", - "bytes"_a) - .def(py::init([](const std::string& filename) { - return new DecodeSource(std::make_unique(std::filesystem::path(filename))); - }), - "Constructor initializing DecodeSource with filename pointing to the file with image.", - "filename"_a) - .def_property_readonly("code_stream", &DecodeSource::CodeStreamInstance, - "Returns the code stream to be decoded into an image."); - py::implicitly_convertible(); - py::implicitly_convertible, DecodeSource>(); - py::implicitly_convertible(); - py::implicitly_convertible(); - py::implicitly_convertible(); -} diff --git a/src/rocjpeg/roc_pyjpeg_decode_source.h b/src/rocjpeg/roc_pyjpeg_decode_source.h deleted file mode 100644 index 8911f224..00000000 --- a/src/rocjpeg/roc_pyjpeg_decode_source.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#pragma once - -#include "roc_pyjpeg_codestream.h" - -namespace py = pybind11; -using namespace py::literals; - -class DecodeSource { - public: - DecodeSource(std::unique_ptr code_stream); - DecodeSource(const CodeStream* code_stream_ptr); - ~DecodeSource(); - - DecodeSource(DecodeSource&&) = default; - DecodeSource& operator=(DecodeSource&&) = default; - - DecodeSource(const DecodeSource&) = delete; - DecodeSource& operator=(DecodeSource const&) = delete; - - const CodeStream* CodeStreamInstance() const; - - static void ExportToPython(py::module& m); - - private: - std::unique_ptr code_stream_; // owned by this instance - const CodeStream* code_stream_ptr_ = nullptr; // externally provided -}; diff --git a/src/rocjpeg/roc_pyjpeg_decoder.cpp b/src/rocjpeg/roc_pyjpeg_decoder.cpp deleted file mode 100644 index ef08f9bc..00000000 --- a/src/rocjpeg/roc_pyjpeg_decoder.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "roc_pyjpeg_decoder.h" -#include "roc_pyjpeg_utils.h" -#include "roc_pyjpeg_codestream.h" -#include "roc_pyjpeg_images.h" - -using namespace std; - -void Decoder::ExportToPython(py::module& m) { - // Decoder Class - py::class_(m, "Decoder", "Decoder for image decoding operations. " - "It provides methods to decode images from various sources such as files or data streams. ") - .def(py::init( - [](int device_id, int backend, RocJpegOutputFormat output_format = ROCJPEG_OUTPUT_RGB) { - return new Decoder(device_id, backend, output_format); - }), - R"pbdoc( - Initialize decoder. - - Args: - device_id: Device id to execute decoding on. - - backend: CPU or GPU backend. - - )pbdoc", - py::arg("device_id") = 0, py::arg("backend") = 0, py::arg("output_format") = ROCJPEG_OUTPUT_RGB) - .def("SetOutputFormat",&Decoder::SetOutputFormat) - .def("read", py::overload_cast(&Decoder::decode), R"pbdoc( - Executes decoding from a filename. - - Args: - path: File path to decode. - - Returns: - rocPyJpeg.Image or None if the image cannot be decoded because of any reason. - )pbdoc", - "path"_a) - .def("read", py::overload_cast&>(&Decoder::decode), - R"pbdoc( - Executes decoding from a batch of file paths. - - Args: - path: List of file paths to decode. - - Returns: - List of decoded rocPyJpeg.Image's. There is None in returned list on positions which could not be decoded. - - )pbdoc", - "paths"_a) - .def("decode", py::overload_cast(&Decoder::decode), R"pbdoc( - Executes decoding of data from a DecodeSource handle (code stream handle). - - Args: - src: decode source object. - - Returns: - rocPyJpeg.Image or None if the image cannot be decoded because of any reason. - - )pbdoc", - "src"_a) - .def("decode", py::overload_cast&>(&Decoder::decode), - R"pbdoc( - Executes decoding from a batch of DecodeSource handles (code stream handle). - - Args: - srcs: List of DecodeSource objects - - Returns: - List of decoded rocPyJpeg.Image's. There is None in returned list on positions which could not be decoded. - )pbdoc", - "srcs"_a); -} - -Decoder::Decoder(int device_id, int backend, RocJpegOutputFormat output_format) { - SetOutputFormat(output_format); // save user choice if sent for output format - m_device_id = device_id; // save user device id - m_backend = RocJpegBackend(backend);// save user backend choice - // create decode obj - PY_CHECK_ROCJPEG(rocJpegCreate(m_backend, m_device_id, &rocjpeg_handle)); - SetFormat(output_format); // init -} - -// receiving single code_stream -std::pair Decoder::decode(DecodeSource* data) { - float elapsed_ms = 0.0; - // keep code stream ptr in class (alive) - assert(data); - // img 'instance' to return - PyJpegImages img; - // get current data/file associated code_stream instance - const CodeStream* c_stream = data->CodeStreamInstance(); - // runtime sanity check - if(!c_stream->stream_handle) { - return {elapsed_ms, img}; // last item is this instance - } - // DECODE one single JPEG image - if( GetImageInfo(c_stream->stream_handle, img) == EXIT_SUCCESS) { - auto start = std::chrono::high_resolution_clock::now(); - RocJpegStatus status = rocJpegDecode(rocjpeg_handle, c_stream->stream_handle, &img.decode_params, &img.output_image); - auto end = std::chrono::high_resolution_clock::now(); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "ERROR: Failed to decode image. Status code: " << status << std::endl; - return {elapsed_ms, img}; - } - // to export to python (use dlpack(GPU MEM) {and numpy host array}) -- GPU Tensor - img.ToDlpackTensor(user_output_format, m_device_id); - elapsed_ms = std::chrono::duration(end - start).count(); - } - return {elapsed_ms, img}; // return one image -} - -// receiving multiple code_streams -std::pair> Decoder::decode(std::vector& decode_source_arg) { - - float elapsed_ms = 0.0; - RocJpegStatus status = ROCJPEG_STATUS_SUCCESS; - int batch_size = decode_source_arg.size(); - int count_of_valid_instances = 0; - std::vector stream_handles; - std::vector decode_params_list; - std::vector destinations; - - // we return a list of images - std::vector images_; - - if(batch_size <= 0) - return {elapsed_ms, images_}; - - // loop the whole list length - Process as one BATCH - for (auto* data : decode_source_arg) { - if (!data) - continue; - // get current data/file associated code_stream instance - const CodeStream* c_stream = data->CodeStreamInstance(); - // runtime sanity check - if(!c_stream->stream_handle) - continue; - // one img 'instance' - PyJpegImages img; - // add to the list for 'rocJpegDecodeBatched()' - if( GetImageInfo(c_stream->stream_handle, img) == EXIT_FAILURE) { - continue; - } - stream_handles.push_back(c_stream->stream_handle); - decode_params_list.push_back(img.decode_params); - destinations.push_back(img.output_image); - count_of_valid_instances++; - images_.push_back(img); - } - - // at least one image - if(count_of_valid_instances > 0) { - // DECODE ALL files/images in the batch one-time - auto start = std::chrono::high_resolution_clock::now(); - status = rocJpegDecodeBatched( rocjpeg_handle, - stream_handles.data(), - count_of_valid_instances, // less or equal to the batch_size - decode_params_list.data(), - destinations.data() - ); - auto end = std::chrono::high_resolution_clock::now(); - elapsed_ms += std::chrono::duration(end - start).count(); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "ERROR: Failed to decode the image batch. Status code: " << status << std::endl; - return {elapsed_ms, images_}; // return the image list - } - // here 'images_' vector carries the count of 'valid' images - // to export to python (use dlpack(GPU MEM) {and numpy host array}) - if (status == ROCJPEG_STATUS_SUCCESS) { - for(int i = 0; i < count_of_valid_instances; i++) { - images_[i].ToDlpackTensor(user_output_format, m_device_id); // GPU Tensor - } - } - } - return {elapsed_ms, images_}; // return the image list -} - -// set the user desired output_format -void Decoder::SetOutputFormat(RocJpegOutputFormat output_format) { - if(output_format != ROCJPEG_OUTPUT_RGB && output_format != ROCJPEG_OUTPUT_RGB_PLANAR) { - std::cerr << "ERROR: Unsupported output format, defaulting to ROCJPEG_OUTPUT_RGB." << std::endl; - user_output_format = ROCJPEG_OUTPUT_RGB; // default - return; - } - user_output_format = output_format; -} - -Decoder::~Decoder() { - // delete/destroy MAIN decode obj - if(rocjpeg_handle != nullptr) { - PY_CHECK_ROCJPEG(rocJpegDestroy(rocjpeg_handle)); - rocjpeg_handle = nullptr; - } -} - -// Get Image Info, Pitch, Sizes, and alloc GPU MEM -int Decoder::GetImageInfo(RocJpegStreamHandle stream_handle, PyJpegImages& img) { - uint8_t num_components = 0; - uint32_t widths[ROCJPEG_MAX_COMPONENT] = {}; - uint32_t heights[ROCJPEG_MAX_COMPONENT] = {}; - uint32_t channel_sizes[ROCJPEG_MAX_COMPONENT] = {}; - // default, reset - img.decode_params.output_format = user_output_format; - // Get the image info - RocJpegStatus rocjpeg_status = rocJpegGetImageInfo(rocjpeg_handle, stream_handle, &num_components, &img.subsampling, widths, heights); - if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "ERROR: Failed to get image info with " << rocJpegGetErrorName(rocjpeg_status) << std::endl; - return EXIT_FAILURE; - } - // Check limits of w/h & subsampling - if (widths[0] < 64 || heights[0] < 64) { - std::cerr << "The image resolution is not supported by VCN Hardware" << std::endl; - return EXIT_FAILURE; - } - if (img.subsampling == ROCJPEG_CSS_411 || img.subsampling == ROCJPEG_CSS_UNKNOWN) { - std::cerr << "The image resolution is not supported by VCN Hardware" << std::endl; - return EXIT_FAILURE; - } - // save the output w/h to the image instance - img.m_width = widths[0]; - img.m_height = heights[0]; - // Get Channel Pitch And Sizes - PyRocJpegUtils rocjpeg_utils; - if (rocjpeg_utils.GetChannelPitchAndSizes(img.decode_params, img.subsampling, widths, heights, img.num_channels, img.output_image, channel_sizes)) { - std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl; - return EXIT_FAILURE; - } - // allocate memory for each channel - hipError_t hip_status = hipSuccess; - for (int i = 0; i < img.num_channels; i++) { - if (img.output_image.channel[i] != nullptr) { - hip_status = hipFree((void *)img.output_image.channel[i]); - if (hip_status != hipSuccess) - return EXIT_FAILURE; - img.output_image.channel[i] = nullptr; - } - hip_status = hipMalloc(&img.output_image.channel[i], channel_sizes[i]); - if (hip_status != hipSuccess) - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg_decoder.h b/src/rocjpeg/roc_pyjpeg_decoder.h deleted file mode 100644 index 1bf53bce..00000000 --- a/src/rocjpeg/roc_pyjpeg_decoder.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef PY_ROC_JPEG_HEADER -#define PY_ROC_JPEG_HEADER -#pragma once - -#include "roc_pyjpeg_utils.h" -#include "roc_pyjpeg_decode_source.h" -#include "roc_pyjpeg_images.h" - -class Decoder { - -public: - Decoder(int device_id, int backend, RocJpegOutputFormat output_format = ROCJPEG_OUTPUT_RGB); - ~Decoder(); - - std::pair decode(DecodeSource* data); - std::pair> decode(std::vector& data_list); - - static void ExportToPython(py::module& m); - - // set output image format - void SetOutputFormat(RocJpegOutputFormat output_format); - - RocJpegOutputFormat GetFormat() {return user_output_format;}; - void SetFormat(RocJpegOutputFormat fmt) { user_output_format = fmt;}; - -private: - int m_device_id; - RocJpegBackend m_backend; - RocJpegHandle rocjpeg_handle; // main session - RocJpegOutputFormat user_output_format; // user can adjust - int GetImageInfo(RocJpegStreamHandle stream_handle, PyJpegImages& img); // finalize the parsing job -}; - -#endif // PY_ROC_JPEG_HEADER \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg_images.cpp b/src/rocjpeg/roc_pyjpeg_images.cpp deleted file mode 100644 index 1696e102..00000000 --- a/src/rocjpeg/roc_pyjpeg_images.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include -#include "rocjpeg/rocjpeg.h" -#include "common/roc_pybuffer.h" -#include "roc_pyjpeg_images.h" -#include "roc_pyjpeg.h" - -namespace py = pybind11; -using namespace py::literals; - -using namespace std; - -#include - -void PyJpegImages::ExportToPython(py::module& m) { - // PyJpegImages - py::class_>(m, "PyJpegImages", py::module_local()) - .def(py::init<>()) - .def_readwrite("ext_buf", &PyJpegImages::ext_buf) - .def("to_numpy", &PyJpegImages::to_numpy, py::arg("index") = 0, "Export a given plane as a 'numpy' uint 8 bits array") - // DL Pack Tensor - .def_property_readonly("shapeY", [](std::shared_ptr& self) { - return self->ext_buf[0]->shape(); - }, "Get the shape of the Y plane buffer as an array") - .def_property_readonly("shapeUV", [](std::shared_ptr& self) { - return self->ext_buf[1]->shape(); - }, "Get the shape of the U plane buffer as an array") - .def_property_readonly("shapeU", [](std::shared_ptr& self) { - return self->ext_buf[1]->shape(); - }, "Get the shape of the U plane buffer as an array") - .def_property_readonly("shapeV", [](std::shared_ptr& self) { - return self->ext_buf[2]->shape(); - }, "Get the shape of the V plane buffer as an array") - .def_property_readonly("shape", [](std::shared_ptr& self) { - return self->ext_buf[0]->shape(); - }, "Get the shape of the buffer as an array") - .def_property_readonly("strides", [](std::shared_ptr& self) { - return self->ext_buf[0]->strides(); - }, "Get the strides of the buffer") - .def_property_readonly("dtype", [](std::shared_ptr& self) { - return self->ext_buf[0]->dtype(); - }, "Get the data type of the buffer") - .def("__dlpack__", [](std::shared_ptr& self, py::object stream) { - return self->ext_buf[0]->dlpack(stream); - }, py::arg("stream") = NULL, "Export the buffer as a DLPack tensor") - .def("__dlpack_device__", [](std::shared_ptr& self) { - return py::make_tuple(py::int_(static_cast(DLDeviceType::kDLROCM)), py::int_(static_cast(0))); - }, "Get the device associated with the buffer") - .def_readwrite("height", &PyJpegImages::m_height, - R"pbdoc( - The vertical dimension of the entire image in pixels. - )pbdoc") - .def_readwrite("width", &PyJpegImages::m_width, - R"pbdoc( - The horizontal dimension of the entire image in pixels. - )pbdoc"); -} - -py::array_t PyJpegImages::to_numpy(int index) { - py::array_t ret; - if (index < 0 || index >= static_cast(ext_buf.size())) - throw std::out_of_range("Invalid channel index"); - auto& buf = ext_buf[index]; - uint8_t* data_ptr = static_cast(buf->data()); - py::tuple py_shape = buf->shape(); - if (py_shape.size() == 3) { - const ssize_t height = py_shape[0].cast(); - const ssize_t width = py_shape[1].cast(); - const ssize_t channels = py_shape[2].cast(); - std::vector shape = { height, width, channels }; - std::vector strides = { width * channels, channels, 1 }; - ret = py::array_t(shape, strides, data_ptr, py::cast(buf)); - } else if (py_shape.size() == 2) { - const ssize_t height = py_shape[0].cast(); - const ssize_t width = py_shape[1].cast(); - const ssize_t row_stride = buf->strides()[0].cast(); - std::vector shape = { height, width }; - std::vector strides = { row_stride, 1 }; - ret = py::array_t(shape, strides, data_ptr, py::cast(buf)); - } else { - throw std::runtime_error("Unsupported shape: only 2D or 3D supported"); - } - return ret; -} - -bool PyJpegImages::GetOutputDims(std::vector& widths, std::vector& heights, - uint32_t img_width, uint32_t img_height, RocJpegOutputFormat output_format, - RocJpegChromaSubsampling subsampling) { - switch (output_format) { - case ROCJPEG_OUTPUT_NATIVE: - switch (subsampling) { - case ROCJPEG_CSS_444: - widths[2] = widths[1] = widths[0] = img_width; - heights[2] = heights[1] = heights[0] = img_height; - break; - case ROCJPEG_CSS_440: - widths[2] = widths[1] = widths[0] = img_width; - heights[0] = img_height; - heights[2] = heights[1] = img_height >> 1; - break; - case ROCJPEG_CSS_422: - widths[0] = img_width * 2; - heights[0] = img_height; - break; - case ROCJPEG_CSS_420: - widths[1] = widths[0] = img_width; - heights[0] = img_height; - heights[1] = img_height >> 1; - break; - case ROCJPEG_CSS_400: - widths[0] = img_width; - heights[0] = img_height; - break; - default: - std::cout << "Unknown chroma subsampling!" << std::endl; - return false; - } - break; - case ROCJPEG_OUTPUT_YUV_PLANAR: - switch (subsampling) { - case ROCJPEG_CSS_444: - widths[2] = widths[1] = widths[0] = img_width; - heights[2] = heights[1] = heights[0] = img_height; - break; - case ROCJPEG_CSS_440: - widths[2] = widths[1] = widths[0] = img_width; - heights[0] = img_height; - heights[2] = heights[1] = img_height >> 1; - break; - case ROCJPEG_CSS_422: - widths[0] = img_width; - widths[2] = widths[1] = widths[0] >> 1; - heights[2] = heights[1] = heights[0] = img_height; - break; - case ROCJPEG_CSS_420: - widths[0] = img_width; - widths[2] = widths[1] = widths[0] >> 1; - heights[0] = img_height; - heights[2] = heights[1] = img_height >> 1; - break; - case ROCJPEG_CSS_400: - widths[0] = img_width; - heights[0] = img_height; - break; - default: - std::cout << "Unknown chroma subsampling!" << std::endl; - return false; - } - break; - case ROCJPEG_OUTPUT_Y: - widths[0] = img_width; - heights[0] = img_height; - break; - case ROCJPEG_OUTPUT_RGB: - widths[0] = img_width * 3; - heights[0] = img_height; - break; - case ROCJPEG_OUTPUT_RGB_PLANAR: - widths[2] = widths[1] = widths[0] = img_width; - heights[2] = heights[1] = heights[0] = img_height; - break; - default: - std::cout << "Unknown output format!" << std::endl; - return false; - } - return true; -} - -bool PyJpegImages::ToDlpackTensor(RocJpegOutputFormat output_format, int device_id) { - uint32_t img_width = m_width; - uint32_t img_height = m_height; - std::vector widths; - std::vector heights; - widths.resize(ROCJPEG_MAX_COMPONENT); - heights.resize(ROCJPEG_MAX_COMPONENT); - if(GetOutputDims(widths, heights, img_width, img_height, output_format, subsampling) == false) - return false; - uint32_t bit_depth = 8; - std::string type_str(static_cast("|u1")); - switch(output_format) { - case ROCJPEG_OUTPUT_RGB_PLANAR: { // each color plane in a channel separately R[0], G[1], and B[2] - uint32_t surf_stride[3] = {widths[0], widths[1], widths[2]}; // ROCJPEG_OUTPUT_RGB_PLANAR all same width = img_width - for(int i = 0; i < 3; i++) { - std::vector shape{ static_cast(heights[i]), static_cast(widths[i])}; // depend on get_output_dims() - std::vector stride{ static_cast(surf_stride[i]), 1, 0}; - // RGB PLANAR using VCN JPEG decoder @ first, second, and third channel of RocJpegImage - ext_buf[i]->LoadDLPack(shape, stride, bit_depth, type_str, (void *)output_image.channel[i], device_id); // device_id was set/saved at the constructor - } - } - break; - default: - case ROCJPEG_OUTPUT_RGB: { // all the RGB interleaved in one channel [0] - uint32_t surf_stride = widths[0]; // ROCJPEG_OUTPUT_RGB width is * 3 for RGB interleaved - std::vector shape{ static_cast(heights[0]), static_cast(widths[0]/3), 3}; // widths[0]/3 for ROCJPEG_OUTPUT_RGB - std::vector stride{ static_cast(surf_stride), 1, 0}; // python assumes same dim for both shape & strides - // interleaved RGB using VCN JPEG decoder written to first channel of RocJpegImage - ext_buf[0]->LoadDLPack(shape, stride, bit_depth, type_str, (void *)output_image.channel[0], device_id); // device_id was set/saved at the constructor - } - break; - } - return true; -} diff --git a/src/rocjpeg/roc_pyjpeg_images.h b/src/rocjpeg/roc_pyjpeg_images.h deleted file mode 100644 index b993aa10..00000000 --- a/src/rocjpeg/roc_pyjpeg_images.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef PY_ROC_JPEG_IMAGES_HEADER -#define PY_ROC_JPEG_IMAGES_HEADER -#pragma once - -#include -#include "rocjpeg/rocjpeg.h" -#include "common/roc_pybuffer.h" -#include "roc_pyjpeg_codestream.h" - -// TODO: need to implement a case for YUV to add to the RGB and RGB-Planar - -class PyJpegImages { - -public: - PyJpegImages() { - // init GPU mem -python access - ext_buf.push_back(std::make_shared()); - ext_buf.push_back(std::make_shared()); - ext_buf.push_back(std::make_shared()); - // default, reset - memset(&decode_params, 0, sizeof(RocJpegDecodeParams)); - memset(&output_image, 0, sizeof(RocJpegImage)); - num_channels = 0; - subsampling = ROCJPEG_CSS_UNKNOWN; - } - ~PyJpegImages() {}; - - static void ExportToPython(py::module& m); - - // The image in the GPU MEM represented with dlpack via this ext_buf (for external buffer) - std::vector> ext_buf; // external buffer, a view on the GPU MEM of the decoded image - - // public to be accessed by python pybind - int m_width; - int m_height; - py::array_t to_numpy(int index = 0); - RocJpegChromaSubsampling subsampling; - - // not exposed to outside - uint32_t num_channels = 0; - RocJpegImage output_image; - RocJpegDecodeParams decode_params; - bool ToDlpackTensor(RocJpegOutputFormat output_format, int device_id); - -private: - bool GetOutputDims(std::vector& widths, std::vector& heights, uint32_t img_width, uint32_t img_height, RocJpegOutputFormat output_format, RocJpegChromaSubsampling subsampling); -}; - -#endif // PY_ROC_JPEG_IMAGES_HEADER \ No newline at end of file diff --git a/src/rocjpeg/roc_pyjpeg_utils.h b/src/rocjpeg/roc_pyjpeg_utils.h deleted file mode 100644 index eb364a97..00000000 --- a/src/rocjpeg/roc_pyjpeg_utils.h +++ /dev/null @@ -1,253 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef ROC_PY_JPEG_UTILS -#define ROC_PY_JPEG_UTILS -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace fs = std::experimental::filesystem; - -#include -#include "rocjpeg/rocjpeg.h" - -#define PY_CHECK_ROCJPEG(call) { \ - RocJpegStatus rocjpeg_status = (call); \ - if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) { \ - std::cerr << #call << " returned " << rocJpegGetErrorName(rocjpeg_status) << " at " << __FILE__ << ":" << __LINE__ << std::endl;\ - exit(1); \ - } \ -} - -#define PY_CHECK_HIP(call) { \ - hipError_t hip_status = (call); \ - if (hip_status != hipSuccess) { \ - std::cout << "rocJPEG failure: '#" << hip_status << "' at " << __FILE__ << ":" << __LINE__ << std::endl;\ - exit(1); \ - } \ -} - -/** - * @class PyRocJpegUtils - * @brief Utility class for rocPyJpeg. - * - * This class provides utility functions such as getting file paths, initializing HIP device, - * getting chroma subsampling string, getting channel pitch and sizes, getting output file extension, and saving images. - */ -class PyRocJpegUtils { -public: - /** - * @brief Initializes the HIP device. - * - * This function initializes the HIP device with the specified device ID. - * - * @param device_id The device ID. - * @return True if successful, false otherwise. - */ - std::tuple InitHipDevice(int device_id, bool display_prop = true) { - int num_devices; - hipDeviceProp_t hip_dev_prop; - PY_CHECK_HIP(hipGetDeviceCount(&num_devices)); - if (num_devices < 1) { - std::cerr << "ERROR: didn't find any GPU!" << std::endl; - return std::make_tuple(num_devices, false); - } - // if '-' then caller needs only count of devices - if(device_id<0) - return std::make_tuple(num_devices, true); - if (device_id >= num_devices) { - std::cerr << "ERROR: the requested device_id is not found!" << std::endl; - return std::make_tuple(num_devices, false); - } - PY_CHECK_HIP(hipSetDevice(device_id)); - - if(display_prop) { - PY_CHECK_HIP(hipGetDeviceProperties(&hip_dev_prop, device_id)); - std::cout << "Using GPU device " << device_id << ": " << hip_dev_prop.name << "[" << hip_dev_prop.gcnArchName << "] on PCI bus " << - std::setfill('0') << std::setw(2) << std::right << std::hex << hip_dev_prop.pciBusID << ":" << std::setfill('0') << std::setw(2) << - std::right << std::hex << hip_dev_prop.pciDomainID << "." << hip_dev_prop.pciDeviceID << std::dec << std::endl; - } - return std::make_tuple(num_devices, true); - } - /** - * @brief Gets the chroma subsampling string. - * - * This function gets the chroma subsampling string based on the specified subsampling value. - * - * @param subsampling The chroma subsampling value. - * @param chroma_sub_sampling The string to store the chroma subsampling. - */ - void GetChromaSubsamplingStr(RocJpegChromaSubsampling subsampling, std::string &chroma_sub_sampling) { - switch (subsampling) { - case ROCJPEG_CSS_444: - chroma_sub_sampling = "YUV 4:4:4"; - break; - case ROCJPEG_CSS_440: - chroma_sub_sampling = "YUV 4:4:0"; - break; - case ROCJPEG_CSS_422: - chroma_sub_sampling = "YUV 4:2:2"; - break; - case ROCJPEG_CSS_420: - chroma_sub_sampling = "YUV 4:2:0"; - break; - case ROCJPEG_CSS_411: - chroma_sub_sampling = "YUV 4:1:1"; - break; - case ROCJPEG_CSS_400: - chroma_sub_sampling = "YUV 4:0:0"; - break; - case ROCJPEG_CSS_UNKNOWN: - chroma_sub_sampling = "UNKNOWN"; - break; - default: - chroma_sub_sampling = ""; - break; - } - } - - /** - * @brief Gets the channel pitch and sizes. - * - * This function gets the channel pitch and sizes based on the specified output format, chroma subsampling, - * output image, and channel sizes. - * - * @param decode_params The decode parameters that specify the output format and crop rectangle. - * @param subsampling The chroma subsampling. - * @param widths The array to store the channel widths. - * @param heights The array to store the channel heights. - * @param num_channels The number of channels. - * @param output_image The output image. - * @param channel_sizes The array to store the channel sizes. - * @return The channel pitch. - */ - int GetChannelPitchAndSizes(RocJpegDecodeParams decode_params, RocJpegChromaSubsampling subsampling, uint32_t *widths, uint32_t *heights, - uint32_t &num_channels, RocJpegImage &output_image, uint32_t *channel_sizes) { - - bool is_roi_valid = false; - uint32_t roi_width; - uint32_t roi_height; - roi_width = decode_params.crop_rectangle.right - decode_params.crop_rectangle.left; - roi_height = decode_params.crop_rectangle.bottom - decode_params.crop_rectangle.top; - if (roi_width > 0 && roi_height > 0 && roi_width <= widths[0] && roi_height <= heights[0]) { - is_roi_valid = true; - } - switch (decode_params.output_format) { - case ROCJPEG_OUTPUT_NATIVE: - switch (subsampling) { - case ROCJPEG_CSS_444: - num_channels = 3; - output_image.pitch[2] = output_image.pitch[1] = output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[2] = channel_sizes[1] = channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - case ROCJPEG_CSS_440: - num_channels = 3; - output_image.pitch[2] = output_image.pitch[1] = output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - channel_sizes[2] = channel_sizes[1] = align(output_image.pitch[0] * ((is_roi_valid ? roi_height : heights[0]) >> 1), mem_alignment); - break; - case ROCJPEG_CSS_422: - num_channels = 1; - output_image.pitch[0] = (is_roi_valid ? roi_width : widths[0]) * 2; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - case ROCJPEG_CSS_420: - num_channels = 2; - output_image.pitch[1] = output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - channel_sizes[1] = align(output_image.pitch[1] * ((is_roi_valid ? roi_height : heights[0]) >> 1), mem_alignment); - break; - case ROCJPEG_CSS_400: - num_channels = 1; - output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - default: - std::cout << "Unknown chroma subsampling!" << std::endl; - return EXIT_FAILURE; - } - break; - case ROCJPEG_OUTPUT_YUV_PLANAR: - if (subsampling == ROCJPEG_CSS_400) { - num_channels = 1; - output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - } else { - num_channels = 3; - output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - output_image.pitch[1] = is_roi_valid ? roi_width : widths[1]; - output_image.pitch[2] = is_roi_valid ? roi_width : widths[2]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - channel_sizes[1] = align(output_image.pitch[1] * (is_roi_valid ? roi_height : heights[1]), mem_alignment); - channel_sizes[2] = align(output_image.pitch[2] * (is_roi_valid ? roi_height : heights[2]), mem_alignment); - } - break; - case ROCJPEG_OUTPUT_Y: - num_channels = 1; - output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - case ROCJPEG_OUTPUT_RGB: - num_channels = 1; - output_image.pitch[0] = (is_roi_valid ? roi_width : widths[0]) * 3; - channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - case ROCJPEG_OUTPUT_RGB_PLANAR: - num_channels = 3; - output_image.pitch[2] = output_image.pitch[1] = output_image.pitch[0] = is_roi_valid ? roi_width : widths[0]; - channel_sizes[2] = channel_sizes[1] = channel_sizes[0] = align(output_image.pitch[0] * (is_roi_valid ? roi_height : heights[0]), mem_alignment); - break; - default: - std::cout << "Unknown output format!" << std::endl; - return EXIT_FAILURE; - } - return EXIT_SUCCESS; - } - -private: - static const int mem_alignment = 4 * 1024 * 1024; - /** - * @brief Aligns a value to a specified alignment. - * - * This function takes a value and aligns it to the specified alignment. It returns the aligned value. - * - * @param value The value to be aligned. - * @param alignment The alignment value. - * @return The aligned value. - */ - static inline int align(int value, int alignment) { - return (value + alignment - 1) & ~(alignment - 1); - } -}; - -#endif //ROC_PY_JPEG_UTILS \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 814f1f4a..3ad3c528 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -67,15 +67,9 @@ if(EXISTS "${ROCM_PATH}/lib/pyRocVideoDecode") set(VIDEO_DECODE_PYBIND_SCRIPTS ON) message("-- ${White}${PROJECT_NAME}: rocPyDecode found at ${ROCM_PATH}/lib/pyRocVideoDecode${ColourReset}") endif() -set(JPEG_DECODE_PYBIND_SCRIPTS OFF) -if(EXISTS "${ROCM_PATH}/lib/pyRocJpegDecode") - set(JPEG_DECODE_PYBIND_SCRIPTS ON) - message("-- ${White}${PROJECT_NAME}: rocPyJPEG found at ${ROCM_PATH}/lib/pyRocJpegDecode${ColourReset}") -endif() # find requirements find_package(rocdecode 1.0.0 REQUIRED) -find_package(rocjpeg 1.0.0 REQUIRED) set(Python3_FIND_VIRTUALENV FIRST) find_package(Python3 REQUIRED) # rocdecode info @@ -88,23 +82,10 @@ message("-- \t${White}rocdecode_VERSION -- ${rocdecode_VERSION}${ColourReset}") message("-- \t${White}rocdecode_VERSION_MAJOR -- ${rocdecode_VERSION_MAJOR}${ColourReset}") message("-- \t${White}rocdecode_VERSION_MINOR -- ${rocdecode_VERSION_MINOR}${ColourReset}") message("-- \t${White}rocdecode_VERSION_PATCH -- ${rocdecode_VERSION_PATCH}${ColourReset}") -# rocjpeg info -message("-- ${White}${PROJECT_NAME}: rocjpeg found with find_package(rocjpeg REQUIRED)${ColourReset}") -message("-- \t${White}rocjpeg_INCLUDE_DIR -- ${rocjpeg_INCLUDE_DIR}${ColourReset}") -message("-- \t${White}rocjpeg_LIB_DIR -- ${rocjpeg_LIB_DIR}${ColourReset}") -message("-- \t${White}rocjpeg_LIBRARY -- ${rocjpeg_LIBRARY}${ColourReset}") -message("-- \t${White}rocjpeg_FOUND -- ${rocjpeg_FOUND}${ColourReset}") -message("-- \t${White}rocjpeg_VERSION -- ${rocjpeg_VERSION}${ColourReset}") -message("-- \t${White}rocjpeg_VERSION_MAJOR -- ${rocjpeg_VERSION_MAJOR}${ColourReset}") -message("-- \t${White}rocjpeg_VERSION_MINOR -- ${rocjpeg_VERSION_MINOR}${ColourReset}") -message("-- \t${White}rocjpeg_VERSION_PATCH -- ${rocjpeg_VERSION_PATCH}${ColourReset}") if(NOT VIDEO_DECODE_PYBIND_SCRIPTS) message("-- ${Yellow}NOTE: ${PROJECT_NAME} requires the video decode bindings to be built and installed before running CTests${ColourReset}") endif() -if(NOT JPEG_DECODE_PYBIND_SCRIPTS) - message("-- ${Yellow}NOTE: ${PROJECT_NAME} requires the JPEG decode bindings to be built and installed before running CTests${ColourReset}") -endif() # Tests execute_process(COMMAND ${Python3_EXECUTABLE} -c "import torch" RESULT_VARIABLE TORCH_PYTHON_RESULT OUTPUT_QUIET ERROR_QUIET) @@ -211,17 +192,3 @@ add_test(NAME all_other_decoder_apis WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) set_property(TEST all_other_decoder_apis PROPERTY ENVIRONMENT "PYTHONPATH=${ROCM_PATH}/lib:$PYTHONPATH") -# 15 - jpeg_decode_single_file_test -if(TORCH_PYTHON_RESULT EQUAL 0) - add_test(NAME jpeg_decode_python - COMMAND ${Python3_EXECUTABLE} ${ROCM_PATH}/lib/pyRocJpegDecode/samples/rocjpeg/jpegdecode.py - -i ${ROCM_PATH}/share/rocjpeg/images/mug_420.jpg - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_property(TEST jpeg_decode_python PROPERTY ENVIRONMENT "PYTHONPATH=${ROCM_PATH}/lib:$PYTHONPATH") -endif(TORCH_PYTHON_RESULT EQUAL 0) -# 16 - jpegdecodebatched_test -add_test(NAME jpeg_decode_batched_python - COMMAND ${Python3_EXECUTABLE} ${ROCM_PATH}/lib/pyRocJpegDecode/samples/rocjpeg/jpegdecodebatched.py - -i ${ROCM_PATH}/share/rocjpeg/images/ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -set_property(TEST jpeg_decode_batched_python PROPERTY ENVIRONMENT "PYTHONPATH=${ROCM_PATH}/lib:$PYTHONPATH")