From 441342b19b6843bde5bb8475f584d4e245f65789 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Thu, 28 Mar 2024 15:37:12 -0700 Subject: [PATCH 01/21] moving all Jupyter notebook examples to a new directory --- .../examples/notebooks/augmentation_examples.ipynb | 0 .../notebooks/classification_training_flowerdataset.ipynb | 0 .../examples/notebooks}/create_classification_flower_dataset.py | 0 .../{image_processing => notebooks}/decoder_examples.ipynb | 2 +- .../examples/notebooks}/resize_implementation.ipynb | 0 .../examples/notebooks}/tf_dataloader.ipynb | 0 .../examples/notebooks/video_decoder.ipynb | 0 .../examples/notebooks/video_reader_with_label.ipynb | 0 8 files changed, 1 insertion(+), 1 deletion(-) rename rocAL_pybind/examples/rocAL_example_doc/Augmentation_examples.ipynb => docs/examples/notebooks/augmentation_examples.ipynb (100%) rename rocAL_pybind/examples/rocAL_example_doc/Classification_training_flowerdataset.ipynb => docs/examples/notebooks/classification_training_flowerdataset.ipynb (100%) rename {rocAL_pybind/examples/rocAL_example_doc => docs/examples/notebooks}/create_classification_flower_dataset.py (100%) rename docs/examples/{image_processing => notebooks}/decoder_examples.ipynb (99%) rename {rocAL_pybind/examples/rocAL_example_doc => docs/examples/notebooks}/resize_implementation.ipynb (100%) rename {rocAL_pybind/examples/rocAL_example_doc => docs/examples/notebooks}/tf_dataloader.ipynb (100%) rename rocAL_pybind/examples/rocAL_example_doc/Video_decoder.ipynb => docs/examples/notebooks/video_decoder.ipynb (100%) rename rocAL_pybind/examples/rocAL_example_doc/VideoReader_with_label.ipynb => docs/examples/notebooks/video_reader_with_label.ipynb (100%) diff --git a/rocAL_pybind/examples/rocAL_example_doc/Augmentation_examples.ipynb b/docs/examples/notebooks/augmentation_examples.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/Augmentation_examples.ipynb rename to docs/examples/notebooks/augmentation_examples.ipynb diff --git a/rocAL_pybind/examples/rocAL_example_doc/Classification_training_flowerdataset.ipynb b/docs/examples/notebooks/classification_training_flowerdataset.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/Classification_training_flowerdataset.ipynb rename to docs/examples/notebooks/classification_training_flowerdataset.ipynb diff --git a/rocAL_pybind/examples/rocAL_example_doc/create_classification_flower_dataset.py b/docs/examples/notebooks/create_classification_flower_dataset.py similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/create_classification_flower_dataset.py rename to docs/examples/notebooks/create_classification_flower_dataset.py diff --git a/docs/examples/image_processing/decoder_examples.ipynb b/docs/examples/notebooks/decoder_examples.ipynb similarity index 99% rename from docs/examples/image_processing/decoder_examples.ipynb rename to docs/examples/notebooks/decoder_examples.ipynb index cb1bef27e..1545f0314 100644 --- a/docs/examples/image_processing/decoder_examples.ipynb +++ b/docs/examples/notebooks/decoder_examples.ipynb @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ diff --git a/rocAL_pybind/examples/rocAL_example_doc/resize_implementation.ipynb b/docs/examples/notebooks/resize_implementation.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/resize_implementation.ipynb rename to docs/examples/notebooks/resize_implementation.ipynb diff --git a/rocAL_pybind/examples/rocAL_example_doc/tf_dataloader.ipynb b/docs/examples/notebooks/tf_dataloader.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/tf_dataloader.ipynb rename to docs/examples/notebooks/tf_dataloader.ipynb diff --git a/rocAL_pybind/examples/rocAL_example_doc/Video_decoder.ipynb b/docs/examples/notebooks/video_decoder.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/Video_decoder.ipynb rename to docs/examples/notebooks/video_decoder.ipynb diff --git a/rocAL_pybind/examples/rocAL_example_doc/VideoReader_with_label.ipynb b/docs/examples/notebooks/video_reader_with_label.ipynb similarity index 100% rename from rocAL_pybind/examples/rocAL_example_doc/VideoReader_with_label.ipynb rename to docs/examples/notebooks/video_reader_with_label.ipynb From 78cc3a4d8c3909182f6139a0e3b7b66452b02abf Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Thu, 28 Mar 2024 15:50:16 -0700 Subject: [PATCH 02/21] move tensorflow pets training example, rename file and update dockerfile and readme for the same --- docker/rocal-on-rhel-09.dockerfile | 2 +- ...buntu-20-with-pytorch-with-mesa.dockerfile | 2 +- docker/rocal-on-ubuntu-20.dockerfile | 2 +- docker/rocal-on-ubuntu-22.dockerfile | 2 +- docker/rocal-with-pytorch.dockerfile | 2 +- docker/rocal-with-tensorflow.dockerfile | 73 +++++++++++++++++++ docs/examples/pytorch/README.md | 7 +- docs/examples/tf/pets_training/README.md | 15 ++++ .../download_and_preprocess_dataset.sh | 0 .../tf/pets_training}/requirements.sh | 0 .../examples/tf/pets_training/train.py | 0 .../examples/tf_petsTrainingExample/README.md | 20 ----- 12 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 docker/rocal-with-tensorflow.dockerfile create mode 100644 docs/examples/tf/pets_training/README.md rename {rocAL_pybind/examples/tf_petsTrainingExample => docs/examples/tf/pets_training}/download_and_preprocess_dataset.sh (100%) rename {rocAL_pybind/examples/tf_petsTrainingExample => docs/examples/tf/pets_training}/requirements.sh (100%) rename rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py => docs/examples/tf/pets_training/train.py (100%) delete mode 100644 rocAL_pybind/examples/tf_petsTrainingExample/README.md diff --git a/docker/rocal-on-rhel-09.dockerfile b/docker/rocal-on-rhel-09.dockerfile index c831c8038..fbfd4a760 100644 --- a/docker/rocal-on-rhel-09.dockerfile +++ b/docker/rocal-on-rhel-09.dockerfile @@ -34,4 +34,4 @@ WORKDIR $ROCAL_WORKSPACE # Install MIVisionX RUN git clone https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX.git && \ - mkdir build && cd build && cmake -DBACKEND=HIP -DROCAL=OFF ../MIVisionX && make -j8 && make install \ No newline at end of file + mkdir build && cd build && cmake -DBACKEND=HIP ../MIVisionX && make -j8 && make install \ No newline at end of file diff --git a/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile b/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile index a8d3ab5ef..0267782c0 100644 --- a/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile +++ b/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile @@ -65,7 +65,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ # install MIVisionX RUN git clone https://github.com/ROCm/MIVisionX.git && cd MIVisionX && \ - mkdir build && cd build && cmake -DBACKEND=HIP -DROCAL=OFF ../ && make -j8 && make install + mkdir build && cd build && cmake -DBACKEND=HIP ../ && make -j8 && make install ENV ROCAL_WORKSPACE=/workspace WORKDIR $ROCAL_WORKSPACE diff --git a/docker/rocal-on-ubuntu-20.dockerfile b/docker/rocal-on-ubuntu-20.dockerfile index 24a25ed47..99af654ef 100644 --- a/docker/rocal-on-ubuntu-20.dockerfile +++ b/docker/rocal-on-ubuntu-20.dockerfile @@ -61,7 +61,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ # install MIVisionX RUN git clone https://github.com/ROCm/MIVisionX.git && cd MIVisionX && \ - mkdir build && cd build && cmake -DBACKEND=HIP -DROCAL=OFF ../ && make -j8 && make install + mkdir build && cd build && cmake -DBACKEND=HIP ../ && make -j8 && make install ENV ROCAL_WORKSPACE=/workspace WORKDIR $ROCAL_WORKSPACE diff --git a/docker/rocal-on-ubuntu-22.dockerfile b/docker/rocal-on-ubuntu-22.dockerfile index a28403457..20f1b010b 100644 --- a/docker/rocal-on-ubuntu-22.dockerfile +++ b/docker/rocal-on-ubuntu-22.dockerfile @@ -64,7 +64,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ # Install MIVisionX RUN git clone https://github.com/ROCm/MIVisionX && cd MIVisionX && \ - mkdir build && cd build && cmake -DBACKEND=HIP -DROCAL=OFF ../ && make -j8 && make install + mkdir build && cd build && cmake -DBACKEND=HIP ../ && make -j8 && make install ENV ROCAL_WORKSPACE=/workspace WORKDIR $ROCAL_WORKSPACE diff --git a/docker/rocal-with-pytorch.dockerfile b/docker/rocal-with-pytorch.dockerfile index f955e9146..aee91ccbf 100644 --- a/docker/rocal-with-pytorch.dockerfile +++ b/docker/rocal-with-pytorch.dockerfile @@ -52,7 +52,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ # install MIVisionX RUN git clone https://github.com/ROCm/MIVisionX.git && cd MIVisionX && \ - mkdir build && cd build && cmake -DBACKEND=HIP -DROCAL=OFF ../ && make -j8 && make install && cd + mkdir build && cd build && cmake -DBACKEND=HIP ../ && make -j8 && make install && cd ENV ROCAL_WORKSPACE=/workspace WORKDIR $ROCAL_WORKSPACE diff --git a/docker/rocal-with-tensorflow.dockerfile b/docker/rocal-with-tensorflow.dockerfile new file mode 100644 index 000000000..3bc795ff6 --- /dev/null +++ b/docker/rocal-with-tensorflow.dockerfile @@ -0,0 +1,73 @@ +ARG TENSORFLOW_VERSION=latest +FROM rocm/tensorflow:${TENSORFLOW_VERSION} + +ENV ROCAL_DEPS_ROOT=/rocAL-deps +WORKDIR $ROCAL_DEPS_ROOT + +RUN apt-get update -y + +# install rocAL base dependencies +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install gcc g++ cmake pkg-config git + +# install OpenCV +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev python-dev python-numpy \ + libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev unzip && \ + mkdir OpenCV && cd OpenCV && wget https://github.com/opencv/opencv/archive/4.6.0.zip && unzip 4.6.0.zip && \ + mkdir build && cd build && cmake -DWITH_GTK=ON -DWITH_JPEG=ON -DBUILD_JPEG=ON -DWITH_OPENCL=OFF ../opencv-4.6.0 && make -j8 && sudo make install && sudo ldconfig && cd + +# install FFMPEG +ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/" +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libsdl2-dev libtool libva-dev \ + libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev \ + nasm yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev && \ + wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n4.4.2.zip && unzip n4.4.2.zip && cd FFmpeg-n4.4.2/ && sudo ldconfig && \ + ./configure --enable-shared --disable-static --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libass --enable-gpl --enable-nonfree && \ + make -j8 && sudo make install && cd + +# install rocAL neural net dependency +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install rocblas rocblas-dev miopen-hip miopen-hip-dev migraphx && \ + mkdir neuralNet && cd neuralNet && wget https://sourceforge.net/projects/half/files/half/1.12.0/half-1.12.0.zip && \ + unzip half-1.12.0.zip -d half-files && sudo mkdir -p /usr/local/include/half && sudo cp half-files/include/half.hpp /usr/local/include/half && cd + +# install rocAL dependency +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install wget libbz2-dev libssl-dev python-dev python3-dev libgflags-dev libgoogle-glog-dev liblmdb-dev nasm yasm libjsoncpp-dev clang && \ + git clone -b 3.0.1 https://github.com/libjpeg-turbo/libjpeg-turbo.git && cd libjpeg-turbo && mkdir build && cd build && \ + cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RELEASE -DENABLE_STATIC=FALSE -DCMAKE_INSTALL_DEFAULT_LIBDIR=lib -DWITH_JPEG8=TRUE ../ && \ + make -j4 && sudo make install && cd && \ + git clone https://github.com/ROCm/rpp.git && cd rpp && mkdir build && cd build && \ + cmake -DBACKEND=HIP ../ && make -j4 && sudo make install && cd ../../ && \ + git clone -b v3.12.4 https://github.com/protocolbuffers/protobuf.git && cd protobuf && git submodule update --init --recursive && \ + ./autogen.sh && ./configure && make -j8 && make check -j8 && sudo make install && sudo ldconfig && cd +ENV CUPY_INSTALL_USE_HIP=1 +ENV ROCM_HOME=/opt/rocm +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g++ hipblas hipsparse rocrand hipfft rocfft rocthrust-dev hipcub-dev python3-dev && \ + git clone https://github.com/Tencent/rapidjson.git && cd rapidjson && mkdir build && cd build && \ + cmake ../ && make -j4 && sudo make install && cd ../../ && \ + pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ + cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ + git clone -b rocm6.1_internal_testing https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ + pip install -e . --no-cache-dir -vvvv + +# install MIVisionX +RUN git clone https://github.com/ROCm/MIVisionX.git && cd MIVisionX && \ + mkdir build && cd build && cmake -DBACKEND=HIP ../ && make -j8 && make install && cd + +ENV ROCAL_WORKSPACE=/workspace +WORKDIR $ROCAL_WORKSPACE + +# Install rocAL +RUN git clone -b develop https://github.com/ROCm/rocAL && \ + mkdir build && cd build && cmake -DPYTHONVERSION=3.9 ../rocAL && make -j8 && cmake --build . --target PyPackageInstall && make install + +WORKDIR /workspace + +#install tensorflow dependencies - Compile protos and Install TensorFlow Object Detection API. +RUN cd ~/models/research/ && \ +protoc object_detection/protos/*.proto --python_out=. && \ +cp object_detection/packages/tf2/setup.py . && \ +python -m pip install . + +#upgrade pip +RUN pip3 install --upgrade pip \ No newline at end of file diff --git a/docs/examples/pytorch/README.md b/docs/examples/pytorch/README.md index 9ae0ded87..277960db9 100644 --- a/docs/examples/pytorch/README.md +++ b/docs/examples/pytorch/README.md @@ -1,7 +1,12 @@ * This example shows how to run training using pytorch and ToyNet with 2 classes * Use a dataset with 2 classes -To run the sample: +### Building the required Pytorch Rocm docker +* Use the instructions in the [docker section](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker) to build the required [Pytorch docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/pytorch) +* Upgrade pip to the latest version. +* Run requirements.sh to install the required packages. + +### To run the sample: * Install rocal_pybind ``` diff --git a/docs/examples/tf/pets_training/README.md b/docs/examples/tf/pets_training/README.md new file mode 100644 index 000000000..f3fc184b3 --- /dev/null +++ b/docs/examples/tf/pets_training/README.md @@ -0,0 +1,15 @@ +## Running Pets Training Example + +### Building the required TF Rocm docker +* Use the instructions in the [docker section](https://github.com/ROCm/rocAL/docker) to build the required [Tensorflow docker](https://github.com/ROCm/rocAL/docker/rocal-with-tensorflow.dockerfile) +* Upgrade pip to the latest version. + +### Running the training + +* For first run, to setup dataset, edit "train.py" and set "DATASET_DOWNLOAD_AND_PREPROCESS = True" +* For subsequent runs, after the dataset has already been downloaded and preprocessed, set "DATASET_DOWNLOAD_AND_PREPROCESS = False" + +To run this example for the first run or subsequent runs, just execute: +``` +python3 train.py +``` diff --git a/rocAL_pybind/examples/tf_petsTrainingExample/download_and_preprocess_dataset.sh b/docs/examples/tf/pets_training/download_and_preprocess_dataset.sh similarity index 100% rename from rocAL_pybind/examples/tf_petsTrainingExample/download_and_preprocess_dataset.sh rename to docs/examples/tf/pets_training/download_and_preprocess_dataset.sh diff --git a/rocAL_pybind/examples/tf_petsTrainingExample/requirements.sh b/docs/examples/tf/pets_training/requirements.sh similarity index 100% rename from rocAL_pybind/examples/tf_petsTrainingExample/requirements.sh rename to docs/examples/tf/pets_training/requirements.sh diff --git a/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py b/docs/examples/tf/pets_training/train.py similarity index 100% rename from rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py rename to docs/examples/tf/pets_training/train.py diff --git a/rocAL_pybind/examples/tf_petsTrainingExample/README.md b/rocAL_pybind/examples/tf_petsTrainingExample/README.md deleted file mode 100644 index b6a19b8da..000000000 --- a/rocAL_pybind/examples/tf_petsTrainingExample/README.md +++ /dev/null @@ -1,20 +0,0 @@ -## Running tf_petsTrainingExample - -### Building the required TF Rocm docker -* Use the instructions in the [docker section](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker) to build the required [Tensorflow docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/tensorflow) -* Upgrade pip to the latest version. - -### Building the required Pytorch Rocm docker -* Use the instructions in the [docker section](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker) to build the required [Pytorch docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/pytorch) -* Upgrade pip to the latest version. -* Run requirements.sh to install the required packages. - -### Running the training - -* For first run, to setup dataset, edit "train_withROCAL_withTFRecordReader.py" and set "DATASET_DOWNLOAD_AND_PREPROCESS = True" -* For subsequent runs, after the dataset has already been downloaded and preprocessed, set "DATASET_DOWNLOAD_AND_PREPROCESS = False" - -To run this example for the first run or subsequent runs, just execute: -``` -python3 train_withROCAL_withTFRecordReader.py -``` From d7a5597565d24644c07f7a9b7390743da5cd96ea Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Thu, 28 Mar 2024 15:54:04 -0700 Subject: [PATCH 03/21] rename toy training example --- .../pytorch/toynet_training/README.md | 15 ++ .../examples/pytorch/toynet_training/train.py | 210 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 docs/examples/pytorch/toynet_training/README.md create mode 100644 docs/examples/pytorch/toynet_training/train.py diff --git a/docs/examples/pytorch/toynet_training/README.md b/docs/examples/pytorch/toynet_training/README.md new file mode 100644 index 000000000..0f0c63c4a --- /dev/null +++ b/docs/examples/pytorch/toynet_training/README.md @@ -0,0 +1,15 @@ +* This example shows how to run training using pytorch and ToyNet with 2 classes +* Use a dataset with 2 classes + +### Building the required Pytorch Rocm docker +* Use the instructions in the [docker section](https://github.com/ROCm/rocAL/docker) to build the required [Pytorch docker](https://github.com/ROCm/rocAL/docker/rocal-with-pytorch.dockerfile) +* Upgrade pip to the latest version. +* Run requirements.sh to install the required packages. + +### To run the sample: +* Install rocal_pybind + +``` +python3 train.py +``` +* rocal device can be cpu/gpu. diff --git a/docs/examples/pytorch/toynet_training/train.py b/docs/examples/pytorch/toynet_training/train.py new file mode 100644 index 000000000..d66ddb628 --- /dev/null +++ b/docs/examples/pytorch/toynet_training/train.py @@ -0,0 +1,210 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc. +# +# 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 sys +from amd.rocal.plugin.pytorch import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import os +import torch.nn as nn +import torch.nn.functional as F +import torch.optim as optim +import torch + +def trainPipeline(data_path, batch_size, num_classes, one_hot, local_rank, world_size, num_thread, crop, rocal_cpu, fp16): + pipe = Pipeline(batch_size=batch_size, num_threads=num_thread, device_id=local_rank, seed=local_rank+10, + rocal_cpu=rocal_cpu, tensor_dtype = types.FLOAT16 if fp16 else types.FLOAT, tensor_layout=types.NCHW, + prefetch_queue_depth = 7) + with pipe: + jpegs, labels = fn.readers.file(file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + rocal_device = 'cpu' if rocal_cpu else 'gpu' + # decode = fn.decoders.image(jpegs, output_type=types.RGB,file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, + file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + res = fn.resize(decode, resize_x=224, resize_y=224) + flip_coin = fn.random.coin_flip(probability=0.5) + cmnp = fn.crop_mirror_normalize(res, device="gpu", + output_dtype=types.FLOAT, + output_layout=types.NCHW, + crop=(crop, crop), + mirror=flip_coin, + image_type=types.RGB, + mean=[0.485 * 255,0.456 * 255,0.406 * 255], + std=[0.229 * 255,0.224 * 255,0.225 * 255]) + if(one_hot): + _ = fn.one_hot(labels, num_classes) + pipe.set_outputs(cmnp) + print('rocal "{0}" variant'.format(rocal_device)) + return pipe + +class trainLoader(): + def __init__(self, data_path, batch_size, num_thread, crop, rocal_cpu): + super(trainLoader, self).__init__() + self.data_path = data_path + self.batch_size = batch_size + self.num_thread = num_thread + self.crop = crop + self.rocal_cpu = rocal_cpu + self.num_classes = 1000 + self.one_hot = 0.0 + self.local_rank = 0 + self.world_size = 1 + self.fp16 = True + + def get_pytorch_train_loader(self): + print("in get_pytorch_train_loader function") + pipe_train = trainPipeline(self.data_path, self.batch_size, self.num_classes, self.one_hot, self.local_rank, + self.world_size, self.num_thread, self.crop, self.rocal_cpu, self.fp16) + pipe_train.build() + train_loader = ROCALClassificationIterator(pipe_train, device="cpu" if self.rocal_cpu else "cuda", device_id = self.local_rank) + if self.rocal_cpu: + return PrefetchedWrapper_rocal(train_loader, self.rocal_cpu) ,len(train_loader) + else: + return train_loader , len(train_loader) + +class PrefetchedWrapper_rocal(object): + def prefetched_loader(loader, rocal_cpu): + + stream = torch.cuda.Stream() + first = True + input = None + target = None + for next_input, next_target in loader: + with torch.cuda.stream(stream): + if rocal_cpu: + next_input = next_input.cuda(non_blocking=True) + next_target = next_target.cuda(non_blocking=True) + + if not first: + yield input, target + else: + first = False + + torch.cuda.current_stream().wait_stream(stream) + input = next_input + target = next_target + + yield input, target + + def __init__(self, dataloader, rocal_cpu): + self.dataloader = dataloader + self.epoch = 0 + self.rocal_cpu = rocal_cpu + + def reset(self): + self.dataloader.reset() + + def __iter__(self): + self.epoch += 1 + return PrefetchedWrapper_rocal.prefetched_loader(self.dataloader, self.rocal_cpu) + +class ToyNet(nn.Module): + def __init__(self,num_classes): + super(ToyNet, self).__init__() + self.conv1 = nn.Conv2d(3, 6, 5) + self.pool = nn.MaxPool2d(2, 2) + self.conv2 = nn.Conv2d(6, 16, 5) + self.conv3 = nn.Conv2d(16, 64, 3) + self.conv4 = nn.Conv2d(64, 256, 3) + self.fc0 = nn.Linear(256 * 11*11, 2048) + self.fc1 = nn.Linear(2048, 512) + self.fc2 = nn.Linear(512, 128) + self.fc3 = nn.Linear(128, num_classes) # Two classes only + self.m = nn.Softmax() + + def forward(self, x): + x = self.pool(F.relu(self.conv1(x))) + x = self.pool(F.relu(self.conv2(x))) + x = self.pool(F.relu(self.conv3(x))) + x = self.pool(F.relu(self.conv4(x))) + x = x.view(-1, 256 * 11 *11) + x = F.relu(self.fc0(x)) + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + x = self.fc3(x) + return x + +def main(): + if len(sys.argv) < 4: + print ('Please pass image_folder cpu/gpu batch_size') + exit(0) + if(sys.argv[2] == "cpu"): + rocal_cpu = True + else: + rocal_cpu = False + bs = int(sys.argv[3]) + nt = 1 + crop_size = 224 + device="cpu" if rocal_cpu else "cuda" + image_path = sys.argv[1] + dataset_train = image_path + '/train' + num_classes = len(next(os.walk(image_path))[1]) + print("num_classes:: ",num_classes) + + net = ToyNet(num_classes) + net.to(device) + + #train loader + train_loader_obj = trainLoader(dataset_train, batch_size=bs, num_thread=nt, crop=crop_size, rocal_cpu=rocal_cpu) + train_loader, train_loader_len = train_loader_obj.get_pytorch_train_loader() + + criterion = nn.CrossEntropyLoss() + optimizer = optim.SGD(net.parameters(), lr=0.0005, momentum=0.9) + + # Training loop + for epoch in range(10): # loop over the dataset multiple times + print("\n epoch:: ",epoch) + running_loss = 0.0 + + for i, (inputs,labels) in enumerate(train_loader, 0): + + sys.stdout.write("\r Mini-batch " + str(i)) + # print("Images",inputs) + # print("Labels",labels) + inputs, labels = inputs.to(device), labels.to(device) + optimizer.zero_grad() + + outputs = net(inputs) + + loss = criterion(outputs, labels) + loss.backward() + optimizer.step() + + # print statistics + running_loss += loss.item() + print_interval = 10 + if i % print_interval == (print_interval-1): + print('[%d, %5d] loss: %.3f' % + (epoch + 1, i + 1, running_loss / print_interval)) + running_loss = 0.0 + train_loader.reset() + + print('Finished Training') + + +if __name__ == '__main__': + main() From acadc8a23cbb1d9708bde324d33ee38e5db2e448 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Thu, 28 Mar 2024 16:34:42 -0700 Subject: [PATCH 04/21] moving all python tests to a separate directory --- tests/cpp_api/CMakeLists.txt | 163 ++++ tests/cpp_api/rocAL_basic_test/CMakeLists.txt | 98 +++ .../rocAL_basic_test/rocal_basic_test.cpp | 219 +++++ tests/cpp_api/rocAL_dataloader/CMakeLists.txt | 98 +++ tests/cpp_api/rocAL_dataloader/README.md | 24 + .../rocAL_dataloader/rocAL_dataloader.cpp | 243 ++++++ .../rocAL_dataloader_mt/CMakeLists.txt | 132 +++ tests/cpp_api/rocAL_dataloader_mt/README.md | 24 + .../rocAL_dataloader_mt.cpp | 257 ++++++ .../rocAL_dataloader_tf/CMakeLists.txt | 75 ++ tests/cpp_api/rocAL_dataloader_tf/README.md | 24 + .../rocAL_dataloader_tf.cpp | 274 ++++++ .../rocAL_external_source/CMakeLists.txt | 73 ++ tests/cpp_api/rocAL_external_source/README.md | 28 + .../rocal_external_source.cpp | 426 +++++++++ .../rocAL_performance_tests/CMakeLists.txt | 98 +++ .../cpp_api/rocAL_performance_tests/README.md | 23 + .../rocAL_performance_tests.cpp | 336 ++++++++ .../CMakeLists.txt | 76 ++ .../README.md | 23 + .../rocAL_performance_tests_with_depth.cpp | 593 +++++++++++++ tests/cpp_api/rocAL_unittests/CMakeLists.txt | 73 ++ tests/cpp_api/rocAL_unittests/README.md | 51 ++ .../pixel_comparison/image_comparison.py | 180 ++++ .../rocAL_unittests/rocAL_unittests.cpp | 814 ++++++++++++++++++ .../cpp_api/rocAL_unittests/testAllScripts.sh | 177 ++++ .../rocAL_video_unittests/CMakeLists.txt | 75 ++ tests/cpp_api/rocAL_video_unittests/README.md | 132 +++ .../rocAL_video_unittests.cpp | 327 +++++++ .../samples/sequence_reader.png | Bin 0 -> 12447 bytes .../samples/sequence_rearrange.png | Bin 0 -> 15552 bytes .../samples/video_reader.png | Bin 0 -> 13369 bytes .../rocAL_video_unittests/testScript.sh | 62 ++ tests/python_api/README.md | 67 ++ tests/python_api/caffe2_reader.py | 129 +++ tests/python_api/caffe_reader.py | 135 +++ tests/python_api/coco_pipeline.py | 231 +++++ tests/python_api/decoder.py | 60 ++ tests/python_api/external_source_reader.py | 279 ++++++ tests/python_api/image_comparison.py | 207 +++++ tests/python_api/parse_config.py | 126 +++ tests/python_api/pipeline.py | 122 +++ .../python_api/prefetch_queue_depth/README.md | 40 + .../prefetch_queue_depth.py | 77 ++ .../pytorch_classification_reader.py | 108 +++ tests/python_api/readers_test_file.sh | 346 ++++++++ tests/python_api/tf_classification_reader.py | 109 +++ tests/python_api/tf_detection_pipeline.py | 161 ++++ tests/python_api/unit_test.py | 533 ++++++++++++ tests/python_api/unit_tests.sh | 165 ++++ tests/python_api/video_pipeline.py | 166 ++++ 51 files changed, 8259 insertions(+) create mode 100644 tests/cpp_api/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_basic_test/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp create mode 100644 tests/cpp_api/rocAL_dataloader/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_dataloader/README.md create mode 100644 tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp create mode 100644 tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_dataloader_mt/README.md create mode 100644 tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp create mode 100644 tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_dataloader_tf/README.md create mode 100644 tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp create mode 100644 tests/cpp_api/rocAL_external_source/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_external_source/README.md create mode 100644 tests/cpp_api/rocAL_external_source/rocal_external_source.cpp create mode 100644 tests/cpp_api/rocAL_performance_tests/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_performance_tests/README.md create mode 100644 tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp create mode 100644 tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_performance_tests_with_depth/README.md create mode 100644 tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp create mode 100644 tests/cpp_api/rocAL_unittests/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_unittests/README.md create mode 100644 tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py create mode 100644 tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp create mode 100755 tests/cpp_api/rocAL_unittests/testAllScripts.sh create mode 100644 tests/cpp_api/rocAL_video_unittests/CMakeLists.txt create mode 100644 tests/cpp_api/rocAL_video_unittests/README.md create mode 100644 tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp create mode 100644 tests/cpp_api/rocAL_video_unittests/samples/sequence_reader.png create mode 100644 tests/cpp_api/rocAL_video_unittests/samples/sequence_rearrange.png create mode 100644 tests/cpp_api/rocAL_video_unittests/samples/video_reader.png create mode 100755 tests/cpp_api/rocAL_video_unittests/testScript.sh create mode 100644 tests/python_api/README.md create mode 100644 tests/python_api/caffe2_reader.py create mode 100644 tests/python_api/caffe_reader.py create mode 100755 tests/python_api/coco_pipeline.py create mode 100644 tests/python_api/decoder.py create mode 100644 tests/python_api/external_source_reader.py create mode 100644 tests/python_api/image_comparison.py create mode 100644 tests/python_api/parse_config.py create mode 100644 tests/python_api/pipeline.py create mode 100644 tests/python_api/prefetch_queue_depth/README.md create mode 100644 tests/python_api/prefetch_queue_depth/prefetch_queue_depth.py create mode 100644 tests/python_api/pytorch_classification_reader.py create mode 100755 tests/python_api/readers_test_file.sh create mode 100644 tests/python_api/tf_classification_reader.py create mode 100644 tests/python_api/tf_detection_pipeline.py create mode 100644 tests/python_api/unit_test.py create mode 100755 tests/python_api/unit_tests.sh create mode 100644 tests/python_api/video_pipeline.py diff --git a/tests/cpp_api/CMakeLists.txt b/tests/cpp_api/CMakeLists.txt new file mode 100644 index 000000000..b41c96906 --- /dev/null +++ b/tests/cpp_api/CMakeLists.txt @@ -0,0 +1,163 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required (VERSION 3.5) + +# rocal_basic_test +add_test( + NAME + rocAL_basic_test_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_basic_test" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_basic_test" + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 +) +add_test(NAME rocAL_basic_test_gpu + COMMAND rocal_basic_test + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) +add_test(NAME rocAL_basic_test_gray + COMMAND rocal_basic_test + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 0 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) +add_test(NAME rocAL_basic_test_rgb + COMMAND rocal_basic_test + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) + +# TBD - rocAL_dataloader unit test options non-functional - NEEDS TO BE ADDED ONCE RESOLVED +#add_test( +# NAME +# rocAL_dataloader +# COMMAND +# "${CMAKE_CTEST_COMMAND}" +# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader" +# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader" +# --build-generator "${CMAKE_GENERATOR}" +# --test-command "rocal_dataloader" +# ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet +#) + +# rocal_dataloader_mt +add_test( + NAME + rocAL_dataloader_mt_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_mt" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_dataloader_mt" + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 0 +) +add_test(NAME rocAL_dataloader_mt_gpu + COMMAND rocal_dataloader_mt + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt) + +# TBD - rocAL_dataloader_tf unit test non-functional +#add_test( +# NAME +# rocAL_dataloader_tf +# COMMAND +# "${CMAKE_CTEST_COMMAND}" +# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_tf" +# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_tf" +# --build-generator "${CMAKE_GENERATOR}" +# --test-command "rocal_dataloader_tf" +# ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet +#) + +# rocal_performance_tests +# TBD - peformance test needs to run with default options +add_test( + NAME + rocAL_performance_tests_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_performance_tests" + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 0 +) +add_test(NAME rocAL_performance_tests_gpu + COMMAND rocal_performance_tests + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests) + +# rocal_performance_tests_with_depth +add_test( + NAME + rocAL_performance_tests_with_depth_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests_with_depth" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_performance_tests_with_depth" + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 0 +) +add_test(NAME rocAL_performance_tests_with_depth_gpu + COMMAND rocal_performance_tests_with_depth + ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth) + +# rocal_unittests +add_test( + NAME + rocAL_unittests_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_unittests" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_unittests" + 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 0 1 +) +add_test(NAME rocAL_unittests_gpu + COMMAND rocal_unittests + 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) +add_test(NAME rocAL_unittests_gray + COMMAND rocal_unittests + 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 0 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) + +# rocal_video_unittests +add_test( + NAME + rocAL_video_unittests + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_video_unittests" + "${CMAKE_CURRENT_BINARY_DIR}/rocAL_video_unittests" + --build-generator "${CMAKE_GENERATOR}" + --test-command "rocal_video_unittests" + ${CMAKE_SOURCE_DIR}/data/videos/AMD_driving_virtual_20.mp4 +) diff --git a/tests/cpp_api/rocAL_basic_test/CMakeLists.txt b/tests/cpp_api/rocAL_basic_test/CMakeLists.txt new file mode 100644 index 000000000..bcb2b7b57 --- /dev/null +++ b/tests/cpp_api/rocAL_basic_test/CMakeLists.txt @@ -0,0 +1,98 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project(rocal_basic_test) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp b/tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp new file mode 100644 index 000000000..a7a91e7ba --- /dev/null +++ b/tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp @@ -0,0 +1,219 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include + +#include "rocal_api.h" +#define TEST_2 + +#include "opencv2/opencv.hpp" +using namespace cv; +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define cvDestroyWindow destroyWindow +#endif +#define DISPLAY 0 +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + std::cout << "Usage: rocal_basic_test decode_width decode_height decode_shard_counts \n"; + return -1; + } + int argIdx = 0; + const char *folderPath1 = argv[++argIdx]; + const char *label_text_file_path = argv[++argIdx]; + int rgb = 1; // process color images + int decode_width = 0; + int decode_height = 0; + int test_case = 0; + bool processing_device = 0; + size_t decode_shard_counts = 1; + + if (argc >= argIdx + MIN_ARG_COUNT) + test_case = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_shard_counts = atoi(argv[++argIdx]); + + int inputBatchSize = 4; + + std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; + + auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor decoded_output; + + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + if (decode_height <= 0 || decode_width <= 0) + decoded_output = rocalJpegFileSource(handle, folderPath1, color_format, decode_shard_counts, false, false); + else + decoded_output = rocalJpegFileSource(handle, folderPath1, color_format, decode_shard_counts, false, false, false, + ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height); + if (strcmp(label_text_file_path, "") == 0) + rocalCreateLabelReader(handle, folderPath1); + else + rocalCreateTextFileBasedLabelReader(handle, label_text_file_path); + rocalCropResizeFixed(handle, decoded_output, 224, 224, true, 0.9, 1.1, 0.1, 0.1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + } + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; + int w = rocalGetOutputWidth(handle); + int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); + std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + + const int total_tests = 4; + int test_id = -1; + int ImageNameLen[inputBatchSize]; + int run_len[] = {2 * inputBatchSize, 4 * inputBatchSize, 1 * inputBatchSize, 50 * inputBatchSize}; + + std::vector names; + names.resize(inputBatchSize); + + while (++test_id < total_tests) { + std::cout << "#### Started test id " << test_id << "\n"; + std::cout << "Available images = " << rocalGetRemainingImages(handle) << std::endl; + int process_image_count = ((test_case == 0) ? rocalGetRemainingImages(handle) : run_len[test_id]); + std::cout << ">>>>> Going to process " << process_image_count << " images , press a key" << std::endl; + if (DISPLAY) + cv::waitKey(0); + const unsigned number_of_cols = process_image_count / inputBatchSize; + cv::Mat mat_output(h, w * number_of_cols, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + auto win_name = "output"; + if (DISPLAY) + cv::namedWindow(win_name, CV_WINDOW_AUTOSIZE); + + int col_counter = 0; + int counter = 0; + + while ((test_case == 0) ? !rocalIsEmpty(handle) : (counter < run_len[test_id])) { + if (rocalRun(handle) != 0) + break; + + rocalCopyToOutput(handle, mat_input.data, h * w * p); + + counter += inputBatchSize; + RocalTensorList labels = rocalGetImageLabels(handle); + + unsigned imagename_size = rocalGetImageNameLen(handle, ImageNameLen); + char imageNames[imagename_size]; + rocalGetImageName(handle, imageNames); + std::string imageNamesStr(imageNames); + + int pos = 0; + int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); + for (int i = 0; i < inputBatchSize; i++) { + names[i] = imageNamesStr.substr(pos, ImageNameLen[i]); + pos += ImageNameLen[i]; + std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - " << std::endl; + } + std::cout << std::endl; + + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + if (DISPLAY) + cv::imshow(win_name, mat_output); + else + cv::imwrite("output.png", mat_output); + } else { + if (DISPLAY) + cv::imshow(win_name, mat_output); + else + cv::imwrite("output.png", mat_output); + } + // The delay here simulates possible latency between runs due to training + if (DISPLAY) + cv::waitKey(200); + col_counter = (col_counter + 1) % number_of_cols; + } + std::cout << ">>>>> Done test id " << test_id << " processed " << counter << " images ,press a key \n"; + if (DISPLAY) + cv::waitKey(0); + std::cout << "#### Going to reset\n"; + rocalResetLoaders(handle); + mat_input.release(); + mat_output.release(); + mat_color.release(); + if (DISPLAY) + cvDestroyWindow(win_name); + std::cout << "#### Done reset\n"; + } + + rocalRelease(handle); + + return 0; +} diff --git a/tests/cpp_api/rocAL_dataloader/CMakeLists.txt b/tests/cpp_api/rocAL_dataloader/CMakeLists.txt new file mode 100644 index 000000000..2e3e0b25e --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader/CMakeLists.txt @@ -0,0 +1,98 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required (VERSION 3.5) + +project(rocal_dataloader) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cpp_api/rocAL_dataloader/README.md b/tests/cpp_api/rocAL_dataloader/README.md new file mode 100644 index 000000000..92fd56615 --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader/README.md @@ -0,0 +1,24 @@ +# rocal_dataloader application +This application demonstrates a basic usage of rocAL's C API to load RAW images from the disk and modify them in different possible ways and displays the output images. +

+ +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ```` + rocal_dataloader + ```` diff --git a/tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp b/tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp new file mode 100644 index 000000000..540efd196 --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp @@ -0,0 +1,243 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define cvDestroyWindow destroyWindow +#endif + +#define DISPLAY +using namespace std::chrono; + +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf("Usage: image_augmentation decode_width decode_height batch_size display_on_off \n"); + return -1; + } + int argIdx = 0; + const char *folderPath1 = argv[++argIdx]; + bool display = 0; // Display the images + // int aug_depth = 1;// how deep is the augmentation tree + int decode_width = 32; + int decode_height = 32; + int inputBatchSize = 4; + bool processing_device = 1; + + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + inputBatchSize = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + display = atoi(argv[++argIdx]); + + std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; + // The cifar10 dataloader only supports ROCAL_COLOR_RGB_PLANAR + RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; + + auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + // Creating uniformly distributed random objects to override some of the default augmentation parameters + // RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand( 0.3, 0.5 ); + // RocalIntParam color_temp_adj = rocalCreateIntParameter(0); + + // Creating a custom random object to set a limited number of values to randomize the rotation angle + // create Cifar10 meta data reader + // rocalCreateTextCifar10LabelReader(handle, folderPath1, "data_batch"); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + // create Cifar10 meta data reader + rocalCreateTextCifar10LabelReader(handle, folderPath1, "data_batch"); + RocalTensor input0; + input0 = rocalRawCIFAR10Source(handle, folderPath1, color_format, false, decode_width, decode_height, "data_batch_", false); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "rawCIFAR10 source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } +#if 0 + const size_t num_values = 3; + float values[num_values] = {0,10,135}; + double frequencies[num_values] = {1, 5, 5}; + + RocalFloatParam rand_angle = rocalCreateFloatRand( values , frequencies, num_values); + // Creating successive blur nodes to simulate a deep branch of augmentations + RocalTensor input2 = rocalCropResize(handle, input0, resize_w, resize_h, false, rand_crop_area); + for(int i = 0 ; i < aug_depth; i++) + { + input2 = rocalBlurFixed(handle, input2, 17.25, (i == (aug_depth -1)) ? true:false ); + } + + RocalTensor input4 = rocalColorTemp(handle, input0, false, color_temp_adj); + + RocalTensor input5 = rocalWarpAffine(handle, input4, false); + + RocalTensor input6 = rocalJitter(handle, input5, false); + + rocalVignette(handle, input6, true); + + RocalTensor input7 = rocalPixelate(handle, input0, false); + + RocalTensor input8 = rocalSnow(handle, input0, false); + + RocalTensor input9 = rocalBlend(handle, input7, input8, false); + + RocalTensor input10 = rocalLensCorrection(handle, input9, false); + + rocalExposure(handle, input10, true); +#else + // uncomment the following to add augmentation if needed + // just do one augmentation to test + rocalRain(handle, input0, true); +#endif + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + } + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; + + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int n = rocalGetAugmentationBranchCount(handle); + int h = n * rocalGetOutputHeight(handle) * inputBatchSize; + int w = rocalGetOutputWidth(handle); + int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || + (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) + ? 3 + : 1); + std::cout << "output width " << w << " output height " << h << " color planes " << p << " n " << n << std::endl; + const unsigned number_of_cols = 1; // no augmented case + auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w * number_of_cols, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + int col_counter = 0; + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int counter = 0; + std::vector names; + int image_name_length[inputBatchSize]; + names.resize(inputBatchSize); + int iter_cnt = 0; + while (!rocalIsEmpty(handle) && (iter_cnt < 100)) { + if (rocalRun(handle) != 0) + break; + rocalCopyToOutput(handle, mat_input.data, h * w * p); + counter += inputBatchSize; + RocalTensorList labels = rocalGetImageLabels(handle); + unsigned img_name_size = rocalGetImageNameLen(handle, image_name_length); + char img_name[img_name_size]; + rocalGetImageName(handle, img_name); + std::string image_name(img_name); + int pos = 0; + int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); + for (int i = 0; i < inputBatchSize; i++) { + names[i] = image_name.substr(pos, image_name_length[i]); + pos += image_name_length[i]; + std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - "; + } + std::cout << std::endl; + iter_cnt++; + + if (!display) + continue; + + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + + if (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + // convert planar to packed for OPENCV + for (int j = 0; j < n; j++) { + int const single_h = rocalGetOutputHeight(handle); + for (int n = 0; n < inputBatchSize; n++) { + unsigned channel_size = w * single_h * p; + unsigned char *interleavedp = mat_output.data + channel_size * n; + unsigned char *planarp = mat_input.data + channel_size * n; + for (int i = 0; i < (w * single_h); i++) { + interleavedp[i * 3 + 0] = planarp[i + 0 * w * single_h]; + interleavedp[i * 3 + 1] = planarp[i + 1 * w * single_h]; + interleavedp[i * 3 + 2] = planarp[i + 2 * w * single_h]; + } + } + } + cv::imwrite("output.png", mat_output); + } + // Cifar10 dataloader only supports ROCAL_COLOR_RGB_PLANAR + cv::waitKey(1); + col_counter = (col_counter + 1) % number_of_cols; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + return 0; +} diff --git a/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt b/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt new file mode 100644 index 000000000..da0f6c6ef --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt @@ -0,0 +1,132 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required (VERSION 3.5) + +project (rocal_dataloader_mt) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +if(NOT DEFINED BACKEND) + set(BACKEND "HIP") # set default backend to HIP +endif() + +if("${BACKEND}" STREQUAL "OPENCL") + find_package(OpenCL QUIET) + if(OpenCL_FOUND) + set(ENABLE_OPENCL 1) + set(ENABLE_HIP 0) + include_directories($${OpenCL_INCLUDE_DIRS} ${OpenCL_INCLUDE_DIRS}/Headers) + target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES}) + else() + message("-- ${Yellow}NOTE: OpenCL Not Found -- runVX built for CPU only${ColourReset}") + endif() +elseif ("${BACKEND}" STREQUAL "HIP") + list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH} ${ROCM_PATH}/hip) + find_package(HIP QUIET) + if(HIP_FOUND) + message("-- ${White}rocAL_dataloader_mt -- Using HIP -- Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER} ${ColourReset}) + set(ENABLE_HIP 1) + set(ENABLE_OPENCL 0) + include_directories(${HIP_PATH}/include) + link_directories(${HIP_PATH}/lib) + message("-- ${Green}rali_dataloader_mt built with HIP Support${ColourReset}") + else() + message("-- ${Yellow}NOTE: HIP Not Found -- rali_dataloader_mt built for CPU only${ColourReset}") + endif() +else() + message("-- ${Yellow}NOTE: GPU Support Not Found or Turned OFF -- rali_dataloader_mt app built for CPU only${ColourReset}") +endif() + + +include_directories (${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories (${ROCM_PATH}/lib) + +add_executable(${PROJECT_NAME} ./rocAL_dataloader_mt.cpp) +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 3 ) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=1) + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message("-- WARNING: OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) + endif() +else() + message("-- WARNING: OpenCV Not Found -- No Display Support") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall -pthread") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cpp_api/rocAL_dataloader_mt/README.md b/tests/cpp_api/rocAL_dataloader_mt/README.md new file mode 100644 index 000000000..c60f54596 --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_mt/README.md @@ -0,0 +1,24 @@ +# rocAL_dataloader_mt application +This application demonstrates a basic usage of rocAL's C API to use sharded data_loader in a multithreaded application. +

+ +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ```` + rocAL_dataloader_mt =1)/(cpu:0)> + ```` diff --git a/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp b/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp new file mode 100644 index 000000000..5a00fd03f --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp @@ -0,0 +1,257 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include +#include +#include +using namespace cv; + +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define cvDestroyWindow destroyWindow +#else +#include +#endif + +#include "rocal_api.h" +#include "rocal_api_types.h" + +#define PRINT_NAMES_AND_LABELS 0 // uncomment for printing names and labels +// #define ROCAL_MEMCPY_TO_HOST 0 //For HOST 0 / GPU 1 +#define DISPLAY 0 +using namespace std::chrono; +std::mutex g_mtx; // mutex for critical section + +int thread_func(const char *path, int gpu_mode, RocalImageColor color_format, int shard_id, int num_shards, int dec_width, int dec_height, int batch_size, bool shuffle, bool display, int dec_mode) { + std::unique_lock lck(g_mtx, std::defer_lock); + std::cout << ">>> Running on " << (gpu_mode >= 0 ? "GPU" : "CPU") << std::endl; + std::cout << ">>> Running on shard_id: " << shard_id << std::endl; + color_format = RocalImageColor::ROCAL_COLOR_RGB24; + int gpu_id = (gpu_mode < 0) ? 0 : gpu_mode; + RocalDecoderType dec_type = (RocalDecoderType)dec_mode; + std::cout << ">>> Running on decoder mode - dec_mode<0(tjpeg)/1(opencv)/2(hwdec) : " << dec_type << std::endl; + lck.lock(); + // looks like OpenVX has some issue loading kernels from multiple threads at the same time + auto handle = rocalCreate(batch_size, (gpu_mode < 0) ? RocalProcessMode::ROCAL_PROCESS_CPU : RocalProcessMode::ROCAL_PROCESS_GPU, gpu_id, 1); + lck.unlock(); + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal context" + << "<" << shard_id << num_shards << " >" << std::endl; + return -1; + } + std::cout << "ROCAL created context for " + << "<" << shard_id << num_shards << " >" << std::endl; + // create JPEG data loader based on numshards and shard_id + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + RocalTensor decoded_output; + if (dec_width <= 0 || dec_height <= 0) + decoded_output = rocalJpegFileSourceSingleShard(handle, path, color_format, shard_id, num_shards, false, shuffle, false); + else + decoded_output = rocalJpegFileSourceSingleShard(handle, path, color_format, shard_id, num_shards, false, + shuffle, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, dec_width, dec_height, dec_type); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "rocalJpegFileSourceSingleShard<" << shard_id << " , " << num_shards << ">" + << " could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + // create meta data reader + rocalCreateLabelReader(handle, path); + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + rocalResize(handle, decoded_output, 224, 224, true); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + return -1; + } + + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; + + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int n = rocalGetAugmentationBranchCount(handle); + int h = n * rocalGetOutputHeight(handle) * batch_size; + int w = rocalGetOutputWidth(handle); + int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || + (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) + ? 3 + : 1); + std::cout << "output width " << w << " output height " << h << " color planes " << p << " n " << n << std::endl; + const unsigned number_of_cols = 1; // no augmented case + // printf("Allocated output tensor of size(flat) %d\n", h*w*p+256); + auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w * number_of_cols, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + int col_counter = 0; + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int counter = 0; + std::vector names; + names.resize(batch_size); + int image_name_length[batch_size]; + if (DISPLAY) + cv::namedWindow("output", CV_WINDOW_AUTOSIZE); + int iter_cnt = 0; + + while (!rocalIsEmpty(handle) /*&& (iter_cnt < 100)*/) { + // std::cout << "processing iter: " << iter_cnt << std::endl; + if (rocalRun(handle) != 0) + break; + // copy output to host as image + rocalCopyToOutput(handle, mat_input.data, h * w * p); + RocalTensorList labels = rocalGetImageLabels(handle); + unsigned img_name_size = rocalGetImageNameLen(handle, image_name_length); + char img_name[img_name_size]; + rocalGetImageName(handle, img_name); +#if PRINT_NAMES_AND_LABELS + std::string imageNamesStr(img_name); + int pos = 0; + int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); + for (int i = 0; i < batch_size; i++) { + names[i] = imageNamesStr.substr(pos, image_name_length[i]); + pos += image_name_length[i]; + std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - "; + } + std::cout << std::endl; +#endif + iter_cnt++; + + if (!display) + continue; + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + if (DISPLAY) + cv::imshow("output.png", mat_output); + else + cv::imwrite("output.png", mat_output); + + col_counter = (col_counter + 1) % number_of_cols; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "For shard_id: " << shard_id << std::endl; + std::cout << "Load time: " + << " " << rocal_timing.load_time << std::endl; + std::cout << "Decode time: " + << " " << rocal_timing.decode_time << std::endl; + std::cout << "Process time: " + << " " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time: " + << " " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + return 0; +} + +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf( + "Usage: rocal_dataloader_mt 1(gpu)/cpu=0> num_shards, \ + decode_width decode_height batch_size shuffle display_on_off dec_mode<0(tjpeg)/1(opencv)/2(hwdec)>\n"); + return -1; + } + int argIdx = 0; + const char *path = argv[++argIdx]; + bool display = 1; // Display the images + // int aug_depth = 1;// how deep is the augmentation tree + int decode_width = 1024; + int decode_height = 1024; + int inputBatchSize = 16; + int num_shards = 2; + bool shuffle = 0; + int num_gpus = 0; + int dec_mode = 0; + + if (argc >= argIdx + MIN_ARG_COUNT) + num_gpus = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + num_shards = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + inputBatchSize = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + shuffle = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + display = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + dec_mode = atoi(argv[++argIdx]); + + // gpu mode needs either OPENCL or HIP enabled +#if !(ENABLE_HIP || ENABLE_OPENCL) + num_gpus = 0; +#endif + std::cout << "#GPUs :" << num_gpus << std::endl; + + // launch threads process shards + std::thread loader_threads[num_shards]; + auto gpu_id = num_gpus ? 0 : -1; + int th_id; + for (th_id = 0; th_id < num_shards; th_id++) { + loader_threads[th_id] = std::thread(thread_func, path, gpu_id, RocalImageColor::ROCAL_COLOR_RGB24, th_id, num_shards, decode_width, decode_height, inputBatchSize, + shuffle, display, dec_mode); + if (num_gpus) gpu_id = (gpu_id + 1) % num_gpus; + } + for (auto &th : loader_threads) { + th.join(); + } +} diff --git a/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt b/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt new file mode 100644 index 000000000..2b5b286fa --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt @@ -0,0 +1,75 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project(rocal_dataloader_tf) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_dataloader_tf/README.md b/tests/cpp_api/rocAL_dataloader_tf/README.md new file mode 100644 index 000000000..268875bc0 --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_tf/README.md @@ -0,0 +1,24 @@ +# rocal_dataloader_tf application +This application demonstrates a basic usage of rocAL's C API to load TfRecords from the disk and modify them in different possible ways and displays the output images. + +## Build Instructions + +### Pre-requisites +* Ubuntu 16.04/18.04 Linux +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* Google protobuf 3.11.1 or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ```` + rocal_dataloader + ```` diff --git a/tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp b/tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp new file mode 100644 index 000000000..6fc4d6b6e --- /dev/null +++ b/tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp @@ -0,0 +1,274 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define cvDestroyWindow destroyWindow +#endif + +#define DISPLAY 0 +using namespace std::chrono; + +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf("Usage: rocal_dataloader_tf display_on_off \n"); + return -1; + } + int argIdx = 0; + const char *folderPath1 = argv[++argIdx]; + bool display = 0; // Display the images + // int aug_depth = 1;// how deep is the augmentation tree + int rgb = 0; // process gray images + int decode_width = 28; // mnist data_set + int decode_height = 28; + int inputBatchSize = 16; + bool processing_device = 1; + + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + inputBatchSize = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + display = atoi(argv[++argIdx]); + + std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; + RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_U8; + if (rgb == 0) + color_format = RocalImageColor::ROCAL_COLOR_U8; + else if (rgb == 1) + color_format = RocalImageColor::ROCAL_COLOR_RGB24; + else if (rgb == 2) + color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; + + auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor decoded_output; + // hardcoding the following for mnist tfrecords + std::string feature_map_image = "image/encoded"; + std::string feature_map_filename = "image/filename"; + std::string feature_map_label = "image/class/label"; + + rocalCreateTFReader(handle, folderPath1, 1, feature_map_label.c_str(), feature_map_filename.c_str()); + decoded_output = rocalJpegTFRecordSource(handle, folderPath1, color_format, 1, false, feature_map_image.c_str(), feature_map_filename.c_str(), false, false, ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + +#if 0 + const size_t num_values = 3; + float values[num_values] = {0,10,135}; + double frequencies[num_values] = {1, 5, 5}; + + RocalFloatParam rand_angle = rocalCreateFloatRand( values , frequencies, num_values); + // Creating successive blur nodes to simulate a deep branch of augmentations + RocalTensor input2 = rocalCropResize(handle, decoded_output, resize_w, resize_h, false, rand_crop_area);; + for(int i = 0 ; i < aug_depth; i++) + { + input2 = rocalBlurFixed(handle, input2, 17.25, (i == (aug_depth -1)) ? true:false ); + } + + + RocalTensor input4 = rocalColorTemp(handle, decoded_output, false, color_temp_adj); + + RocalTensor input5 = rocalWarpAffine(handle, input4, false); + + RocalTensor input6 = rocalJitter(handle, input5, false); + + rocalVignette(handle, input6, true); + + + + RocalTensor input7 = rocalPixelate(handle, decoded_output, false); + + RocalTensor input8 = rocalSnow(handle, decoded_output, false); + + RocalTensor input9 = rocalBlend(handle, input7, input8, false); + + RocalTensor image10 = rocalLensCorrection(handle, input9, false); + + rocalExposure(handle, image10, true); +#else + // uncomment the following to add augmentation if needed + // just do one augmentation to test + rocalResize(handle, decoded_output, 300, 300, true); +#endif + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + } + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; + + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int n = rocalGetAugmentationBranchCount(handle); + int h = n * rocalGetOutputHeight(handle) * inputBatchSize; + int w = rocalGetOutputWidth(handle); + int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || + (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) + ? 3 + : 1); + printf("After get output dims\n"); + std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; + const unsigned number_of_cols = 1; // no augmented case + printf("Before memalloc\n"); + + auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w * number_of_cols, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + int col_counter = 0; + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int counter = 0; + std::vector names; + names.resize(inputBatchSize); + int ImageNameLen[inputBatchSize]; + + int iter_cnt = 0; + while (!rocalIsEmpty(handle) && (iter_cnt < 100)) { + // if ((iter_cnt %16) == 0) + printf("Processing iter: %d\n", iter_cnt); + if (rocalRun(handle) != 0) { + std::cout << "rocalRun Failed" << std::endl; + break; + } + + rocalCopyToOutput(handle, mat_input.data, h * w * p); + counter += inputBatchSize; + + RocalTensorList labels = rocalGetImageLabels(handle); + unsigned img_name_size = rocalGetImageNameLen(handle, ImageNameLen); + char img_name[img_name_size]; + rocalGetImageName(handle, img_name); + std::string imageNamesStr(img_name); + int pos = 0; + int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); + for (int i = 0; i < inputBatchSize; i++) { + names[i] = imageNamesStr.substr(pos, ImageNameLen[i]); + pos += ImageNameLen[i]; + std::cout << "\n name: " << names[i] << " label: " << labels_buffer[i] << std::endl; + } + std::cout << std::endl; + + iter_cnt++; + if (!display) + continue; + + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::Mat mat_color; + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + if (DISPLAY) + cv::imshow("output", mat_output); + else + cv::imwrite("output.png", mat_output); + } else if (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR) { + // convert planar to packed for OPENCV + for (int j = 0; j < n; j++) { + int const kWidth = w; + int const kHeight = rocalGetOutputHeight(handle); + int single_h = kHeight / inputBatchSize; + for (int n = 0; n < inputBatchSize; n++) { + unsigned channel_size = kWidth * single_h * p; + unsigned char *interleavedp = mat_output.data + channel_size * n; + unsigned char *planarp = mat_input.data + channel_size * n; + for (int i = 0; i < (kWidth * single_h); i++) { + interleavedp[i * 3 + 0] = planarp[i + 0 * kWidth * single_h]; + interleavedp[i * 3 + 1] = planarp[i + 1 * kWidth * single_h]; + interleavedp[i * 3 + 2] = planarp[i + 2 * kWidth * single_h]; + } + } + } + if (DISPLAY) + cv::imshow("output", mat_output); + else + cv::imwrite("output.png", mat_output); + } else { + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + if (DISPLAY) + cv::imshow("output", mat_output); + else + cv::imwrite("output.png", mat_output); + } + if (DISPLAY) + cv::waitKey(1); + col_counter = (col_counter + 1) % number_of_cols; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + return 0; +} diff --git a/tests/cpp_api/rocAL_external_source/CMakeLists.txt b/tests/cpp_api/rocAL_external_source/CMakeLists.txt new file mode 100644 index 000000000..935d7de34 --- /dev/null +++ b/tests/cpp_api/rocAL_external_source/CMakeLists.txt @@ -0,0 +1,73 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project (rocal_external_source) +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_external_source/README.md b/tests/cpp_api/rocAL_external_source/README.md new file mode 100644 index 000000000..acaf18f52 --- /dev/null +++ b/tests/cpp_api/rocAL_external_source/README.md @@ -0,0 +1,28 @@ +# rocal_external_source application + +This application demonstrates a basic usage of rocAL's C++ API to load images from external source and add augmentations and displays the output images. + +## Build Instructions + +### Pre-requisites + +* Ubuntu Linux, [version `18.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + + ````bash + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/rpp/lib + mkdir build + cd build + cmake ../ + make + ```` + +### running the application + + ````bash + rocal_external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode + ```` diff --git a/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp b/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp new file mode 100644 index 000000000..3c3f24cc3 --- /dev/null +++ b/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp @@ -0,0 +1,426 @@ +/* +MIT License + +Copyright (c) 2023 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 +#include +#include +#include +#include + +#include "rocal_api.h" + +using namespace cv; +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#endif + +#define DISPLAY +using namespace std::chrono; + +template +void convert_float_to_uchar_buffer(T *input_float_buffer, unsigned char *output_uchar_buffer, size_t data_size) { + for (size_t i = 0; i < data_size; i++) { + output_uchar_buffer[i] = (unsigned char)(*(input_float_buffer + i) * 255); + } +} + +const std::array, 3> color_mappings = { + {std::make_pair(ROCAL_COLOR_U8, 1), + std::make_pair(ROCAL_COLOR_RGB24, 3), + std::make_pair(ROCAL_COLOR_RGB_PLANAR, 3)} + }; + +int main(int argc, const char **argv) { + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf( + "Usage: rocal_external_source " + " decode_width decode_height batch_size " + "gray_scale/rgb/rgbplanar display_on_off external_source_mode\n"); + return -1; + } + int argIdx = 0; + const char *folder_path = argv[++argIdx]; + bool display = 1; // Display the images + int rgb = 1; // process color images + int decode_width = 224; // Decoding width + int decode_height = 224; // Decoding height + int input_batch_size = 2; // Batch size + bool processing_device = 0; // CPU Processing + int mode = 0; // File mode + + if (argc >= argIdx + MIN_ARG_COUNT) processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) input_batch_size = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) display = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) mode = atoi(argv[++argIdx]); + + std::cerr << "\n Mode:: " << mode << std::endl; + std::cerr << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; + RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; + color_format = color_mappings[rgb].first; + int channels = color_mappings[rgb].second; + + auto handle = rocalCreate(input_batch_size, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cerr << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + rocalSetSeed(0); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor input1; + RocalTensorOutputType tensor_output_type = RocalTensorOutputType::ROCAL_UINT8; + std::vector srcsize_height, srcsize_width; + uint32_t max_height = 0, max_width = 0; + DIR *_src_dir; + struct dirent *_entity; + std::vector file_names; + std::vector input_buffer; + if ((_src_dir = opendir(folder_path)) == nullptr) { + std::cerr << "\n ERROR: Failed opening the directory at " << folder_path; + exit(0); + } + + while ((_entity = readdir(_src_dir)) != nullptr) { + if (_entity->d_type != DT_REG) continue; + + std::string file_path = folder_path; + file_path.append(_entity->d_name); + file_names.push_back(file_path); + } + if (mode != 0) { + if (mode == 1) { + // Mode 1 is Raw compressed + // srcsize_height and srcsize_width resized based on total file count + srcsize_height.resize(file_names.size()); + srcsize_width.resize(file_names.size()); + for (uint32_t i = 0; i < file_names.size(); i++) { + FILE *_current_fPtr; + _current_fPtr = fopen(file_names[i].c_str(), "rb"); // Open the file, + if (!_current_fPtr) // Check if it is ready for reading + return 0; + fseek(_current_fPtr, 0, + SEEK_END); // Take the file read pointer to the end + size_t _current_file_size = ftell( + _current_fPtr); // Check how many bytes are there between and the + // current read pointer position (end of the file) + unsigned char *input_data = static_cast( + malloc(sizeof(unsigned char) * _current_file_size)); + if (_current_file_size == 0) { // If file is empty continue + fclose(_current_fPtr); + _current_fPtr = nullptr; + return 0; + } + + fseek(_current_fPtr, 0, + SEEK_SET); // Take the file pointer back to the start + size_t actual_read_size = fread(input_data, sizeof(unsigned char), + _current_file_size, _current_fPtr); + input_buffer.push_back(input_data); + srcsize_height[i] = actual_read_size; // It stored the actual file size + } + } else if (mode == 2) { // Raw un compressed + srcsize_height.resize(file_names.size()); + srcsize_width.resize(file_names.size()); + for (uint32_t i = 0; i < file_names.size(); i++) { + Mat image; + image = imread(file_names[i], 1); + if (image.empty()) { + std::cout << "Could not read the image: " << file_names[i] << std::endl; + return 1; + } + srcsize_height[i] = image.rows; + srcsize_width[i] = image.cols; + max_height = std::max(max_height, srcsize_height[i]); + max_width = std::max(max_width, srcsize_width[i]); + } + unsigned long long image_dim_max = (unsigned long long)max_height * (unsigned long long)max_width * 3; + unsigned char *complete_image_buffer = (unsigned char *)malloc(sizeof(unsigned char) * file_names.size() * image_dim_max); + uint32_t elements_in_row_max = max_width * 3; + unsigned char *temp_buffer, *temp_image; + for (uint32_t i = 0; i < file_names.size(); i++) { + temp_image = temp_buffer = complete_image_buffer + (i * image_dim_max); + Mat image = imread(file_names[i], 1); + if (image.empty()) { + std::cout << "Could not read the image: " << file_names[i] << std::endl; + return 1; + } + cvtColor(image, image, cv::COLOR_BGR2RGB); + unsigned char *ip_image = image.data; + uint32_t elements_in_row = srcsize_width[i] * 3; + for (uint32_t j = 0; j < srcsize_height[i]; j++) { + memcpy(temp_buffer, ip_image, elements_in_row * sizeof(unsigned char)); + ip_image += elements_in_row; + temp_buffer += elements_in_row_max; + } + input_buffer.push_back(temp_image); + } + } + } + if (max_height != 0 && max_width != 0) { + input1 = rocalJpegExternalFileSource( + handle, color_format, false, false, false, + ROCAL_USE_USER_GIVEN_SIZE, max_width, max_height, + RocalDecoderType::ROCAL_DECODER_TJPEG, RocalExternalSourceMode(mode)); + } else { + input1 = rocalJpegExternalFileSource( + handle, color_format, false, false, false, + ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height, + RocalDecoderType::ROCAL_DECODER_TJPEG, RocalExternalSourceMode(mode)); + } + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cerr << "JPEG source could not initialize : " + << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + // uncomment the following to add augmentation if needed + int resize_w = decode_width, resize_h = decode_height; + // just do one augmentation to test + rocalResize(handle, input1, resize_w, resize_h, true); // Remove this later + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cerr << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cerr << err_msg << std::endl; + } + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cerr << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + cv::Mat mat_color; + const unsigned number_of_cols = 1; // no augmented case + int col_counter = 0; + printf("Going to process images\n"); + printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int index = 0; + bool eos = false; + int total_images = file_names.size(); + int counter = 0; + std::vector names; + std::vector labels; + bool set_labels = true; + names.resize(input_batch_size); + labels.resize(total_images); + RocalTensorList output_tensor_list; + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? ((tensor_output_type == RocalTensorOutputType::ROCAL_FP32) ? CV_32FC3 : CV_8UC3) : CV_8UC1); + std::vector ROI_xywh; + ROI_xywh.resize(input_batch_size); + while (static_cast(rocalGetRemainingImages(handle)) >= input_batch_size) { + std::vector input_images; + std::vector input_batch_buffer; + std::vector label_buffer; + for (int i = 0; i < input_batch_size; i++) { + if (mode == 0) { + input_images.push_back(file_names.back()); + file_names.pop_back(); + if ((file_names.size()) == 0) { + eos = true; + } + label_buffer.push_back(labels.back()); + labels.pop_back(); + } else { + if (mode == 1) { + input_batch_buffer.push_back(input_buffer.back()); + input_buffer.pop_back(); + ROI_xywh[i].h = srcsize_height.back(); + srcsize_height.pop_back(); + label_buffer.push_back(labels.back()); + labels.pop_back(); + } else { + input_batch_buffer.push_back(input_buffer.back()); + input_buffer.pop_back(); + ROI_xywh[i].w = srcsize_width.back(); + srcsize_width.pop_back(); + ROI_xywh[i].h = srcsize_height.back(); + srcsize_height.pop_back(); + label_buffer.push_back(labels.back()); + labels.pop_back(); + } + if ((file_names.size()) == 0 || input_buffer.size() == 0) { + eos = true; + } + } + } + if (index + 1 <= (total_images / input_batch_size)) { + std::cerr << "\n************************** Gonna process Batch *************************" << index; + std::cerr << "\n Mode ********************* " << mode; + if (mode == 0) { + rocalExternalSourceFeedInput(handle, input_images, set_labels, {}, ROI_xywh, + decode_width, decode_height, channels, + RocalExternalSourceMode(0), + RocalTensorLayout(0), eos); + } else if (mode == 1) { + rocalExternalSourceFeedInput(handle, {}, set_labels, input_batch_buffer, + ROI_xywh, decode_width, decode_height, + channels, RocalExternalSourceMode(mode), + RocalTensorLayout(0), eos); + } else if (mode == 2) { + rocalExternalSourceFeedInput(handle, {}, set_labels, input_batch_buffer, + ROI_xywh, max_width, max_height, + channels, RocalExternalSourceMode(mode), + RocalTensorLayout(0), eos); + } + } + if (rocalRun(handle) != 0) { + std::cerr << "rocalRun(handle) != 0 --- breaking"; + break; + } + + if (!display) continue; + // Dump the output image + output_tensor_list = rocalGetOutputTensors(handle); + std::vector compression_params; + compression_params.push_back(IMWRITE_PNG_COMPRESSION); + compression_params.push_back(9); + + cv::Mat mat_input; + cv::Mat mat_output; + int h = 0, w = 0 ; + for (uint64_t idx = 0; idx < output_tensor_list->size(); idx++) { + if (output_tensor_list->at(idx)->layout() == RocalTensorLayout::ROCAL_NHWC) { + h = output_tensor_list->at(idx)->dims().at(1) * output_tensor_list->at(idx)->dims().at(0); + w = output_tensor_list->at(idx)->dims().at(2); + } + + mat_input = cv::Mat(h, w, cv_color_format); + mat_output = cv::Mat(h, w, cv_color_format); + unsigned char *out_buffer = nullptr; + if (output_tensor_list->at(idx)->data_type() == RocalTensorOutputType::ROCAL_FP32) { + float *out_f_buffer = nullptr; + if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { + out_f_buffer = (float *)malloc(output_tensor_list->at(idx)->data_size()); + output_tensor_list->at(idx)->copy_data(out_f_buffer); + } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) + out_f_buffer = (float *)output_tensor_list->at(idx)->buffer(); + + out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 4); + convert_float_to_uchar_buffer(out_f_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 4); + // if(out_f_buffer != nullptr) free(out_f_buffer); + } + if (output_tensor_list->at(idx)->data_type() == RocalTensorOutputType::ROCAL_FP16) { + half *out_f16_buffer = nullptr; + if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { + out_f16_buffer = (half *)malloc(output_tensor_list->at(idx)->data_size()); + output_tensor_list->at(idx)->copy_data(out_f16_buffer); + } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) + out_f16_buffer = (half *)output_tensor_list->at(idx)->buffer(); + + out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 2); + convert_float_to_uchar_buffer(out_f16_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 2); + // if(out_f16_buffer != nullptr) free(out_f16_buffer); + } else { + if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { + out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size()); + output_tensor_list->at(idx)->copy_data(out_buffer); + } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) + out_buffer = (unsigned char *)(output_tensor_list->at(idx)->buffer()); + } + + mat_input.data = (unsigned char *)out_buffer; + + mat_input.copyTo(mat_output(cv::Rect(0, 0, w, h))); + std::string outName = "external_source_output"; + std::string out_filename = outName + ".png"; // in case the user specifies non png filename + if (display) + out_filename = outName + std::to_string(index) + std::to_string(idx) + ".png"; // in case the user specifies non png filename + + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + cv::imwrite(out_filename, mat_color, compression_params); + } else { + cv::imwrite(out_filename, mat_output, compression_params); + } + // if(out_buffer != nullptr) free(out_buffer); + } + mat_input.release(); + mat_output.release(); + + cv::waitKey(1); + + uint pipeline_type = 1; // External Source Reader Support given for the classification pipeline only + switch (pipeline_type) { + case 1: // classification pipeline + { + if(set_labels) + { + auto labels_tensor_list = rocalGetImageLabels(handle); + int *labels_ptr = static_cast(label_buffer.data()); + for (size_t i = 0; i < label_buffer.size(); i++) { + labels_tensor_list->at(i)->set_mem_handle(labels_ptr); + std::cerr << ">>>>> LABELS : " << labels_ptr[0] << "\t"; + labels_ptr++; + } + } + else + std::cerr<<"\n labels are not set"; + } break; + default: { + std::cerr << "Not a valid pipeline type ! Exiting!\n"; + return -1; + } + } + col_counter = (col_counter + 1) % number_of_cols; + index++; + counter += input_batch_size; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cerr << std::endl; + std::cerr << "Load time " << rocal_timing.load_time << std::endl; + std::cerr << "Decode time " << rocal_timing.decode_time << std::endl; + std::cerr << "Process time " << rocal_timing.process_time << std::endl; + std::cerr << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cerr << ">>>>> " << counter + << " images/frames Processed. Total Elapsed Time " << dur / 1000000 + << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + return 0; +} diff --git a/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt b/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt new file mode 100644 index 000000000..0d235c805 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt @@ -0,0 +1,98 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project (rocal_performance_tests) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cpp_api/rocAL_performance_tests/README.md b/tests/cpp_api/rocAL_performance_tests/README.md new file mode 100644 index 000000000..e808e7bc4 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests/README.md @@ -0,0 +1,23 @@ +# rocAL Performance Tests +This application is used to run performance tests on the rocAL API for graphs of depth size 1. + + +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ```` +rocAL_performance_tests [test image folder] [image width] [image height] [test case] [batch size] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] + ```` diff --git a/tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp b/tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp new file mode 100644 index 000000000..0ebfe69d6 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp @@ -0,0 +1,336 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define cvDestroyWindow destroyWindow +#endif + +#define DISPLAY +using namespace std::chrono; + +int test(int test_case, const char* path, int rgb, int processing_device, int width, int height, int batch_size, int shards, int shuffle); +int main(int argc, const char** argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + printf("Usage: rocal_performance_tests \n"); + if (argc < MIN_ARG_COUNT) + return -1; + + int argIdx = 0; + const char* path = argv[++argIdx]; + int width = atoi(argv[++argIdx]); + int height = atoi(argv[++argIdx]); + + int rgb = 1; // process color images + bool processing_device = 1; + int test_case = 0; + int batch_size = 10; + int shards = 4; + int shuffle = 0; + + if (argc >= argIdx + MIN_ARG_COUNT) + test_case = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + batch_size = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + shards = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + shuffle = atoi(argv[++argIdx]); + + test(test_case, path, rgb, processing_device, width, height, batch_size, shards, shuffle); + + return 0; +} + +int test(int test_case, const char* path, int rgb, int processing_device, int width, int height, int batch_size, int shards, int shuffle) { + size_t num_threads = shards; + int inputBatchSize = batch_size; + int decode_max_width = 0; + int decode_max_height = 0; + std::cout << ">>> test case " << test_case << std::endl; + std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; + printf(">>> Batch size = %d -- shard count = %lu\n", inputBatchSize, num_threads); + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; + + auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal context\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + rocalSetSeed(0); + + // Creating uniformly distributed random objects to override some of the default augmentation parameters + RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); + RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); + + // Creating a custom random object to set a limited number of values to randomize the rotation angle + const size_t num_values = 3; + float values[num_values] = {0, 10, 135}; + double frequencies[num_values] = {1, 5, 5}; + RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, + sizeof(values) / sizeof(values[0])); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor tensor0; + RocalTensor tensor0_b; + + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + if (decode_max_height <= 0 || decode_max_width <= 0) + tensor0 = rocalJpegFileSource(handle, path, color_format, num_threads, false, shuffle, true); + else + tensor0 = rocalJpegFileSource(handle, path, color_format, num_threads, false, shuffle, false, + ROCAL_USE_USER_GIVEN_SIZE, decode_max_width, decode_max_height); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + int resize_w = width, resize_h = height; + + switch (test_case) { + case 0: { + std::cout << ">>>>>>> Running " + << "rocalResize" << std::endl; + rocalResize(handle, tensor0, resize_w, resize_h, true); + } break; + case 1: { + std::cout << ">>>>>>> Running " + << "rocalCropResize" << std::endl; + rocalCropResize(handle, tensor0, resize_w, resize_h, true, rand_crop_area); + } break; + case 2: { + std::cout << ">>>>>>> Running " + << "rocalRotate" << std::endl; + rocalRotate(handle, tensor0, true, rand_angle); + } break; + case 3: { + std::cout << ">>>>>>> Running " + << "rocalBrightness" << std::endl; + rocalBrightness(handle, tensor0, true); + } break; + case 4: { + std::cout << ">>>>>>> Running " + << "rocalGamma" << std::endl; + rocalGamma(handle, tensor0, true); + } break; + case 5: { + std::cout << ">>>>>>> Running " + << "rocalContrast" << std::endl; + rocalContrast(handle, tensor0, true); + } break; + case 6: { + std::cout << ">>>>>>> Running " + << "rocalFlip" << std::endl; + rocalFlip(handle, tensor0, true); + } break; + case 7: { + std::cout << ">>>>>>> Running " + << "rocalBlur" << std::endl; + rocalBlur(handle, tensor0, true); + } break; + case 8: { + std::cout << ">>>>>>> Running " + << "rocalBlend" << std::endl; + tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); + rocalBlend(handle, tensor0, tensor0_b, true); + } break; + case 9: { + std::cout << ">>>>>>> Running " + << "rocalWarpAffine" << std::endl; + rocalWarpAffine(handle, tensor0, true); + } break; + case 10: { + std::cout << ">>>>>>> Running " + << "rocalFishEye" << std::endl; + rocalFishEye(handle, tensor0, true); + } break; + case 11: { + std::cout << ">>>>>>> Running " + << "rocalVignette" << std::endl; + rocalVignette(handle, tensor0, true); + } break; + case 12: { + std::cout << ">>>>>>> Running " + << "rocalJitter" << std::endl; + rocalJitter(handle, tensor0, true); + } break; + case 13: { + std::cout << ">>>>>>> Running " + << "rocalSnPNoise" << std::endl; + rocalSnPNoise(handle, tensor0, true); + } break; + case 14: { + std::cout << ">>>>>>> Running " + << "rocalSnow" << std::endl; + rocalSnow(handle, tensor0, true); + } break; + case 15: { + std::cout << ">>>>>>> Running " + << "rocalRain" << std::endl; + rocalRain(handle, tensor0, true); + } break; + case 16: { + std::cout << ">>>>>>> Running " + << "rocalColorTemp" << std::endl; + rocalColorTemp(handle, tensor0, true, color_temp_adj); + } break; + case 17: { + std::cout << ">>>>>>> Running " + << "rocalFog" << std::endl; + rocalFog(handle, tensor0, true); + } break; + case 18: { + std::cout << ">>>>>>> Running " + << "rocalLensCorrection" << std::endl; + rocalLensCorrection(handle, tensor0, true); + } break; + case 19: { + std::cout << ">>>>>>> Running " + << "rocalPixelate" << std::endl; + rocalPixelate(handle, tensor0, true); + } break; + case 20: { + std::cout << ">>>>>>> Running " + << "rocalExposure" << std::endl; + rocalExposure(handle, tensor0, true); + } break; + case 21: { + std::cout << ">>>>>>> Running " + << "rocalHue" << std::endl; + rocalHue(handle, tensor0, true); + } break; + case 22: { + std::cout << ">>>>>>> Running " + << "rocalSaturation" << std::endl; + rocalSaturation(handle, tensor0, true); + } break; + case 23: { + std::cout << ">>>>>>> Running " + << "rocalCopy" << std::endl; + rocalCopy(handle, tensor0, true); + } break; + case 24: { + std::cout << ">>>>>>> Running " + << "rocalColorTwist" << std::endl; + rocalColorTwist(handle, tensor0, true); + } break; + case 25: { + std::cout << ">>>>>>> Running " + << "rocalCropMirrorNormalize" << std::endl; + std::vector mean; + std::vector std_dev; + rocalCropMirrorNormalize(handle, tensor0, 200, 200, 50, 50, mean, std_dev, true); + } break; + case 26: { + std::cout << ">>>>>>> Running " + << "rocalCrop " << std::endl; + rocalCrop(handle, tensor0, true); + } break; + case 27: { + std::cout << ">>>>>>> Running " + << "rocalResizeCropMirror" << std::endl; + rocalResizeCropMirror(handle, tensor0, resize_w, resize_h, true); + } break; + case 28: { + std::cout << ">>>>>>> Running " + << "No-Op" << std::endl; + rocalNop(handle, tensor0, true); + } break; + default: + std::cout << "Not a valid option! Exiting!\n"; + return -1; + } + + // Calling the API to verify and build the augmentation graph + rocalVerify(handle); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); + return -1; + } + + printf("Augmented copies count %lu\n", rocalGetAugmentationBranchCount(handle)); + + printf("Going to process images\n"); + // printf("Remaining images %d \n", rocalGetRemainingImages(handle)); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + + int i = 0; + while (i++ < 100 && !rocalIsEmpty(handle)) { + if (rocalRun(handle) != 0) + break; + + // auto last_colot_temp = rocalGetIntValue(color_temp_adj); + // rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); + + // rocalCopyToOutput(handle, mat_input.data, h * w * p); + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << "Total time " << dur << std::endl; + std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + + rocalRelease(handle); + + return 0; +} diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt b/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt new file mode 100644 index 000000000..7276c54b8 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt @@ -0,0 +1,76 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ + +cmake_minimum_required (VERSION 3.5) + +project (rocal_performance_tests_with_depth) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/README.md b/tests/cpp_api/rocAL_performance_tests_with_depth/README.md new file mode 100644 index 000000000..b1c190e26 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests_with_depth/README.md @@ -0,0 +1,23 @@ +# rocAL Performance Tests with Depth +This application can be used to run performance tests on rocAL graphs with depth greater than 1. +This is very similar to the rocAL Performance Tests app except it takes an extra parameter to specify depth. + +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ```` +rocAL_performance_tests_with_depth [test image folder] [image width] [image height] [test case] [batch size] [graph depth] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] + ```` diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp b/tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp new file mode 100644 index 000000000..082af2bb6 --- /dev/null +++ b/tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp @@ -0,0 +1,593 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; + +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#endif + +#define DISPLAY 0 +using namespace std::chrono; + +int test(int test_case, const char* path, int rgb, int gpu, int width, int height, int batch_size, int graph_depth); +int main(int argc, const char** argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + printf("Usage: image_augmentation test_case batch_size graph_depth gpu=1/cpu=0 rgb=1/grayscale =0 \n"); + if (argc < MIN_ARG_COUNT) + return -1; + + int argIdx = 0; + const char* path = argv[++argIdx]; + int width = atoi(argv[++argIdx]); + int height = atoi(argv[++argIdx]); + + int rgb = 1; // process color images + bool gpu = 1; + int test_case = 0; + int batch_size = 10; + int graph_depth = 1; + + if (argc >= argIdx + MIN_ARG_COUNT) + test_case = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + batch_size = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + graph_depth = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + gpu = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + test(test_case, path, rgb, gpu, width, height, batch_size, graph_depth); + + return 0; +} + +int test(int test_case, const char* path, int rgb, int gpu, int width, int height, int batch_size, int graph_depth) { + size_t num_threads = 1; + int inputBatchSize = 1; + int decode_max_width = width; + int decode_max_height = height; + std::cout << ">>> test case " << test_case << std::endl; + std::cout << ">>> Running on " << (gpu ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 + : RocalImageColor::ROCAL_COLOR_U8; + + auto handle = rocalCreate(inputBatchSize, + gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, + 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + rocalSetSeed(0); + + // Creating uniformly distributed random objects to override some of the default augmentation parameters + RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); + RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); + + // Creating a custom random object to set a limited number of values to randomize the rotation angle + const size_t num_values = 3; + float values[num_values] = {0, 10, 135}; + double frequencies[num_values] = {1, 5, 5}; + RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, + sizeof(values) / sizeof(values[0])); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor input_image; + RocalTensor tensor0; + RocalTensor tensor0_b; + + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + if (decode_max_height <= 0 || decode_max_width <= 0) + input_image = rocalJpegFileSource(handle, path, color_format, num_threads, false, true); + else + input_image = rocalJpegFileSource(handle, path, color_format, num_threads, false, true, false, + ROCAL_USE_USER_GIVEN_SIZE, decode_max_width, decode_max_height); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + int resize_w = width, resize_h = height; + + switch (test_case) { + case 0: { + std::cout << ">>>>>>> Running " + << "rocalResize" << std::endl; + + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalResize(handle, tensor0, resize_w, resize_h, true); + } + } + } break; + case 1: { + std::cout << ">>>>>>> Running " + << "rocalCropResize" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalCropResize(handle, tensor0, resize_w, resize_h, true, rand_crop_area); + } + } + } break; + case 2: { + std::cout << ">>>>>>> Running " + << "rocalCropResizeFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalCropResizeFixed(handle, tensor0, resize_w, resize_h, true, 0.25, 1.2, 0.6, 0.4); + } + } + } break; + case 3: { + std::cout << ">>>>>>> Running " + << "rocalRotate" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalRotate(handle, tensor0, true, rand_angle); + } + } + } break; + case 4: { + std::cout << ">>>>>>> Running " + << "rocalRotateFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalRotateFixed(handle, tensor0, 45, true, resize_w, resize_h); + } + } + } break; + case 5: { + std::cout << ">>>>>>> Running " + << "rocalBrightness" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalBrightness(handle, tensor0, true); + } + } + } break; + case 6: { + std::cout << ">>>>>>> Running " + << "rocalBrightnessFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalBrightnessFixed(handle, tensor0, 4, 50, true); + } + } + } break; + case 7: { + std::cout << ">>>>>>> Running " + << "rocalGamma" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalGamma(handle, tensor0, true); + } + } + } break; + case 8: { + std::cout << ">>>>>>> Running " + << "rocalGammaFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalGammaFixed(handle, tensor0, 0.5, true); + } + } + } break; + case 9: { + std::cout << ">>>>>>> Running " + << "rocalContrast" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalContrast(handle, tensor0, true); + } + } + } break; + case 10: { + std::cout << ">>>>>>> Running " + << "rocalContrastFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalContrastFixed(handle, tensor0, 30, 380, true); + } + } + } break; + case 11: { + std::cout << ">>>>>>> Running " + << "rocalFlip horizontal" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalFlip(handle, tensor0, true); + } + } + } break; + case 12: { + std::cout << ">>>>>>> Running " + << "rocalFlip vertical" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalFlip(handle, tensor0, true); + } + } + } break; + case 13: { + std::cout << ">>>>>>> Running " + << "rocalBlur" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalBlur(handle, tensor0, true); + } + } + } break; + case 14: { + std::cout << ">>>>>>> Running " + << "rocalBlurFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalBlurFixed(handle, tensor0, 17.25, true); + } + } + } break; + case 15: { + std::cout << ">>>>>>> Running " + << "rocalBlend" << std::endl; + + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalBlend(handle, tensor0, tensor0_b, true); + } + } + } break; + case 16: { + std::cout << ">>>>>>> Running " + << "rocalBlendFixed" << std::endl; + tensor0 = input_image; + tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); + for (int k = 0; k < graph_depth; k++) { + rocalBlendFixed(handle, tensor0, tensor0_b, 0.5, true); + } + } + } break; + + case 17: { + std::cout << ">>>>>>> Running " + << "rocalWarpAffine" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalWarpAffine(handle, tensor0, true); + } + } + } break; + case 18: { + std::cout << ">>>>>>> Running " + << "rocalWarpAffineFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalWarpAffineFixed(handle, tensor0, true, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5); + } + } + } break; + case 19: { + std::cout << ">>>>>>> Running " + << "rocalFishEye" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalFishEye(handle, tensor0, true); + } + } + } break; + case 20: { + std::cout << ">>>>>>> Running " + << "rocalVignette" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalVignette(handle, tensor0, true); + } + } + } break; + case 21: { + std::cout << ">>>>>>> Running " + << "rocalVignetteFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalVignetteFixed(handle, tensor0, 40, true); + } + } + } break; + case 22: { + std::cout << ">>>>>>> Running " + << "rocalJitter" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalJitter(handle, tensor0, true); + } + } + } break; + case 23: { + std::cout << ">>>>>>> Running " + << "rocalJitterFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalJitterFixed(handle, tensor0, 3, true); + } + } + } break; + case 24: { + std::cout << ">>>>>>> Running " + << "rocalSnPNoise" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalSnPNoise(handle, tensor0, true); + } + } + } break; + case 25: { + std::cout << ">>>>>>> Running " + << "rocalSnPNoiseFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalSnPNoiseFixed(handle, tensor0, true, 0.2, 0.2, 0.2, 0.5, 0); + } + } + } break; + case 26: { + std::cout << ">>>>>>> Running " + << "rocalSnow" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalSnow(handle, tensor0, true); + } + } + } break; + case 27: { + std::cout << ">>>>>>> Running " + << "rocalSnowFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalSnowFixed(handle, tensor0, 0.5, true); + } + } + } break; + case 28: { + std::cout << ">>>>>>> Running " + << "rocalRain" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalRain(handle, tensor0, true); + } + } + } break; + case 29: { + std::cout << ">>>>>>> Running " + << "rocalRainFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalRainFixed(handle, tensor0, 0.5, 2, 16, 0.25, true); + } + } + } break; + case 30: { + std::cout << ">>>>>>> Running " + << "rocalColorTemp" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalColorTemp(handle, tensor0, true, color_temp_adj); + } + } + } break; + case 31: { + std::cout << ">>>>>>> Running " + << "rocalColorTempFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalColorTempFixed(handle, tensor0, 70, true); + } + } + } break; + case 32: { + std::cout << ">>>>>>> Running " + << "rocalFog" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalFog(handle, tensor0, true); + } + } + } break; + case 33: { + std::cout << ">>>>>>> Running " + << "rocalFogFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalFogFixed(handle, tensor0, true, 2.5); + } + } + } break; + case 34: { + std::cout << ">>>>>>> Running " + << "rocalLensCorrection" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalLensCorrection(handle, tensor0, true); + } + } + } break; + case 35: { + std::cout << ">>>>>>> Running " + << "rocalLensCorrectionFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalLensCorrectionFixed(handle, tensor0, 2.9, 1.5, true); + } + } + } break; + case 36: { + std::cout << ">>>>>>> Running " + << "rocalPixelate" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalPixelate(handle, tensor0, true); + } + } + } break; + case 37: { + std::cout << ">>>>>>> Running " + << "rocalExposure" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalExposure(handle, tensor0, true); + } + } + } break; + case 38: { + std::cout << ">>>>>>> Running " + << "rocalExposureFixed" << std::endl; + for (int j = 0; j < batch_size; j++) { + tensor0 = input_image; + for (int k = 0; k < graph_depth; k++) { + tensor0 = rocalExposureFixed(handle, tensor0, 1, true); + } + } + } break; + default: + std::cout << "Not a valid option! Exiting!\n"; + return -1; + } + + // Calling the API to verify and build the augmentation graph + rocalVerify(handle); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); + return -1; + } + + printf("Augmented copies count %lu\n", rocalGetAugmentationBranchCount(handle)); + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle); + int w = rocalGetOutputWidth(handle); + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + if (DISPLAY) + cv::namedWindow("output", CV_WINDOW_AUTOSIZE); + printf("Going to process images\n"); + printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + + int i = 0; + while (i++ < 1000) { + if (rocalRun(handle) != 0) + break; + + auto last_colot_temp = rocalGetIntValue(color_temp_adj); + rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); + + // rocalCopyToOutput(handle, mat_input.data, h * w * p); + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + + return 0; +} diff --git a/tests/cpp_api/rocAL_unittests/CMakeLists.txt b/tests/cpp_api/rocAL_unittests/CMakeLists.txt new file mode 100644 index 000000000..59de69611 --- /dev/null +++ b/tests/cpp_api/rocAL_unittests/CMakeLists.txt @@ -0,0 +1,73 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project (rocal_unittests) +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_unittests/README.md b/tests/cpp_api/rocAL_unittests/README.md new file mode 100644 index 000000000..dd4247fde --- /dev/null +++ b/tests/cpp_api/rocAL_unittests/README.md @@ -0,0 +1,51 @@ +# rocAL Unit Tests +This application can be used to verify the functionality of the API offered by rocAL. + +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 3.4+](https://github.com/opencv/opencv/releases/tag/3.4.0) +* ROCm Performance Primitives (RPP) +* Python3 +* Pillow + +Install Pillow library using `python3 -m pip install Pillow` + +### Build +```` +mkdir build +cd build +cmake ../ +make +```` +## Running the application + +``` +./rocAL_unittests + +Usage: ./rocAL_unittests reader-type pipeline-type=1(classification)2(detection)3(keypoints) output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all) +``` + +### Output verification + +The bash script `testAllScript.sh` can be used to run and dump the outputs for all test cases in rocAL and run the python script to verify the correctness of the generated outputs with the golden outputs. + +Input data is available in the following link : [MIVisionX-data](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data) + +`export ROCAL_DATA_PATH=` + +``` +./testAllScripts.sh +``` + +Device Type +* Option 0 - For only HOST backend +* Option 1 - For only HIP backend +* Option 2 - For both HOST and HIP backend + +Color Format +* Option 0 - For only Greyscale inputs +* Option 1 - For only RGB inputs +* Option 2 - For both Greyscale and RGB inputs diff --git a/tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py b/tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py new file mode 100644 index 000000000..f2aa93c62 --- /dev/null +++ b/tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py @@ -0,0 +1,180 @@ +# Copyright (c) 2023 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. + +from PIL import Image +import os +import sys +import datetime +import logging + + +def compare_pixels(img1, img2, aug_name, width, height, image_offset=0): + pixel_difference = [0, 0, 0, 0, 0, 0] + if "rgb" in aug_name: + pixels1 = img1.load() + pixels2 = img2.load() + channel = 3 + else: + pixels1 = img1.convert("L").load() + pixels2 = img2.convert("L").load() + channel = 1 + total_valid_pixel_count = width * height * channel + for wt in range(width): + for ht in range(height): + ht = ht + image_offset + if pixels1[wt, ht] != pixels2[wt, ht]: + if channel == 1: + diff_val = abs(pixels1[wt, ht] - pixels2[wt, ht]) + diff_val = min(diff_val, 5) + pixel_difference[diff_val] += 1 + else: + for ch in range(channel): + diff_val = abs( + pixels1[wt, ht][ch] - pixels2[wt, ht][ch]) + diff_val = min(diff_val, 5) + pixel_difference[diff_val] += 1 + else: + pixel_difference[0] += channel + return pixel_difference, total_valid_pixel_count + + +def main(): + timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S_") + handlers = [ + logging.FileHandler("./rocal_unittest_log_file_" + timestamp + ".log"), + logging.StreamHandler(), + ] + logging.basicConfig(level=logging.INFO, handlers=handlers) + if len(sys.argv) < 3: + print("Please pass ref_output_folder_path rocal_ouput_folder_path") + logging.error( + "Please pass ref_output_folder_path rocal_ouput_folder_path") + exit(0) + + # Open the two images + ref_output_path = sys.argv[1] + rocal_output_path = sys.argv[2] + + if not (os.path.exists(ref_output_path) and os.path.exists(rocal_output_path)): + logging.error("Path does not Exists") + exit() + + total_case_count = 0 + passed_case_count = 0 + failed_case_count = 0 + failed_case_list = [] + golden_output_dir_list = os.listdir(ref_output_path) + rocal_output_dir_list = os.listdir(rocal_output_path) + randomized_augmentation = ["Snow", "Rain", "Jitter", "SNPNoise"] + golden_file_path = "" + for aug_name in rocal_output_dir_list: + temp = aug_name.split(".") + file_name_split = temp[0].split("_") + if len(file_name_split) > 3: + file_name_split.pop() + golden_file_path = "_".join(file_name_split) + ".png" + else: + golden_file_path = aug_name + + # For randomized augmentation + if file_name_split[0] in randomized_augmentation: + total_case_count = total_case_count + 1 + augmentation_name = aug_name.split(".")[0] + logging.info("Running %s", augmentation_name) + passed_case_count = passed_case_count + 1 + logging.info("PASSED ") + elif golden_file_path in golden_output_dir_list: + total_case_count = total_case_count + 1 + ref_file_path = ref_output_path + golden_file_path + rocal_file_path = rocal_output_path + aug_name + if os.path.exists(rocal_file_path) and os.path.exists(ref_file_path): + logging.info("Running %s ", aug_name.split(".")[0]) + img1 = Image.open(ref_file_path) + img2 = Image.open(rocal_file_path) + + # Check if the images have the same dimensions + if img1.size != img2.size: + logging.info( + "Golden output and augmentation outputs are having different sizes. Exiting!") + exit() + + # Compare the pixel values for each image + pixel_diff = None + total_count = 0 + if "larger" in aug_name: + resize_width = 400 + resize_height = 300 + image_offset = 400 + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, resize_width, resize_height) + pixel_diff2, total_count2 = compare_pixels( + img1, img2, aug_name, resize_width, resize_height, image_offset) + pixel_diff = [x + y for x, + y in zip(pixel_diff, pixel_diff2)] + total_count = total_count + total_count2 + elif "smaller" in aug_name: + resize_width = 533 + resize_height = 400 + image_offset = 2400 + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, resize_width, resize_height) + pixel_diff2, total_count2 = compare_pixels( + img1, img2, aug_name, resize_width, resize_height, image_offset) + pixel_diff = [x + y for x, + y in zip(pixel_diff, pixel_diff2)] + total_count = total_count + total_count2 + else: + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, img1.size[0], img1.size[1]) + total_pixel_diff = 0 + for pix_diff in range(1, 6): + total_pixel_diff += pixel_diff[pix_diff] + mismatch_percentage = round( + (total_pixel_diff / total_count) * 100, 2) + if ((total_pixel_diff == 0) or (mismatch_percentage < 5.0 and pixel_diff[1] == total_pixel_diff) or # Ignore test cases with single pixel differences less than 5% of total pixel count + (mismatch_percentage < 0.5 and ("Blend" in aug_name or "Rotate" in aug_name) and "hip" in aug_name)): # Ignore mismatch in rotate augmentation less than 0.5% of total pixel count + passed_case_count = passed_case_count + 1 + logging.info("PASSED") + else: + failed_case_list.append(golden_file_path) + failed_case_count = failed_case_count + 1 + logging.info("FAILED") + logging.info("Printing pixel mismatch %s", pixel_diff) + logging.info("Mismatach percentage %0.2f", + mismatch_percentage) + for pix_diff in range(1, 6): + logging.info("Percentage of %d pixel mismatch %0.2f", pix_diff, round( + (pixel_diff[pix_diff] / total_pixel_diff) * 100, 2)) + else: + logging.info( + "Skipping the testcase as file not found %s", rocal_file_path) + else: + logging.info("File not found in ref_output_folder %s", + golden_file_path) + if len(failed_case_list) != 0: + logging.info("Failing cases: {}".format(", ".join(failed_case_list))) + logging.info( + "Total case passed --> {} / {} ".format(passed_case_count, total_case_count)) + logging.info( + "Total case failed --> {} / {} ".format(failed_case_count, total_case_count)) + + +if __name__ == "__main__": + main() diff --git a/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp b/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp new file mode 100644 index 000000000..d02e91d3a --- /dev/null +++ b/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp @@ -0,0 +1,814 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; + +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#endif + +#define DISPLAY 0 +// #define RANDOMBBOXCROP + +using namespace std::chrono; + +std::string get_interpolation_type(unsigned int val, RocalResizeInterpolationType &interpolation_type) { + switch (val) { + case 0: { + interpolation_type = ROCAL_NEAREST_NEIGHBOR_INTERPOLATION; + return "NearestNeighbor"; + } + case 2: { + interpolation_type = ROCAL_CUBIC_INTERPOLATION; + return "Bicubic"; + } + case 3: { + interpolation_type = ROCAL_LANCZOS_INTERPOLATION; + return "Lanczos"; + } + case 4: { + interpolation_type = ROCAL_GAUSSIAN_INTERPOLATION; + return "Gaussian"; + } + case 5: { + interpolation_type = ROCAL_TRIANGULAR_INTERPOLATION; + return "Triangular"; + } + default: { + interpolation_type = ROCAL_LINEAR_INTERPOLATION; + return "Bilinear"; + } + } +} + +std::string get_scaling_mode(unsigned int val, RocalResizeScalingMode &scale_mode) { + switch (val) { + case 1: { + scale_mode = ROCAL_SCALING_MODE_STRETCH; + return "Stretch"; + } + case 2: { + scale_mode = ROCAL_SCALING_MODE_NOT_SMALLER; + return "NotSmaller"; + } + case 3: { + scale_mode = ROCAL_SCALING_MODE_NOT_LARGER; + return "Notlarger"; + } + default: { + scale_mode = ROCAL_SCALING_MODE_DEFAULT; + return "Default"; + } + } +} + +int test(int test_case, int reader_type, const char *path, const char *outName, int rgb, int gpu, int width, int height, int num_of_classes, int display_all, int resize_interpolation_type, int resize_scaling_mode); +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf("Usage: rocal_unittests reader-type output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all)\n"); + return -1; + } + + int argIdx = 0; + int reader_type = atoi(argv[++argIdx]); + const char *path = argv[++argIdx]; + const char *outName = argv[++argIdx]; + int width = atoi(argv[++argIdx]); + int height = atoi(argv[++argIdx]); + int display_all = 0; + + int rgb = 1; // process color images + bool gpu = 1; + int test_case = 3; // For Rotate + int num_of_classes = 0; + int resize_interpolation_type = 1; // For Bilinear interpolations + int resize_scaling_mode = 0; // For Default scaling mode + + if (argc >= argIdx + MIN_ARG_COUNT) + test_case = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + gpu = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + num_of_classes = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + display_all = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + resize_interpolation_type = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + resize_scaling_mode = atoi(argv[++argIdx]); + + test(test_case, reader_type, path, outName, rgb, gpu, width, height, num_of_classes, display_all, resize_interpolation_type, resize_scaling_mode); + + return 0; +} + +int test(int test_case, int reader_type, const char *path, const char *outName, int rgb, int gpu, int width, int height, int num_of_classes, int display_all, int resize_interpolation_type, int resize_scaling_mode) { + size_t num_threads = 1; + unsigned int input_batch_size = 2; + int decode_max_width = width; + int decode_max_height = height; + int pipeline_type = -1; + std::cout << ">>> test case " << test_case << std::endl; + std::cout << ">>> Running on " << (gpu ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 + : RocalImageColor::ROCAL_COLOR_U8; + + auto handle = rocalCreate(input_batch_size, + gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, + 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>> Getting the path for MIVisionX-data <<<<<<<<<<<<<<<<*/ + + std::string rocal_data_path; + if (std::getenv("ROCAL_DATA_PATH")) + rocal_data_path = std::getenv("ROCAL_DATA_PATH"); + + /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ + + rocalSetSeed(0); + + // Creating uniformly distributed random objects to override some of the default augmentation parameters + RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); + RocalIntParam mirror = rocalCreateIntParameter(1); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + +#if defined RANDOMBBOXCROP + bool all_boxes_overlap = true; + bool no_crop = false; +#endif + + RocalTensor decoded_output; + RocalTensorLayout output_tensor_layout = (rgb != 0) ? RocalTensorLayout::ROCAL_NHWC : RocalTensorLayout::ROCAL_NCHW; + RocalTensorOutputType output_tensor_dtype = RocalTensorOutputType::ROCAL_UINT8; + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + switch (reader_type) { + case 1: // image_partial decode + { + std::cout << ">>>>>>> Running PARTIAL DECODE" << std::endl; + pipeline_type = 1; + rocalCreateLabelReader(handle, path); + std::vector area = {0.08, 1}; + std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; + decoded_output = rocalFusedJpegCrop(handle, path, color_format, num_threads, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 2: // coco detection + { + std::cout << ">>>>>>> Running COCO READER" << std::endl; + pipeline_type = 2; + if (strcmp(rocal_data_path.c_str(), "") == 0) { + std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; + exit(0); + } + // setting the default json path to ROCAL_DATA_PATH coco sample train annotation + std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img/annotations/instances_train2017.json"; + rocalCreateCOCOReader(handle, json_path.c_str(), true); + if (decode_max_height <= 0 || decode_max_width <= 0) + decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false); + else + decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 3: // coco detection partial + { + std::cout << ">>>>>>> Running COCO READER PARTIAL" << std::endl; + pipeline_type = 2; + if (strcmp(rocal_data_path.c_str(), "") == 0) { + std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; + exit(0); + } + // setting the default json path to ROCAL_DATA_PATH coco sample train annotation + std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img/annotations/instances_train2017.json"; + rocalCreateCOCOReader(handle, json_path.c_str(), true); +#if defined RANDOMBBOXCROP + rocalRandomBBoxCrop(handle, all_boxes_overlap, no_crop); +#endif + std::vector area = {0.08, 1}; + std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; + decoded_output = rocalJpegCOCOFileSourcePartial(handle, path, json_path.c_str(), color_format, num_threads, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 4: // tf classification + { + std::cout << ">>>>>>> Running TF CLASSIFICATION READER" << std::endl; + pipeline_type = 1; + char key1[25] = "image/encoded"; + char key2[25] = "image/class/label"; + char key8[25] = "image/filename"; + rocalCreateTFReader(handle, path, true, key2, key8); + decoded_output = rocalJpegTFRecordSource(handle, path, color_format, num_threads, false, key1, key8, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 5: // tf detection + { + std::cout << ">>>>>>> Running TF DETECTION READER" << std::endl; + pipeline_type = 2; + char key1[25] = "image/encoded"; + char key2[25] = "image/object/class/label"; + char key3[25] = "image/object/class/text"; + char key4[25] = "image/object/bbox/xmin"; + char key5[25] = "image/object/bbox/ymin"; + char key6[25] = "image/object/bbox/xmax"; + char key7[25] = "image/object/bbox/ymax"; + char key8[25] = "image/filename"; + rocalCreateTFReaderDetection(handle, path, true, key2, key3, key4, key5, key6, key7, key8); + decoded_output = rocalJpegTFRecordSource(handle, path, color_format, num_threads, false, key1, key8, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 6: // caffe classification + { + std::cout << ">>>>>>> Running CAFFE CLASSIFICATION READER" << std::endl; + pipeline_type = 1; + rocalCreateCaffeLMDBLabelReader(handle, path); + decoded_output = rocalJpegCaffeLMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 7: // caffe detection + { + std::cout << ">>>>>>> Running CAFFE DETECTION READER" << std::endl; + pipeline_type = 2; + rocalCreateCaffeLMDBReaderDetection(handle, path); + decoded_output = rocalJpegCaffeLMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 8: // caffe2 classification + { + std::cout << ">>>>>>> Running CAFFE2 CLASSIFICATION READER" << std::endl; + pipeline_type = 1; + rocalCreateCaffe2LMDBLabelReader(handle, path, true); + decoded_output = rocalJpegCaffe2LMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 9: // caffe2 detection + { + std::cout << ">>>>>>> Running CAFFE2 DETECTION READER" << std::endl; + pipeline_type = 2; + rocalCreateCaffe2LMDBReaderDetection(handle, path, true); + decoded_output = rocalJpegCaffe2LMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 10: // coco reader keypoints + { + std::cout << ">>>>>>> Running COCO KEYPOINTS READER" << std::endl; + pipeline_type = 3; + if (strcmp(rocal_data_path.c_str(), "") == 0) { + std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; + exit(0); + } + // setting the default json path to ROCAL_DATA_PATH coco sample train annotation + std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img_keypoints/annotations/person_keypoints_val2017.json"; + float sigma = 3.0; + rocalCreateCOCOReaderKeyPoints(handle, json_path.c_str(), true, sigma, (unsigned)width, (unsigned)height); + if (decode_max_height <= 0 || decode_max_width <= 0) + decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false); + else + decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + case 11: // mxnet reader + { + std::cout << ">>>>>>> Running MXNET READER" << std::endl; + pipeline_type = 1; + rocalCreateMXNetReader(handle, path, true); + decoded_output = rocalMXNetRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + default: { + std::cout << ">>>>>>> Running IMAGE READER" << std::endl; + pipeline_type = 1; + rocalCreateLabelReader(handle, path); + if (decode_max_height <= 0 || decode_max_width <= 0) + decoded_output = rocalJpegFileSource(handle, path, color_format, num_threads, false, true); + else + decoded_output = rocalJpegFileSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); + } break; + } + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + int resize_w = width, resize_h = height; // height and width + + RocalTensor input = decoded_output; + // RocalTensor input = rocalResize(handle, decoded_output, resize_w, resize_h, false); // uncomment when processing images of different size + RocalTensor output; + + if ((test_case == 48 || test_case == 49 || test_case == 50) && rgb == 0) { + std::cout << "Not a valid option! Exiting!\n"; + return -1; + } + switch (test_case) { + case 0: { + std::cout << ">>>>>>> Running " + << "rocalResize" << std::endl; + resize_w = 400; + resize_h = 400; + std::string interpolation_type_name, scaling_node_name; + RocalResizeInterpolationType interpolation_type; + RocalResizeScalingMode scale_mode; + interpolation_type_name = get_interpolation_type(resize_interpolation_type, interpolation_type); + scaling_node_name = get_scaling_mode(resize_scaling_mode, scale_mode); + std::cerr << " \n Interpolation_type_name " << interpolation_type_name; + std::cerr << " \n Scaling_node_name " << scaling_node_name << std::endl; + if (scale_mode != ROCAL_SCALING_MODE_DEFAULT && interpolation_type != ROCAL_LINEAR_INTERPOLATION) { // (Reference output available for bilinear interpolation for this + std::cerr << " \n Running " << scaling_node_name << " scaling mode with Bilinear interpolation for comparison \n"; + interpolation_type = ROCAL_LINEAR_INTERPOLATION; + } + if (scale_mode == ROCAL_SCALING_MODE_STRETCH) // For reference Output comparison + output = rocalResize(handle, input, resize_w, 0, true, scale_mode, {}, 0, 0, interpolation_type); + else + output = rocalResize(handle, input, resize_w, resize_h, true, scale_mode, {}, 0, 0, interpolation_type); + } break; + case 1: { + std::cout << ">>>>>>> Running " + << "rocalCropResize" << std::endl; + output = rocalCropResize(handle, input, resize_w, resize_h, true); + } break; + case 2: { + std::cout << ">>>>>>> Running " + << "rocalRotate" << std::endl; + output = rocalRotate(handle, input, true); + } break; + case 3: { + std::cout << ">>>>>>> Running " + << "rocalBrightness" << std::endl; + output = rocalBrightness(handle, input, true); + } break; + case 4: { + std::cout << ">>>>>>> Running " + << "rocalGamma" << std::endl; + output = rocalGamma(handle, input, true); + } break; + case 5: { + std::cout << ">>>>>>> Running " + << "rocalContrast" << std::endl; + output = rocalContrast(handle, input, true); + } break; + case 6: { + std::cout << ">>>>>>> Running " + << "rocalFlip" << std::endl; + output = rocalFlip(handle, input, true); + } break; + case 7: { + std::cout << ">>>>>>> Running " + << "rocalBlur" << std::endl; + output = rocalBlur(handle, input, true); + } break; + case 8: { + std::cout << ">>>>>>> Running " + << "rocalBlend" << std::endl; + RocalTensor output_1 = rocalRotate(handle, input, false); + output = rocalBlend(handle, input, output_1, true); + } break; + case 9: { + std::cout << ">>>>>>> Running " + << "rocalWarpAffine" << std::endl; + output = rocalWarpAffine(handle, input, true); + } break; + case 10: { + std::cout << ">>>>>>> Running " + << "rocalFishEye" << std::endl; + output = rocalFishEye(handle, input, true); + } break; + case 11: { + std::cout << ">>>>>>> Running " + << "rocalVignette" << std::endl; + output = rocalVignette(handle, input, true); + } break; + case 12: { + std::cout << ">>>>>>> Running " + << "rocalJitter" << std::endl; + output = rocalJitter(handle, input, true); + } break; + case 13: { + std::cout << ">>>>>>> Running " + << "rocalSnPNoise" << std::endl; + output = rocalSnPNoise(handle, input, true); + } break; + case 14: { + std::cout << ">>>>>>> Running " + << "rocalSnow" << std::endl; + output = rocalSnow(handle, input, true); + } break; + case 15: { + std::cout << ">>>>>>> Running " + << "rocalRain" << std::endl; + output = rocalRain(handle, input, true); + } break; + case 16: { + std::cout << ">>>>>>> Running " + << "rocalColorTemp" << std::endl; + output = rocalColorTemp(handle, input, true); + } break; + case 17: { + std::cout << ">>>>>>> Running " + << "rocalFog" << std::endl; + output = rocalFog(handle, input, true); + } break; + case 18: { + std::cout << ">>>>>>> Running " + << "rocalLensCorrection" << std::endl; + output = rocalLensCorrection(handle, input, true); + } break; + case 19: { + std::cout << ">>>>>>> Running " + << "rocalPixelate" << std::endl; + output = rocalPixelate(handle, input, true); + } break; + case 20: { + std::cout << ">>>>>>> Running " + << "rocalExposure" << std::endl; + output = rocalExposure(handle, input, true); + } break; + case 21: { + std::cout << ">>>>>>> Running " + << "rocalHue" << std::endl; + output = rocalHue(handle, input, true); + } break; + case 22: { + std::cout << ">>>>>>> Running " + << "rocalSaturation" << std::endl; + output = rocalSaturation(handle, input, true); + } break; + case 23: { + std::cout << ">>>>>>> Running " + << "rocalCopy" << std::endl; + output = rocalCopy(handle, input, true); + } break; + case 24: { + std::cout << ">>>>>>> Running " + << "rocalColorTwist" << std::endl; + output = rocalColorTwist(handle, input, true); + } break; + case 25: { + std::cout << ">>>>>>> Running " + << "rocalCropMirrorNormalize" << std::endl; + std::vector mean = {128, 128, 128}; + std::vector std_dev = {1.2, 1.2, 1.2}; + output = rocalCropMirrorNormalize(handle, input, 224, 224, 0, 0, mean, std_dev, true, mirror, output_tensor_layout, output_tensor_dtype); + } break; + case 26: { + std::cout << ">>>>>>> Running " + << "rocalCrop" << std::endl; + output = rocalCrop(handle, input, true); + } break; + case 27: { + std::cout << ">>>>>>> Running " + << "rocalResizeCropMirror" << std::endl; + output = rocalResizeCropMirror(handle, input, resize_w, resize_h, true); + } break; + + case 30: { + std::cout << ">>>>>>> Running " + << "rocalCropResizeFixed" << std::endl; + output = rocalCropResizeFixed(handle, input, resize_w, resize_h, true, 0.25, 1.2, 0.6, 0.4); + } break; + case 31: { + std::cout << ">>>>>>> Running " + << "rocalRotateFixed" << std::endl; + output = rocalRotateFixed(handle, input, 45, true); + } break; + case 32: { + std::cout << ">>>>>>> Running " + << "rocalBrightnessFixed" << std::endl; + output = rocalBrightnessFixed(handle, input, 1.90, 20, true); + } break; + case 33: { + std::cout << ">>>>>>> Running " + << "rocalGammaFixed" << std::endl; + output = rocalGammaFixed(handle, input, 0.5, true); + } break; + case 34: { + std::cout << ">>>>>>> Running " + << "rocalContrastFixed" << std::endl; + output = rocalContrastFixed(handle, input, 30, 80, true); + } break; + case 35: { + std::cout << ">>>>>>> Running " + << "rocalBlurFixed" << std::endl; + output = rocalBlurFixed(handle, input, 5, true); + } break; + case 36: { + std::cout << ">>>>>>> Running " + << "rocalBlendFixed" << std::endl; + RocalTensor output_1 = rocalRotateFixed(handle, input, 45, false); + output = rocalBlendFixed(handle, input, output_1, 0.5, true); + } break; + case 37: { + std::cout << ">>>>>>> Running " + << "rocalWarpAffineFixed" << std::endl; + output = rocalWarpAffineFixed(handle, input, 1, 1, 0.5, 0.5, 7, 7, true); + } break; + case 38: { + std::cout << ">>>>>>> Running " + << "rocalVignetteFixed" << std::endl; + output = rocalVignetteFixed(handle, input, 50, true); + } break; + case 39: { + std::cout << ">>>>>>> Running " + << "rocalJitterFixed" << std::endl; + output = rocalJitterFixed(handle, input, 3, true); + } break; + case 40: { + std::cout << ">>>>>>> Running " + << "rocalSnPNoiseFixed" << std::endl; + output = rocalSnPNoiseFixed(handle, input, 0.2, 0.2, 0.2, 0.5, true, 0); + } break; + case 41: { + std::cout << ">>>>>>> Running " + << "rocalSnowFixed" << std::endl; + output = rocalSnowFixed(handle, input, 0.2, true); + } break; + case 42: { + std::cout << ">>>>>>> Running " + << "rocalRainFixed" << std::endl; + output = rocalRainFixed(handle, input, 0.5, 2, 16, 0.25, true); + } break; + case 43: { + std::cout << ">>>>>>> Running " + << "rocalColorTempFixed" << std::endl; + output = rocalColorTempFixed(handle, input, 70, true); + } break; + case 44: { + std::cout << ">>>>>>> Running " + << "rocalFogFixed" << std::endl; + output = rocalFogFixed(handle, input, 0.5, true); + } break; + case 45: { + std::cout << ">>>>>>> Running " + << "rocalLensCorrectionFixed" << std::endl; + output = rocalLensCorrectionFixed(handle, input, 2.9, 1.2, true); + } break; + case 46: { + std::cout << ">>>>>>> Running " + << "rocalExposureFixed" << std::endl; + output = rocalExposureFixed(handle, input, 1, true); + } break; + case 47: { + std::cout << ">>>>>>> Running " + << "rocalFlipFixed" << std::endl; + output = rocalFlipFixed(handle, input, 1, 0, true); + } break; + case 48: { + std::cout << ">>>>>>> Running " + << "rocalHueFixed" << std::endl; + output = rocalHueFixed(handle, input, 150, true); + } break; + case 49: { + std::cout << ">>>>>>> Running " + << "rocalSaturationFixed" << std::endl; + output = rocalSaturationFixed(handle, input, 0.3, true); + } break; + case 50: { + std::cout << ">>>>>>> Running " + << "rocalColorTwistFixed" << std::endl; + output = rocalColorTwistFixed(handle, input, 0.2, 10.0, 100.0, 0.25, true); + } break; + case 51: { + std::cout << ">>>>>>> Running " + << "rocalCropFixed" << std::endl; + output = rocalCropFixed(handle, input, 224, 224, 1, true, 0, 0, 0); + } break; + case 52: { + std::cout << ">>>>>>> Running " + << "rocalCropCenterFixed" << std::endl; + output = rocalCropCenterFixed(handle, input, 224, 224, 2, true); + } break; + case 53: { + std::cout << ">>>>>>> Running " + << "rocalResizeCropMirrorFixed" << std::endl; + output = rocalResizeCropMirrorFixed(handle, input, 400, 400, true, 200, 200, mirror); + } break; + case 54: { + std::cout << ">>>>>>> Running " + << "rocalSSDRandomCrop" << std::endl; + output = rocalSSDRandomCrop(handle, input, true); + } break; + case 55: { + std::cout << ">>>>>>> Running " + << "rocalCropMirrorNormalizeFixed_center crop" << std::endl; + std::vector mean = {128, 128, 128}; + std::vector std_dev = {1.2, 1.2, 1.2}; + output = rocalCropMirrorNormalize(handle, input, 224, 224, 0.5, 0.5, mean, std_dev, true, mirror); + } break; + case 56: { + std::vector mean = {128, 128, 128}; + std::vector std_dev = {1.2, 1.2, 1.2}; + std::cout << ">>>>>>> Running " + << " Resize Mirror Normalize " << std::endl; + output = rocalResizeMirrorNormalize(handle, input, 400, 400, mean, std_dev, true, ROCAL_SCALING_MODE_DEFAULT, + {}, 0, 0, ROCAL_LINEAR_INTERPOLATION, mirror); + } break; + + default: + std::cout << "Not a valid option! Exiting!\n"; + return -1; + } + + // Calling the API to verify and build the augmentation graph + rocalVerify(handle); + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); + return -1; + } + + auto number_of_outputs = rocalGetAugmentationBranchCount(handle); + std::cout << "\n\nAugmented copies count " << number_of_outputs << "\n"; + + if (number_of_outputs != 1) { + std::cout << "More than 1 output set in the pipeline"; + return -1; + } + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * input_batch_size; + int w = rocalGetOutputWidth(handle); + int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); + const unsigned number_of_cols = 1; // 1920 / w; + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + int col_counter = 0; + if (DISPLAY) + cv::namedWindow("output", CV_WINDOW_AUTOSIZE); + printf("Going to process images\n"); + printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int index = 0; + + while (rocalGetRemainingImages(handle) >= input_batch_size) { + index++; + if (rocalRun(handle) != 0) + break; + int image_name_length[input_batch_size]; + switch (pipeline_type) { + case 1: { // classification pipeline + RocalTensorList labels = rocalGetImageLabels(handle); + int *label_id = reinterpret_cast(labels->at(0)->buffer()); // The labels are present contiguously in memory + int img_size = rocalGetImageNameLen(handle, image_name_length); + char img_name[img_size]; + int label_one_hot_encoded[input_batch_size * num_of_classes]; + rocalGetImageName(handle, img_name); + if (num_of_classes != 0) { + rocalGetOneHotImageLabels(handle, label_one_hot_encoded, num_of_classes, RocalOutputMemType::ROCAL_MEMCPY_HOST); + } + std::cerr << "\nPrinting image names of batch: " << img_name << "\n"; + for (unsigned int i = 0; i < input_batch_size; i++) { + std::cerr << "\t Printing label_id : " << label_id[i] << std::endl; + if(num_of_classes != 0) + { + std::cout << "One Hot Encoded labels:"<<"\t"; + for (int j = 0; j < num_of_classes; j++) + { + int idx_value = label_one_hot_encoded[(i*num_of_classes)+j]; + if(idx_value == 0) + std::cout << idx_value << "\t"; + else + { + std::cout << idx_value << "\t"; + } + } + } + std::cout << "\n"; + } + } break; + case 2: { // detection pipeline + int img_size = rocalGetImageNameLen(handle, image_name_length); + char img_name[img_size]; + rocalGetImageName(handle, img_name); + std::cerr << "\nPrinting image names of batch: " << img_name; + RocalTensorList bbox_labels = rocalGetBoundingBoxLabel(handle); + RocalTensorList bbox_coords = rocalGetBoundingBoxCords(handle); + for (unsigned i = 0; i < bbox_labels->size(); i++) { + int *labels_buffer = reinterpret_cast(bbox_labels->at(i)->buffer()); + float *bbox_buffer = reinterpret_cast(bbox_coords->at(i)->buffer()); + std::cerr << "\n>>>>> BBOX LABELS : "; + for (unsigned j = 0; j < bbox_labels->at(i)->dims().at(0); j++) + std::cerr << labels_buffer[j] << " "; + std::cerr << "\n>>>>> BBOX : " << bbox_coords->at(i)->dims().at(0) << " : \n"; + for (unsigned j = 0, j4 = 0; j < bbox_coords->at(i)->dims().at(0); j++, j4 = j * 4) + std::cerr << bbox_buffer[j4] << " " << bbox_buffer[j4 + 1] << " " << bbox_buffer[j4 + 2] << " " << bbox_buffer[j4 + 3] << "\n"; + } + int img_sizes_batch[input_batch_size * 2]; + rocalGetImageSizes(handle, img_sizes_batch); + for (int i = 0; i < (int)input_batch_size; i++) { + std::cout << "\nwidth:" << img_sizes_batch[i * 2]; + std::cout << "\nHeight:" << img_sizes_batch[(i * 2) + 1]; + } + } break; + case 3: { // keypoints pipeline + int size = input_batch_size; + RocalJointsData *joints_data; + rocalGetJointsDataPtr(handle, &joints_data); + for (int i = 0; i < size; i++) { + std::cout << "ImageID: " << joints_data->image_id_batch[i] << std::endl; + std::cout << "AnnotationID: " << joints_data->annotation_id_batch[i] << std::endl; + std::cout << "ImagePath: " << joints_data->image_path_batch[i] << std::endl; + std::cout << "Center: " << joints_data->center_batch[i][0] << " " << joints_data->center_batch[i][1] << std::endl; + std::cout << "Scale: " << joints_data->scale_batch[i][0] << " " << joints_data->scale_batch[i][1] << std::endl; + std::cout << "Score: " << joints_data->score_batch[i] << std::endl; + std::cout << "Rotation: " << joints_data->rotation_batch[i] << std::endl; + + for (int k = 0; k < 17; k++) { + std::cout << "x : " << joints_data->joints_batch[i][k][0] << " , y : " << joints_data->joints_batch[i][k][1] << " , v : " << joints_data->joints_visibility_batch[i][k][0] << std::endl; + } + } + } break; + default: { + std::cout << "Not a valid pipeline type ! Exiting!\n"; + return -1; + } + } + auto last_colot_temp = rocalGetIntValue(color_temp_adj); + rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); + + rocalCopyToOutput(handle, mat_input.data, h * w * p); + + std::vector compression_params; + compression_params.push_back(IMWRITE_PNG_COMPRESSION); + compression_params.push_back(9); + + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + std::string out_filename = std::string(outName) + ".png"; // in case the user specifies non png filename + if (display_all) + out_filename = std::string(outName) + std::to_string(index) + ".png"; // in case the user specifies non png filename + + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + if (DISPLAY) + cv::imshow("output", mat_output); + else + cv::imwrite(out_filename, mat_color, compression_params); + } else { + if (DISPLAY) + cv::imshow("output", mat_output); + else + cv::imwrite(out_filename, mat_output, compression_params); + } + col_counter = (col_counter + 1) % number_of_cols; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + if (!output) + return -1; + return 0; +} diff --git a/tests/cpp_api/rocAL_unittests/testAllScripts.sh b/tests/cpp_api/rocAL_unittests/testAllScripts.sh new file mode 100755 index 000000000..b41bd95b3 --- /dev/null +++ b/tests/cpp_api/rocAL_unittests/testAllScripts.sh @@ -0,0 +1,177 @@ +#!/bin/bash +cwd=$(pwd) +if [ -d build ];then + sudo rm -rf ./build/* +else + mkdir build +fi +cd build || exit +cmake .. +make -j"$(nproc)" + +if [[ $ROCAL_DATA_PATH == "" ]] +then + echo "Need to export ROCAL_DATA_PATH" + exit +fi + +# Path to inputs and outputs available in MIVisionX-data +image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ +tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ +caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ +caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ +caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ +caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ +mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ +output_path=../rocal_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ +golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ + +display=0 +device=0 +width=640 +height=480 +device_name="host" +rgb_name=("gray" "rgb") +rgb=1 +dev_start=0 +dev_end=1 +rgb_start=0 +rgb_end=1 + +if [ "$#" -gt 0 ]; then + if [ "$1" -eq 0 ]; then # For only HOST backend + dev_start=0 + dev_end=0 + elif [ "$1" -eq 1 ]; then # For only HIP backend + dev_start=1 + dev_end=1 + elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend + dev_start=0 + dev_end=1 + fi +fi + +if [ "$#" -gt 1 ]; then + if [ "$2" -eq 0 ]; then # For only Greyscale inputs + rgb_start=0 + rgb_end=0 + elif [ "$2" -eq 1 ]; then # For only RGB inputs + rgb_start=1 + rgb_end=1 + elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs + rgb_start=0 + rgb_end=1 + fi +fi + +mkdir "$output_path" + +for ((device=dev_start;device<=dev_end;device++)) +do + if [ $device -eq 1 ] + then + device_name="hip" + echo "Running HIP Backend..." + else + echo "Running HOST Backend..." + fi + for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) + do + # FileSource Reader + ./rocal_unittests 0 "$image_path" "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" $width $height 45 $device $rgb 0 $display + ./rocal_unittests 0 "$image_path" "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" $width $height 46 $device $rgb 0 $display + ./rocal_unittests 0 "$image_path" "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" $width $height 47 $device $rgb 0 $display + + # FileSource Reader + partial decoder + ./rocal_unittests 1 "$image_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 41 $device $rgb 0 $display + ./rocal_unittests 1 "$image_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 42 $device $rgb 0 $display + ./rocal_unittests 1 "$image_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 40 $device $rgb 0 $display + + # coco detection + ./rocal_unittests 2 "$coco_detection_path" "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" $width $height 33 $device $rgb 0 $display + ./rocal_unittests 2 "$coco_detection_path" "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" $width $height 34 $device $rgb 0 $display + ./rocal_unittests 2 "$coco_detection_path" "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" $width $height 38 $device $rgb 0 $display + + # coco detection + partial decoder + ./rocal_unittests 3 "$coco_detection_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 41 $device $rgb 0 $display + ./rocal_unittests 3 "$coco_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 42 $device $rgb 0 $display + ./rocal_unittests 3 "$coco_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 40 $device $rgb 0 $display + + # tf classification + ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" $width $height 36 $device $rgb 0 $display + ./rocal_unittests 4 "$tf_classification_path" "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" $width $height 37 $device $rgb 0 $display + ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" $width $height 35 $device $rgb 0 $display + + # tf detection + ./rocal_unittests 5 "$tf_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" $width $height 40 $device $rgb 0 $display + ./rocal_unittests 5 "$tf_detection_path" "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" $width $height 43 $device $rgb 0 $display + ./rocal_unittests 5 "$tf_detection_path" "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" $width $height 44 $device $rgb 0 $display + + # caffe classification + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" $width $height 31 $device $rgb 0 $display + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" $width $height 32 $device $rgb 0 $display + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" $width $height 48 $device $rgb 0 $display + + # caffe detection + ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" $width $height 49 $device $rgb 0 $display + ./rocal_unittests 7 "$caffe_detection_path" "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" $width $height 50 $device $rgb 0 $display + ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" $width $height 42 $device $rgb 0 $display + + # caffe2 classification + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" $width $height 52 $device $rgb 0 $display + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" $width $height 53 $device $rgb 0 $display + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" $width $height 41 $device $rgb 0 $display + + # caffe2 detection + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" $width $height 10 $device $rgb 0 $display + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropCenterCMN_${rgb_name[$rgb]}_${device_name}" $width $height 55 $device $rgb 0 $display + + # mxnet + ./rocal_unittests 11 "$mxnet_path" "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" $width $height 39 $device $rgb 0 $display + ./rocal_unittests 11 "$mxnet_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display + ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display + + # CMN + ./rocal_unittests 0 "$image_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 2 "$coco_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 4 "$tf_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 5 "$tf_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 7 "$caffe_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 25 $device $rgb 0 $display + ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display + + # crop + ./rocal_unittests 0 "$image_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 2 "$coco_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 4 "$tf_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 5 "$tf_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 51 $device $rgb 0 $display + ./rocal_unittests 11 "$mxnet_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 51 $device $rgb 0 $display + + # resize + # Last two parameters are interpolation type and scaling mode + ./rocal_unittests 0 "$image_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" $width $height 0 $device $rgb 0 $display 1 0 + ./rocal_unittests 2 "$coco_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" $width $height 0 $device $rgb 0 $display 1 1 + ./rocal_unittests 4 "$tf_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" $width $height 0 $device $rgb 0 $display 1 2 + ./rocal_unittests 5 "$tf_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" $width $height 0 $device $rgb 0 $display 1 3 + ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" $width $height 0 $device $rgb 0 $display 2 0 + # ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" $width $height 0 $device $rgb 0 $display 0 0 + ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" $width $height 0 $device $rgb 0 $display 3 0 + ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" $width $height 0 $device $rgb 0 $display 5 0 + ./rocal_unittests 11 "$mxnet_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" $width $height 0 $device $rgb 0 $display 4 0 + + done +done + +pwd + +# Run python script to compare rocAL outputs with golden ouptuts +python3 "$cwd"/pixel_comparison/image_comparison.py "$golden_output_path" "$output_path" diff --git a/tests/cpp_api/rocAL_video_unittests/CMakeLists.txt b/tests/cpp_api/rocAL_video_unittests/CMakeLists.txt new file mode 100644 index 000000000..81bec5c67 --- /dev/null +++ b/tests/cpp_api/rocAL_video_unittests/CMakeLists.txt @@ -0,0 +1,75 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ +cmake_minimum_required(VERSION 3.5) + +project (rocal_video_unittests) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") + +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(OpenCV QUIET) +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/lib/) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + +target_link_libraries(${PROJECT_NAME} rocal) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_video_unittests/README.md b/tests/cpp_api/rocAL_video_unittests/README.md new file mode 100644 index 000000000..af791c77d --- /dev/null +++ b/tests/cpp_api/rocAL_video_unittests/README.md @@ -0,0 +1,132 @@ +# rocAL Video Unit Tests +This application can be used to verify the functionality of the video API offered by rocAL. + +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, version - `18.04` / `20.04` +* rocAL library (Part of the MIVisionX toolkit) +* [OpenCV 4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) +* [FFmpeg n4.4.2](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2) +* ROCm Performance Primitives (RPP) + +### Running the application +Executing the below command will build and run the application for the specified test case. + +```` +./testScript.sh +```` + +The arguments passed to the Video Pipeline can be modified in the bash script [testScript.sh](./testScript.sh). + +The outputs will be dumped inside the build/output_frames folder. + +The sample video files and folder are available in the In the following path : [video and sequence samples](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples). + +The data samples can be downloaded from the MIVisionX-data repository. + +``` +git clone https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data.git +``` + +## Description + +### Test Cases + +The following test cases are supported in this unittest: +1. Video Reader - Reads the video file/folder and returns a sequence of frames. +2. Video Reader Resize (reader followed by resize augmentation) - Reads the video file/folder and returns a sequence of re-sized frames. +3. Sequence Reader - Reads the folder of images and returns a sequence of images. + +### Arguments used in test script + +INPUT_PATH : Input passed by the user. It can be a video file path, folder path containing videos or a text file. + + NOTE: + + * Inputs for cases 1 and 2 - Video file / folder containing videos + * Input for case 3 - Folder containing sequence of images [sample folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence) + +READER_CASE : Value passed can be 1/2/3 depending upon the selected reader (default value : 1). + +SAVE_FRAMES : Saves the output frames or avi files in the build/output_frames folder. + +DEVICE : CPU:0/GPU:1 device is supported. + +HARDWARE_DECODE_MODE : Uses Hardware decoder if set to true. + +SHUFFLE : Shuffles the sequences if set to true. + +BATCH SIZE : Number of sequences in a batch. + +SEQUENCE LENGTH : Number of frames in a sequence. + +STEP : The frame interval between sequences. + +STRIDE : The frame interval between frames within a sequence. + +RESIZE_WIDTH : Resize width value. + +RESIZE_HEIGHT : Resize height value. + +FILELIST_FRAMENUM : If set to true the inputs from text file will be considered as frame numbers otherwise they will be considered as timestamps. + +ENABLE_METADATA : If set to true, prints the labels and names of the associated frames in the sequence. + +ENABLE_FRAME_NUMBER : If set to true, prints the starting frame number of the sequences. + +ENABLE_TIMESTAMPS : If set to true, prints the timestamp of each frame in the sequences. + +ENABLE_SEQUENCE_REARRANGE : If set to true, the frames in each sequence will be rearranged in the order specified by the user. The order should contain values in the range of [0, sequence_length) + +## Test case examples + +**Example 1: Video Reader** + +> ./testScript.sh <[path/to/test_frame_num.mp4](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/blob/main/rocal_data/video_and_sequence_samples/test_frame/test_frame_num.mp4)> 1 + +Arguments to be modified in testScript.sh to get the following output: + +- BATCH_SIZE=2 +- SEQUENCE_LENGTH= 3 +- STEP=3 +- STRIDE=5 + +![video_reader.png](./samples/video_reader.png) + +To test with VideoReaderResize pass reader_case as 2: +> ./testScript.sh 2 + +Also RESIZE_WIDTH and RESIZE_HEIGHT can be changed in testScript.sh + +
+ +**Example 2: Sequence Reader** + +> ./testScript.sh <[path/to/sequence_folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence)> 3 + +![sequence_reader.png](./samples/sequence_reader.png) + +NOTE : + +The input to the sequence reader should be a directory of images. + +The output of Sequence Reader may be different from the Video Reader because the names of the images from the input directory are sorted in lexicographic order and then split into sequences. + +
+ +**Example 3: Sequence Rearrange** + +> ./testScript.sh 1 + +Arguments to be modified in testScript.sh to enable sequence rearrange: + +ENABLE_SEQUENCE_REARRANGE=1 + +![sequence_rearrange.png](./samples/sequence_rearrange.png) + +New Sequence order : (2, 1, 1, 0), The order can be changed directly in rocAL_video_unittests.cpp file. The values specified in the order can only be in the range [0,sequence_length) + +**NOTE**: + +The outputs frames will be dumped inside the build/output_frames folder. The above images are for illustration purpose only. diff --git a/tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp b/tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp new file mode 100644 index 000000000..dae9a3128 --- /dev/null +++ b/tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp @@ -0,0 +1,327 @@ +/* +MIT License + +Copyright (c) 2020 - 2023 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 + +#include +#include +#include +#include +#include +#include + +#include "opencv2/opencv.hpp" +#include "rocal_api.h" +using namespace cv; + +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#endif + +using namespace std::chrono; + +bool IsPathExist(const char *s) { + struct stat buffer; + return (stat(s, &buffer) == 0); +} + +int check_extension(std::string file_name) { + // store the position of last '.' in the file name + int position = file_name.find_last_of("."); + // store the characters after the '.' from the file_name string + std::string result = file_name.substr(position + 1); + if ((result.compare("txt") == 0) || (result.size() == 0) || (result.compare("mp4") == 0)) + return -1; + return 0; +} + +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf("Usage: rocal_video_unittests \n"); + return -1; + } + + int argIdx = 0; + const char *source_path = argv[++argIdx]; + int reader_case = 0; + bool save_frames = 1; // Saves the frames + int rgb = 1; // process color images + unsigned resize_width = 0; + unsigned resize_height = 0; + bool processing_device = 1; + size_t shard_count = 1; + bool shuffle = false; + unsigned input_batch_size = 1; + unsigned sequence_length = 1; + unsigned ouput_frames_per_sequence = 1; + unsigned frame_step = 1; + unsigned frame_stride = 1; + bool file_list_frame_num = true; + bool enable_metadata = false; + bool enable_framenumbers = false; + bool enable_timestamps = true; + bool enable_sequence_rearrange = false; + bool is_output = true; + unsigned hardware_decode_mode = 0; + if (argc >= argIdx + MIN_ARG_COUNT) + reader_case = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + hardware_decode_mode = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + input_batch_size = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + ouput_frames_per_sequence = sequence_length = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + frame_step = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + frame_stride = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + save_frames = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + shuffle = atoi(argv[++argIdx]) ? true : false; + if (argc >= argIdx + MIN_ARG_COUNT) + resize_width = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + resize_height = atoi(argv[++argIdx]); + if (argc >= argIdx + MIN_ARG_COUNT) + file_list_frame_num = atoi(argv[++argIdx]) ? true : false; + if (argc >= argIdx + MIN_ARG_COUNT) + enable_metadata = atoi(argv[++argIdx]) ? true : false; + if (argc >= argIdx + MIN_ARG_COUNT) + enable_framenumbers = atoi(argv[++argIdx]) ? true : false; + if (argc >= argIdx + MIN_ARG_COUNT) + enable_timestamps = atoi(argv[++argIdx]) ? true : false; + if (argc >= argIdx + MIN_ARG_COUNT) + enable_sequence_rearrange = atoi(argv[++argIdx]) ? true : false; + + auto decoder_mode = ((hardware_decode_mode == 1) ? RocalDecodeDevice::ROCAL_HW_DECODE : RocalDecodeDevice::ROCAL_SW_DECODE); + if (!IsPathExist(source_path)) { + std::cout << "\nThe folder/file path does not exist\n"; + return -1; + } + if (enable_sequence_rearrange) { + is_output = false; + } + std::cerr << "Batch size : " << input_batch_size << std::endl; + std::cerr << "Sequence length : " << sequence_length << std::endl; + std::cerr << "Frame step : " << frame_step << std::endl; + std::cerr << "Frame stride : " << frame_stride << std::endl; + if (reader_case == 2) { + std::cerr << "Resize Width : " << resize_width << std::endl; + std::cerr << "Resize height : " << resize_height << std::endl; + } + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; + RocalContext handle; + handle = rocalCreate(input_batch_size, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal contex\n"; + return -1; + } + if (reader_case == 3) { + if (check_extension(source_path) < 0) { + std::cerr << "\n[ERR] Text file/ Video File passed as input to SEQUENCE READER\n"; + return -1; + } + if (enable_metadata) { + std::cout << "METADATA cannot be enabled for SEQUENCE READER"; + enable_metadata = false; + } + if (enable_framenumbers) + enable_framenumbers = false; + if (enable_timestamps) + enable_timestamps = false; + } else if (enable_metadata) { + std::cout << "\n>>>> META DATA READER\n"; + rocalCreateVideoLabelReader(handle, source_path, sequence_length, frame_step, frame_stride, file_list_frame_num); + } + + RocalTensor input1; + switch (reader_case) { + default: { + std::cout << "\n>>>> VIDEO READER\n"; + input1 = rocalVideoFileSource(handle, source_path, color_format, decoder_mode, shard_count, sequence_length, shuffle, is_output, false, frame_step, frame_stride, file_list_frame_num); + break; + } + case 2: { + std::cout << "\n>>>> VIDEO READER RESIZE\n"; + if (resize_width == 0 || resize_height == 0) { + std::cerr << "\n[ERR]Resize width and height are passed as NULL values\n"; + return -1; + } + input1 = rocalVideoFileResize(handle, source_path, color_format, decoder_mode, shard_count, sequence_length, resize_width, resize_height, shuffle, is_output, false, frame_step, frame_stride, file_list_frame_num); + break; + } + case 3: { + std::cout << "\n>>>> SEQUENCE READER\n"; + enable_framenumbers = enable_timestamps = 0; + input1 = rocalSequenceReader(handle, source_path, color_format, shard_count, sequence_length, is_output, shuffle, false, frame_step, frame_stride); + break; + } + } + if (enable_sequence_rearrange) { + std::cout << "\n>>>> ENABLE SEQUENCE REARRANGE\n"; + std::vector new_order = {0, 0, 1, 1, 0}; // The integers in new order should range only from 0 to sequence_length - 1 + ouput_frames_per_sequence = new_order.size(); + input1 = rocalSequenceRearrange(handle, input1, new_order, true); + } + RocalIntParam color_temp_adj = rocalCreateIntParameter(0); + + // Calling the API to verify and build the augmentation graph + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cerr << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + } + + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cerr << "[ERR]Could not verify the augmentation graph" << std::endl; + return -1; + } + std::cout << "\nRemaining images " << rocalGetRemainingImages(handle) << std::endl; + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + if (save_frames) + mkdir("output_frames", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // Create directory in which images will be stored + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * input_batch_size * ouput_frames_per_sequence; + int w = rocalGetOutputWidth(handle); + int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); + int single_image_height = h / (input_batch_size * ouput_frames_per_sequence); + std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color, mat_output; + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int counter = 0; + int color_temp_increment = 1; + int count = 0; + while (!rocalIsEmpty(handle)) { + count++; + if (rocalRun(handle) != 0) + break; + + if (rocalGetIntValue(color_temp_adj) <= -99 || rocalGetIntValue(color_temp_adj) >= 99) + color_temp_increment *= -1; + + rocalUpdateIntParameter(rocalGetIntValue(color_temp_adj) + color_temp_increment, color_temp_adj); + rocalCopyToOutput(handle, mat_input.data, h * w * p); + counter += input_batch_size; + if (save_frames) { + std::string batch_path = "output_frames/" + std::to_string(count); + int status = mkdir(batch_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (status) continue; + for (unsigned b = 0; b < input_batch_size; b++) // Iterates over each sequence in the batch + { + std::string seq_path = batch_path + "/seq_" + std::to_string(b); + std::string save_video_path = seq_path + "_output_video.avi"; + + int frame_width = static_cast(w); // get the width of frames of the video + int frame_height = static_cast(single_image_height); // get the height of frames of the video + Size frame_size(frame_width, frame_height); + int frames_per_second = 10; + + // Create and initialize the VideoWriter object + VideoWriter video_writer(save_video_path, VideoWriter::fourcc('M', 'J', 'P', 'G'), + frames_per_second, frame_size, true); + // If the VideoWriter object is not initialized successfully, exit the program + if (video_writer.isOpened() == false) { + std::cout << "Cannot save the video to a file" << std::endl; + return -1; + } + + for (unsigned i = 0; i < ouput_frames_per_sequence; i++) // Iterates over the frames in each sequence + { + std::string save_image_path = seq_path + "_output_" + std::to_string(i) + ".png"; + mat_output = mat_input(cv::Rect(0, ((b * single_image_height * ouput_frames_per_sequence) + (i * single_image_height)), w, single_image_height)); + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + cv::imwrite(save_image_path, mat_color); + video_writer.write(mat_color); + } else { + cv::imwrite(save_image_path, mat_output); + video_writer.write(mat_output); + } + } + video_writer.release(); + } + } + if (enable_metadata) { + int image_name_length[input_batch_size]; + RocalTensorList labels = rocalGetImageLabels(handle); + int img_size = rocalGetImageNameLen(handle, image_name_length); + char img_name[img_size]; + rocalGetImageName(handle, img_name); + + std::cout << "\nPrinting image names of batch: " << img_name << "\n"; + std::cout << "\t Printing label_id : "; + int *label_id = reinterpret_cast(labels->at(0)->buffer()); + for (unsigned i = 0; i < input_batch_size; i++) { + std::cout << label_id[i] << "\t"; + } + std::cout << std::endl; + } + if (enable_framenumbers || enable_timestamps) { + unsigned int start_frame_num[input_batch_size]; + float frame_timestamps[input_batch_size * sequence_length]; + rocalGetSequenceStartFrameNumber(handle, start_frame_num); + if (enable_timestamps) { + rocalGetSequenceFrameTimestamps(handle, frame_timestamps); + } + for (unsigned i = 0; i < input_batch_size; i++) { + if (enable_framenumbers) + std::cout << "\nFrame number : " << start_frame_num[i] << std::endl; + if (enable_timestamps) + for (unsigned j = 0; j < sequence_length; j++) + std::cout << "T" << j << " : " << frame_timestamps[(i * sequence_length) + j] << "\t"; + std::cout << "\n"; + } + } + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + return 0; +} diff --git a/tests/cpp_api/rocAL_video_unittests/samples/sequence_reader.png b/tests/cpp_api/rocAL_video_unittests/samples/sequence_reader.png new file mode 100644 index 0000000000000000000000000000000000000000..b55c66e8e3264850ba4e0460e80bf2f32e00b760 GIT binary patch literal 12447 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 YSmxL6iLnrZ7B5FwWkvky|2+x+U!@Jp!vFvP literal 0 HcmV?d00001 diff --git a/tests/cpp_api/rocAL_video_unittests/testScript.sh b/tests/cpp_api/rocAL_video_unittests/testScript.sh new file mode 100755 index 000000000..728c90c3e --- /dev/null +++ b/tests/cpp_api/rocAL_video_unittests/testScript.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +################ AVAILABLE READERS ###################### +## DEFAULT : VideoReader ## +## READER_CASE 2 : VideoReaderResize ## +## READER_CASE 3 : SequenceReader ## +######################################################### +INPUT_PATH=$1 +READER_CASE=$2 + +if [ -z "$INPUT_PATH" ] + then + echo "No input argument supplied" + exit +fi + +# Handles relative input path +if [ ! -d "$INPUT_PATH" & [[ "$INPUT_PATH" != /* ]] +then + CWD=$(pwd) + INPUT_PATH="$CWD/$INPUT_PATH" +fi + +if [ -z "$READER_CASE" ] + then + READER_CASE=1 +fi + +# Building video unit test +sudo rm -rvf build* +mkdir build +cd build || exit +cmake .. +make + +# Arguments used in video unit test +SAVE_FRAMES=1 # (save_frames:on/off) +RGB=1 # (rgb:1/gray:0) +DEVICE=0 # (cpu:0/gpu:1) +HARDWARE_DECODE_MODE=0 # (hardware_decode_mode:on/off) +SHUFFLE=0 # (shuffle:on/off) + +BATCH_SIZE=1 # Number of sequences per batch +SEQUENCE_LENGTH=3 # Number of frames per sequence +STEP=3 # Frame interval from one sequence to another sequence +STRIDE=1 # Frame interval within frames in a sequences +RESIZE_WIDTH=1280 # width with which frames should be resized (applicable only for READER_CASE 2) +RESIZE_HEIGHT=720 # height with which frames should be resized (applicable only for READER_CASE 2) + +FILELIST_FRAMENUM=1 # enables file number or timestamps parsing for text file input +ENABLE_METADATA=0 # outputs labels and names of the associated frames +ENABLE_FRAME_NUMBER=0 # outputs the starting frame numbers of the sequences in the batch +ENABLE_TIMESTAMPS=0 # outputs timestamps of the frames in the batch +ENABLE_SEQUENCE_REARRANGE=0 # rearranges the frames in the sequence NOTE: The order needs to be set in the rocAL_video_unittests.cpp + +echo ./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ +$RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ +$ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE + +./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ +$RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ +$ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE diff --git a/tests/python_api/README.md b/tests/python_api/README.md new file mode 100644 index 000000000..3b2b5ad5e --- /dev/null +++ b/tests/python_api/README.md @@ -0,0 +1,67 @@ +## Set environmental variables +`export ROCAL_DATA_PATH=/Absolute/Path/Of/MIVisionX-data/`` + +## Reader Pipeline tests: +* To test all the reader pipelines with a single script +* The default value of number of gpu's is "1" & display is "ON" by default +./readers_test_file.sh + +### Options: +* To test a single reader / multiple reader pipelines: Use the same script `readers_test_file.sh` as above and make the respective " Pipeline " to test equal to "1" + +``` +unit_test = 1 +coco_pipeline = 0 +``` + +* Example : To run COCO Pipeline +``` +unit_test=0 +coco_pipeline=1 +caffe_reader=0 +caffe2_reader=0 +tf_classification_reader=0 +tf_detection_pipeline=0 +``` + +* To set number of GPUs/display/backend: +``` +./readers_test_file.sh -n -d +./readers_test_file.sh -n "1" -d "false" -b "cpu" +``` + +## Augmentation + Reader Tests: +* This runs all augmentations and readers and compare them with golden outputs for both backends (HIP/HOST) + +`./unit_tests.sh` + +## Command line for individual files: +* Test a single reader pipeline +* Example: COCO Pipeline +``` + # Mention the number of gpus + gpus_per_node=4 + + # Mention Batch Size + batch_size=10 + + # python version + ver=$(python -V 2>&1 | sed 's/.* \([0-9]\).\([0-9]\).*/\1\.\2/') + + # Mention dataset_path + data_dir=$ROCAL_DATA_PATH/coco/coco_10_img/val_10images_2017/ + + # Mention json path + json_path=$ROCAL_DATA_PATH/coco/coco_10_img/annotations/instances_val2017.json + + # coco_pipeline.py + # By default : cpu backend, NCHW format , fp32 + # Annotation must be a json file + + # For printing all the arguments that can be passed from user + python$ver coco_pipeline.py -h + + python$ver coco_pipeline.py --image-dataset-path $data_dir --json-path $json_path --batch-size $batch_size --display --rocal-gpu --NHWC \ + --local-rank 0 --world-size $gpus_per_node --num-threads 1 --num-epochs 1 2>&1 | tee -a run.log.coco_pipeline.txt +``` +### [ NOTE: Refer parse_config.py for more info on other args] diff --git a/tests/python_api/caffe2_reader.py b/tests/python_api/caffe2_reader.py new file mode 100644 index 000000000..4caf647d9 --- /dev/null +++ b/tests/python_api/caffe2_reader.py @@ -0,0 +1,129 @@ +# Copyright (c) 2018 - 2023 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 sys +from amd.rocal.plugin.pytorch import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.types as types +import amd.rocal.fn as fn +import os +from parse_config import parse_args + + +def draw_patches(img, idx, bboxes=None, args=None): + # image is expected as a tensor, bboxes as tensors + import cv2 + if args.rocal_gpu: + image = img.cpu().numpy() + else: + image = img.detach().numpy() + if not args.NHWC: + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + if args.classification: + cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" + + str(idx)+"_"+"train"+".png", image) + else: + if bboxes is not None: + bboxes = bboxes.detach().numpy() + for (l, t, r, b) in bboxes: + loc_ = [l, t, r, b] + color = (255, 0, 0) + thickness = 2 + image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( + (loc_[2])), int((loc_[3]))), color, thickness) + cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" + + str(idx)+"_"+"train"+".png", image) + + +def main(): + args = parse_args() + # Args + image_path = args.image_dataset_path + rocal_cpu = False if args.rocal_gpu else True + batch_size = args.batch_size + rocal_bbox = False if args.classification else True + num_threads = args.num_threads + local_rank = args.local_rank + random_seed = args.seed + display = True if args.display else False + device = "gpu" if args.rocal_gpu else "cpu" + tensor_layout = types.NHWC if args.NHWC else types.NCHW + num_classes = len(next(os.walk(image_path))[1]) + print("num_classes:: ", num_classes) + try: + if args.classification: + path = "OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" + else: + path = "OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=local_rank, + seed=random_seed, rocal_cpu=rocal_cpu) + with pipe: + if rocal_bbox: + jpegs, labels, bboxes = fn.readers.caffe2( + path=image_path, bbox=rocal_bbox) + else: + jpegs, labels = fn.readers.caffe2(path=image_path, bbox=rocal_bbox) + images = fn.decoders.image( + jpegs, output_type=types.RGB, path=image_path, random_shuffle=True) + images = fn.resize(images, resize_width=224, + resize_height=224, output_layout=tensor_layout) + pipe.set_outputs(images) + pipe.build() + data_loader = ROCALClassificationIterator(pipe, display=0, device=device) + + # Training loop + cnt = 0 + for epoch in range(1): # loop over the dataset multiple times + print("epoch:: ", epoch) + if not rocal_bbox: + for i, ([image_batch], labels) in enumerate(data_loader, 0): # Classification + if args.print_tensor: + sys.stdout.write("\r Mini-batch " + str(i)) + print("Images", image_batch) + print("Labels", labels) + for element in list(range(batch_size)): + cnt += 1 + draw_patches(image_batch[element], cnt, args=args) + data_loader.reset() + else: + for i, ([image_batch], bboxes, labels) in enumerate(data_loader, 0): # Detection + if i == 0: + if args.print_tensor: + sys.stdout.write("\r Mini-batch " + str(i)) + print("Images", image_batch) + print("Bboxes", bboxes) + print("Labels", labels) + for element in list(range(batch_size)): + cnt += 1 + draw_patches(image_batch[element], + cnt, bboxes[element], args=args) + data_loader.reset() + + print("############################## CAFFE2 READER (CLASSIFCATION/ DETECTION) SUCCESS ############################") + + +if __name__ == "__main__": + main() diff --git a/tests/python_api/caffe_reader.py b/tests/python_api/caffe_reader.py new file mode 100644 index 000000000..9cec39c82 --- /dev/null +++ b/tests/python_api/caffe_reader.py @@ -0,0 +1,135 @@ +# Copyright (c) 2018 - 2023 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 sys +from amd.rocal.plugin.pytorch import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.types as types +import amd.rocal.fn as fn +import os +import cv2 +from parse_config import parse_args + + +def draw_patches(img, idx, bboxes=None, args=None): + # image is expected as a tensor, bboxes as tensors + if args.rocal_gpu: + image = img.cpu().numpy() + else: + image = img.detach().numpy() + if not args.NHWC: + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + if args.classification: + cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" + + str(idx)+"_"+"train"+".png", image) + else: + if bboxes is not None: + bboxes = bboxes.detach().numpy() + for (l, t, r, b) in bboxes: + loc_ = [l, t, r, b] + color = (255, 0, 0) + thickness = 2 + image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( + (loc_[2])), int((loc_[3]))), color, thickness) + cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/DETECTION/" + + str(idx)+"_"+"train"+".png", image) + +def main(): + args = parse_args() + # Args + image_path = args.image_dataset_path + rocal_cpu = False if args.rocal_gpu else True + batch_size = args.batch_size + rocal_bbox = False if args.classification else True + num_threads = args.num_threads + local_rank = args.local_rank + world_size = args.world_size + random_seed = args.seed + device = "gpu" if args.rocal_gpu else "cpu" + tensor_layout = types.NHWC if args.NHWC else types.NCHW + num_classes = len(next(os.walk(image_path))[1]) + try: + if args.classification: + path = "OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" + else: + path = "OUTPUT_FOLDER/CAFFE_READER/DETECTION/" + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + print("num_classes:: ", num_classes) + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, + device_id=args.local_rank, seed=random_seed, rocal_cpu=rocal_cpu) + # Use pipeline instance to make calls to reader, decoder & augmentation's + with pipe: + if rocal_bbox: + jpegs, labels, bboxes = fn.readers.caffe( + path=image_path, bbox=rocal_bbox) + images = fn.decoders.image( + jpegs, path=image_path, shard_id=local_rank, random_shuffle=True) + + else: + jpegs, labels = fn.readers.caffe(path=image_path, bbox=rocal_bbox) + images = fn.decoders.image(jpegs, path=image_path, output_type=types.RGB, + shard_id=local_rank, num_shards=world_size, random_shuffle=True) + + images = fn.resize(images, resize_width=224, + resize_height=224, output_layout=tensor_layout) + pipe.set_outputs(images) + # Build the pipeline + pipe.build() + # Dataloader + data_loader = ROCALClassificationIterator( + pipe, display=0, device=device, device_id=args.local_rank) + # Training loop + cnt = 0 + # Enumerate over the Dataloader + for epoch in range(args.num_epochs): # loop over the dataset multiple times + print("epoch:: ", epoch) + if not rocal_bbox: + for i, ([image_batch], labels) in enumerate(data_loader, 0): # Classification + if args.print_tensor: + sys.stdout.write("\r Mini-batch " + str(i)) + print("Images", image_batch) + print("Labels", labels) + for element in list(range(batch_size)): + cnt += 1 + draw_patches(image_batch[element], cnt, args=args) + data_loader.reset() + else: + for i, ([image_batch], bboxes, labels) in enumerate(data_loader, 0): # Detection + if i == 0: + if args.print_tensor: + sys.stdout.write("\r Mini-batch " + str(i)) + print("Images", image_batch) + print("Bboxes", bboxes) + print("Labels", labels) + for element in list(range(batch_size)): + cnt += 1 + draw_patches(image_batch[element], + cnt, bboxes[element], args=args) + data_loader.reset() + print("############################## CAFFE READER (CLASSIFCATION/ DETECTION) SUCCESS ############################") + +if __name__ == "__main__": + main() diff --git a/tests/python_api/coco_pipeline.py b/tests/python_api/coco_pipeline.py new file mode 100755 index 000000000..79baaadd4 --- /dev/null +++ b/tests/python_api/coco_pipeline.py @@ -0,0 +1,231 @@ +# Copyright (c) 2018 - 2023 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. + +from math import sqrt +import torch +import itertools +import os +import ctypes +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import numpy as np +from parse_config import parse_args + + +class ROCALCOCOIterator(object): + """ + COCO ROCAL iterator for pyTorch. + + Parameters + ---------- + pipelines : list of amd.rocal.pipeline.Pipeline + List of pipelines to use + size : int + Epoch size. + """ + + def __init__(self, pipelines, tensor_layout=types.NCHW, reverse_channels=False, multiplier=None, offset=None, tensor_dtype=types.FLOAT, device="cpu", display=False): + + try: + assert pipelines is not None, "Number of provided pipelines has to be at least 1" + except Exception as ex: + print(ex) + self.loader = pipelines + self.tensor_format = tensor_layout + self.multiplier = multiplier if multiplier else [1.0, 1.0, 1.0] + self.offset = offset if offset else [0.0, 0.0, 0.0] + self.reverse_channels = reverse_channels + self.tensor_dtype = tensor_dtype + self.device = device + self.device_id = self.loader._device_id + self.bs = self.loader._batch_size + self.output_list = self.dimensions = self.torch_dtype = None + self.display = display + # Image id of a batch of images + self.image_id = np.zeros(self.bs, dtype="int32") + # Count of labels/ bboxes in a batch + self.bboxes_label_count = np.zeros(self.bs, dtype="int32") + # Image sizes of a batch + self.img_size = np.zeros((self.bs * 2), dtype="int32") + self.output_memory_type = self.loader._output_memory_type + + def next(self): + return self.__next__() + + def __next__(self): + if self.loader.rocal_run() != 0: + raise StopIteration + else: + self.output_tensor_list = self.loader.get_output_tensors() + + if self.output_list is None: + self.output_list = [] + for i in range(len(self.output_tensor_list)): + self.dimensions = self.output_tensor_list[i].dimensions() + self.torch_dtype = self.output_tensor_list[i].dtype() + if self.device == "cpu": + self.output = torch.empty( + self.dimensions, dtype=getattr(torch, self.torch_dtype)) + else: + torch_gpu_device = torch.device('cuda', self.device_id) + self.output = torch.empty(self.dimensions, dtype=getattr( + torch, self.torch_dtype), device=torch_gpu_device) + self.output_tensor_list[i].copy_data(ctypes.c_void_p( + self.output.data_ptr()), self.output_memory_type) + self.output_list.append(self.output) + else: + for i in range(len(self.output_tensor_list)): + self.output_tensor_list[i].copy_data(ctypes.c_void_p( + self.output_list[i].data_ptr()), self.output_memory_type) + + self.labels = self.loader.get_bounding_box_labels() + # 1D bboxes array in a batch + self.bboxes = self.loader.get_bounding_box_cords() + self.loader.get_image_id(self.image_id) + image_id_tensor = torch.tensor(self.image_id) + image_size_tensor = torch.tensor(self.img_size).view(-1, self.bs, 2) + + for i in range(self.bs): + if self.display: + img = self.output + draw_patches(img[i], self.image_id[i], + self.bboxes[i], self.device, self.tensor_dtype, self.tensor_format) + return (self.output), self.bboxes, self.labels, image_id_tensor, image_size_tensor + + def reset(self): + self.loader.rocal_reset_loaders() + + def __iter__(self): + return self + + +def draw_patches(img, idx, bboxes, device, dtype, layout): + # image is expected as a tensor, bboxes as numpy + import cv2 + if device == "cpu": + image = img.detach().numpy() + else: + image = img.cpu().numpy() + if dtype == types.FLOAT16: + image = (image).astype('uint8') + if layout == types.NCHW: + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + bboxes = np.reshape(bboxes, (-1, 4)) + + for (l, t, r, b) in bboxes: + loc_ = [l, t, r, b] + color = (255, 0, 0) + thickness = 2 + image = cv2.UMat(image).get() + image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( + (loc_[2])), int((loc_[3]))), color, thickness) + cv2.imwrite("OUTPUT_FOLDER/COCO_READER/" + + str(idx)+"_"+"train"+".png", image) + + +def main(): + args = parse_args() + # Args + image_path = args.image_dataset_path + annotation_path = args.json_path + rocal_cpu = False if args.rocal_gpu else True + batch_size = args.batch_size + display = args.display + num_threads = args.num_threads + local_rank = args.local_rank + world_size = args.world_size + random_seed = args.seed + tensor_format = types.NHWC if args.NHWC else types.NCHW + tensor_dtype = types.FLOAT16 if args.fp16 else types.FLOAT + try: + path = "OUTPUT_FOLDER/COCO_READER/" + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=args.local_rank, + seed=random_seed, rocal_cpu=rocal_cpu, tensor_layout=tensor_format, tensor_dtype=tensor_dtype) + # Use pipeline instance to make calls to reader, decoder & augmentation's + with pipe: + jpegs, bboxes, labels = fn.readers.coco( + annotations_file=annotation_path) + images_decoded = fn.decoders.image(jpegs, output_type=types.RGB, file_root=image_path, + annotations_file=annotation_path, random_shuffle=False, shard_id=local_rank, num_shards=world_size) + res_images = fn.resize( + images_decoded, resize_width=300, resize_height=300) + saturation = fn.uniform(range=[0.1, 0.4]) + contrast = fn.uniform(range=[0.1, 25.0]) + brightness = fn.uniform(range=[0.875, 1.125]) + hue = fn.uniform(range=[5.0, 170.0]) + ct_images = fn.color_twist( + res_images, saturation=saturation, contrast=contrast, brightness=brightness, hue=hue) + flip_coin = fn.random.coin_flip(probability=0.5) + cmn_images = fn.crop_mirror_normalize(ct_images, + crop=(224, 224), + crop_pos_x=0.0, + crop_pos_y=0.0, + mean=[0, 0, 0], + std=[1, 1, 1], + mirror=flip_coin, + output_layout=tensor_format, + output_dtype=tensor_dtype) + pipe.set_outputs(cmn_images) + # Build the pipeline + pipe.build() + # Dataloader + if (args.rocal_gpu): + data_loader = ROCALCOCOIterator( + pipe, multiplier=pipe._multiplier, offset=pipe._offset, display=display, tensor_layout=tensor_format, tensor_dtype=tensor_dtype, device="cuda") + else: + data_loader = ROCALCOCOIterator( + pipe, multiplier=pipe._multiplier, offset=pipe._offset, display=display, tensor_layout=tensor_format, tensor_dtype=tensor_dtype, device="cpu") + + import timeit + start = timeit.default_timer() + # Enumerate over the Dataloader + for epoch in range(int(args.num_epochs)): + print("EPOCH:::::", epoch) + for i, it in enumerate(data_loader, 0): + if args.print_tensor: + print("**************", i, "*******************") + print("**************starts*******************") + print("\nIMAGES : \n", it[0]) + print("\nBBOXES:\n", it[1]) + print("\nLABELS:\n", it[2]) + print("\nIMAGE ID:\n", it[3]) + print("\nIMAGE SIZE:\n", it[4]) + print("**************ends*******************") + print("**************", i, "*******************") + data_loader.reset() + # Your statements here + stop = timeit.default_timer() + + print('\n Time: ', stop - start) + + print("############################## COCO READER SUCCESS ############################") + + +if __name__ == '__main__': + main() diff --git a/tests/python_api/decoder.py b/tests/python_api/decoder.py new file mode 100644 index 000000000..073fa383c --- /dev/null +++ b/tests/python_api/decoder.py @@ -0,0 +1,60 @@ + +import sys +from amd.rocal.pipeline import pipeline_def +from amd.rocal.plugin.generic import ROCALClassificationIterator +import amd.rocal.fn as fn +import amd.rocal.types as types +import matplotlib.gridspec as gridspec +import matplotlib.pyplot as plt +import cupy as cp + +seed = 1549361629 +image_dir = "../../../data/images/AMD-tinyDataSet/" +batch_size = 4 +gpu_id = 0 + +def show_images(image_batch, device): + columns = 4 + rows = (batch_size + 1) // (columns) + #fig = plt.figure(figsize = (32,(32 // columns) * rows)) + gs = gridspec.GridSpec(rows, columns) + for j in range(rows*columns): + #print('\n Display image: ', j) + plt.subplot(gs[j]) + img = image_batch[j] + plt.axis("off") + if device == "cpu": + plt.imshow(img) + else: + plt.imshow(cp.asnumpy(img)) + plt.show() + + +def show_pipeline_output(pipe, device): + pipe.build() + data_loader = ROCALClassificationIterator(pipe, device) + images = next(iter(data_loader)) + show_images(images[0][0], device) + +@pipeline_def(seed=seed) +def image_decoder_pipeline(device="cpu", path=image_dir): + jpegs, labels = fn.readers.file(file_root=path) + images = fn.decoders.image(jpegs, file_root=path, device=device, output_type=types.RGB, shard_id=0, num_shards=1, random_shuffle=False) + return fn.resize(images, device=device, resize_width=300, resize_height=300) + +def main(): + print ('Optional arguments: ') + bs = batch_size + rocal_device = "cpu" + img_folder = image_dir + if len(sys.argv) > 1: + if(sys.argv[1] == "gpu"): + rocal_device = "gpu" + if len(sys.argv) > 2: + img_folder = sys.argv[2] + pipe = image_decoder_pipeline(batch_size=bs, num_threads=1, device_id=gpu_id, rocal_cpu=True, tensor_layout=types.NHWC, + reverse_channels=True, mean = [0, 0, 0], std=[255,255,255], device=rocal_device, path=img_folder) + show_pipeline_output(pipe, device=rocal_device) + +if __name__ == '__main__': + main() diff --git a/tests/python_api/external_source_reader.py b/tests/python_api/external_source_reader.py new file mode 100644 index 000000000..a871d78e5 --- /dev/null +++ b/tests/python_api/external_source_reader.py @@ -0,0 +1,279 @@ +from random import shuffle +from amd.rocal.pipeline import Pipeline +from amd.rocal.plugin.generic import ROCALClassificationIterator +import amd.rocal.fn as fn +import amd.rocal.types as types +import os +import numpy as np +import cupy as cp +import cv2 +from PIL import Image + + +def main(): + batch_size = 3 + data_dir = os.environ["ROCAL_DATA_PATH"] + \ + "/coco/coco_10_img/train_10images_2017/" + device = "cpu" + try: + path_mode0 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE0/" + isExist = os.path.exists(path_mode0) + if not isExist: + os.makedirs(path_mode0) + except OSError as error: + print(error) + try: + path_mode1 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE1/" + isExist = os.path.exists(path_mode1) + if not isExist: + os.makedirs(path_mode1) + except OSError as error: + print(error) + try: + path_mode2 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE2/" + isExist = os.path.exists(path_mode2) + if not isExist: + os.makedirs(path_mode2) + except OSError as error: + print(error) + + def image_dump(img, idx, device="cpu", mode=0): + if device == "gpu": + img = cp.asnumpy(img) + img = img.transpose([1, 2, 0]) # NCHW + img = (img).astype('uint8') + if mode!=2: + img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) + cv2.imwrite("OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE" + str(mode) + "/"+ + str(idx)+"_"+"train"+".png", img) + + ##################### MODE 0 ######################### + # Define the Data Source for all image samples - User needs to define their own source + class ExternalInputIteratorMode0(object): + def __init__(self, batch_size): + self.images_dir = data_dir + self.batch_size = batch_size + self.files = [] + import glob + for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): + self.files.append(filename) + shuffle(self.files) + + def __iter__(self): + self.i = 0 + self.n = len(self.files) + return self + + def __next__(self): + batch = [] + labels = [] + label = 1 + for _ in range(self.batch_size): + jpeg_filename = self.files[self.i] + batch.append(jpeg_filename) + labels.append(label) + label = label + 1 + self.i = (self.i + 1) % self.n + labels = np.array(labels).astype('int32') + return batch, labels + + # Mode 0 + external_input_source = ExternalInputIteratorMode0(batch_size) + + # Create the pipeline + external_source_pipeline_mode0 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, + seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) + + with external_source_pipeline_mode0: + jpegs, _ = fn.external_source( + source=external_input_source, mode=types.EXTSOURCE_FNAME) + output = fn.resize(jpegs, resize_width=300, resize_height=300, + output_layout=types.NCHW, output_dtype=types.UINT8) + external_source_pipeline_mode0.set_outputs(output) + + # build the external_source_pipeline_mode0 + external_source_pipeline_mode0.build() + # Index starting from 0 + cnt = 0 + # Dataloader + data_loader = ROCALClassificationIterator( + external_source_pipeline_mode0, device=device) + for i, output_list in enumerate(data_loader, 0): + print("**************MODE 0*******************") + print("**************", i, "*******************") + print("**************starts*******************") + print("\nImages:\n", output_list) + print("**************ends*******************") + print("**************", i, "*******************") + for img in output_list[0][0]: + cnt = cnt + 1 + image_dump(img, cnt, device=device, mode=0) + + ##################### MODE 0 ######################### + + ##################### MODE 1 ######################### + # Define the Data Source for all image samples + class ExternalInputIteratorMode1(object): + def __init__(self, batch_size): + self.images_dir = data_dir + self.batch_size = batch_size + self.files = [] + import os + import glob + for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): + self.files.append(filename) + + def __iter__(self): + self.i = 0 + self.n = len(self.files) + self.maxWidth = None + self.maxHeight = None + return self + + def __next__(self): + batch = [] + labels = [] + srcsize_height = [] + label = 1 + for x in range(self.batch_size): + jpeg_filename = self.files[self.i] + f = open(jpeg_filename, 'rb') + numpy_buffer = np.frombuffer(f.read(), dtype=np.uint8) + batch.append(numpy_buffer) + srcsize_height.append(len(numpy_buffer)) + labels.append(label) + label = label + 1 + self.i = (self.i + 1) % self.n + labels = np.array(labels).astype('int32') + return (batch, labels, srcsize_height) + +# Mode 1 + eii_1 = ExternalInputIteratorMode1(batch_size) + + # Create the pipeline + external_source_pipeline_mode1 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, + seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) + + with external_source_pipeline_mode1: + jpegs, _ = fn.external_source( + source=eii_1, mode=types.EXTSOURCE_RAW_COMPRESSED, max_width=2000, max_height=2000) + output = fn.resize(jpegs, resize_width=2000, resize_height=2000, + output_layout=types.NCHW, output_dtype=types.UINT8) + external_source_pipeline_mode1.set_outputs(output) + + # build the external_source_pipeline_mode1 + external_source_pipeline_mode1.build() + # Index starting from 0 + cnt = 0 + # Dataloader + data_loader = ROCALClassificationIterator( + external_source_pipeline_mode1, device=device) + for i, output_list in enumerate(data_loader, 0): + print("**************MODE 1*******************") + print("**************", i, "*******************") + print("**************starts*******************") + print("\nImages:\n", output_list) + print("**************ends*******************") + print("**************", i, "*******************") + for img in output_list[0][0]: + cnt = cnt + 1 + image_dump(img, cnt, device=device, mode=1) + ##################### MODE 1 ######################### + + ##################### MODE 2 ######################### + # Define the Data Source for all image samples + + class ExternalInputIteratorMode2(object): + def __init__(self, batch_size): + self.images_dir = data_dir + self.batch_size = batch_size + self.files = [] + self.maxHeight = self.maxWidth = 0 + import os + import glob + for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): + self.files.append(filename) + shuffle(self.files) + self.i = 0 + self.n = len(self.files) + + for x in range(self.n): + jpeg_filename = self.files[x] + label = 1 + image = cv2.imread(jpeg_filename, cv2.IMREAD_COLOR) + # Check if the image was loaded successfully + if image is None: + print("Error: Failed to load the image.") + else: + # Get the height and width of the image + height, width = image.shape[:2] + self.maxHeight = height if height > self.maxHeight else self.maxHeight + self.maxWidth = width if width > self.maxWidth else self.maxWidth + + def __iter__(self): + return self + + def __next__(self): + batch = [] + batch_of_numpy = [] + labels = [] + label = 1 + roi_height = [] + roi_width = [] + self.out_image = np.zeros( + (self.batch_size, self.maxHeight, self.maxWidth, 3), dtype="uint8") + for x in range(self.batch_size): + jpeg_filename = self.files[self.i] + image = cv2.imread(jpeg_filename, cv2.IMREAD_COLOR) + # Check if the image was loaded successfully + if image is None: + print("Error: Failed to load the image.") + else: + # Get the height and width of the image + height, width = image.shape[:2] + batch.append(np.asarray(image)) + roi_height.append(height) + roi_width.append(width) + self.out_image[x][:roi_height[x], :roi_width[x], :] = batch[x] + batch_of_numpy.append(self.out_image[x]) + labels.append(label) + label = label + 1 + self.i = (self.i + 1) % self.n + labels = np.array(labels).astype('int32') + return (batch_of_numpy, labels, roi_height, roi_width, self.maxHeight, self.maxWidth) + + +# Mode 2 + eii_2 = ExternalInputIteratorMode2(batch_size) + + # Create the pipeline + external_source_pipeline_mode2 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, + seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) + + with external_source_pipeline_mode2: + jpegs, _ = fn.external_source(source=eii_2, mode=types.EXTSOURCE_RAW_UNCOMPRESSED, + max_width=eii_2.maxWidth, max_height=eii_2.maxHeight) + output = fn.resize(jpegs, resize_width=300, resize_height=300, + output_layout=types.NCHW, output_dtype=types.UINT8) + external_source_pipeline_mode2.set_outputs(output) + + # build the external_source_pipeline_mode2 + external_source_pipeline_mode2.build() + # Index starting from 0 + cnt = 0 + # Dataloader + data_loader = ROCALClassificationIterator( + external_source_pipeline_mode2, device=device) + for i, output_list in enumerate(data_loader, 0): + print("**************MODE 2*******************") + print("**************", i, "*******************") + print("**************starts*******************") + print("\nImages:\n", output_list) + print("**************ends*******************") + print("**************", i, "*******************") + for img in output_list[0][0]: + cnt = cnt+1 + image_dump(img, cnt, device=device, mode=2) + ##################### MODE 2 ######################### +if __name__ == '__main__': + main() diff --git a/tests/python_api/image_comparison.py b/tests/python_api/image_comparison.py new file mode 100644 index 000000000..a0e8ad4fc --- /dev/null +++ b/tests/python_api/image_comparison.py @@ -0,0 +1,207 @@ +# Copyright (c) 2023 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. + +from PIL import Image +import os +import sys +import datetime +import logging +import ast + + +def compare_pixels(img1, img2, aug_name, width, height, image_offset=0): + pixel_difference = [0, 0, 0, 0, 0, 0] + if "rgb" in aug_name: + pixels1 = img1.load() + pixels2 = img2.load() + channel = 3 + else: + pixels1 = img1.convert("L").load() + pixels2 = img2.convert("L").load() + channel = 1 + total_valid_pixel_count = width * height * channel + for wt in range(width): + for ht in range(height): + ht = ht + image_offset + if pixels1[wt, ht] != pixels2[wt, ht]: + if channel == 1: + diff_val = abs(pixels1[wt, ht] - pixels2[wt, ht]) + diff_val = min(diff_val, 5) + pixel_difference[diff_val] += 1 + else: + for ch in range(channel): + diff_val = abs( + pixels1[wt, ht][ch] - pixels2[wt, ht][ch]) + diff_val = min(diff_val, 5) + pixel_difference[diff_val] += 1 + else: + pixel_difference[0] += channel + return pixel_difference, total_valid_pixel_count + +def compare_file_with_list(filename, reference_list): + with open(filename, 'r') as file: + file_contents = file.read().strip() + file_contents = ast.literal_eval(file_contents) + if len(file_contents) != len(reference_list): + print("File content and existing list have different lengths.") + return -1 # Return a negative value to indicate a mismatch in lengths + mismatch_count = 0 + for file_inner_list, list_inner_list in zip(file_contents, reference_list): + if file_inner_list != list_inner_list: + mismatch_count += 1 + return mismatch_count + +def main(): + timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S_") + handlers = [ + logging.FileHandler("./rocal_unittest_log_file_" + timestamp + ".log"), + logging.StreamHandler(), + ] + logging.basicConfig(level=logging.INFO, handlers=handlers) + if len(sys.argv) < 3: + print("Please pass ref_output_folder_path rocal_ouput_folder_path") + logging.error( + "Please pass ref_output_folder_path rocal_ouput_folder_path") + exit(0) + # Open the two images + ref_output_path = sys.argv[1] + rocal_output_path = sys.argv[2] + + if not (os.path.exists(ref_output_path) and os.path.exists(rocal_output_path)): + logging.error("Path does not Exists") + exit() + total_case_count = 0 + passed_case_count = 0 + failed_case_count = 0 + failed_case_list = [] + golden_output_dir_list = os.listdir(ref_output_path) + rocal_output_dir_list = os.listdir(rocal_output_path) + randomized_augmentation = ["Snow", "Rain", "Jitter", "SNPNoise"] + spl_case_meta_data = ["OneHot"] + golden_file_path = "" + for aug_name in rocal_output_dir_list: + temp = aug_name.split(".") + file_name_split = temp[0].split("_") + if len(file_name_split) > 3: + file_name_split.pop() + golden_file_path = "_".join(file_name_split) + ".png" + else: + golden_file_path = aug_name + + # For randomized augmentation + if file_name_split[0] in randomized_augmentation: + total_case_count = total_case_count + 1 + augmentation_name = aug_name.split(".")[0] + logging.info("Running %s", augmentation_name) + passed_case_count = passed_case_count + 1 + logging.info("PASSED ") + elif file_name_split[0] in spl_case_meta_data: + total_case_count = total_case_count + 1 + reference_list = [[1, 0], [1, 0]] + rocal_file_path = rocal_output_path + aug_name + if os.path.exists(rocal_file_path): + logging.info("Running %s ", aug_name.split(".")[0]) + total_mismatches = compare_file_with_list(rocal_file_path, reference_list) + if total_mismatches == 0: + passed_case_count = passed_case_count + 1 + logging.info("PASSED") + else: + failed_case_list.append(file_name_split[0]) + failed_case_count = failed_case_count + 1 + logging.info("FAILED") + logging.info("Printing total mismatches in one hot encode %s", total_mismatches) + elif golden_file_path in golden_output_dir_list: + total_case_count = total_case_count + 1 + ref_file_path = ref_output_path + golden_file_path + rocal_file_path = rocal_output_path + aug_name + if os.path.exists(rocal_file_path) and os.path.exists(ref_file_path): + logging.info("Running %s ", aug_name.split(".")[0]) + img1 = Image.open(ref_file_path) + img2 = Image.open(rocal_file_path) + + # Check if the images have the same dimensions + if img1.size != img2.size: + logging.info( + "Golden output and augmentation outputs are having different sizes. Exiting!") + exit() + + # Compare the pixel values for each image + pixel_diff = None + total_count = 0 + if "larger" in aug_name: + resize_width = 400 + resize_height = 300 + image_offset = 400 + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, resize_width, resize_height) + pixel_diff2, total_count2 = compare_pixels( + img1, img2, aug_name, resize_width, resize_height, image_offset) + pixel_diff = [x + y for x, + y in zip(pixel_diff, pixel_diff2)] + total_count = total_count + total_count2 + elif "smaller" in aug_name: + resize_width = 533 + resize_height = 400 + image_offset = 2400 + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, resize_width, resize_height) + pixel_diff2, total_count2 = compare_pixels( + img1, img2, aug_name, resize_width, resize_height, image_offset) + pixel_diff = [x + y for x, + y in zip(pixel_diff, pixel_diff2)] + total_count = total_count + total_count2 + else: + pixel_diff, total_count = compare_pixels( + img1, img2, aug_name, img1.size[0], img1.size[1]) + total_pixel_diff = 0 + for pix_diff in range(1, 6): + total_pixel_diff += pixel_diff[pix_diff] + mismatch_percentage = round( + (total_pixel_diff / total_count) * 100, 2) + if ((total_pixel_diff == 0) or (mismatch_percentage < 5.0 and pixel_diff[1] == total_pixel_diff) or # Ignore test cases with single pixel differences less than 5% of total pixel count + (mismatch_percentage < 0.5 and ("Blend" in aug_name or "Rotate" in aug_name) and "hip" in aug_name)): # Ignore mismatch in rotate augmentation less than 0.5% of total pixel count + passed_case_count = passed_case_count + 1 + logging.info("PASSED") + else: + failed_case_list.append(golden_file_path) + failed_case_count = failed_case_count + 1 + logging.info("FAILED") + logging.info("Printing pixel mismatch %s", pixel_diff) + logging.info("Mismatach percentage %0.2f", + mismatch_percentage) + for pix_diff in range(1, 6): + logging.info("Percentage of %d pixel mismatch %0.2f", pix_diff, round( + (pixel_diff[pix_diff] / total_pixel_diff) * 100, 2)) + else: + logging.info( + "Skipping the testcase as file not found %s", rocal_file_path) + else: + logging.info("File not found in ref_output_folder %s", + golden_file_path) + if len(failed_case_list) != 0: + logging.info("Failing cases: {}".format(", ".join(failed_case_list))) + logging.info( + "Total case passed --> {} / {} ".format(passed_case_count, total_case_count)) + logging.info( + "Total case failed --> {} / {} ".format(failed_case_count, total_case_count)) + + +if __name__ == "__main__": + main() diff --git a/tests/python_api/parse_config.py b/tests/python_api/parse_config.py new file mode 100644 index 000000000..afbacb1fd --- /dev/null +++ b/tests/python_api/parse_config.py @@ -0,0 +1,126 @@ +# Copyright (c) 2018 - 2023 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. + +from argparse import ArgumentParser +import random + + +def parse_args(): + parser = ArgumentParser(description="Train Single Shot MultiBox Detector" + " on COCO") + + common_group = parser.add_argument_group( + 'common', 'common-related options') + # Data-related + common_group.add_argument('--image-dataset-path', '-d', type=str, + help='image folder files') + common_group.add_argument('--batch-size', '-b', type=int, default=10, + help='number of examples for each iteration') + common_group.add_argument('--display', action="store_true", + help='--display:to display output from the pipeline') + common_group.add_argument('--no-display', dest='display', action="store_false", + help='--no-display:to not display output from the pipeline') + # case when none of the above is specified + parser.set_defaults(display=False) + common_group.add_argument('--max-height', '-mh', type=int, default=1000, + help='maximum height set during decoding') + common_group.add_argument('--max-width', '-mw', type=int, default=1000, + help='maximum width set during decoding') + common_group.add_argument('--color-format', '-c', type=int, default=1, + help='color format used during decoding') + + common_group.add_argument('--print_tensor', action="store_true", + help='--print_tensor: to print tensor output from the pipeline') + common_group.add_argument('--no-print_tensor', dest='print_tensor', action="store_false", + help='--no-print_tensor: to not print tensor output from the pipeline') + # case when none of the above is specified + parser.set_defaults(print_tensor=False) + + common_group.add_argument('--classification', action="store_true", + help='--classification: to use for classification') + common_group.add_argument('--no-classification', dest='classification', action="store_false", + help='--no-classification: to use for detection pipeline') + # case when none of the above is specified + parser.set_defaults(classification=True) + + common_group.add_argument('--rocal-gpu', default=False, action="store_true", + help='--use_gpu to use gpu') + common_group.add_argument('--no-rocal-gpu', dest='rocal-gpu', action="store_false", + help='--no-rocal-gpu to use cpu backend') + + common_group.add_argument('--one-hot-encode', action="store_true", + help='--one-hot-encode: to use for one-hot-encoding of labels') + common_group.add_argument('--no-one-hot-encode', dest='one-hot-encode', action="store_false", + help='--no-one-hot-encode: to used when we do not want to one hot encode the labels') + # case when none of the above is specified + parser.set_defaults(one_hot_encode=False) + + common_group.add_argument('--NHWC', action='store_true', + help='run input pipeline NHWC format') + common_group.add_argument('--no-NHWC', dest='NHWC', action='store_false', + help='run input pipeline NCHW format') + parser.set_defaults(NHWC=True) # case when none of the above is specified + + common_group.add_argument('--fp16', default=False, action='store_true', + help='run input pipeline fp16 format') + + common_group.add_argument('--local-rank', type=int, default=0, + help='Device ID used by rocAL pipeline') + common_group.add_argument('--world-size', '-w', type=int, default=1, + help='number of partitions to split the dataset') + common_group.add_argument('--num-threads', '-nt', type=int, default=1, + help='number of CPU threads used by the rocAL pipeline.') + common_group.add_argument('--num-epochs', '-e', type=int, default=1, + help='number of epochs to run') + common_group.add_argument('--seed', '-s', type=int, default=random.SystemRandom().randint(0, 2**32 - 1), + help='manually set random seed') + + # unit_test.py related options + python_unit_test = parser.add_argument_group( + 'python-unittest', 'python-unittest-related options') + python_unit_test.add_argument('--reader-type', '-r', type=str, default="file", + help='Reader used for reading and decoding the images') + python_unit_test.add_argument('--augmentation-name', '-aug_name', type=str, default="resize", + help='refer python unit test for all augmentation names ') + python_unit_test.add_argument('--output-file-name', '-f', type=str, default="", + help='file name to save the augmentation outputs') + python_unit_test.add_argument('--interpolation-type', '-i', type=int, default=1, + help='interpolation type used for resize and crop') + python_unit_test.add_argument('--scaling-mode', '-sm', type=int, default=0, + help='scaling mode type used for resize') + # coco_pipeline.py related options + coco_pipeline = parser.add_argument_group( + 'coco-pipeline', 'coco-pipeline-related options') + coco_pipeline.add_argument('--json-path', '-json-path', type=str, + help='coco dataset json path') + # caffe_reader.py related options + caffe_pipeline = parser.add_argument_group( + 'caffe-pipeline', 'caffe-pipeline-related options') + caffe_pipeline.add_argument('--detection', '-detection', type=str, + help='detection') + # video_pipeline.py related options + video_pipeline = parser.add_argument_group( + 'video-pipeline', 'video-pipeline-related options') + video_pipeline.add_argument('--video-path', '-video-path', type=str, + help='video path') + video_pipeline.add_argument('--sequence-length', '-sequence-length', type=int, + help='video path') + + return parser.parse_args() diff --git a/tests/python_api/pipeline.py b/tests/python_api/pipeline.py new file mode 100644 index 000000000..603dee8a4 --- /dev/null +++ b/tests/python_api/pipeline.py @@ -0,0 +1,122 @@ +# Copyright (c) 2023 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 random +from amd.rocal.plugin.pytorch import ROCALClassificationIterator + +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import sys +import cv2 +import os + + +def draw_patches(img, idx, device=True, layout="NCHW"): + # image is expected as a tensor, bboxes as numpy + import cv2 + if device is False: + image = img.cpu().numpy() + else: + image = img.numpy() + if layout == "NCHW": + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + + str(idx)+"_"+"train"+".png", image * 255) + + +def main(): + if len(sys.argv) < 3: + print('Please pass image_folder cpu/gpu batch_size') + exit(0) + try: + path = "OUTPUT_FOLDER/FILE_READER/" + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + data_path = sys.argv[1] + rocal_cpu = True if sys.argv[2] == "cpu" else False + batch_size = int(sys.argv[3]) + num_threads = 1 + device_id = 0 + random_seed = random.SystemRandom().randint(0, 2**32 - 1) + local_rank = 0 + world_size = 1 + + image_classification_train_pipeline = Pipeline( + batch_size=batch_size, num_threads=num_threads, device_id=device_id, seed=random_seed, rocal_cpu=rocal_cpu) + + with image_classification_train_pipeline: + jpegs, _ = fn.readers.file(file_root=data_path) + decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, + file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + res = fn.resize(decode, resize_width=224, resize_height=224, + output_layout=types.NCHW, output_dtype=types.UINT8) + flip_coin = fn.random.coin_flip(probability=0.5) + cmnp = fn.crop_mirror_normalize(res, + output_layout=types.NCHW, + output_dtype=types.FLOAT, + crop=(224, 224), + mirror=flip_coin, + mean=[0.485 * 255, 0.456 * + 255, 0.406 * 255], + std=[0.229 * 255, 0.224 * 255, 0.225 * 255]) + image_classification_train_pipeline.set_outputs(cmnp) + +# There are 2 ways to get the outputs from the pipeline +# 1. Use the iterator +# 2. use the pipe.run() + +# Method 1 + # use the iterator + image_classification_train_pipeline.build() + imageIteratorPipeline = ROCALClassificationIterator( + image_classification_train_pipeline) + cnt = 0 + for i, it in enumerate(imageIteratorPipeline): + print(it) + print("************************************** i *************************************", i) + for img in it[0]: + cnt += 1 + draw_patches(img[0], cnt, device=rocal_cpu, layout="NCHW") + imageIteratorPipeline.reset() + print("*********************************************************************") + +# Method 2 + iter = 0 + # use pipe.run() call + output_data_batch = image_classification_train_pipeline.run() + print("\n Output Data Batch: ", output_data_batch) + # length depends on the number of augmentations + for i in range(len(output_data_batch)): + print("\n Output Layout: ", output_data_batch[i].layout()) + print("\n Output Dtype: ", output_data_batch[i].dtype()) + for image_counter in range(output_data_batch[i].batch_size()): + image = output_data_batch[i].at(image_counter) + image = image.transpose([1, 2, 0]) + cv2.imwrite("output_images_iter" + str(i) + str(image_counter) + + ".jpg", cv2.cvtColor(image * 255, cv2.COLOR_RGB2BGR)) + + +if __name__ == '__main__': + main() diff --git a/tests/python_api/prefetch_queue_depth/README.md b/tests/python_api/prefetch_queue_depth/README.md new file mode 100644 index 000000000..b44ecff17 --- /dev/null +++ b/tests/python_api/prefetch_queue_depth/README.md @@ -0,0 +1,40 @@ +## Test +This application briefs how to configure and pass the prefetch_queue_depth pipeline arugument. +This test aims to evaluate the prefetch queue depth support and the perfomance boost up. + +## Prefetch queue depth +* The rocAL pipeline allows the buffering of one or more batches of data. +* This can be achieved by configuring the prefetch_queue_depth pipeline argument which sets the depth of buffer in both load and output routine. +* Configuring this paramter controls the buffer that keeps the decoded image batch ready for processing and the processed image batch ready for user. +* The default prefetch depth is 2. +* Depending on the machine configuration decreasing or increasing prefetch_queue_depth helps in achieving better performance. + +## Running the app +`python3 ./prefetch_queue_depth.py ` + +## Example +* Run with 5000 images from COCO2017 Val dataset and batch size 128 on AMD Eng Sample: 100-000000248-08_35/21_N Processor with nproc - 128. + +prefetch_queue_depth as 2 + +``` +OK: loaded 82 kernels from libvx_rpp.so +Pipeline has been created succesfully +Time taken (averaged over 10 runs) 434458 milli seconds +``` + +prefetch_queue_depth as 4 + +``` +OK: loaded 82 kernels from libvx_rpp.so +Pipeline has been created succesfully +Time taken (averaged over 10 runs) 433953 milli seconds +``` + +prefetch_queue_depth as 8 + +``` +OK: loaded 82 kernels from libvx_rpp.so +Pipeline has been created succesfully +Time taken (averaged over 10 runs) 420856 milli seconds +``` diff --git a/tests/python_api/prefetch_queue_depth/prefetch_queue_depth.py b/tests/python_api/prefetch_queue_depth/prefetch_queue_depth.py new file mode 100644 index 000000000..222480815 --- /dev/null +++ b/tests/python_api/prefetch_queue_depth/prefetch_queue_depth.py @@ -0,0 +1,77 @@ +# Copyright (c) 2018 - 2023 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. + +from amd.rocal.plugin.generic import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import sys +import datetime +import time + +def HybridTrainPipe(batch_size, num_threads, device_id, data_dir, rocal_cpu=True, prefetch_queue_depth=2): + world_size = 1 + local_rank = 0 + resize_width = 300 + resize_height = 300 + decoder_device = 'cpu' # hardcoding decoder_device to cpu until VCN can decode all JPEGs + + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=device_id, + rocal_cpu=rocal_cpu, prefetch_queue_depth=prefetch_queue_depth) + with pipe: + jpegs, _ = fn.readers.file(file_root=data_dir) + images = fn.decoders.image(jpegs, file_root=data_dir, device=decoder_device, + output_type=types.RGB, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + images = fn.resize(images, resize_width=resize_width, + resize_height=resize_height) + output = fn.rain(images, rain=0.5) + pipe.set_outputs(output) + return pipe + + +def main(): + if len(sys.argv) < 5: + print('Please pass image_folder cpu/gpu batch_size prefetch_queue_depth') + exit(0) + image_folder_path = sys.argv[1] + if (sys.argv[2] == "cpu"): + rocal_cpu = True + else: + rocal_cpu = False + batch_size = int(sys.argv[3]) + prefetch_queue_depth = int(sys.argv[4]) + num_threads = 8 + device_id = 0 + pipe = HybridTrainPipe(batch_size=batch_size, num_threads=num_threads, device_id=device_id, + data_dir=image_folder_path, rocal_cpu=rocal_cpu, prefetch_queue_depth=prefetch_queue_depth) + pipe.build() + imageIterator = ROCALClassificationIterator(pipe) + start = datetime.datetime.now() + for _ in range(0, 10): + for _ in imageIterator: + time.sleep(1) + imageIterator.reset() + end = datetime.datetime.now() + print("Time taken (averaged over 10 runs) ", int( + (end - start).total_seconds() * 1000) / 10, "milli seconds") + +if __name__ == '__main__': + main() diff --git a/tests/python_api/pytorch_classification_reader.py b/tests/python_api/pytorch_classification_reader.py new file mode 100644 index 000000000..0ac21c72d --- /dev/null +++ b/tests/python_api/pytorch_classification_reader.py @@ -0,0 +1,108 @@ +# Copyright (c) 2018 - 2023 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 random +from amd.rocal.plugin.pytorch import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import numpy as np +import sys +import os + + +def draw_patches(img, idx, layout="nchw", dtype="fp32", device="cpu"): + # image is expected as a tensor + import cv2 + if device == "cpu": + image = img.detach().numpy() + else: + image = img.cpu().numpy() + if layout == "nchw": + image = image.transpose([1, 2, 0]) + if dtype == "fp16": + image = image.astype("uint8") + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + str(idx) + + "_" + "train" + ".png", image * 255) + + +def main(): + if len(sys.argv) < 3: + print("Please pass image_folder cpu/gpu batch_size") + exit(0) + try: + path = "OUTPUT_FOLDER/FILE_READER/" + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + data_path = sys.argv[1] + rocal_cpu = True if sys.argv[2] == "cpu" else False + batch_size = int(sys.argv[3]) + num_threads = 1 + device_id = 0 + random_seed = random.SystemRandom().randint(0, 2**32 - 1) + + local_rank = 0 + world_size = 1 + + image_classification_train_pipeline = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=device_id, + seed=random_seed, rocal_cpu=rocal_cpu, tensor_layout=types.NHWC, tensor_dtype=types.FLOAT16) + + with image_classification_train_pipeline: + jpegs, labels = fn.readers.file(file_root=data_path) + decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, + file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) + res = fn.resize(decode, resize_width=224, resize_height=224, + output_layout=types.NCHW, output_dtype=types.UINT8) + flip_coin = fn.random.coin_flip(probability=0.5) + cmnp = fn.crop_mirror_normalize(res, + output_layout=types.NHWC, + output_dtype=types.FLOAT16, + crop=(224, 224), + mirror=flip_coin, + mean=[0.485 * 255, 0.456 * + 255, 0.406 * 255], + std=[0.229 * 255, 0.224 * 255, 0.225 * 255]) + image_classification_train_pipeline.set_outputs(cmnp) + + image_classification_train_pipeline.build() + imageIteratorPipeline = ROCALClassificationIterator( + image_classification_train_pipeline) + cnt = 0 + for epoch in range(3): + print( + "+++++++++++++++++++++++++++++EPOCH+++++++++++++++++++++++++++++++++++++", epoch) + for i, it in enumerate(imageIteratorPipeline): + print(it) + print( + "************************************** i *************************************", i) + for img in it[0]: + cnt += 1 + draw_patches(img[0], cnt, layout="nhwc", + dtype="fp16", device=rocal_cpu) + imageIteratorPipeline.reset() + print("*********************************************************************") + + +if __name__ == "__main__": + main() diff --git a/tests/python_api/readers_test_file.sh b/tests/python_api/readers_test_file.sh new file mode 100755 index 000000000..d5ddd4a9a --- /dev/null +++ b/tests/python_api/readers_test_file.sh @@ -0,0 +1,346 @@ +#!/bin/bash + +if [[ $# -gt 0 ]]; then + helpFunction() + { + echo "" + echo "Usage: $0 [-n number_of_gpus] [-d dump_outputs] [-b backend] [-p print_tensor]" + echo -e "\t-n Description of what is the number of gpus to be used" + echo -e "\t-d Description of what is the display param" + echo -e "\t-d Description of what is the print tensor param" + exit 1 # Exit script after printing help + } + + while getopts "n:d:b:p:" opt + do + echo "In while loop" + echo $opt + case "$opt" in + n ) number_of_gpus="$OPTARG" ;; + d ) dump_outputs="$OPTARG" ;; + b ) backend="$OPTARG" ;; + p ) print_tensor="$OPTARG" ;; + ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent + esac + done + + # Print helpFunction in case parameters are empty + + if [ -z "$backend" ]; + then + backend_arg=no-rocal-gpu + else + if [[ $backend == "cpu" || $backend == "CPU" ]]; then + backend_arg=no-rocal-gpu + elif [[ $backend == "gpu" || $backend == "GPU" ]]; then + backend_arg=rocal-gpu + fi + fi + + if [ -z "$number_of_gpus" ]; + then + gpus_per_node=1 + else + gpus_per_node=$number_of_gpus + fi + + + if [ -z "$dump_outputs" ]; + then + display_arg=display #True by default + else + if [[ $dump_outputs == "true" || $dump_outputs == "True" ]]; then + display_arg=display + elif [[ $dump_outputs == "false" || $dump_outputs == "False" ]]; then + display_arg=no-display + fi + fi + + if [ -z "$print_tensor" ]; + then + print_tensor_arg=print_tensor #True by default + else + if [[ $print_tensor == "true" || $print_tensor == "True" ]]; then + print_tensor_arg=print_tensor + elif [[ $print_tensor == "false" || $print_tensor == "False" ]]; then + print_tensor_arg=no-print_tensor + fi + fi + + + echo $display_arg + echo $backend_arg + echo $print_tensor_arg + + +else + #DEFAULT ARGS + gpus_per_node=1 + display_arg=display + backend_arg=no-rocal-gpu #CPU by default + print_tensor_arg=no-print_tensor +fi + + +CURRENTDATE=`date +"%Y-%m-%d-%T"` + +# Mention Batch Size +batch_size=10 + +# python version +ver=$(python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";) + + +#################################################################################################################################### +# USER TO MAKE CHANGES HERE FOR TEST +# Make the respective " Pipeline " to test equal to 1 +rocAL_api_python_unittest=1 +coco_pipeline=1 +caffe_reader=1 +caffe2_reader=1 +rocAL_api_tf_classification_reader=1 +rocAL_api_tf_detection_pipeline=1 +rocAL_api_video_pipeline=1 +#################################################################################################################################### + + + + +#################################################################################################################################### +if [[ rocAL_api_python_unittest -eq 1 ]]; then + + # Mention dataset_path + data_dir=$ROCAL_DATA_PATH/rocal_data/images_jpg/labels_folder/ + + + # rocAL_api_python_unittest.py + # By default : cpu backend, NCHW format , fp32 + # Please pass image_folder augmentation_nanme in addition to other common args + # Refer rocAL_api_python_unitest.py for all augmentation names + python"$ver" rocAL_api_python_unittest.py \ + --image-dataset-path $data_dir \ + --augmentation-name snow \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 2 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ coco_pipeline -eq 1 ]]; then + + # Mention dataset_path + data_dir=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/val_10images_2017/ + + + # Mention json path + json_path=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/annotations/instances_val2017.json + + # coco_pipeline.py + # By default : cpu backend, NCHW format , fp32 + # Please pass annotation path in addition to other common args + # Annotation must be a json file + python"$ver" coco_pipeline.py \ + --image-dataset-path $data_dir \ + --json-path $json_path \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ caffe_reader -eq 1 ]]; then + + # Mention dataset_path + # Classification + data_dir=$ROCAL_DATA_PATH/rocal_data/caffe/classification/ + + # caffe_reader.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" caffe_reader.py \ + --image-dataset-path $data_dir \ + --classification \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + + +#################################################################################################################################### +if [[ caffe_reader -eq 1 ]]; then + + # Mention dataset_path + # Detection + data_dir=$ROCAL_DATA_PATH/rocal_data/caffe/detection/ + + # caffe_reader.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" caffe_reader.py \ + --image-dataset-path $data_dir \ + --no-classification \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + + +#################################################################################################################################### +if [[ caffe2_reader -eq 1 ]]; then + + # Mention dataset_path + # Classification + data_dir=$ROCAL_DATA_PATH/rocal_data/caffe2/classification/ + + # caffe2_reader.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" caffe2_reader.py \ + --image-dataset-path $data_dir \ + --classification \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ caffe2_reader -eq 1 ]]; then + + # Mention dataset_path + # Detection + data_dir=$ROCAL_DATA_PATH/rocal_data/caffe2/detection/ + + # caffe2_reader.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" caffe2_reader.py \ + --image-dataset-path $data_dir \ + --no-classification \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ rocAL_api_tf_classification_reader -eq 1 ]]; then + + # Mention dataset_path + # Classification + data_dir=$ROCAL_DATA_PATH/rocal_data/tf/classification/ + # rocAL_api_tf_classification_reader.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" rocAL_api_tf_classification_reader.py \ + --image-dataset-path $data_dir \ + --classification \ + --batch-size $batch_size \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ rocAL_api_tf_detection_pipeline -eq 1 ]]; then + + # Mention dataset_path + # Detection + data_dir=$ROCAL_DATA_PATH/rocal_data/tf/detection/ + # rocAL_api_tf_detection_pipeline.py + # By default : cpu backend, NCHW format , fp32 + # use --classification for Classification / --no-classification for Detection + + python"$ver" rocAL_api_tf_detection_pipeline.py \ + --image-dataset-path $data_dir \ + --no-classification \ + --batch-size 100 \ + --$display_arg \ + --$backend_arg \ + --NHWC \ + --local-rank 0 \ + --$print_tensor_arg \ + --world-size $gpus_per_node \ + --num-threads 1 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### + + +#################################################################################################################################### +if [[ rocAL_api_video_pipeline -eq 1 ]]; then + + # Mention dataset_path + # Detection + data_dir=$ROCAL_DATA_PATH/rocal_data/video_and_sequence_samples/labelled_videos/ + # rocAL_api_video_pipeline.py + # By default : cpu backend, NCHW format , fp32 + + python"$ver" rocAL_api_video_pipeline.py \ + --video-path $data_dir \ + --$backend_arg \ + --batch-size 10 \ + --$display_arg \ + --$print_tensor_arg \ + --sequence-length 3 \ + --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt +fi +#################################################################################################################################### diff --git a/tests/python_api/tf_classification_reader.py b/tests/python_api/tf_classification_reader.py new file mode 100644 index 000000000..44fcd87a1 --- /dev/null +++ b/tests/python_api/tf_classification_reader.py @@ -0,0 +1,109 @@ +# Copyright (c) 2018 - 2023 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. + +from amd.rocal.plugin.tf import ROCALIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.types as types +import os +import amd.rocal.fn as fn +import tensorflow as tf +import numpy as np +from parse_config import parse_args +import cupy as cp + + +def draw_patches(img, idx, device_type, args=None): + import cv2 + args = parse_args() + if device_type == "gpu": + img = cp.asnumpy(img) + if not args.NHWC: + img = img.transpose([0, 1, 2]) + image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) + cv2.imwrite("OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" + + str(idx) + "_" + "train" + ".png", image) + + +def main(): + args = parse_args() + # Args + image_path = args.image_dataset_path + rocal_cpu = False if args.rocal_gpu else True + device = "cpu" if rocal_cpu else "gpu" + batch_size = args.batch_size + one_hot_labels = 1 if args.one_hot_encode else 0 + num_threads = args.num_threads + tensor_layout = types.NHWC if args.NHWC else types.NCHW + tf_record_reader_type = 0 + feature_key_map = { + 'image/encoded': 'image/encoded', + 'image/class/label': 'image/class/label', + 'image/filename': 'image/filename' + } + try: + path = "OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" + is_exist = os.path.exists(path) + if not is_exist: + os.makedirs(path) + except OSError as error: + print(error) + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, + device_id=args.local_rank, seed=2, rocal_cpu=rocal_cpu) + # Use pipeline instance to make calls to reader, decoder & augmentation's + with pipe: + inputs = fn.readers.tfrecord(path=image_path, reader_type=tf_record_reader_type, user_feature_key_map=feature_key_map, + features={ + "image/encoded": tf.io.FixedLenFeature((), tf.string, ""), + "image/class/label": tf.io.FixedLenFeature([1], tf.int64, -1), + "image/filename": tf.io.FixedLenFeature((), tf.string, "") + } + ) + jpegs = inputs["image/encoded"] + images = fn.decoders.image( + jpegs, user_feature_key_map=feature_key_map, output_type=types.RGB, path=image_path) + resized = fn.resize(images, resize_width=300, + resize_height=300, output_layout=tensor_layout) + if one_hot_labels == 1: + labels = inputs["image/class/label"] + _ = fn.one_hot(labels, num_classes=1000) + pipe.set_outputs(resized) + # Build the pipeline + pipe.build() + # Dataloader + image_iterator = ROCALIterator(pipe, device=device) + cnt = 0 + # Enumerate over the Dataloader + for i, ([images_array], labels_array) in enumerate(image_iterator, 0): + if args.print_tensor: + print("\n", i) + print("lables_array", labels_array) + print("\n\nPrinted first batch with", (batch_size), "images!") + for element in list(range(batch_size)): + cnt += 1 + draw_patches(images_array[element], cnt, device, args=args) + break + image_iterator.reset() + + print("############################## TF CLASSIFICATION SUCCESS ############################") + + +if __name__ == "__main__": + main() diff --git a/tests/python_api/tf_detection_pipeline.py b/tests/python_api/tf_detection_pipeline.py new file mode 100644 index 000000000..8b9aa3920 --- /dev/null +++ b/tests/python_api/tf_detection_pipeline.py @@ -0,0 +1,161 @@ +# Copyright (c) 2018 - 2023 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. + +from amd.rocal.plugin.tf import ROCALIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.types as types +import tensorflow as tf +import amd.rocal.fn as fn +import numpy as np +import os +import cupy as cp +from parse_config import parse_args + + +def get_onehot(image_labels_array, num_classes): + one_hot_vector_list = [] + for label in image_labels_array: + one_hot_vector = np.zeros(num_classes) + if label[0] != 0: + np.put(one_hot_vector, label[0] - 1, 1) + one_hot_vector_list.append(one_hot_vector) + + one_hot_vector_array = np.array(one_hot_vector_list) + + return one_hot_vector_array + + +def get_weights(num_bboxes): + weights_array = np.zeros(num_bboxes) + for pos in list(range(num_bboxes)): + np.put(weights_array, pos, 1) + return weights_array + + +def draw_patches(img, idx, bboxes, device_type, args=None): + import cv2 + args = parse_args() + if device_type == "gpu": + img = cp.asnumpy(img) + if not args.NHWC: + img = img.transpose([0, 1, 2]) + image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) + image = cv2.normalize(image, None, alpha=0, beta=255, + norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F) + for (l, t, r, b) in bboxes: + loc_ = [l, t, r, b] + color = (255, 0, 0) + thickness = 2 + image = cv2.UMat(image).get() + image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( + (loc_[2])), int((loc_[3]))), color, thickness) + cv2.imwrite("OUTPUT_FOLDER/TF_READER/DETECTION/" + + str(idx) + "_" + "train" + ".png", image) + + +def main(): + args = parse_args() + # Args + image_path = args.image_dataset_path + num_classes = 91 + rocal_cpu = False if args.rocal_gpu else True + device = "cpu" if rocal_cpu else "gpu" + batch_size = args.batch_size + num_threads = args.num_threads + tensor_layout = types.NHWC if args.NHWC else types.NCHW + tf_record_reader_type = 1 + feature_key_map = { + 'image/encoded': 'image/encoded', + 'image/class/label': 'image/object/class/label', + 'image/class/text': 'image/object/class/text', + 'image/object/bbox/xmin': 'image/object/bbox/xmin', + 'image/object/bbox/ymin': 'image/object/bbox/ymin', + 'image/object/bbox/xmax': 'image/object/bbox/xmax', + 'image/object/bbox/ymax': 'image/object/bbox/ymax', + 'image/filename': 'image/filename' + } + try: + path = "OUTPUT_FOLDER/TF_READER/DETECTION" + is_exist = os.path.exists(path) + if not is_exist: + os.makedirs(path) + except OSError as error: + print(error) + + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, + device_id=args.local_rank, seed=2, rocal_cpu=rocal_cpu) + with pipe: + inputs = fn.readers.tfrecord(path=image_path, reader_type=tf_record_reader_type, user_feature_key_map=feature_key_map, + features={ + 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), + 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), + 'image/class/text': tf.io.FixedLenFeature([], tf.string, ''), + 'image/object/bbox/xmin': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/ymin': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/xmax': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/ymax': tf.io.VarLenFeature(dtype=tf.float32), + 'image/filename': tf.io.FixedLenFeature((), tf.string, "") + } + ) + jpegs = inputs["image/encoded"] + _ = inputs["image/class/label"] + decoded_images = fn.decoders.image_random_crop(jpegs, user_feature_key_map=feature_key_map, output_type=types.RGB, + random_aspect_ratio=[ + 0.8, 1.25], + random_area=[0.1, 1.0], + num_attempts=100, path=image_path) + resized = fn.resize(decoded_images, resize_width=300, + resize_height=300, output_layout=tensor_layout) + pipe.set_outputs(resized) + pipe.build() + image_iterator = ROCALIterator(pipe, device=device) + + cnt = 0 + for i, ([images_array], bboxes_array, labels_array, num_bboxes_array) in enumerate(image_iterator, 0): + print("ROCAL augmentation pipeline - Processing batch %d....." % i) + + for element in list(range(batch_size)): + cnt += 1 + if args.print_tensor: + print("Processing image %d....." % element) + features_dict = { + "image": images_array[element], + "true_image_shape": np.array([len(images_array[element]), len(images_array[element, 0]), len(images_array[element, 0, 0])]) + } + labels_dict = { + "num_groundtruth_boxes": num_bboxes_array[element], + "groundtruth_boxes": bboxes_array[element], + "groundtruth_classes": get_onehot(labels_array[element], num_classes), + "groundtruth_weights": get_weights(num_bboxes_array[element]) + } + processed_tensors = (features_dict, labels_dict) + if args.print_tensor: + print("\nPROCESSED_TENSORS:\n", processed_tensors) + draw_patches(images_array[element], cnt, + bboxes_array[element], device, args=args) + print("\n\nPrinted first batch with", (batch_size), "images!") + break + image_iterator.reset() + + print("############################## TF DETECTION SUCCESS ############################") + + +if __name__ == "__main__": + main() diff --git a/tests/python_api/unit_test.py b/tests/python_api/unit_test.py new file mode 100644 index 000000000..bfd81590c --- /dev/null +++ b/tests/python_api/unit_test.py @@ -0,0 +1,533 @@ +# Copyright (c) 2018 - 2023 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. + +from amd.rocal.plugin.generic import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +from parse_config import parse_args +import os +import sys +import cv2 +import cupy as cp + +INTERPOLATION_TYPES = { + 0: types.NEAREST_NEIGHBOR_INTERPOLATION, + 1: types.LINEAR_INTERPOLATION, + 2: types.CUBIC_INTERPOLATION, + 3: types.LANCZOS_INTERPOLATION, + 4: types.GAUSSIAN_INTERPOLATION, + 5: types.TRIANGULAR_INTERPOLATION +} + +SCALING_MODES = { + 0: types.SCALING_MODE_DEFAULT, + 1: types.SCALING_MODE_STRETCH, + 2: types.SCALING_MODE_NOT_SMALLER, + 3: types.SCALING_MODE_NOT_LARGER +} + + +def draw_patches(img, idx, device, args=None): + # image is expected as a tensor, bboxes as numpy + if device == "gpu": + img = cp.asnumpy(img) + if args.fp16: + img = (img).astype('uint8') + if not args.color_format: + img = img.transpose([0, 2, 3, 1]) + images_list = [] + for im in img: + images_list.append(im) + img = cv2.vconcat(images_list) + if args.color_format: + img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) + else: + img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + cv2.imwrite(args.output_file_name + ".png", img, + [cv2.IMWRITE_PNG_COMPRESSION, 9]) + +def dump_meta_data(labels, device, args=None): + if device == "gpu": + labels = cp.asnumpy(labels) + labels_list = labels.tolist() + with open(args.output_file_name, 'w') as file: + for label in labels_list: + file.write(str(label) + '\n') + +def main(): + args = parse_args() + # Args + data_path = args.image_dataset_path + reader_type = args.reader_type + augmentation_name = args.augmentation_name + print("\n AUGMENTATION NAME: ", augmentation_name) + rocal_cpu = False if args.rocal_gpu else True + device = "cpu" if rocal_cpu else "cuda" + batch_size = args.batch_size + max_height = args.max_height + max_width = args.max_width + color_format = types.RGB if args.color_format else types.GRAY + tensor_layout = types.NHWC if args.color_format else types.NCHW + tensor_dtype = types.UINT8 + num_threads = args.num_threads + random_seed = args.seed + local_rank = args.local_rank + world_size = args.world_size + interpolation_type = INTERPOLATION_TYPES[args.interpolation_type] + scaling_mode = SCALING_MODES[args.scaling_mode] + if (scaling_mode != types.SCALING_MODE_DEFAULT and interpolation_type != + types.LINEAR_INTERPOLATION): + interpolation_type = types.LINEAR_INTERPOLATION + if augmentation_name in ["hue", "saturation", "color_twist"] and color_format == types.GRAY: + print("Not a valid option! Exiting!") + sys.exit(0) + + try: + path = "OUTPUT_FOLDER/FILE_READER/" + args.augmentation_name + isExist = os.path.exists(path) + if not isExist: + os.makedirs(path) + except OSError as error: + print(error) + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, + num_threads=num_threads, + device_id=local_rank, + seed=random_seed, + rocal_cpu=rocal_cpu, + tensor_layout=tensor_layout, + tensor_dtype=tensor_dtype, + output_memory_type=types.HOST_MEMORY if rocal_cpu else types.DEVICE_MEMORY) + # Set Params + output_set = 0 + rocal_device = 'cpu' if rocal_cpu else 'gpu' + # hardcoding decoder_device to cpu to compare against golden outputs taken with turbojpeg decoder + decoder_device = 'cpu' + # Use pipeline instance to make calls to reader, decoder & augmentation's + with pipe: + if reader_type == "file": + jpegs, labels = fn.readers.file(file_root=data_path) + images = fn.decoders.image(jpegs, + file_root=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "coco": + annotation_path = args.json_path + jpegs, _, _ = fn.readers.coco(annotations_file=annotation_path) + images = fn.decoders.image(jpegs, + file_root=data_path, + annotations_file=annotation_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "tf_classification": + try: + import tensorflow as tf + except ImportError: + print('Install tensorflow to run tf_classification tests') + exit() + featureKeyMap = { + 'image/encoded': 'image/encoded', + 'image/class/label': 'image/class/label', + 'image/filename': 'image/filename' + } + features = { + 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), + 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), + 'image/filename': tf.io.FixedLenFeature((), tf.string, "") + } + inputs = fn.readers.tfrecord( + data_path, featureKeyMap, features, reader_type=0) + jpegs = inputs["image/encoded"] + images = fn.decoders.image(jpegs, user_feature_key_map=featureKeyMap, + output_type=color_format, path=data_path, + max_decoded_width=max_width, + max_decoded_height=max_height, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "tf_detection": + try: + import tensorflow as tf + except ImportError: + print('Install tensorflow to run tf_detection tests') + exit() + featureKeyMap = { + 'image/encoded': 'image/encoded', + 'image/class/label': 'image/object/class/label', + 'image/class/text': 'image/object/class/text', + 'image/object/bbox/xmin': 'image/object/bbox/xmin', + 'image/object/bbox/ymin': 'image/object/bbox/ymin', + 'image/object/bbox/xmax': 'image/object/bbox/xmax', + 'image/object/bbox/ymax': 'image/object/bbox/ymax', + 'image/filename': 'image/filename' + } + features = { + 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), + 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), + 'image/class/text': tf.io.FixedLenFeature([], tf.string, ''), + 'image/object/bbox/xmin': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/ymin': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/xmax': tf.io.VarLenFeature(dtype=tf.float32), + 'image/object/bbox/ymax': tf.io.VarLenFeature(dtype=tf.float32), + 'image/filename': tf.io.FixedLenFeature((), tf.string, "") + } + inputs = fn.readers.tfrecord( + path=data_path, reader_type=1, features=features, user_feature_key_map=featureKeyMap) + jpegs = inputs["image/encoded"] + _ = inputs["image/class/label"] + images = fn.decoders.image_random_crop(jpegs, user_feature_key_map=featureKeyMap, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False, path=data_path) + + elif reader_type == "caffe_classification": + jpegs, _ = fn.readers.caffe(path=data_path, bbox=False) + images = fn.decoders.image(jpegs, + path=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "caffe_detection": + jpegs, _, _ = fn.readers.caffe(path=data_path, bbox=True) + images = fn.decoders.image(jpegs, + path=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "caffe2_classification": + jpegs, _ = fn.readers.caffe2(path=data_path) + images = fn.decoders.image(jpegs, + path=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "caffe2_detection": + jpegs, _, _ = fn.readers.caffe2(path=data_path, bbox=True) + images = fn.decoders.image(jpegs, + path=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + elif reader_type == "mxnet": + jpegs = fn.readers.mxnet(path=data_path) + images = fn.decoders.image(jpegs, + path=data_path, + device=decoder_device, + max_decoded_width=max_width, + max_decoded_height=max_height, + output_type=color_format, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=False) + + if augmentation_name == "resize": + resize_w = 400 + resize_h = 400 + if (scaling_mode == types.SCALING_MODE_STRETCH): + resize_h = 480 + output = fn.resize(images, + resize_width=resize_w, + resize_height=resize_h, + output_layout=tensor_layout, + output_dtype=tensor_dtype, + scaling_mode=scaling_mode, + interpolation_type=interpolation_type) + elif augmentation_name == "rotate": + output = fn.rotate(images, + angle=45.0, + dest_width=640, + dest_height=480, + output_layout=tensor_layout, + output_dtype=tensor_dtype, + interpolation_type=interpolation_type) + elif augmentation_name == "brightness": + output = fn.brightness(images, + brightness=1.9, + brightness_shift=20.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "gamma_correction": + output = fn.gamma_correction(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "contrast": + output = fn.contrast(images, + contrast=30.0, + contrast_center=80.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "flip": + output = fn.flip(images, + horizontal=1, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "blur": + output = fn.blur(images, + window_size=5, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "warp_affine": + output = fn.warp_affine(images, dest_height=480, dest_width=640, matrix=[1.0, 1.0, 0.5, 0.5, 7.0, 7.0], + output_layout=tensor_layout, output_dtype=tensor_dtype, interpolation_type=types.LINEAR_INTERPOLATION) + elif augmentation_name == "fish_eye": + output = fn.fish_eye(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "vignette": + output = fn.vignette(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "jitter": + output = fn.jitter(images, + kernel_size=3, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "snp_noise": + output = fn.snp_noise(images, + p_noise=0.2, + p_salt=0.2, + noise_val=0.2, + salt_val=0.5, + seed=0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "snow": + output = fn.snow(images, + snow=0.2, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "rain": + output = fn.rain(images, + rain=0.5, + rain_width=2, + rain_height=16, + rain_transparency=0.25, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "fog": + output = fn.fog(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "pixelate": + output = fn.pixelate(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "exposure": + output = fn.exposure(images, + exposure=1.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "hue": + output = fn.hue(images, + hue=150.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "saturation": + output = fn.saturation(images, + saturation=0.3, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "color_twist": + output = fn.color_twist(images, + brightness=0.2, + contrast=10.0, + hue=100.0, + saturation=0.25, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "crop": + output = fn.crop(images, + crop=(3, 224, 224), + crop_pos_x=0.0, + crop_pos_y=0.0, + crop_pos_z=0.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "crop_mirror_normalize": + output = fn.crop_mirror_normalize(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype, + crop=(224, 224), + crop_pos_x=0.0, + crop_pos_y=0.0, + mean=[128, 128, 128], + std=[1.2, 1.2, 1.2]) + elif augmentation_name == "resize_mirror_normalize": + resize_w = 400 + resize_h = 400 + if (scaling_mode == types.SCALING_MODE_STRETCH): + resize_h = 480 + output = fn.resize_mirror_normalize(images, + resize_width=resize_w, + resize_height=resize_h, + output_layout=tensor_layout, + output_dtype=tensor_dtype, + scaling_mode=scaling_mode, + interpolation_type=interpolation_type, + mean=[128, 128, 128], + std=[1.2, 1.2, 1.2]) + elif augmentation_name == "nop": + output = fn.nop(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "centre_crop": + output = fn.centre_crop(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "color_temp": + output = fn.color_temp(images, + adjustment_value=70, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "copy": + output = fn.copy(images, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "resize_crop_mirror": + output = fn.resize_crop_mirror(images, + resize_height=400, + resize_width=400, + crop_h=200, + crop_w=200, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "lens_correction": + output = fn.lens_correction(images, + strength=2.9, + zoom=1.2, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "blend": + output1 = fn.rotate(images, + angle=45.0, + dest_width=640, + dest_height=480, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + output = fn.blend(images, + output1, + ratio=0.5, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "resize_crop": + output = fn.resize_crop(images, + resize_width=640, + resize_height=480, + crop_area_factor=0.25, + crop_aspect_ratio=1.2, + x_drift=0.6, + y_drift=0.4, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "center_crop": + output = fn.center_crop(images, + crop=[2, 224, 224], + output_layout=tensor_layout, + output_dtype=tensor_dtype) + elif augmentation_name == "one_hot": + output = fn.crop(images, + crop=(3, 224, 224), + crop_pos_x=0.0, + crop_pos_y=0.0, + crop_pos_z=0.0, + output_layout=tensor_layout, + output_dtype=tensor_dtype) + num_classes = len(next(os.walk(data_path))[1]) + labels_onehot = fn.one_hot(labels, num_classes=num_classes) + + if output_set == 0: + pipe.set_outputs(output) + # build the pipeline + pipe.build() + # Dataloader + data_loader = ROCALClassificationIterator( + pipe, device=device, device_id=local_rank) + cnt = 0 + import timeit + start = timeit.default_timer() + + # Enumerate over the Dataloader + for epoch in range(int(args.num_epochs)): + print("EPOCH:::::", epoch) + for i, (output_list, labels) in enumerate(data_loader, 0): + for j in range(len(output_list)): + if args.print_tensor: + print("**************", i, "*******************") + print("**************starts*******************") + print("\nImages:\n", output_list[j]) + print("\nLABELS:\n", labels) + print("**************ends*******************") + print("**************", i, "*******************") + if args.augmentation_name == "one_hot": + dump_meta_data(labels, rocal_device, args=args) + else: + draw_patches(output_list[j], cnt, rocal_device, args=args) + cnt += len(output_list[j]) + + data_loader.reset() + + stop = timeit.default_timer() + + print('\n Time: ', stop - start) + print('Number of times loop iterates is:', cnt) + + print( + f"############################## {augmentation_name.upper()} SUCCESS ############################") + + +if __name__ == '__main__': + main() diff --git a/tests/python_api/unit_tests.sh b/tests/python_api/unit_tests.sh new file mode 100755 index 000000000..fdf6d1a07 --- /dev/null +++ b/tests/python_api/unit_tests.sh @@ -0,0 +1,165 @@ +#!/bin/bash +cwd=$(pwd) + +if [[ $ROCAL_DATA_PATH == "" ]] +then + echo "Need to export ROCAL_DATA_PATH" + exit +fi + +# Path to inputs and outputs available in MIVisionX-data +one_hot_data_path=${ROCAL_DATA_PATH}/rocal_data/images_jpg/labels_folder/ +image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +coco_json_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/annotations/instances_train2017.json +tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ +tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ +caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ +caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ +caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ +caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ +mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ +output_path=./rocal_python_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ +golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ + +display=0 +batch_size=2 +device=0 +width=640 +height=480 +device_name="host" +rgb_name=("gray" "rgb") +rgb=1 +dev_start=0 +dev_end=1 +rgb_start=0 +rgb_end=1 + +if [ "$#" -gt 0 ]; then + if [ "$1" -eq 0 ]; then # For only HOST backend + dev_start=0 + dev_end=0 + elif [ "$1" -eq 1 ]; then # For only HIP backend + dev_start=1 + dev_end=1 + elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend + dev_start=0 + dev_end=1 + fi +fi + +if [ "$#" -gt 1 ]; then + if [ "$2" -eq 0 ]; then # For only Greyscale inputs + rgb_start=0 + rgb_end=0 + elif [ "$2" -eq 1 ]; then # For only RGB inputs + rgb_start=1 + rgb_end=1 + elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs + rgb_start=0 + rgb_end=1 + fi +fi + +mkdir "$output_path" + +for ((device=dev_start;device<=dev_end;device++)) +do + if [ $device -eq 1 ] + then + device_name="hip" + backend_arg=rocal-gpu + echo "Running HIP Backend..." + else + backend_arg=no-rocal-gpu + echo "Running HOST Backend..." + fi + for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) + do + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name lens_correction --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name exposure --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name flip --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" + + # coco detection + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name gamma_correction --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name contrast --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name vignette --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" + + # # tf classification + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name blend --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name warp_affine --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name blur --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" + + # tf detection + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name snp_noise --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name color_temp --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name fog --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" + + # caffe classification + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name rotate --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name brightness --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name hue --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" + + # caffe detection + python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name saturation --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name color_twist --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name rain --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" + + # caffe2 classification + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name center_crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name resize_crop_mirror --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name snow --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" + + # caffe2 detection + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name fish_eye --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name pixelate --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name center_crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}_cmn" + + # mxnet + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name jitter --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name resize_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ResizeMirrorNormalize_${rgb_name[$rgb]}_${device_name}" + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" + + # CMN + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" + python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" + + # crop + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" + python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" + + # resize + python"$ver" unit_test.py --image-dataset-path "$image_path" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" + python"$ver" unit_test.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 1 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" + python"$ver" unit_test.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 2 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" + python"$ver" unit_test.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 3 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 2 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" + # python"$ver" unit_test.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 0 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" + python"$ver" unit_test.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 3 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" + python"$ver" unit_test.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 5 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" + python"$ver" unit_test.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 4 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" + + # Special Case - One Hot Encoded Labels + python"$ver" unit_test.py --image-dataset-path "$one_hot_data_path" --augmentation-name one_hot --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}OneHot_${rgb_name[$rgb]}_${device_name}" + + done +done + +pwd + +# Run python script to compare rocAL outputs with golden ouptuts +python3 "$cwd"/image_comparison.py "$golden_output_path" "$output_path" diff --git a/tests/python_api/video_pipeline.py b/tests/python_api/video_pipeline.py new file mode 100644 index 000000000..1a1556a9a --- /dev/null +++ b/tests/python_api/video_pipeline.py @@ -0,0 +1,166 @@ +# Copyright (c) 2018 - 2023 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 +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types +import numpy as np +from parse_config import parse_args + + +class ROCALVideoIterator(object): + """ + ROCALVideoIterator for pyTorch. + + Parameters + ---------- + pipelines : list of amd.rocal.pipeline.Pipeline + List of pipelines to use + size : int + Epoch size. + """ + + def __init__(self, pipelines, tensor_layout=types.NCHW, reverse_channels=False, multiplier=None, offset=None, tensor_dtype=types.FLOAT, display=False, sequence_length=3): + + try: + assert pipelines is not None, "Number of provided pipelines has to be at least 1" + except Exception as ex: + print(ex) + + self.loader = pipelines + self.tensor_format = tensor_layout + self.multiplier = multiplier if multiplier else [1.0, 1.0, 1.0] + self.offset = offset if offset else [0.0, 0.0, 0.0] + self.reverse_channels = reverse_channels + self.tensor_dtype = tensor_dtype + self.batch_size = self.loader._batch_size + self.rim = self.loader.get_remaining_images() + self.display = display + self.iter_num = 0 + self.sequence_length = sequence_length + print("____________REMAINING IMAGES____________:", self.rim) + self.output = self.dimensions = self.dtype = None + + def next(self): + return self.__next__() + + def __next__(self): + if (self.loader.is_empty()): + raise StopIteration + + if self.loader.rocal_run() != 0: + raise StopIteration + self.output_tensor_list = self.loader.get_output_tensors() + self.iter_num += 1 + # Copy output from buffer to numpy array + if self.output is None: + self.dimensions = self.output_tensor_list[0].dimensions() + self.dtype = self.output_tensor_list[0].dtype() + self.layout = self.output_tensor_list[0].layout() + self.output = np.empty( + (self.dimensions[0]*self.dimensions[1], self.dimensions[2], self.dimensions[3], self.dimensions[4]), dtype=self.dtype) + self.output_tensor_list[0].copy_data(self.output) + img = torch.from_numpy(self.output) + # Display Frames in a video sequence + if self.display: + for batch_i in range(self.batch_size): + draw_frames(img[batch_i], batch_i, self.iter_num, self.layout) + return img + + def reset(self): + self.loader.rocal_reset_loaders() + + def __iter__(self): + return self + + def __del__(self): + self.loader.rocal_release() + + +def draw_frames(img, batch_idx, iter_idx, layout): + # image is expected as a tensor, bboxes as numpy + import cv2 + image = img.detach().numpy() + if layout == 'NFCHW': + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + import os + if not os.path.exists("OUTPUT_FOLDER/VIDEO_READER"): + os.makedirs("OUTPUT_FOLDER/VIDEO_READER") + image = cv2.UMat(image).get() + cv2.imwrite("OUTPUT_FOLDER/VIDEO_READER/" + + "iter_"+str(iter_idx)+"_batch_"+str(batch_idx)+".png", image) + + +def main(): + # Args + args = parse_args() + video_path = args.video_path + rocal_cpu = False if args.rocal_gpu else True + batch_size = args.batch_size + user_sequence_length = args.sequence_length + display = args.display + num_threads = args.num_threads + random_seed = args.seed + tensor_format = types.NFHWC if args.NHWC else types.NFCHW + tensor_dtype = types.FLOAT16 if args.fp16 else types.FLOAT + # Create Pipeline instance + pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=args.local_rank, seed=random_seed, rocal_cpu=rocal_cpu, + tensor_layout=tensor_format, tensor_dtype=tensor_dtype) + # Use pipeline instance to make calls to reader, decoder & augmentation's + with pipe: + images = fn.readers.video(file_root=video_path, sequence_length=user_sequence_length, + random_shuffle=False, image_type=types.RGB) + crop_size = (512, 960) + output_images = fn.crop_mirror_normalize(images, + output_layout=tensor_format, + output_dtype=tensor_dtype, + crop=crop_size, + mean=[0, 0, 0], + std=[1, 1, 1]) + pipe.set_outputs(output_images) + # Build the pipeline + pipe.build() + # Dataloader + data_loader = ROCALVideoIterator(pipe, multiplier=pipe._multiplier, + offset=pipe._offset, display=display, sequence_length=user_sequence_length) + import timeit + start = timeit.default_timer() + # Enumerate over the Dataloader + for epoch in range(int(args.num_epochs)): + print("EPOCH:::::", epoch) + for i, it in enumerate(data_loader, 0): + if args.print_tensor: + print("**************", i, "*******************") + print("**************starts*******************") + print("\n IMAGES : \n", it) + print("**************ends*******************") + print("**************", i, "*******************") + data_loader.reset() + # Your statements here + stop = timeit.default_timer() + + print('\n Time: ', stop - start) + print("############################## VIDEO READER SUCCESS ############################") + + +if __name__ == '__main__': + main() From 7294668103603887b9ae4f68eb38e9db6ab2c38a Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 08:57:39 -0700 Subject: [PATCH 05/21] renmaing cpp tests --- CMakeLists.txt | 2 +- docs/examples/image_processing/decoder.py | 60 -- docs/examples/pytorch/README.md | 15 - docs/examples/pytorch/test_training.py | 210 ----- .../examples/PYTHON_UNITTEST_TEST_FILE.sh | 165 ---- rocAL_pybind/examples/READERS_TEST_FILE.sh | 346 -------- rocAL_pybind/examples/README.md | 68 -- rocAL_pybind/examples/image_comparison.py | 207 ----- rocAL_pybind/examples/parse_config.py | 126 --- .../examples/prefetch_queue_depth/README.md | 40 - .../prefetch_queue_depth.py | 77 -- .../examples/rocAL_api_caffe2_reader.py | 129 --- .../examples/rocAL_api_caffe_reader.py | 135 --- .../examples/rocAL_api_coco_pipeline.py | 231 ----- ...ocAL_api_external_source_reader_example.py | 279 ------ rocAL_pybind/examples/rocAL_api_pipeline.py | 122 --- .../examples/rocAL_api_python_unittest.py | 533 ------------ ...rocAL_api_pytorch_classification_reader.py | 108 --- .../rocAL_api_tf_classification_reader.py | 109 --- .../rocAL_api_tf_detection_pipeline.py | 161 ---- .../examples/rocAL_api_video_pipeline.py | 166 ---- tests/README.md | 4 +- tests/cpp_api/CMakeLists.txt | 120 +-- .../basic_test}/CMakeLists.txt | 2 +- .../basic_test.cpp} | 2 +- .../CMakeLists.txt | 2 +- .../dataloader}/README.md | 8 +- .../dataloader.cpp} | 0 .../dataloader_multithread}/CMakeLists.txt | 6 +- .../README.md | 8 +- .../dataloader_multithread.cpp} | 2 +- .../dataloader_tf}/CMakeLists.txt | 4 +- .../dataloader_tf}/README.md | 5 +- .../dataloader_tf.cpp} | 2 +- .../external_source}/CMakeLists.txt | 2 +- .../README.md | 4 +- .../external_source/external_source.cpp} | 2 +- .../CMakeLists.txt | 2 +- .../performance_tests}/README.md | 4 +- .../performance_tests.cpp} | 2 +- .../CMakeLists.txt | 2 +- .../README.md | 2 +- .../performance_tests_with_depth.cpp} | 0 tests/cpp_api/rocAL_dataloader/README.md | 24 - .../rocAL_dataloader_mt/CMakeLists.txt | 132 --- .../rocAL_dataloader_mt.cpp | 257 ------ .../rocAL_dataloader_tf/CMakeLists.txt | 75 -- tests/cpp_api/rocAL_dataloader_tf/README.md | 24 - .../rocAL_external_source/CMakeLists.txt | 73 -- .../rocal_external_source.cpp | 426 --------- .../rocAL_performance_tests/CMakeLists.txt | 98 --- .../cpp_api/rocAL_performance_tests/README.md | 23 - .../CMakeLists.txt | 76 -- tests/cpp_api/rocAL_unittests/README.md | 51 -- .../rocAL_unittests/rocAL_unittests.cpp | 814 ------------------ .../cpp_api/rocAL_unittests/testAllScripts.sh | 177 ---- tests/cpp_api/rocAL_video_unittests/README.md | 132 --- .../CMakeLists.txt | 2 +- .../unit_tests}/README.md | 4 +- .../pixel_comparison/image_comparison.py | 0 tests/cpp_api/unit_tests/testAllScripts.sh | 177 ++++ .../unit_tests/unit_tests.cpp} | 2 +- .../CMakeLists.txt | 2 +- .../video_tests}/README.md | 2 +- .../samples/sequence_reader.png | Bin .../samples/sequence_rearrange.png | Bin .../samples/video_reader.png | Bin .../testScript.sh | 6 +- .../video_tests.cpp} | 2 +- tests/cpp_api_tests/CMakeLists.txt | 163 ---- .../rocAL_basic_test/rocal_basic_test.cpp | 219 ----- .../rocAL_dataloader/CMakeLists.txt | 98 --- .../rocAL_dataloader/rocAL_dataloader.cpp | 243 ------ .../rocAL_dataloader_mt/README.md | 24 - .../rocAL_dataloader_tf/CMakeLists.txt | 75 -- .../rocAL_dataloader_tf.cpp | 274 ------ .../rocAL_external_source/README.md | 28 - .../rocAL_performance_tests/CMakeLists.txt | 98 --- .../rocAL_performance_tests.cpp | 336 -------- .../README.md | 23 - .../rocAL_performance_tests_with_depth.cpp | 593 ------------- .../pixel_comparison/image_comparison.py | 180 ---- .../rocAL_unittests/testAllScripts.sh | 177 ---- .../rocAL_video_unittests/CMakeLists.txt | 75 -- .../rocAL_video_unittests.cpp | 327 ------- .../samples/sequence_reader.png | Bin 12447 -> 0 bytes .../samples/sequence_rearrange.png | Bin 15552 -> 0 bytes .../samples/video_reader.png | Bin 13369 -> 0 bytes .../rocAL_video_unittests/testScript.sh | 62 -- tests/python_api/readers_test_file.sh | 32 +- 90 files changed, 297 insertions(+), 8783 deletions(-) delete mode 100644 docs/examples/image_processing/decoder.py delete mode 100644 docs/examples/pytorch/README.md delete mode 100644 docs/examples/pytorch/test_training.py delete mode 100755 rocAL_pybind/examples/PYTHON_UNITTEST_TEST_FILE.sh delete mode 100755 rocAL_pybind/examples/READERS_TEST_FILE.sh delete mode 100644 rocAL_pybind/examples/README.md delete mode 100644 rocAL_pybind/examples/image_comparison.py delete mode 100644 rocAL_pybind/examples/parse_config.py delete mode 100644 rocAL_pybind/examples/prefetch_queue_depth/README.md delete mode 100644 rocAL_pybind/examples/prefetch_queue_depth/prefetch_queue_depth.py delete mode 100644 rocAL_pybind/examples/rocAL_api_caffe2_reader.py delete mode 100644 rocAL_pybind/examples/rocAL_api_caffe_reader.py delete mode 100755 rocAL_pybind/examples/rocAL_api_coco_pipeline.py delete mode 100644 rocAL_pybind/examples/rocAL_api_external_source_reader_example.py delete mode 100644 rocAL_pybind/examples/rocAL_api_pipeline.py delete mode 100644 rocAL_pybind/examples/rocAL_api_python_unittest.py delete mode 100644 rocAL_pybind/examples/rocAL_api_pytorch_classification_reader.py delete mode 100644 rocAL_pybind/examples/rocAL_api_tf_classification_reader.py delete mode 100644 rocAL_pybind/examples/rocAL_api_tf_detection_pipeline.py delete mode 100644 rocAL_pybind/examples/rocAL_api_video_pipeline.py rename tests/{cpp_api_tests/rocAL_basic_test => cpp_api/basic_test}/CMakeLists.txt (99%) rename tests/cpp_api/{rocAL_basic_test/rocal_basic_test.cpp => basic_test/basic_test.cpp} (97%) rename tests/cpp_api/{rocAL_dataloader => dataloader}/CMakeLists.txt (99%) rename tests/{cpp_api_tests/rocAL_dataloader => cpp_api/dataloader}/README.md (66%) rename tests/cpp_api/{rocAL_dataloader/rocAL_dataloader.cpp => dataloader/dataloader.cpp} (100%) rename tests/{cpp_api_tests/rocAL_dataloader_mt => cpp_api/dataloader_multithread}/CMakeLists.txt (94%) rename tests/cpp_api/{rocAL_dataloader_mt => dataloader_multithread}/README.md (56%) rename tests/{cpp_api_tests/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp => cpp_api/dataloader_multithread/dataloader_multithread.cpp} (98%) rename tests/{cpp_api_tests/rocAL_unittests => cpp_api/dataloader_tf}/CMakeLists.txt (99%) rename tests/{cpp_api_tests/rocAL_dataloader_tf => cpp_api/dataloader_tf}/README.md (72%) rename tests/cpp_api/{rocAL_dataloader_tf/rocAL_dataloader_tf.cpp => dataloader_tf/dataloader_tf.cpp} (98%) rename tests/{cpp_api_tests/rocAL_external_source => cpp_api/external_source}/CMakeLists.txt (98%) rename tests/cpp_api/{rocAL_external_source => external_source}/README.md (74%) rename tests/{cpp_api_tests/rocAL_external_source/rocal_external_source.cpp => cpp_api/external_source/external_source.cpp} (99%) rename tests/cpp_api/{rocAL_basic_test => performance_tests}/CMakeLists.txt (99%) rename tests/{cpp_api_tests/rocAL_performance_tests => cpp_api/performance_tests}/README.md (70%) rename tests/cpp_api/{rocAL_performance_tests/rocAL_performance_tests.cpp => performance_tests/performance_tests.cpp} (98%) rename tests/{cpp_api_tests/rocAL_performance_tests_with_depth => cpp_api/performance_tests_with_depth}/CMakeLists.txt (98%) rename tests/cpp_api/{rocAL_performance_tests_with_depth => performance_tests_with_depth}/README.md (78%) rename tests/cpp_api/{rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp => performance_tests_with_depth/performance_tests_with_depth.cpp} (100%) delete mode 100644 tests/cpp_api/rocAL_dataloader/README.md delete mode 100644 tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt delete mode 100644 tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp delete mode 100644 tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt delete mode 100644 tests/cpp_api/rocAL_dataloader_tf/README.md delete mode 100644 tests/cpp_api/rocAL_external_source/CMakeLists.txt delete mode 100644 tests/cpp_api/rocAL_external_source/rocal_external_source.cpp delete mode 100644 tests/cpp_api/rocAL_performance_tests/CMakeLists.txt delete mode 100644 tests/cpp_api/rocAL_performance_tests/README.md delete mode 100644 tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt delete mode 100644 tests/cpp_api/rocAL_unittests/README.md delete mode 100644 tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp delete mode 100755 tests/cpp_api/rocAL_unittests/testAllScripts.sh delete mode 100644 tests/cpp_api/rocAL_video_unittests/README.md rename tests/cpp_api/{rocAL_unittests => unit_tests}/CMakeLists.txt (99%) rename tests/{cpp_api_tests/rocAL_unittests => cpp_api/unit_tests}/README.md (82%) rename tests/cpp_api/{rocAL_unittests => unit_tests}/pixel_comparison/image_comparison.py (100%) create mode 100755 tests/cpp_api/unit_tests/testAllScripts.sh rename tests/{cpp_api_tests/rocAL_unittests/rocAL_unittests.cpp => cpp_api/unit_tests/unit_tests.cpp} (99%) rename tests/cpp_api/{rocAL_video_unittests => video_tests}/CMakeLists.txt (98%) rename tests/{cpp_api_tests/rocAL_video_unittests => cpp_api/video_tests}/README.md (97%) rename tests/cpp_api/{rocAL_video_unittests => video_tests}/samples/sequence_reader.png (100%) rename tests/cpp_api/{rocAL_video_unittests => video_tests}/samples/sequence_rearrange.png (100%) rename tests/cpp_api/{rocAL_video_unittests => video_tests}/samples/video_reader.png (100%) rename tests/cpp_api/{rocAL_video_unittests => video_tests}/testScript.sh (86%) rename tests/cpp_api/{rocAL_video_unittests/rocAL_video_unittests.cpp => video_tests/video_tests.cpp} (97%) delete mode 100644 tests/cpp_api_tests/CMakeLists.txt delete mode 100644 tests/cpp_api_tests/rocAL_basic_test/rocal_basic_test.cpp delete mode 100644 tests/cpp_api_tests/rocAL_dataloader/CMakeLists.txt delete mode 100644 tests/cpp_api_tests/rocAL_dataloader/rocAL_dataloader.cpp delete mode 100644 tests/cpp_api_tests/rocAL_dataloader_mt/README.md delete mode 100644 tests/cpp_api_tests/rocAL_dataloader_tf/CMakeLists.txt delete mode 100644 tests/cpp_api_tests/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp delete mode 100644 tests/cpp_api_tests/rocAL_external_source/README.md delete mode 100644 tests/cpp_api_tests/rocAL_performance_tests/CMakeLists.txt delete mode 100644 tests/cpp_api_tests/rocAL_performance_tests/rocAL_performance_tests.cpp delete mode 100644 tests/cpp_api_tests/rocAL_performance_tests_with_depth/README.md delete mode 100644 tests/cpp_api_tests/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp delete mode 100644 tests/cpp_api_tests/rocAL_unittests/pixel_comparison/image_comparison.py delete mode 100755 tests/cpp_api_tests/rocAL_unittests/testAllScripts.sh delete mode 100644 tests/cpp_api_tests/rocAL_video_unittests/CMakeLists.txt delete mode 100644 tests/cpp_api_tests/rocAL_video_unittests/rocAL_video_unittests.cpp delete mode 100644 tests/cpp_api_tests/rocAL_video_unittests/samples/sequence_reader.png delete mode 100644 tests/cpp_api_tests/rocAL_video_unittests/samples/sequence_rearrange.png delete mode 100644 tests/cpp_api_tests/rocAL_video_unittests/samples/video_reader.png delete mode 100755 tests/cpp_api_tests/rocAL_video_unittests/testScript.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f6dea8a8..ee15be3a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,7 +142,7 @@ install(FILES docs/README.md DESTINATION ${CMAKE_INSTALL_DATADIR}/doc/rocal) enable_testing() include(CTest) -add_subdirectory(tests/cpp_api_tests) +add_subdirectory(tests/cpp_api) # set package information set(CPACK_PACKAGE_VERSION ${VERSION}) diff --git a/docs/examples/image_processing/decoder.py b/docs/examples/image_processing/decoder.py deleted file mode 100644 index 073fa383c..000000000 --- a/docs/examples/image_processing/decoder.py +++ /dev/null @@ -1,60 +0,0 @@ - -import sys -from amd.rocal.pipeline import pipeline_def -from amd.rocal.plugin.generic import ROCALClassificationIterator -import amd.rocal.fn as fn -import amd.rocal.types as types -import matplotlib.gridspec as gridspec -import matplotlib.pyplot as plt -import cupy as cp - -seed = 1549361629 -image_dir = "../../../data/images/AMD-tinyDataSet/" -batch_size = 4 -gpu_id = 0 - -def show_images(image_batch, device): - columns = 4 - rows = (batch_size + 1) // (columns) - #fig = plt.figure(figsize = (32,(32 // columns) * rows)) - gs = gridspec.GridSpec(rows, columns) - for j in range(rows*columns): - #print('\n Display image: ', j) - plt.subplot(gs[j]) - img = image_batch[j] - plt.axis("off") - if device == "cpu": - plt.imshow(img) - else: - plt.imshow(cp.asnumpy(img)) - plt.show() - - -def show_pipeline_output(pipe, device): - pipe.build() - data_loader = ROCALClassificationIterator(pipe, device) - images = next(iter(data_loader)) - show_images(images[0][0], device) - -@pipeline_def(seed=seed) -def image_decoder_pipeline(device="cpu", path=image_dir): - jpegs, labels = fn.readers.file(file_root=path) - images = fn.decoders.image(jpegs, file_root=path, device=device, output_type=types.RGB, shard_id=0, num_shards=1, random_shuffle=False) - return fn.resize(images, device=device, resize_width=300, resize_height=300) - -def main(): - print ('Optional arguments: ') - bs = batch_size - rocal_device = "cpu" - img_folder = image_dir - if len(sys.argv) > 1: - if(sys.argv[1] == "gpu"): - rocal_device = "gpu" - if len(sys.argv) > 2: - img_folder = sys.argv[2] - pipe = image_decoder_pipeline(batch_size=bs, num_threads=1, device_id=gpu_id, rocal_cpu=True, tensor_layout=types.NHWC, - reverse_channels=True, mean = [0, 0, 0], std=[255,255,255], device=rocal_device, path=img_folder) - show_pipeline_output(pipe, device=rocal_device) - -if __name__ == '__main__': - main() diff --git a/docs/examples/pytorch/README.md b/docs/examples/pytorch/README.md deleted file mode 100644 index 277960db9..000000000 --- a/docs/examples/pytorch/README.md +++ /dev/null @@ -1,15 +0,0 @@ -* This example shows how to run training using pytorch and ToyNet with 2 classes -* Use a dataset with 2 classes - -### Building the required Pytorch Rocm docker -* Use the instructions in the [docker section](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker) to build the required [Pytorch docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/pytorch) -* Upgrade pip to the latest version. -* Run requirements.sh to install the required packages. - -### To run the sample: -* Install rocal_pybind - -``` -python3 test_training.py -``` -* rocal device can be cpu/gpu. diff --git a/docs/examples/pytorch/test_training.py b/docs/examples/pytorch/test_training.py deleted file mode 100644 index d66ddb628..000000000 --- a/docs/examples/pytorch/test_training.py +++ /dev/null @@ -1,210 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc. -# -# 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 sys -from amd.rocal.plugin.pytorch import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import os -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -import torch - -def trainPipeline(data_path, batch_size, num_classes, one_hot, local_rank, world_size, num_thread, crop, rocal_cpu, fp16): - pipe = Pipeline(batch_size=batch_size, num_threads=num_thread, device_id=local_rank, seed=local_rank+10, - rocal_cpu=rocal_cpu, tensor_dtype = types.FLOAT16 if fp16 else types.FLOAT, tensor_layout=types.NCHW, - prefetch_queue_depth = 7) - with pipe: - jpegs, labels = fn.readers.file(file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - rocal_device = 'cpu' if rocal_cpu else 'gpu' - # decode = fn.decoders.image(jpegs, output_type=types.RGB,file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, - file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - res = fn.resize(decode, resize_x=224, resize_y=224) - flip_coin = fn.random.coin_flip(probability=0.5) - cmnp = fn.crop_mirror_normalize(res, device="gpu", - output_dtype=types.FLOAT, - output_layout=types.NCHW, - crop=(crop, crop), - mirror=flip_coin, - image_type=types.RGB, - mean=[0.485 * 255,0.456 * 255,0.406 * 255], - std=[0.229 * 255,0.224 * 255,0.225 * 255]) - if(one_hot): - _ = fn.one_hot(labels, num_classes) - pipe.set_outputs(cmnp) - print('rocal "{0}" variant'.format(rocal_device)) - return pipe - -class trainLoader(): - def __init__(self, data_path, batch_size, num_thread, crop, rocal_cpu): - super(trainLoader, self).__init__() - self.data_path = data_path - self.batch_size = batch_size - self.num_thread = num_thread - self.crop = crop - self.rocal_cpu = rocal_cpu - self.num_classes = 1000 - self.one_hot = 0.0 - self.local_rank = 0 - self.world_size = 1 - self.fp16 = True - - def get_pytorch_train_loader(self): - print("in get_pytorch_train_loader function") - pipe_train = trainPipeline(self.data_path, self.batch_size, self.num_classes, self.one_hot, self.local_rank, - self.world_size, self.num_thread, self.crop, self.rocal_cpu, self.fp16) - pipe_train.build() - train_loader = ROCALClassificationIterator(pipe_train, device="cpu" if self.rocal_cpu else "cuda", device_id = self.local_rank) - if self.rocal_cpu: - return PrefetchedWrapper_rocal(train_loader, self.rocal_cpu) ,len(train_loader) - else: - return train_loader , len(train_loader) - -class PrefetchedWrapper_rocal(object): - def prefetched_loader(loader, rocal_cpu): - - stream = torch.cuda.Stream() - first = True - input = None - target = None - for next_input, next_target in loader: - with torch.cuda.stream(stream): - if rocal_cpu: - next_input = next_input.cuda(non_blocking=True) - next_target = next_target.cuda(non_blocking=True) - - if not first: - yield input, target - else: - first = False - - torch.cuda.current_stream().wait_stream(stream) - input = next_input - target = next_target - - yield input, target - - def __init__(self, dataloader, rocal_cpu): - self.dataloader = dataloader - self.epoch = 0 - self.rocal_cpu = rocal_cpu - - def reset(self): - self.dataloader.reset() - - def __iter__(self): - self.epoch += 1 - return PrefetchedWrapper_rocal.prefetched_loader(self.dataloader, self.rocal_cpu) - -class ToyNet(nn.Module): - def __init__(self,num_classes): - super(ToyNet, self).__init__() - self.conv1 = nn.Conv2d(3, 6, 5) - self.pool = nn.MaxPool2d(2, 2) - self.conv2 = nn.Conv2d(6, 16, 5) - self.conv3 = nn.Conv2d(16, 64, 3) - self.conv4 = nn.Conv2d(64, 256, 3) - self.fc0 = nn.Linear(256 * 11*11, 2048) - self.fc1 = nn.Linear(2048, 512) - self.fc2 = nn.Linear(512, 128) - self.fc3 = nn.Linear(128, num_classes) # Two classes only - self.m = nn.Softmax() - - def forward(self, x): - x = self.pool(F.relu(self.conv1(x))) - x = self.pool(F.relu(self.conv2(x))) - x = self.pool(F.relu(self.conv3(x))) - x = self.pool(F.relu(self.conv4(x))) - x = x.view(-1, 256 * 11 *11) - x = F.relu(self.fc0(x)) - x = F.relu(self.fc1(x)) - x = F.relu(self.fc2(x)) - x = self.fc3(x) - return x - -def main(): - if len(sys.argv) < 4: - print ('Please pass image_folder cpu/gpu batch_size') - exit(0) - if(sys.argv[2] == "cpu"): - rocal_cpu = True - else: - rocal_cpu = False - bs = int(sys.argv[3]) - nt = 1 - crop_size = 224 - device="cpu" if rocal_cpu else "cuda" - image_path = sys.argv[1] - dataset_train = image_path + '/train' - num_classes = len(next(os.walk(image_path))[1]) - print("num_classes:: ",num_classes) - - net = ToyNet(num_classes) - net.to(device) - - #train loader - train_loader_obj = trainLoader(dataset_train, batch_size=bs, num_thread=nt, crop=crop_size, rocal_cpu=rocal_cpu) - train_loader, train_loader_len = train_loader_obj.get_pytorch_train_loader() - - criterion = nn.CrossEntropyLoss() - optimizer = optim.SGD(net.parameters(), lr=0.0005, momentum=0.9) - - # Training loop - for epoch in range(10): # loop over the dataset multiple times - print("\n epoch:: ",epoch) - running_loss = 0.0 - - for i, (inputs,labels) in enumerate(train_loader, 0): - - sys.stdout.write("\r Mini-batch " + str(i)) - # print("Images",inputs) - # print("Labels",labels) - inputs, labels = inputs.to(device), labels.to(device) - optimizer.zero_grad() - - outputs = net(inputs) - - loss = criterion(outputs, labels) - loss.backward() - optimizer.step() - - # print statistics - running_loss += loss.item() - print_interval = 10 - if i % print_interval == (print_interval-1): - print('[%d, %5d] loss: %.3f' % - (epoch + 1, i + 1, running_loss / print_interval)) - running_loss = 0.0 - train_loader.reset() - - print('Finished Training') - - -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/PYTHON_UNITTEST_TEST_FILE.sh b/rocAL_pybind/examples/PYTHON_UNITTEST_TEST_FILE.sh deleted file mode 100755 index bd97c768e..000000000 --- a/rocAL_pybind/examples/PYTHON_UNITTEST_TEST_FILE.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash -cwd=$(pwd) - -if [[ $ROCAL_DATA_PATH == "" ]] -then - echo "Need to export ROCAL_DATA_PATH" - exit -fi - -# Path to inputs and outputs available in MIVisionX-data -one_hot_data_path=${ROCAL_DATA_PATH}/rocal_data/images_jpg/labels_folder/ -image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -coco_json_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/annotations/instances_train2017.json -tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ -tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ -caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ -caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ -caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ -caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ -mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ -output_path=./rocal_python_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ -golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ - -display=0 -batch_size=2 -device=0 -width=640 -height=480 -device_name="host" -rgb_name=("gray" "rgb") -rgb=1 -dev_start=0 -dev_end=1 -rgb_start=0 -rgb_end=1 - -if [ "$#" -gt 0 ]; then - if [ "$1" -eq 0 ]; then # For only HOST backend - dev_start=0 - dev_end=0 - elif [ "$1" -eq 1 ]; then # For only HIP backend - dev_start=1 - dev_end=1 - elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend - dev_start=0 - dev_end=1 - fi -fi - -if [ "$#" -gt 1 ]; then - if [ "$2" -eq 0 ]; then # For only Greyscale inputs - rgb_start=0 - rgb_end=0 - elif [ "$2" -eq 1 ]; then # For only RGB inputs - rgb_start=1 - rgb_end=1 - elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs - rgb_start=0 - rgb_end=1 - fi -fi - -mkdir "$output_path" - -for ((device=dev_start;device<=dev_end;device++)) -do - if [ $device -eq 1 ] - then - device_name="hip" - backend_arg=rocal-gpu - echo "Running HIP Backend..." - else - backend_arg=no-rocal-gpu - echo "Running HOST Backend..." - fi - for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) - do - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name lens_correction --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name exposure --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name flip --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" - - # coco detection - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name gamma_correction --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name contrast --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name vignette --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" - - # # tf classification - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name blend --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name warp_affine --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name blur --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" - - # tf detection - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name snp_noise --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name color_temp --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name fog --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" - - # caffe classification - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name rotate --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name brightness --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name hue --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" - - # caffe detection - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name saturation --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name color_twist --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name rain --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" - - # caffe2 classification - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name center_crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name resize_crop_mirror --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name snow --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" - - # caffe2 detection - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name fish_eye --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name pixelate --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name center_crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}_cmn" - - # mxnet - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name jitter --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name resize_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}ResizeMirrorNormalize_${rgb_name[$rgb]}_${device_name}" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" - - # CMN - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop_mirror_normalize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" - - # crop - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name crop --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" - - # resize - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$image_path" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$coco_detection_path" --reader-type coco --json-path "$coco_json_path" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 1 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_classification_path" --reader-type "tf_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 2 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$tf_detection_path" --reader-type "tf_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 1 --scaling-mode 3 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_classification_path" --reader-type "caffe_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 2 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" - # python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe_detection_path" --reader-type "caffe_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 0 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_classification_path" --reader-type "caffe2_classification" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 3 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$caffe2_detection_path" --reader-type "caffe2_detection" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 5 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$mxnet_path" --reader-type "mxnet" --augmentation-name resize --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --interpolation-type 4 --scaling-mode 0 --$backend_arg -f "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" - - # Special Case - One Hot Encoded Labels - python"$ver" rocAL_api_python_unittest.py --image-dataset-path "$one_hot_data_path" --augmentation-name one_hot --batch-size $batch_size --max-width $width --max-height $height --color-format $rgb --$backend_arg -f "${output_path}OneHot_${rgb_name[$rgb]}_${device_name}" - - done -done - -pwd - -# Run python script to compare rocAL outputs with golden ouptuts -python3 "$cwd"/image_comparison.py "$golden_output_path" "$output_path" diff --git a/rocAL_pybind/examples/READERS_TEST_FILE.sh b/rocAL_pybind/examples/READERS_TEST_FILE.sh deleted file mode 100755 index 8ef726294..000000000 --- a/rocAL_pybind/examples/READERS_TEST_FILE.sh +++ /dev/null @@ -1,346 +0,0 @@ -#!/bin/bash - -if [[ $# -gt 0 ]]; then - helpFunction() - { - echo "" - echo "Usage: $0 [-n number_of_gpus] [-d dump_outputs] [-b backend] [-p print_tensor]" - echo -e "\t-n Description of what is the number of gpus to be used" - echo -e "\t-d Description of what is the display param" - echo -e "\t-d Description of what is the print tensor param" - exit 1 # Exit script after printing help - } - - while getopts "n:d:b:p:" opt - do - echo "In while loop" - echo $opt - case "$opt" in - n ) number_of_gpus="$OPTARG" ;; - d ) dump_outputs="$OPTARG" ;; - b ) backend="$OPTARG" ;; - p ) print_tensor="$OPTARG" ;; - ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent - esac - done - - # Print helpFunction in case parameters are empty - - if [ -z "$backend" ]; - then - backend_arg=no-rocal-gpu - else - if [[ $backend == "cpu" || $backend == "CPU" ]]; then - backend_arg=no-rocal-gpu - elif [[ $backend == "gpu" || $backend == "GPU" ]]; then - backend_arg=rocal-gpu - fi - fi - - if [ -z "$number_of_gpus" ]; - then - gpus_per_node=1 - else - gpus_per_node=$number_of_gpus - fi - - - if [ -z "$dump_outputs" ]; - then - display_arg=display #True by default - else - if [[ $dump_outputs == "true" || $dump_outputs == "True" ]]; then - display_arg=display - elif [[ $dump_outputs == "false" || $dump_outputs == "False" ]]; then - display_arg=no-display - fi - fi - - if [ -z "$print_tensor" ]; - then - print_tensor_arg=print_tensor #True by default - else - if [[ $print_tensor == "true" || $print_tensor == "True" ]]; then - print_tensor_arg=print_tensor - elif [[ $print_tensor == "false" || $print_tensor == "False" ]]; then - print_tensor_arg=no-print_tensor - fi - fi - - - echo $display_arg - echo $backend_arg - echo $print_tensor_arg - - -else - #DEFAULT ARGS - gpus_per_node=1 - display_arg=display - backend_arg=no-rocal-gpu #CPU by default - print_tensor_arg=no-print_tensor -fi - - -CURRENTDATE=`date +"%Y-%m-%d-%T"` - -# Mention Batch Size -batch_size=10 - -# python version -ver=$(python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";) - - -#################################################################################################################################### -# USER TO MAKE CHANGES HERE FOR TEST -# Make the respective " Pipeline " to test equal to 1 -rocAL_api_python_unittest=1 -rocAL_api_coco_pipeline=1 -rocAL_api_caffe_reader=1 -rocAL_api_caffe2_reader=1 -rocAL_api_tf_classification_reader=1 -rocAL_api_tf_detection_pipeline=1 -rocAL_api_video_pipeline=1 -#################################################################################################################################### - - - - -#################################################################################################################################### -if [[ rocAL_api_python_unittest -eq 1 ]]; then - - # Mention dataset_path - data_dir=$ROCAL_DATA_PATH/rocal_data/images_jpg/labels_folder/ - - - # rocAL_api_python_unittest.py - # By default : cpu backend, NCHW format , fp32 - # Please pass image_folder augmentation_nanme in addition to other common args - # Refer rocAL_api_python_unitest.py for all augmentation names - python"$ver" rocAL_api_python_unittest.py \ - --image-dataset-path $data_dir \ - --augmentation-name snow \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 2 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_coco_pipeline -eq 1 ]]; then - - # Mention dataset_path - data_dir=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/val_10images_2017/ - - - # Mention json path - json_path=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/annotations/instances_val2017.json - - # rocAL_api_coco_pipeline.py - # By default : cpu backend, NCHW format , fp32 - # Please pass annotation path in addition to other common args - # Annotation must be a json file - python"$ver" rocAL_api_coco_pipeline.py \ - --image-dataset-path $data_dir \ - --json-path $json_path \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_caffe_reader -eq 1 ]]; then - - # Mention dataset_path - # Classification - data_dir=$ROCAL_DATA_PATH/rocal_data/caffe/classification/ - - # rocAL_api_caffe_reader.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_caffe_reader.py \ - --image-dataset-path $data_dir \ - --classification \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - - -#################################################################################################################################### -if [[ rocAL_api_caffe_reader -eq 1 ]]; then - - # Mention dataset_path - # Detection - data_dir=$ROCAL_DATA_PATH/rocal_data/caffe/detection/ - - # rocAL_api_caffe_reader.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_caffe_reader.py \ - --image-dataset-path $data_dir \ - --no-classification \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - - -#################################################################################################################################### -if [[ rocAL_api_caffe2_reader -eq 1 ]]; then - - # Mention dataset_path - # Classification - data_dir=$ROCAL_DATA_PATH/rocal_data/caffe2/classification/ - - # rocAL_api_caffe2_reader.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_caffe2_reader.py \ - --image-dataset-path $data_dir \ - --classification \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_caffe2_reader -eq 1 ]]; then - - # Mention dataset_path - # Detection - data_dir=$ROCAL_DATA_PATH/rocal_data/caffe2/detection/ - - # rocAL_api_caffe2_reader.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_caffe2_reader.py \ - --image-dataset-path $data_dir \ - --no-classification \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_tf_classification_reader -eq 1 ]]; then - - # Mention dataset_path - # Classification - data_dir=$ROCAL_DATA_PATH/rocal_data/tf/classification/ - # rocAL_api_tf_classification_reader.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_tf_classification_reader.py \ - --image-dataset-path $data_dir \ - --classification \ - --batch-size $batch_size \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_tf_detection_pipeline -eq 1 ]]; then - - # Mention dataset_path - # Detection - data_dir=$ROCAL_DATA_PATH/rocal_data/tf/detection/ - # rocAL_api_tf_detection_pipeline.py - # By default : cpu backend, NCHW format , fp32 - # use --classification for Classification / --no-classification for Detection - - python"$ver" rocAL_api_tf_detection_pipeline.py \ - --image-dataset-path $data_dir \ - --no-classification \ - --batch-size 100 \ - --$display_arg \ - --$backend_arg \ - --NHWC \ - --local-rank 0 \ - --$print_tensor_arg \ - --world-size $gpus_per_node \ - --num-threads 1 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### - - -#################################################################################################################################### -if [[ rocAL_api_video_pipeline -eq 1 ]]; then - - # Mention dataset_path - # Detection - data_dir=$ROCAL_DATA_PATH/rocal_data/video_and_sequence_samples/labelled_videos/ - # rocAL_api_video_pipeline.py - # By default : cpu backend, NCHW format , fp32 - - python"$ver" rocAL_api_video_pipeline.py \ - --video-path $data_dir \ - --$backend_arg \ - --batch-size 10 \ - --$display_arg \ - --$print_tensor_arg \ - --sequence-length 3 \ - --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_log.${CURRENTDATE}.txt -fi -#################################################################################################################################### diff --git a/rocAL_pybind/examples/README.md b/rocAL_pybind/examples/README.md deleted file mode 100644 index a4a192cb5..000000000 --- a/rocAL_pybind/examples/README.md +++ /dev/null @@ -1,68 +0,0 @@ -### TESTING ALL THE READER PIPELINES ON PYTHON IN SINGLE SHOT - -./TEST_FILE.sh - -### TO TEST A SINGLE READER / MULTIPLE READER PIPELINE FROM TEST_FILE.sh - -# Make the respective " Pipeline " to test equal to "1" -rocAL_api_python_unittest=1 -rocAL_api_coco_pipeline=0 - -## INSTALL PYBIND TO RUN ANY TESTS -* [rocAL Pybind Installation](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/README.md) - -## EXPORT ROCAL_DATA_PATH -export ROCAL_DATA_PATH=/Absolute/Path/Of/MIVisionX-data/ - -### TESTING ALL THE AUGMENTATIONS IN A SINGLE SHOT - -./PYTHON_UNITTEST_TEST_FILE.sh (This runs all augmentations and readers and compare them with golden outputs for both backends) - -### TO TEST MULTIPLE READER PIPELINE FROM READERS_TEST_FILE.sh - -./READERS_TEST_FILE.sh (The default value of number of gpu's is "1" & display is "ON" by default) - -./READERS_TEST_FILE.sh -n -d -./READERS_TEST_FILE.sh -n "1" -d "false" -b "cpu" - -### TO TEST A SINGLE READER PIPELINE FROM READERS_TEST_FILE.sh - -example : To run COCO Pipeline - -rocAL_api_python_unittest=0 -rocAL_api_coco_pipeline=1 -rocAL_api_caffe_reader=0 -rocAL_api_caffe2_reader=0 -rocAL_api_tf_classification_reader=0 -rocAL_api_tf_detection_pipeline=0 - -### TO TEST A SINGLE READER PIPELINE FROM CMD LINE - -example: COCO Pipeline - - # Mention the number of gpus - gpus_per_node=4 - - # Mention Batch Size - batch_size=10 - - # python version - ver=$(python -V 2>&1 | sed 's/.* \([0-9]\).\([0-9]\).*/\1\.\2/') - - # Mention dataset_path - data_dir=$ROCAL_DATA_PATH/coco/coco_10_img/val_10images_2017/ - - # Mention json path - json_path=$ROCAL_DATA_PATH/coco/coco_10_img/annotations/instances_val2017.json - - # rocAL_api_coco_pipeline.py - # By default : cpu backend, NCHW format , fp32 - # Annotation must be a json file - - # For printing all the arguments that can be passed from user - python$ver rocAL_api_coco_pipeline.py -h - - python$ver rocAL_api_coco_pipeline.py --image-dataset-path $data_dir --json-path $json_path --batch-size $batch_size --display --rocal-gpu --NHWC \ - --local-rank 0 --world-size $gpus_per_node --num-threads 1 --num-epochs 1 2>&1 | tee -a run.log.rocAL_api_coco_pipeline.txt - -### [ NOTE: REFER parse_config.py for more INFO on other args] diff --git a/rocAL_pybind/examples/image_comparison.py b/rocAL_pybind/examples/image_comparison.py deleted file mode 100644 index a0e8ad4fc..000000000 --- a/rocAL_pybind/examples/image_comparison.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright (c) 2023 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. - -from PIL import Image -import os -import sys -import datetime -import logging -import ast - - -def compare_pixels(img1, img2, aug_name, width, height, image_offset=0): - pixel_difference = [0, 0, 0, 0, 0, 0] - if "rgb" in aug_name: - pixels1 = img1.load() - pixels2 = img2.load() - channel = 3 - else: - pixels1 = img1.convert("L").load() - pixels2 = img2.convert("L").load() - channel = 1 - total_valid_pixel_count = width * height * channel - for wt in range(width): - for ht in range(height): - ht = ht + image_offset - if pixels1[wt, ht] != pixels2[wt, ht]: - if channel == 1: - diff_val = abs(pixels1[wt, ht] - pixels2[wt, ht]) - diff_val = min(diff_val, 5) - pixel_difference[diff_val] += 1 - else: - for ch in range(channel): - diff_val = abs( - pixels1[wt, ht][ch] - pixels2[wt, ht][ch]) - diff_val = min(diff_val, 5) - pixel_difference[diff_val] += 1 - else: - pixel_difference[0] += channel - return pixel_difference, total_valid_pixel_count - -def compare_file_with_list(filename, reference_list): - with open(filename, 'r') as file: - file_contents = file.read().strip() - file_contents = ast.literal_eval(file_contents) - if len(file_contents) != len(reference_list): - print("File content and existing list have different lengths.") - return -1 # Return a negative value to indicate a mismatch in lengths - mismatch_count = 0 - for file_inner_list, list_inner_list in zip(file_contents, reference_list): - if file_inner_list != list_inner_list: - mismatch_count += 1 - return mismatch_count - -def main(): - timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S_") - handlers = [ - logging.FileHandler("./rocal_unittest_log_file_" + timestamp + ".log"), - logging.StreamHandler(), - ] - logging.basicConfig(level=logging.INFO, handlers=handlers) - if len(sys.argv) < 3: - print("Please pass ref_output_folder_path rocal_ouput_folder_path") - logging.error( - "Please pass ref_output_folder_path rocal_ouput_folder_path") - exit(0) - # Open the two images - ref_output_path = sys.argv[1] - rocal_output_path = sys.argv[2] - - if not (os.path.exists(ref_output_path) and os.path.exists(rocal_output_path)): - logging.error("Path does not Exists") - exit() - total_case_count = 0 - passed_case_count = 0 - failed_case_count = 0 - failed_case_list = [] - golden_output_dir_list = os.listdir(ref_output_path) - rocal_output_dir_list = os.listdir(rocal_output_path) - randomized_augmentation = ["Snow", "Rain", "Jitter", "SNPNoise"] - spl_case_meta_data = ["OneHot"] - golden_file_path = "" - for aug_name in rocal_output_dir_list: - temp = aug_name.split(".") - file_name_split = temp[0].split("_") - if len(file_name_split) > 3: - file_name_split.pop() - golden_file_path = "_".join(file_name_split) + ".png" - else: - golden_file_path = aug_name - - # For randomized augmentation - if file_name_split[0] in randomized_augmentation: - total_case_count = total_case_count + 1 - augmentation_name = aug_name.split(".")[0] - logging.info("Running %s", augmentation_name) - passed_case_count = passed_case_count + 1 - logging.info("PASSED ") - elif file_name_split[0] in spl_case_meta_data: - total_case_count = total_case_count + 1 - reference_list = [[1, 0], [1, 0]] - rocal_file_path = rocal_output_path + aug_name - if os.path.exists(rocal_file_path): - logging.info("Running %s ", aug_name.split(".")[0]) - total_mismatches = compare_file_with_list(rocal_file_path, reference_list) - if total_mismatches == 0: - passed_case_count = passed_case_count + 1 - logging.info("PASSED") - else: - failed_case_list.append(file_name_split[0]) - failed_case_count = failed_case_count + 1 - logging.info("FAILED") - logging.info("Printing total mismatches in one hot encode %s", total_mismatches) - elif golden_file_path in golden_output_dir_list: - total_case_count = total_case_count + 1 - ref_file_path = ref_output_path + golden_file_path - rocal_file_path = rocal_output_path + aug_name - if os.path.exists(rocal_file_path) and os.path.exists(ref_file_path): - logging.info("Running %s ", aug_name.split(".")[0]) - img1 = Image.open(ref_file_path) - img2 = Image.open(rocal_file_path) - - # Check if the images have the same dimensions - if img1.size != img2.size: - logging.info( - "Golden output and augmentation outputs are having different sizes. Exiting!") - exit() - - # Compare the pixel values for each image - pixel_diff = None - total_count = 0 - if "larger" in aug_name: - resize_width = 400 - resize_height = 300 - image_offset = 400 - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, resize_width, resize_height) - pixel_diff2, total_count2 = compare_pixels( - img1, img2, aug_name, resize_width, resize_height, image_offset) - pixel_diff = [x + y for x, - y in zip(pixel_diff, pixel_diff2)] - total_count = total_count + total_count2 - elif "smaller" in aug_name: - resize_width = 533 - resize_height = 400 - image_offset = 2400 - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, resize_width, resize_height) - pixel_diff2, total_count2 = compare_pixels( - img1, img2, aug_name, resize_width, resize_height, image_offset) - pixel_diff = [x + y for x, - y in zip(pixel_diff, pixel_diff2)] - total_count = total_count + total_count2 - else: - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, img1.size[0], img1.size[1]) - total_pixel_diff = 0 - for pix_diff in range(1, 6): - total_pixel_diff += pixel_diff[pix_diff] - mismatch_percentage = round( - (total_pixel_diff / total_count) * 100, 2) - if ((total_pixel_diff == 0) or (mismatch_percentage < 5.0 and pixel_diff[1] == total_pixel_diff) or # Ignore test cases with single pixel differences less than 5% of total pixel count - (mismatch_percentage < 0.5 and ("Blend" in aug_name or "Rotate" in aug_name) and "hip" in aug_name)): # Ignore mismatch in rotate augmentation less than 0.5% of total pixel count - passed_case_count = passed_case_count + 1 - logging.info("PASSED") - else: - failed_case_list.append(golden_file_path) - failed_case_count = failed_case_count + 1 - logging.info("FAILED") - logging.info("Printing pixel mismatch %s", pixel_diff) - logging.info("Mismatach percentage %0.2f", - mismatch_percentage) - for pix_diff in range(1, 6): - logging.info("Percentage of %d pixel mismatch %0.2f", pix_diff, round( - (pixel_diff[pix_diff] / total_pixel_diff) * 100, 2)) - else: - logging.info( - "Skipping the testcase as file not found %s", rocal_file_path) - else: - logging.info("File not found in ref_output_folder %s", - golden_file_path) - if len(failed_case_list) != 0: - logging.info("Failing cases: {}".format(", ".join(failed_case_list))) - logging.info( - "Total case passed --> {} / {} ".format(passed_case_count, total_case_count)) - logging.info( - "Total case failed --> {} / {} ".format(failed_case_count, total_case_count)) - - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/parse_config.py b/rocAL_pybind/examples/parse_config.py deleted file mode 100644 index 0e6f2e9cc..000000000 --- a/rocAL_pybind/examples/parse_config.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from argparse import ArgumentParser -import random - - -def parse_args(): - parser = ArgumentParser(description="Train Single Shot MultiBox Detector" - " on COCO") - - common_group = parser.add_argument_group( - 'common', 'common-related options') - # Data-related - common_group.add_argument('--image-dataset-path', '-d', type=str, - help='image folder files') - common_group.add_argument('--batch-size', '-b', type=int, default=10, - help='number of examples for each iteration') - common_group.add_argument('--display', action="store_true", - help='--display:to display output from the pipeline') - common_group.add_argument('--no-display', dest='display', action="store_false", - help='--no-display:to not display output from the pipeline') - # case when none of the above is specified - parser.set_defaults(display=False) - common_group.add_argument('--max-height', '-mh', type=int, default=1000, - help='maximum height set during decoding') - common_group.add_argument('--max-width', '-mw', type=int, default=1000, - help='maximum width set during decoding') - common_group.add_argument('--color-format', '-c', type=int, default=1, - help='color format used during decoding') - - common_group.add_argument('--print_tensor', action="store_true", - help='--print_tensor: to print tensor output from the pipeline') - common_group.add_argument('--no-print_tensor', dest='print_tensor', action="store_false", - help='--no-print_tensor: to not print tensor output from the pipeline') - # case when none of the above is specified - parser.set_defaults(print_tensor=False) - - common_group.add_argument('--classification', action="store_true", - help='--classification: to use for classification') - common_group.add_argument('--no-classification', dest='classification', action="store_false", - help='--no-classification: to use for detection pipeline') - # case when none of the above is specified - parser.set_defaults(classification=True) - - common_group.add_argument('--rocal-gpu', default=False, action="store_true", - help='--use_gpu to use gpu') - common_group.add_argument('--no-rocal-gpu', dest='rocal-gpu', action="store_false", - help='--no-rocal-gpu to use cpu backend') - - common_group.add_argument('--one-hot-encode', action="store_true", - help='--one-hot-encode: to use for one-hot-encoding of labels') - common_group.add_argument('--no-one-hot-encode', dest='one-hot-encode', action="store_false", - help='--no-one-hot-encode: to used when we do not want to one hot encode the labels') - # case when none of the above is specified - parser.set_defaults(one_hot_encode=False) - - common_group.add_argument('--NHWC', action='store_true', - help='run input pipeline NHWC format') - common_group.add_argument('--no-NHWC', dest='NHWC', action='store_false', - help='run input pipeline NCHW format') - parser.set_defaults(NHWC=True) # case when none of the above is specified - - common_group.add_argument('--fp16', default=False, action='store_true', - help='run input pipeline fp16 format') - - common_group.add_argument('--local-rank', type=int, default=0, - help='Device ID used by rocAL pipeline') - common_group.add_argument('--world-size', '-w', type=int, default=1, - help='number of partitions to split the dataset') - common_group.add_argument('--num-threads', '-nt', type=int, default=1, - help='number of CPU threads used by the rocAL pipeline.') - common_group.add_argument('--num-epochs', '-e', type=int, default=1, - help='number of epochs to run') - common_group.add_argument('--seed', '-s', type=int, default=random.SystemRandom().randint(0, 2**32 - 1), - help='manually set random seed') - - # rocAL_api_python_unittest.py related options - python_unit_test = parser.add_argument_group( - 'python-unittest', 'python-unittest-related options') - python_unit_test.add_argument('--reader-type', '-r', type=str, default="file", - help='Reader used for reading and decoding the images') - python_unit_test.add_argument('--augmentation-name', '-aug_name', type=str, default="resize", - help='refer python unit test for all augmentation names ') - python_unit_test.add_argument('--output-file-name', '-f', type=str, default="", - help='file name to save the augmentation outputs') - python_unit_test.add_argument('--interpolation-type', '-i', type=int, default=1, - help='interpolation type used for resize and crop') - python_unit_test.add_argument('--scaling-mode', '-sm', type=int, default=0, - help='scaling mode type used for resize') - # rocAL_api_coco_pipeline.py related options - coco_pipeline = parser.add_argument_group( - 'coco-pipeline', 'coco-pipeline-related options') - coco_pipeline.add_argument('--json-path', '-json-path', type=str, - help='coco dataset json path') - # rocAL_api_caffe_reader.py related options - caffe_pipeline = parser.add_argument_group( - 'caffe-pipeline', 'caffe-pipeline-related options') - caffe_pipeline.add_argument('--detection', '-detection', type=str, - help='detection') - # rocAL_api_video_pipeline.py related options - video_pipeline = parser.add_argument_group( - 'video-pipeline', 'video-pipeline-related options') - video_pipeline.add_argument('--video-path', '-video-path', type=str, - help='video path') - video_pipeline.add_argument('--sequence-length', '-sequence-length', type=int, - help='video path') - - return parser.parse_args() diff --git a/rocAL_pybind/examples/prefetch_queue_depth/README.md b/rocAL_pybind/examples/prefetch_queue_depth/README.md deleted file mode 100644 index b44ecff17..000000000 --- a/rocAL_pybind/examples/prefetch_queue_depth/README.md +++ /dev/null @@ -1,40 +0,0 @@ -## Test -This application briefs how to configure and pass the prefetch_queue_depth pipeline arugument. -This test aims to evaluate the prefetch queue depth support and the perfomance boost up. - -## Prefetch queue depth -* The rocAL pipeline allows the buffering of one or more batches of data. -* This can be achieved by configuring the prefetch_queue_depth pipeline argument which sets the depth of buffer in both load and output routine. -* Configuring this paramter controls the buffer that keeps the decoded image batch ready for processing and the processed image batch ready for user. -* The default prefetch depth is 2. -* Depending on the machine configuration decreasing or increasing prefetch_queue_depth helps in achieving better performance. - -## Running the app -`python3 ./prefetch_queue_depth.py ` - -## Example -* Run with 5000 images from COCO2017 Val dataset and batch size 128 on AMD Eng Sample: 100-000000248-08_35/21_N Processor with nproc - 128. - -prefetch_queue_depth as 2 - -``` -OK: loaded 82 kernels from libvx_rpp.so -Pipeline has been created succesfully -Time taken (averaged over 10 runs) 434458 milli seconds -``` - -prefetch_queue_depth as 4 - -``` -OK: loaded 82 kernels from libvx_rpp.so -Pipeline has been created succesfully -Time taken (averaged over 10 runs) 433953 milli seconds -``` - -prefetch_queue_depth as 8 - -``` -OK: loaded 82 kernels from libvx_rpp.so -Pipeline has been created succesfully -Time taken (averaged over 10 runs) 420856 milli seconds -``` diff --git a/rocAL_pybind/examples/prefetch_queue_depth/prefetch_queue_depth.py b/rocAL_pybind/examples/prefetch_queue_depth/prefetch_queue_depth.py deleted file mode 100644 index 222480815..000000000 --- a/rocAL_pybind/examples/prefetch_queue_depth/prefetch_queue_depth.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from amd.rocal.plugin.generic import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import sys -import datetime -import time - -def HybridTrainPipe(batch_size, num_threads, device_id, data_dir, rocal_cpu=True, prefetch_queue_depth=2): - world_size = 1 - local_rank = 0 - resize_width = 300 - resize_height = 300 - decoder_device = 'cpu' # hardcoding decoder_device to cpu until VCN can decode all JPEGs - - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=device_id, - rocal_cpu=rocal_cpu, prefetch_queue_depth=prefetch_queue_depth) - with pipe: - jpegs, _ = fn.readers.file(file_root=data_dir) - images = fn.decoders.image(jpegs, file_root=data_dir, device=decoder_device, - output_type=types.RGB, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - images = fn.resize(images, resize_width=resize_width, - resize_height=resize_height) - output = fn.rain(images, rain=0.5) - pipe.set_outputs(output) - return pipe - - -def main(): - if len(sys.argv) < 5: - print('Please pass image_folder cpu/gpu batch_size prefetch_queue_depth') - exit(0) - image_folder_path = sys.argv[1] - if (sys.argv[2] == "cpu"): - rocal_cpu = True - else: - rocal_cpu = False - batch_size = int(sys.argv[3]) - prefetch_queue_depth = int(sys.argv[4]) - num_threads = 8 - device_id = 0 - pipe = HybridTrainPipe(batch_size=batch_size, num_threads=num_threads, device_id=device_id, - data_dir=image_folder_path, rocal_cpu=rocal_cpu, prefetch_queue_depth=prefetch_queue_depth) - pipe.build() - imageIterator = ROCALClassificationIterator(pipe) - start = datetime.datetime.now() - for _ in range(0, 10): - for _ in imageIterator: - time.sleep(1) - imageIterator.reset() - end = datetime.datetime.now() - print("Time taken (averaged over 10 runs) ", int( - (end - start).total_seconds() * 1000) / 10, "milli seconds") - -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/rocAL_api_caffe2_reader.py b/rocAL_pybind/examples/rocAL_api_caffe2_reader.py deleted file mode 100644 index 4caf647d9..000000000 --- a/rocAL_pybind/examples/rocAL_api_caffe2_reader.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright (c) 2018 - 2023 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 sys -from amd.rocal.plugin.pytorch import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.types as types -import amd.rocal.fn as fn -import os -from parse_config import parse_args - - -def draw_patches(img, idx, bboxes=None, args=None): - # image is expected as a tensor, bboxes as tensors - import cv2 - if args.rocal_gpu: - image = img.cpu().numpy() - else: - image = img.detach().numpy() - if not args.NHWC: - image = image.transpose([1, 2, 0]) - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - if args.classification: - cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" + - str(idx)+"_"+"train"+".png", image) - else: - if bboxes is not None: - bboxes = bboxes.detach().numpy() - for (l, t, r, b) in bboxes: - loc_ = [l, t, r, b] - color = (255, 0, 0) - thickness = 2 - image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( - (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" + - str(idx)+"_"+"train"+".png", image) - - -def main(): - args = parse_args() - # Args - image_path = args.image_dataset_path - rocal_cpu = False if args.rocal_gpu else True - batch_size = args.batch_size - rocal_bbox = False if args.classification else True - num_threads = args.num_threads - local_rank = args.local_rank - random_seed = args.seed - display = True if args.display else False - device = "gpu" if args.rocal_gpu else "cpu" - tensor_layout = types.NHWC if args.NHWC else types.NCHW - num_classes = len(next(os.walk(image_path))[1]) - print("num_classes:: ", num_classes) - try: - if args.classification: - path = "OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" - else: - path = "OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=local_rank, - seed=random_seed, rocal_cpu=rocal_cpu) - with pipe: - if rocal_bbox: - jpegs, labels, bboxes = fn.readers.caffe2( - path=image_path, bbox=rocal_bbox) - else: - jpegs, labels = fn.readers.caffe2(path=image_path, bbox=rocal_bbox) - images = fn.decoders.image( - jpegs, output_type=types.RGB, path=image_path, random_shuffle=True) - images = fn.resize(images, resize_width=224, - resize_height=224, output_layout=tensor_layout) - pipe.set_outputs(images) - pipe.build() - data_loader = ROCALClassificationIterator(pipe, display=0, device=device) - - # Training loop - cnt = 0 - for epoch in range(1): # loop over the dataset multiple times - print("epoch:: ", epoch) - if not rocal_bbox: - for i, ([image_batch], labels) in enumerate(data_loader, 0): # Classification - if args.print_tensor: - sys.stdout.write("\r Mini-batch " + str(i)) - print("Images", image_batch) - print("Labels", labels) - for element in list(range(batch_size)): - cnt += 1 - draw_patches(image_batch[element], cnt, args=args) - data_loader.reset() - else: - for i, ([image_batch], bboxes, labels) in enumerate(data_loader, 0): # Detection - if i == 0: - if args.print_tensor: - sys.stdout.write("\r Mini-batch " + str(i)) - print("Images", image_batch) - print("Bboxes", bboxes) - print("Labels", labels) - for element in list(range(batch_size)): - cnt += 1 - draw_patches(image_batch[element], - cnt, bboxes[element], args=args) - data_loader.reset() - - print("############################## CAFFE2 READER (CLASSIFCATION/ DETECTION) SUCCESS ############################") - - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/rocAL_api_caffe_reader.py b/rocAL_pybind/examples/rocAL_api_caffe_reader.py deleted file mode 100644 index 9cec39c82..000000000 --- a/rocAL_pybind/examples/rocAL_api_caffe_reader.py +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright (c) 2018 - 2023 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 sys -from amd.rocal.plugin.pytorch import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.types as types -import amd.rocal.fn as fn -import os -import cv2 -from parse_config import parse_args - - -def draw_patches(img, idx, bboxes=None, args=None): - # image is expected as a tensor, bboxes as tensors - if args.rocal_gpu: - image = img.cpu().numpy() - else: - image = img.detach().numpy() - if not args.NHWC: - image = image.transpose([1, 2, 0]) - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - if args.classification: - cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" + - str(idx)+"_"+"train"+".png", image) - else: - if bboxes is not None: - bboxes = bboxes.detach().numpy() - for (l, t, r, b) in bboxes: - loc_ = [l, t, r, b] - color = (255, 0, 0) - thickness = 2 - image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( - (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/DETECTION/" + - str(idx)+"_"+"train"+".png", image) - -def main(): - args = parse_args() - # Args - image_path = args.image_dataset_path - rocal_cpu = False if args.rocal_gpu else True - batch_size = args.batch_size - rocal_bbox = False if args.classification else True - num_threads = args.num_threads - local_rank = args.local_rank - world_size = args.world_size - random_seed = args.seed - device = "gpu" if args.rocal_gpu else "cpu" - tensor_layout = types.NHWC if args.NHWC else types.NCHW - num_classes = len(next(os.walk(image_path))[1]) - try: - if args.classification: - path = "OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" - else: - path = "OUTPUT_FOLDER/CAFFE_READER/DETECTION/" - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - print("num_classes:: ", num_classes) - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, - device_id=args.local_rank, seed=random_seed, rocal_cpu=rocal_cpu) - # Use pipeline instance to make calls to reader, decoder & augmentation's - with pipe: - if rocal_bbox: - jpegs, labels, bboxes = fn.readers.caffe( - path=image_path, bbox=rocal_bbox) - images = fn.decoders.image( - jpegs, path=image_path, shard_id=local_rank, random_shuffle=True) - - else: - jpegs, labels = fn.readers.caffe(path=image_path, bbox=rocal_bbox) - images = fn.decoders.image(jpegs, path=image_path, output_type=types.RGB, - shard_id=local_rank, num_shards=world_size, random_shuffle=True) - - images = fn.resize(images, resize_width=224, - resize_height=224, output_layout=tensor_layout) - pipe.set_outputs(images) - # Build the pipeline - pipe.build() - # Dataloader - data_loader = ROCALClassificationIterator( - pipe, display=0, device=device, device_id=args.local_rank) - # Training loop - cnt = 0 - # Enumerate over the Dataloader - for epoch in range(args.num_epochs): # loop over the dataset multiple times - print("epoch:: ", epoch) - if not rocal_bbox: - for i, ([image_batch], labels) in enumerate(data_loader, 0): # Classification - if args.print_tensor: - sys.stdout.write("\r Mini-batch " + str(i)) - print("Images", image_batch) - print("Labels", labels) - for element in list(range(batch_size)): - cnt += 1 - draw_patches(image_batch[element], cnt, args=args) - data_loader.reset() - else: - for i, ([image_batch], bboxes, labels) in enumerate(data_loader, 0): # Detection - if i == 0: - if args.print_tensor: - sys.stdout.write("\r Mini-batch " + str(i)) - print("Images", image_batch) - print("Bboxes", bboxes) - print("Labels", labels) - for element in list(range(batch_size)): - cnt += 1 - draw_patches(image_batch[element], - cnt, bboxes[element], args=args) - data_loader.reset() - print("############################## CAFFE READER (CLASSIFCATION/ DETECTION) SUCCESS ############################") - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/rocAL_api_coco_pipeline.py b/rocAL_pybind/examples/rocAL_api_coco_pipeline.py deleted file mode 100755 index 79baaadd4..000000000 --- a/rocAL_pybind/examples/rocAL_api_coco_pipeline.py +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from math import sqrt -import torch -import itertools -import os -import ctypes -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import numpy as np -from parse_config import parse_args - - -class ROCALCOCOIterator(object): - """ - COCO ROCAL iterator for pyTorch. - - Parameters - ---------- - pipelines : list of amd.rocal.pipeline.Pipeline - List of pipelines to use - size : int - Epoch size. - """ - - def __init__(self, pipelines, tensor_layout=types.NCHW, reverse_channels=False, multiplier=None, offset=None, tensor_dtype=types.FLOAT, device="cpu", display=False): - - try: - assert pipelines is not None, "Number of provided pipelines has to be at least 1" - except Exception as ex: - print(ex) - self.loader = pipelines - self.tensor_format = tensor_layout - self.multiplier = multiplier if multiplier else [1.0, 1.0, 1.0] - self.offset = offset if offset else [0.0, 0.0, 0.0] - self.reverse_channels = reverse_channels - self.tensor_dtype = tensor_dtype - self.device = device - self.device_id = self.loader._device_id - self.bs = self.loader._batch_size - self.output_list = self.dimensions = self.torch_dtype = None - self.display = display - # Image id of a batch of images - self.image_id = np.zeros(self.bs, dtype="int32") - # Count of labels/ bboxes in a batch - self.bboxes_label_count = np.zeros(self.bs, dtype="int32") - # Image sizes of a batch - self.img_size = np.zeros((self.bs * 2), dtype="int32") - self.output_memory_type = self.loader._output_memory_type - - def next(self): - return self.__next__() - - def __next__(self): - if self.loader.rocal_run() != 0: - raise StopIteration - else: - self.output_tensor_list = self.loader.get_output_tensors() - - if self.output_list is None: - self.output_list = [] - for i in range(len(self.output_tensor_list)): - self.dimensions = self.output_tensor_list[i].dimensions() - self.torch_dtype = self.output_tensor_list[i].dtype() - if self.device == "cpu": - self.output = torch.empty( - self.dimensions, dtype=getattr(torch, self.torch_dtype)) - else: - torch_gpu_device = torch.device('cuda', self.device_id) - self.output = torch.empty(self.dimensions, dtype=getattr( - torch, self.torch_dtype), device=torch_gpu_device) - self.output_tensor_list[i].copy_data(ctypes.c_void_p( - self.output.data_ptr()), self.output_memory_type) - self.output_list.append(self.output) - else: - for i in range(len(self.output_tensor_list)): - self.output_tensor_list[i].copy_data(ctypes.c_void_p( - self.output_list[i].data_ptr()), self.output_memory_type) - - self.labels = self.loader.get_bounding_box_labels() - # 1D bboxes array in a batch - self.bboxes = self.loader.get_bounding_box_cords() - self.loader.get_image_id(self.image_id) - image_id_tensor = torch.tensor(self.image_id) - image_size_tensor = torch.tensor(self.img_size).view(-1, self.bs, 2) - - for i in range(self.bs): - if self.display: - img = self.output - draw_patches(img[i], self.image_id[i], - self.bboxes[i], self.device, self.tensor_dtype, self.tensor_format) - return (self.output), self.bboxes, self.labels, image_id_tensor, image_size_tensor - - def reset(self): - self.loader.rocal_reset_loaders() - - def __iter__(self): - return self - - -def draw_patches(img, idx, bboxes, device, dtype, layout): - # image is expected as a tensor, bboxes as numpy - import cv2 - if device == "cpu": - image = img.detach().numpy() - else: - image = img.cpu().numpy() - if dtype == types.FLOAT16: - image = (image).astype('uint8') - if layout == types.NCHW: - image = image.transpose([1, 2, 0]) - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - bboxes = np.reshape(bboxes, (-1, 4)) - - for (l, t, r, b) in bboxes: - loc_ = [l, t, r, b] - color = (255, 0, 0) - thickness = 2 - image = cv2.UMat(image).get() - image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( - (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/COCO_READER/" + - str(idx)+"_"+"train"+".png", image) - - -def main(): - args = parse_args() - # Args - image_path = args.image_dataset_path - annotation_path = args.json_path - rocal_cpu = False if args.rocal_gpu else True - batch_size = args.batch_size - display = args.display - num_threads = args.num_threads - local_rank = args.local_rank - world_size = args.world_size - random_seed = args.seed - tensor_format = types.NHWC if args.NHWC else types.NCHW - tensor_dtype = types.FLOAT16 if args.fp16 else types.FLOAT - try: - path = "OUTPUT_FOLDER/COCO_READER/" - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=args.local_rank, - seed=random_seed, rocal_cpu=rocal_cpu, tensor_layout=tensor_format, tensor_dtype=tensor_dtype) - # Use pipeline instance to make calls to reader, decoder & augmentation's - with pipe: - jpegs, bboxes, labels = fn.readers.coco( - annotations_file=annotation_path) - images_decoded = fn.decoders.image(jpegs, output_type=types.RGB, file_root=image_path, - annotations_file=annotation_path, random_shuffle=False, shard_id=local_rank, num_shards=world_size) - res_images = fn.resize( - images_decoded, resize_width=300, resize_height=300) - saturation = fn.uniform(range=[0.1, 0.4]) - contrast = fn.uniform(range=[0.1, 25.0]) - brightness = fn.uniform(range=[0.875, 1.125]) - hue = fn.uniform(range=[5.0, 170.0]) - ct_images = fn.color_twist( - res_images, saturation=saturation, contrast=contrast, brightness=brightness, hue=hue) - flip_coin = fn.random.coin_flip(probability=0.5) - cmn_images = fn.crop_mirror_normalize(ct_images, - crop=(224, 224), - crop_pos_x=0.0, - crop_pos_y=0.0, - mean=[0, 0, 0], - std=[1, 1, 1], - mirror=flip_coin, - output_layout=tensor_format, - output_dtype=tensor_dtype) - pipe.set_outputs(cmn_images) - # Build the pipeline - pipe.build() - # Dataloader - if (args.rocal_gpu): - data_loader = ROCALCOCOIterator( - pipe, multiplier=pipe._multiplier, offset=pipe._offset, display=display, tensor_layout=tensor_format, tensor_dtype=tensor_dtype, device="cuda") - else: - data_loader = ROCALCOCOIterator( - pipe, multiplier=pipe._multiplier, offset=pipe._offset, display=display, tensor_layout=tensor_format, tensor_dtype=tensor_dtype, device="cpu") - - import timeit - start = timeit.default_timer() - # Enumerate over the Dataloader - for epoch in range(int(args.num_epochs)): - print("EPOCH:::::", epoch) - for i, it in enumerate(data_loader, 0): - if args.print_tensor: - print("**************", i, "*******************") - print("**************starts*******************") - print("\nIMAGES : \n", it[0]) - print("\nBBOXES:\n", it[1]) - print("\nLABELS:\n", it[2]) - print("\nIMAGE ID:\n", it[3]) - print("\nIMAGE SIZE:\n", it[4]) - print("**************ends*******************") - print("**************", i, "*******************") - data_loader.reset() - # Your statements here - stop = timeit.default_timer() - - print('\n Time: ', stop - start) - - print("############################## COCO READER SUCCESS ############################") - - -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/rocAL_api_external_source_reader_example.py b/rocAL_pybind/examples/rocAL_api_external_source_reader_example.py deleted file mode 100644 index a871d78e5..000000000 --- a/rocAL_pybind/examples/rocAL_api_external_source_reader_example.py +++ /dev/null @@ -1,279 +0,0 @@ -from random import shuffle -from amd.rocal.pipeline import Pipeline -from amd.rocal.plugin.generic import ROCALClassificationIterator -import amd.rocal.fn as fn -import amd.rocal.types as types -import os -import numpy as np -import cupy as cp -import cv2 -from PIL import Image - - -def main(): - batch_size = 3 - data_dir = os.environ["ROCAL_DATA_PATH"] + \ - "/coco/coco_10_img/train_10images_2017/" - device = "cpu" - try: - path_mode0 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE0/" - isExist = os.path.exists(path_mode0) - if not isExist: - os.makedirs(path_mode0) - except OSError as error: - print(error) - try: - path_mode1 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE1/" - isExist = os.path.exists(path_mode1) - if not isExist: - os.makedirs(path_mode1) - except OSError as error: - print(error) - try: - path_mode2 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE2/" - isExist = os.path.exists(path_mode2) - if not isExist: - os.makedirs(path_mode2) - except OSError as error: - print(error) - - def image_dump(img, idx, device="cpu", mode=0): - if device == "gpu": - img = cp.asnumpy(img) - img = img.transpose([1, 2, 0]) # NCHW - img = (img).astype('uint8') - if mode!=2: - img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE" + str(mode) + "/"+ - str(idx)+"_"+"train"+".png", img) - - ##################### MODE 0 ######################### - # Define the Data Source for all image samples - User needs to define their own source - class ExternalInputIteratorMode0(object): - def __init__(self, batch_size): - self.images_dir = data_dir - self.batch_size = batch_size - self.files = [] - import glob - for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): - self.files.append(filename) - shuffle(self.files) - - def __iter__(self): - self.i = 0 - self.n = len(self.files) - return self - - def __next__(self): - batch = [] - labels = [] - label = 1 - for _ in range(self.batch_size): - jpeg_filename = self.files[self.i] - batch.append(jpeg_filename) - labels.append(label) - label = label + 1 - self.i = (self.i + 1) % self.n - labels = np.array(labels).astype('int32') - return batch, labels - - # Mode 0 - external_input_source = ExternalInputIteratorMode0(batch_size) - - # Create the pipeline - external_source_pipeline_mode0 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, - seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) - - with external_source_pipeline_mode0: - jpegs, _ = fn.external_source( - source=external_input_source, mode=types.EXTSOURCE_FNAME) - output = fn.resize(jpegs, resize_width=300, resize_height=300, - output_layout=types.NCHW, output_dtype=types.UINT8) - external_source_pipeline_mode0.set_outputs(output) - - # build the external_source_pipeline_mode0 - external_source_pipeline_mode0.build() - # Index starting from 0 - cnt = 0 - # Dataloader - data_loader = ROCALClassificationIterator( - external_source_pipeline_mode0, device=device) - for i, output_list in enumerate(data_loader, 0): - print("**************MODE 0*******************") - print("**************", i, "*******************") - print("**************starts*******************") - print("\nImages:\n", output_list) - print("**************ends*******************") - print("**************", i, "*******************") - for img in output_list[0][0]: - cnt = cnt + 1 - image_dump(img, cnt, device=device, mode=0) - - ##################### MODE 0 ######################### - - ##################### MODE 1 ######################### - # Define the Data Source for all image samples - class ExternalInputIteratorMode1(object): - def __init__(self, batch_size): - self.images_dir = data_dir - self.batch_size = batch_size - self.files = [] - import os - import glob - for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): - self.files.append(filename) - - def __iter__(self): - self.i = 0 - self.n = len(self.files) - self.maxWidth = None - self.maxHeight = None - return self - - def __next__(self): - batch = [] - labels = [] - srcsize_height = [] - label = 1 - for x in range(self.batch_size): - jpeg_filename = self.files[self.i] - f = open(jpeg_filename, 'rb') - numpy_buffer = np.frombuffer(f.read(), dtype=np.uint8) - batch.append(numpy_buffer) - srcsize_height.append(len(numpy_buffer)) - labels.append(label) - label = label + 1 - self.i = (self.i + 1) % self.n - labels = np.array(labels).astype('int32') - return (batch, labels, srcsize_height) - -# Mode 1 - eii_1 = ExternalInputIteratorMode1(batch_size) - - # Create the pipeline - external_source_pipeline_mode1 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, - seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) - - with external_source_pipeline_mode1: - jpegs, _ = fn.external_source( - source=eii_1, mode=types.EXTSOURCE_RAW_COMPRESSED, max_width=2000, max_height=2000) - output = fn.resize(jpegs, resize_width=2000, resize_height=2000, - output_layout=types.NCHW, output_dtype=types.UINT8) - external_source_pipeline_mode1.set_outputs(output) - - # build the external_source_pipeline_mode1 - external_source_pipeline_mode1.build() - # Index starting from 0 - cnt = 0 - # Dataloader - data_loader = ROCALClassificationIterator( - external_source_pipeline_mode1, device=device) - for i, output_list in enumerate(data_loader, 0): - print("**************MODE 1*******************") - print("**************", i, "*******************") - print("**************starts*******************") - print("\nImages:\n", output_list) - print("**************ends*******************") - print("**************", i, "*******************") - for img in output_list[0][0]: - cnt = cnt + 1 - image_dump(img, cnt, device=device, mode=1) - ##################### MODE 1 ######################### - - ##################### MODE 2 ######################### - # Define the Data Source for all image samples - - class ExternalInputIteratorMode2(object): - def __init__(self, batch_size): - self.images_dir = data_dir - self.batch_size = batch_size - self.files = [] - self.maxHeight = self.maxWidth = 0 - import os - import glob - for filename in glob.glob(os.path.join(self.images_dir, '*.jpg')): - self.files.append(filename) - shuffle(self.files) - self.i = 0 - self.n = len(self.files) - - for x in range(self.n): - jpeg_filename = self.files[x] - label = 1 - image = cv2.imread(jpeg_filename, cv2.IMREAD_COLOR) - # Check if the image was loaded successfully - if image is None: - print("Error: Failed to load the image.") - else: - # Get the height and width of the image - height, width = image.shape[:2] - self.maxHeight = height if height > self.maxHeight else self.maxHeight - self.maxWidth = width if width > self.maxWidth else self.maxWidth - - def __iter__(self): - return self - - def __next__(self): - batch = [] - batch_of_numpy = [] - labels = [] - label = 1 - roi_height = [] - roi_width = [] - self.out_image = np.zeros( - (self.batch_size, self.maxHeight, self.maxWidth, 3), dtype="uint8") - for x in range(self.batch_size): - jpeg_filename = self.files[self.i] - image = cv2.imread(jpeg_filename, cv2.IMREAD_COLOR) - # Check if the image was loaded successfully - if image is None: - print("Error: Failed to load the image.") - else: - # Get the height and width of the image - height, width = image.shape[:2] - batch.append(np.asarray(image)) - roi_height.append(height) - roi_width.append(width) - self.out_image[x][:roi_height[x], :roi_width[x], :] = batch[x] - batch_of_numpy.append(self.out_image[x]) - labels.append(label) - label = label + 1 - self.i = (self.i + 1) % self.n - labels = np.array(labels).astype('int32') - return (batch_of_numpy, labels, roi_height, roi_width, self.maxHeight, self.maxWidth) - - -# Mode 2 - eii_2 = ExternalInputIteratorMode2(batch_size) - - # Create the pipeline - external_source_pipeline_mode2 = Pipeline(batch_size=batch_size, num_threads=1, device_id=0, prefetch_queue_depth=4, - seed=1, rocal_cpu=True if device == "cpu" else False, tensor_layout=types.NCHW) - - with external_source_pipeline_mode2: - jpegs, _ = fn.external_source(source=eii_2, mode=types.EXTSOURCE_RAW_UNCOMPRESSED, - max_width=eii_2.maxWidth, max_height=eii_2.maxHeight) - output = fn.resize(jpegs, resize_width=300, resize_height=300, - output_layout=types.NCHW, output_dtype=types.UINT8) - external_source_pipeline_mode2.set_outputs(output) - - # build the external_source_pipeline_mode2 - external_source_pipeline_mode2.build() - # Index starting from 0 - cnt = 0 - # Dataloader - data_loader = ROCALClassificationIterator( - external_source_pipeline_mode2, device=device) - for i, output_list in enumerate(data_loader, 0): - print("**************MODE 2*******************") - print("**************", i, "*******************") - print("**************starts*******************") - print("\nImages:\n", output_list) - print("**************ends*******************") - print("**************", i, "*******************") - for img in output_list[0][0]: - cnt = cnt+1 - image_dump(img, cnt, device=device, mode=2) - ##################### MODE 2 ######################### -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/rocAL_api_pipeline.py b/rocAL_pybind/examples/rocAL_api_pipeline.py deleted file mode 100644 index 603dee8a4..000000000 --- a/rocAL_pybind/examples/rocAL_api_pipeline.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright (c) 2023 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 random -from amd.rocal.plugin.pytorch import ROCALClassificationIterator - -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import sys -import cv2 -import os - - -def draw_patches(img, idx, device=True, layout="NCHW"): - # image is expected as a tensor, bboxes as numpy - import cv2 - if device is False: - image = img.cpu().numpy() - else: - image = img.numpy() - if layout == "NCHW": - image = image.transpose([1, 2, 0]) - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + - str(idx)+"_"+"train"+".png", image * 255) - - -def main(): - if len(sys.argv) < 3: - print('Please pass image_folder cpu/gpu batch_size') - exit(0) - try: - path = "OUTPUT_FOLDER/FILE_READER/" - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - data_path = sys.argv[1] - rocal_cpu = True if sys.argv[2] == "cpu" else False - batch_size = int(sys.argv[3]) - num_threads = 1 - device_id = 0 - random_seed = random.SystemRandom().randint(0, 2**32 - 1) - local_rank = 0 - world_size = 1 - - image_classification_train_pipeline = Pipeline( - batch_size=batch_size, num_threads=num_threads, device_id=device_id, seed=random_seed, rocal_cpu=rocal_cpu) - - with image_classification_train_pipeline: - jpegs, _ = fn.readers.file(file_root=data_path) - decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, - file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - res = fn.resize(decode, resize_width=224, resize_height=224, - output_layout=types.NCHW, output_dtype=types.UINT8) - flip_coin = fn.random.coin_flip(probability=0.5) - cmnp = fn.crop_mirror_normalize(res, - output_layout=types.NCHW, - output_dtype=types.FLOAT, - crop=(224, 224), - mirror=flip_coin, - mean=[0.485 * 255, 0.456 * - 255, 0.406 * 255], - std=[0.229 * 255, 0.224 * 255, 0.225 * 255]) - image_classification_train_pipeline.set_outputs(cmnp) - -# There are 2 ways to get the outputs from the pipeline -# 1. Use the iterator -# 2. use the pipe.run() - -# Method 1 - # use the iterator - image_classification_train_pipeline.build() - imageIteratorPipeline = ROCALClassificationIterator( - image_classification_train_pipeline) - cnt = 0 - for i, it in enumerate(imageIteratorPipeline): - print(it) - print("************************************** i *************************************", i) - for img in it[0]: - cnt += 1 - draw_patches(img[0], cnt, device=rocal_cpu, layout="NCHW") - imageIteratorPipeline.reset() - print("*********************************************************************") - -# Method 2 - iter = 0 - # use pipe.run() call - output_data_batch = image_classification_train_pipeline.run() - print("\n Output Data Batch: ", output_data_batch) - # length depends on the number of augmentations - for i in range(len(output_data_batch)): - print("\n Output Layout: ", output_data_batch[i].layout()) - print("\n Output Dtype: ", output_data_batch[i].dtype()) - for image_counter in range(output_data_batch[i].batch_size()): - image = output_data_batch[i].at(image_counter) - image = image.transpose([1, 2, 0]) - cv2.imwrite("output_images_iter" + str(i) + str(image_counter) + - ".jpg", cv2.cvtColor(image * 255, cv2.COLOR_RGB2BGR)) - - -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/rocAL_api_python_unittest.py b/rocAL_pybind/examples/rocAL_api_python_unittest.py deleted file mode 100644 index bfd81590c..000000000 --- a/rocAL_pybind/examples/rocAL_api_python_unittest.py +++ /dev/null @@ -1,533 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from amd.rocal.plugin.generic import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -from parse_config import parse_args -import os -import sys -import cv2 -import cupy as cp - -INTERPOLATION_TYPES = { - 0: types.NEAREST_NEIGHBOR_INTERPOLATION, - 1: types.LINEAR_INTERPOLATION, - 2: types.CUBIC_INTERPOLATION, - 3: types.LANCZOS_INTERPOLATION, - 4: types.GAUSSIAN_INTERPOLATION, - 5: types.TRIANGULAR_INTERPOLATION -} - -SCALING_MODES = { - 0: types.SCALING_MODE_DEFAULT, - 1: types.SCALING_MODE_STRETCH, - 2: types.SCALING_MODE_NOT_SMALLER, - 3: types.SCALING_MODE_NOT_LARGER -} - - -def draw_patches(img, idx, device, args=None): - # image is expected as a tensor, bboxes as numpy - if device == "gpu": - img = cp.asnumpy(img) - if args.fp16: - img = (img).astype('uint8') - if not args.color_format: - img = img.transpose([0, 2, 3, 1]) - images_list = [] - for im in img: - images_list.append(im) - img = cv2.vconcat(images_list) - if args.color_format: - img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - else: - img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) - cv2.imwrite(args.output_file_name + ".png", img, - [cv2.IMWRITE_PNG_COMPRESSION, 9]) - -def dump_meta_data(labels, device, args=None): - if device == "gpu": - labels = cp.asnumpy(labels) - labels_list = labels.tolist() - with open(args.output_file_name, 'w') as file: - for label in labels_list: - file.write(str(label) + '\n') - -def main(): - args = parse_args() - # Args - data_path = args.image_dataset_path - reader_type = args.reader_type - augmentation_name = args.augmentation_name - print("\n AUGMENTATION NAME: ", augmentation_name) - rocal_cpu = False if args.rocal_gpu else True - device = "cpu" if rocal_cpu else "cuda" - batch_size = args.batch_size - max_height = args.max_height - max_width = args.max_width - color_format = types.RGB if args.color_format else types.GRAY - tensor_layout = types.NHWC if args.color_format else types.NCHW - tensor_dtype = types.UINT8 - num_threads = args.num_threads - random_seed = args.seed - local_rank = args.local_rank - world_size = args.world_size - interpolation_type = INTERPOLATION_TYPES[args.interpolation_type] - scaling_mode = SCALING_MODES[args.scaling_mode] - if (scaling_mode != types.SCALING_MODE_DEFAULT and interpolation_type != - types.LINEAR_INTERPOLATION): - interpolation_type = types.LINEAR_INTERPOLATION - if augmentation_name in ["hue", "saturation", "color_twist"] and color_format == types.GRAY: - print("Not a valid option! Exiting!") - sys.exit(0) - - try: - path = "OUTPUT_FOLDER/FILE_READER/" + args.augmentation_name - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, - num_threads=num_threads, - device_id=local_rank, - seed=random_seed, - rocal_cpu=rocal_cpu, - tensor_layout=tensor_layout, - tensor_dtype=tensor_dtype, - output_memory_type=types.HOST_MEMORY if rocal_cpu else types.DEVICE_MEMORY) - # Set Params - output_set = 0 - rocal_device = 'cpu' if rocal_cpu else 'gpu' - # hardcoding decoder_device to cpu to compare against golden outputs taken with turbojpeg decoder - decoder_device = 'cpu' - # Use pipeline instance to make calls to reader, decoder & augmentation's - with pipe: - if reader_type == "file": - jpegs, labels = fn.readers.file(file_root=data_path) - images = fn.decoders.image(jpegs, - file_root=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "coco": - annotation_path = args.json_path - jpegs, _, _ = fn.readers.coco(annotations_file=annotation_path) - images = fn.decoders.image(jpegs, - file_root=data_path, - annotations_file=annotation_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "tf_classification": - try: - import tensorflow as tf - except ImportError: - print('Install tensorflow to run tf_classification tests') - exit() - featureKeyMap = { - 'image/encoded': 'image/encoded', - 'image/class/label': 'image/class/label', - 'image/filename': 'image/filename' - } - features = { - 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), - 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), - 'image/filename': tf.io.FixedLenFeature((), tf.string, "") - } - inputs = fn.readers.tfrecord( - data_path, featureKeyMap, features, reader_type=0) - jpegs = inputs["image/encoded"] - images = fn.decoders.image(jpegs, user_feature_key_map=featureKeyMap, - output_type=color_format, path=data_path, - max_decoded_width=max_width, - max_decoded_height=max_height, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "tf_detection": - try: - import tensorflow as tf - except ImportError: - print('Install tensorflow to run tf_detection tests') - exit() - featureKeyMap = { - 'image/encoded': 'image/encoded', - 'image/class/label': 'image/object/class/label', - 'image/class/text': 'image/object/class/text', - 'image/object/bbox/xmin': 'image/object/bbox/xmin', - 'image/object/bbox/ymin': 'image/object/bbox/ymin', - 'image/object/bbox/xmax': 'image/object/bbox/xmax', - 'image/object/bbox/ymax': 'image/object/bbox/ymax', - 'image/filename': 'image/filename' - } - features = { - 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), - 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), - 'image/class/text': tf.io.FixedLenFeature([], tf.string, ''), - 'image/object/bbox/xmin': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/ymin': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/xmax': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/ymax': tf.io.VarLenFeature(dtype=tf.float32), - 'image/filename': tf.io.FixedLenFeature((), tf.string, "") - } - inputs = fn.readers.tfrecord( - path=data_path, reader_type=1, features=features, user_feature_key_map=featureKeyMap) - jpegs = inputs["image/encoded"] - _ = inputs["image/class/label"] - images = fn.decoders.image_random_crop(jpegs, user_feature_key_map=featureKeyMap, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False, path=data_path) - - elif reader_type == "caffe_classification": - jpegs, _ = fn.readers.caffe(path=data_path, bbox=False) - images = fn.decoders.image(jpegs, - path=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "caffe_detection": - jpegs, _, _ = fn.readers.caffe(path=data_path, bbox=True) - images = fn.decoders.image(jpegs, - path=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "caffe2_classification": - jpegs, _ = fn.readers.caffe2(path=data_path) - images = fn.decoders.image(jpegs, - path=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "caffe2_detection": - jpegs, _, _ = fn.readers.caffe2(path=data_path, bbox=True) - images = fn.decoders.image(jpegs, - path=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - elif reader_type == "mxnet": - jpegs = fn.readers.mxnet(path=data_path) - images = fn.decoders.image(jpegs, - path=data_path, - device=decoder_device, - max_decoded_width=max_width, - max_decoded_height=max_height, - output_type=color_format, - shard_id=local_rank, - num_shards=world_size, - random_shuffle=False) - - if augmentation_name == "resize": - resize_w = 400 - resize_h = 400 - if (scaling_mode == types.SCALING_MODE_STRETCH): - resize_h = 480 - output = fn.resize(images, - resize_width=resize_w, - resize_height=resize_h, - output_layout=tensor_layout, - output_dtype=tensor_dtype, - scaling_mode=scaling_mode, - interpolation_type=interpolation_type) - elif augmentation_name == "rotate": - output = fn.rotate(images, - angle=45.0, - dest_width=640, - dest_height=480, - output_layout=tensor_layout, - output_dtype=tensor_dtype, - interpolation_type=interpolation_type) - elif augmentation_name == "brightness": - output = fn.brightness(images, - brightness=1.9, - brightness_shift=20.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "gamma_correction": - output = fn.gamma_correction(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "contrast": - output = fn.contrast(images, - contrast=30.0, - contrast_center=80.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "flip": - output = fn.flip(images, - horizontal=1, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "blur": - output = fn.blur(images, - window_size=5, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "warp_affine": - output = fn.warp_affine(images, dest_height=480, dest_width=640, matrix=[1.0, 1.0, 0.5, 0.5, 7.0, 7.0], - output_layout=tensor_layout, output_dtype=tensor_dtype, interpolation_type=types.LINEAR_INTERPOLATION) - elif augmentation_name == "fish_eye": - output = fn.fish_eye(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "vignette": - output = fn.vignette(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "jitter": - output = fn.jitter(images, - kernel_size=3, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "snp_noise": - output = fn.snp_noise(images, - p_noise=0.2, - p_salt=0.2, - noise_val=0.2, - salt_val=0.5, - seed=0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "snow": - output = fn.snow(images, - snow=0.2, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "rain": - output = fn.rain(images, - rain=0.5, - rain_width=2, - rain_height=16, - rain_transparency=0.25, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "fog": - output = fn.fog(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "pixelate": - output = fn.pixelate(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "exposure": - output = fn.exposure(images, - exposure=1.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "hue": - output = fn.hue(images, - hue=150.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "saturation": - output = fn.saturation(images, - saturation=0.3, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "color_twist": - output = fn.color_twist(images, - brightness=0.2, - contrast=10.0, - hue=100.0, - saturation=0.25, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "crop": - output = fn.crop(images, - crop=(3, 224, 224), - crop_pos_x=0.0, - crop_pos_y=0.0, - crop_pos_z=0.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "crop_mirror_normalize": - output = fn.crop_mirror_normalize(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype, - crop=(224, 224), - crop_pos_x=0.0, - crop_pos_y=0.0, - mean=[128, 128, 128], - std=[1.2, 1.2, 1.2]) - elif augmentation_name == "resize_mirror_normalize": - resize_w = 400 - resize_h = 400 - if (scaling_mode == types.SCALING_MODE_STRETCH): - resize_h = 480 - output = fn.resize_mirror_normalize(images, - resize_width=resize_w, - resize_height=resize_h, - output_layout=tensor_layout, - output_dtype=tensor_dtype, - scaling_mode=scaling_mode, - interpolation_type=interpolation_type, - mean=[128, 128, 128], - std=[1.2, 1.2, 1.2]) - elif augmentation_name == "nop": - output = fn.nop(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "centre_crop": - output = fn.centre_crop(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "color_temp": - output = fn.color_temp(images, - adjustment_value=70, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "copy": - output = fn.copy(images, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "resize_crop_mirror": - output = fn.resize_crop_mirror(images, - resize_height=400, - resize_width=400, - crop_h=200, - crop_w=200, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "lens_correction": - output = fn.lens_correction(images, - strength=2.9, - zoom=1.2, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "blend": - output1 = fn.rotate(images, - angle=45.0, - dest_width=640, - dest_height=480, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - output = fn.blend(images, - output1, - ratio=0.5, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "resize_crop": - output = fn.resize_crop(images, - resize_width=640, - resize_height=480, - crop_area_factor=0.25, - crop_aspect_ratio=1.2, - x_drift=0.6, - y_drift=0.4, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "center_crop": - output = fn.center_crop(images, - crop=[2, 224, 224], - output_layout=tensor_layout, - output_dtype=tensor_dtype) - elif augmentation_name == "one_hot": - output = fn.crop(images, - crop=(3, 224, 224), - crop_pos_x=0.0, - crop_pos_y=0.0, - crop_pos_z=0.0, - output_layout=tensor_layout, - output_dtype=tensor_dtype) - num_classes = len(next(os.walk(data_path))[1]) - labels_onehot = fn.one_hot(labels, num_classes=num_classes) - - if output_set == 0: - pipe.set_outputs(output) - # build the pipeline - pipe.build() - # Dataloader - data_loader = ROCALClassificationIterator( - pipe, device=device, device_id=local_rank) - cnt = 0 - import timeit - start = timeit.default_timer() - - # Enumerate over the Dataloader - for epoch in range(int(args.num_epochs)): - print("EPOCH:::::", epoch) - for i, (output_list, labels) in enumerate(data_loader, 0): - for j in range(len(output_list)): - if args.print_tensor: - print("**************", i, "*******************") - print("**************starts*******************") - print("\nImages:\n", output_list[j]) - print("\nLABELS:\n", labels) - print("**************ends*******************") - print("**************", i, "*******************") - if args.augmentation_name == "one_hot": - dump_meta_data(labels, rocal_device, args=args) - else: - draw_patches(output_list[j], cnt, rocal_device, args=args) - cnt += len(output_list[j]) - - data_loader.reset() - - stop = timeit.default_timer() - - print('\n Time: ', stop - start) - print('Number of times loop iterates is:', cnt) - - print( - f"############################## {augmentation_name.upper()} SUCCESS ############################") - - -if __name__ == '__main__': - main() diff --git a/rocAL_pybind/examples/rocAL_api_pytorch_classification_reader.py b/rocAL_pybind/examples/rocAL_api_pytorch_classification_reader.py deleted file mode 100644 index 0ac21c72d..000000000 --- a/rocAL_pybind/examples/rocAL_api_pytorch_classification_reader.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (c) 2018 - 2023 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 random -from amd.rocal.plugin.pytorch import ROCALClassificationIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import numpy as np -import sys -import os - - -def draw_patches(img, idx, layout="nchw", dtype="fp32", device="cpu"): - # image is expected as a tensor - import cv2 - if device == "cpu": - image = img.detach().numpy() - else: - image = img.cpu().numpy() - if layout == "nchw": - image = image.transpose([1, 2, 0]) - if dtype == "fp16": - image = image.astype("uint8") - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + str(idx) + - "_" + "train" + ".png", image * 255) - - -def main(): - if len(sys.argv) < 3: - print("Please pass image_folder cpu/gpu batch_size") - exit(0) - try: - path = "OUTPUT_FOLDER/FILE_READER/" - isExist = os.path.exists(path) - if not isExist: - os.makedirs(path) - except OSError as error: - print(error) - data_path = sys.argv[1] - rocal_cpu = True if sys.argv[2] == "cpu" else False - batch_size = int(sys.argv[3]) - num_threads = 1 - device_id = 0 - random_seed = random.SystemRandom().randint(0, 2**32 - 1) - - local_rank = 0 - world_size = 1 - - image_classification_train_pipeline = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=device_id, - seed=random_seed, rocal_cpu=rocal_cpu, tensor_layout=types.NHWC, tensor_dtype=types.FLOAT16) - - with image_classification_train_pipeline: - jpegs, labels = fn.readers.file(file_root=data_path) - decode = fn.decoders.image_slice(jpegs, output_type=types.RGB, - file_root=data_path, shard_id=local_rank, num_shards=world_size, random_shuffle=True) - res = fn.resize(decode, resize_width=224, resize_height=224, - output_layout=types.NCHW, output_dtype=types.UINT8) - flip_coin = fn.random.coin_flip(probability=0.5) - cmnp = fn.crop_mirror_normalize(res, - output_layout=types.NHWC, - output_dtype=types.FLOAT16, - crop=(224, 224), - mirror=flip_coin, - mean=[0.485 * 255, 0.456 * - 255, 0.406 * 255], - std=[0.229 * 255, 0.224 * 255, 0.225 * 255]) - image_classification_train_pipeline.set_outputs(cmnp) - - image_classification_train_pipeline.build() - imageIteratorPipeline = ROCALClassificationIterator( - image_classification_train_pipeline) - cnt = 0 - for epoch in range(3): - print( - "+++++++++++++++++++++++++++++EPOCH+++++++++++++++++++++++++++++++++++++", epoch) - for i, it in enumerate(imageIteratorPipeline): - print(it) - print( - "************************************** i *************************************", i) - for img in it[0]: - cnt += 1 - draw_patches(img[0], cnt, layout="nhwc", - dtype="fp16", device=rocal_cpu) - imageIteratorPipeline.reset() - print("*********************************************************************") - - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/rocAL_api_tf_classification_reader.py b/rocAL_pybind/examples/rocAL_api_tf_classification_reader.py deleted file mode 100644 index 44fcd87a1..000000000 --- a/rocAL_pybind/examples/rocAL_api_tf_classification_reader.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from amd.rocal.plugin.tf import ROCALIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.types as types -import os -import amd.rocal.fn as fn -import tensorflow as tf -import numpy as np -from parse_config import parse_args -import cupy as cp - - -def draw_patches(img, idx, device_type, args=None): - import cv2 - args = parse_args() - if device_type == "gpu": - img = cp.asnumpy(img) - if not args.NHWC: - img = img.transpose([0, 1, 2]) - image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" + - str(idx) + "_" + "train" + ".png", image) - - -def main(): - args = parse_args() - # Args - image_path = args.image_dataset_path - rocal_cpu = False if args.rocal_gpu else True - device = "cpu" if rocal_cpu else "gpu" - batch_size = args.batch_size - one_hot_labels = 1 if args.one_hot_encode else 0 - num_threads = args.num_threads - tensor_layout = types.NHWC if args.NHWC else types.NCHW - tf_record_reader_type = 0 - feature_key_map = { - 'image/encoded': 'image/encoded', - 'image/class/label': 'image/class/label', - 'image/filename': 'image/filename' - } - try: - path = "OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" - is_exist = os.path.exists(path) - if not is_exist: - os.makedirs(path) - except OSError as error: - print(error) - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, - device_id=args.local_rank, seed=2, rocal_cpu=rocal_cpu) - # Use pipeline instance to make calls to reader, decoder & augmentation's - with pipe: - inputs = fn.readers.tfrecord(path=image_path, reader_type=tf_record_reader_type, user_feature_key_map=feature_key_map, - features={ - "image/encoded": tf.io.FixedLenFeature((), tf.string, ""), - "image/class/label": tf.io.FixedLenFeature([1], tf.int64, -1), - "image/filename": tf.io.FixedLenFeature((), tf.string, "") - } - ) - jpegs = inputs["image/encoded"] - images = fn.decoders.image( - jpegs, user_feature_key_map=feature_key_map, output_type=types.RGB, path=image_path) - resized = fn.resize(images, resize_width=300, - resize_height=300, output_layout=tensor_layout) - if one_hot_labels == 1: - labels = inputs["image/class/label"] - _ = fn.one_hot(labels, num_classes=1000) - pipe.set_outputs(resized) - # Build the pipeline - pipe.build() - # Dataloader - image_iterator = ROCALIterator(pipe, device=device) - cnt = 0 - # Enumerate over the Dataloader - for i, ([images_array], labels_array) in enumerate(image_iterator, 0): - if args.print_tensor: - print("\n", i) - print("lables_array", labels_array) - print("\n\nPrinted first batch with", (batch_size), "images!") - for element in list(range(batch_size)): - cnt += 1 - draw_patches(images_array[element], cnt, device, args=args) - break - image_iterator.reset() - - print("############################## TF CLASSIFICATION SUCCESS ############################") - - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/rocAL_api_tf_detection_pipeline.py b/rocAL_pybind/examples/rocAL_api_tf_detection_pipeline.py deleted file mode 100644 index 8b9aa3920..000000000 --- a/rocAL_pybind/examples/rocAL_api_tf_detection_pipeline.py +++ /dev/null @@ -1,161 +0,0 @@ -# Copyright (c) 2018 - 2023 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. - -from amd.rocal.plugin.tf import ROCALIterator -from amd.rocal.pipeline import Pipeline -import amd.rocal.types as types -import tensorflow as tf -import amd.rocal.fn as fn -import numpy as np -import os -import cupy as cp -from parse_config import parse_args - - -def get_onehot(image_labels_array, num_classes): - one_hot_vector_list = [] - for label in image_labels_array: - one_hot_vector = np.zeros(num_classes) - if label[0] != 0: - np.put(one_hot_vector, label[0] - 1, 1) - one_hot_vector_list.append(one_hot_vector) - - one_hot_vector_array = np.array(one_hot_vector_list) - - return one_hot_vector_array - - -def get_weights(num_bboxes): - weights_array = np.zeros(num_bboxes) - for pos in list(range(num_bboxes)): - np.put(weights_array, pos, 1) - return weights_array - - -def draw_patches(img, idx, bboxes, device_type, args=None): - import cv2 - args = parse_args() - if device_type == "gpu": - img = cp.asnumpy(img) - if not args.NHWC: - img = img.transpose([0, 1, 2]) - image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - image = cv2.normalize(image, None, alpha=0, beta=255, - norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F) - for (l, t, r, b) in bboxes: - loc_ = [l, t, r, b] - color = (255, 0, 0) - thickness = 2 - image = cv2.UMat(image).get() - image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( - (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/TF_READER/DETECTION/" + - str(idx) + "_" + "train" + ".png", image) - - -def main(): - args = parse_args() - # Args - image_path = args.image_dataset_path - num_classes = 91 - rocal_cpu = False if args.rocal_gpu else True - device = "cpu" if rocal_cpu else "gpu" - batch_size = args.batch_size - num_threads = args.num_threads - tensor_layout = types.NHWC if args.NHWC else types.NCHW - tf_record_reader_type = 1 - feature_key_map = { - 'image/encoded': 'image/encoded', - 'image/class/label': 'image/object/class/label', - 'image/class/text': 'image/object/class/text', - 'image/object/bbox/xmin': 'image/object/bbox/xmin', - 'image/object/bbox/ymin': 'image/object/bbox/ymin', - 'image/object/bbox/xmax': 'image/object/bbox/xmax', - 'image/object/bbox/ymax': 'image/object/bbox/ymax', - 'image/filename': 'image/filename' - } - try: - path = "OUTPUT_FOLDER/TF_READER/DETECTION" - is_exist = os.path.exists(path) - if not is_exist: - os.makedirs(path) - except OSError as error: - print(error) - - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, - device_id=args.local_rank, seed=2, rocal_cpu=rocal_cpu) - with pipe: - inputs = fn.readers.tfrecord(path=image_path, reader_type=tf_record_reader_type, user_feature_key_map=feature_key_map, - features={ - 'image/encoded': tf.io.FixedLenFeature((), tf.string, ""), - 'image/class/label': tf.io.FixedLenFeature([1], tf.int64, -1), - 'image/class/text': tf.io.FixedLenFeature([], tf.string, ''), - 'image/object/bbox/xmin': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/ymin': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/xmax': tf.io.VarLenFeature(dtype=tf.float32), - 'image/object/bbox/ymax': tf.io.VarLenFeature(dtype=tf.float32), - 'image/filename': tf.io.FixedLenFeature((), tf.string, "") - } - ) - jpegs = inputs["image/encoded"] - _ = inputs["image/class/label"] - decoded_images = fn.decoders.image_random_crop(jpegs, user_feature_key_map=feature_key_map, output_type=types.RGB, - random_aspect_ratio=[ - 0.8, 1.25], - random_area=[0.1, 1.0], - num_attempts=100, path=image_path) - resized = fn.resize(decoded_images, resize_width=300, - resize_height=300, output_layout=tensor_layout) - pipe.set_outputs(resized) - pipe.build() - image_iterator = ROCALIterator(pipe, device=device) - - cnt = 0 - for i, ([images_array], bboxes_array, labels_array, num_bboxes_array) in enumerate(image_iterator, 0): - print("ROCAL augmentation pipeline - Processing batch %d....." % i) - - for element in list(range(batch_size)): - cnt += 1 - if args.print_tensor: - print("Processing image %d....." % element) - features_dict = { - "image": images_array[element], - "true_image_shape": np.array([len(images_array[element]), len(images_array[element, 0]), len(images_array[element, 0, 0])]) - } - labels_dict = { - "num_groundtruth_boxes": num_bboxes_array[element], - "groundtruth_boxes": bboxes_array[element], - "groundtruth_classes": get_onehot(labels_array[element], num_classes), - "groundtruth_weights": get_weights(num_bboxes_array[element]) - } - processed_tensors = (features_dict, labels_dict) - if args.print_tensor: - print("\nPROCESSED_TENSORS:\n", processed_tensors) - draw_patches(images_array[element], cnt, - bboxes_array[element], device, args=args) - print("\n\nPrinted first batch with", (batch_size), "images!") - break - image_iterator.reset() - - print("############################## TF DETECTION SUCCESS ############################") - - -if __name__ == "__main__": - main() diff --git a/rocAL_pybind/examples/rocAL_api_video_pipeline.py b/rocAL_pybind/examples/rocAL_api_video_pipeline.py deleted file mode 100644 index 1a1556a9a..000000000 --- a/rocAL_pybind/examples/rocAL_api_video_pipeline.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright (c) 2018 - 2023 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 -from amd.rocal.pipeline import Pipeline -import amd.rocal.fn as fn -import amd.rocal.types as types -import numpy as np -from parse_config import parse_args - - -class ROCALVideoIterator(object): - """ - ROCALVideoIterator for pyTorch. - - Parameters - ---------- - pipelines : list of amd.rocal.pipeline.Pipeline - List of pipelines to use - size : int - Epoch size. - """ - - def __init__(self, pipelines, tensor_layout=types.NCHW, reverse_channels=False, multiplier=None, offset=None, tensor_dtype=types.FLOAT, display=False, sequence_length=3): - - try: - assert pipelines is not None, "Number of provided pipelines has to be at least 1" - except Exception as ex: - print(ex) - - self.loader = pipelines - self.tensor_format = tensor_layout - self.multiplier = multiplier if multiplier else [1.0, 1.0, 1.0] - self.offset = offset if offset else [0.0, 0.0, 0.0] - self.reverse_channels = reverse_channels - self.tensor_dtype = tensor_dtype - self.batch_size = self.loader._batch_size - self.rim = self.loader.get_remaining_images() - self.display = display - self.iter_num = 0 - self.sequence_length = sequence_length - print("____________REMAINING IMAGES____________:", self.rim) - self.output = self.dimensions = self.dtype = None - - def next(self): - return self.__next__() - - def __next__(self): - if (self.loader.is_empty()): - raise StopIteration - - if self.loader.rocal_run() != 0: - raise StopIteration - self.output_tensor_list = self.loader.get_output_tensors() - self.iter_num += 1 - # Copy output from buffer to numpy array - if self.output is None: - self.dimensions = self.output_tensor_list[0].dimensions() - self.dtype = self.output_tensor_list[0].dtype() - self.layout = self.output_tensor_list[0].layout() - self.output = np.empty( - (self.dimensions[0]*self.dimensions[1], self.dimensions[2], self.dimensions[3], self.dimensions[4]), dtype=self.dtype) - self.output_tensor_list[0].copy_data(self.output) - img = torch.from_numpy(self.output) - # Display Frames in a video sequence - if self.display: - for batch_i in range(self.batch_size): - draw_frames(img[batch_i], batch_i, self.iter_num, self.layout) - return img - - def reset(self): - self.loader.rocal_reset_loaders() - - def __iter__(self): - return self - - def __del__(self): - self.loader.rocal_release() - - -def draw_frames(img, batch_idx, iter_idx, layout): - # image is expected as a tensor, bboxes as numpy - import cv2 - image = img.detach().numpy() - if layout == 'NFCHW': - image = image.transpose([1, 2, 0]) - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - import os - if not os.path.exists("OUTPUT_FOLDER/VIDEO_READER"): - os.makedirs("OUTPUT_FOLDER/VIDEO_READER") - image = cv2.UMat(image).get() - cv2.imwrite("OUTPUT_FOLDER/VIDEO_READER/" + - "iter_"+str(iter_idx)+"_batch_"+str(batch_idx)+".png", image) - - -def main(): - # Args - args = parse_args() - video_path = args.video_path - rocal_cpu = False if args.rocal_gpu else True - batch_size = args.batch_size - user_sequence_length = args.sequence_length - display = args.display - num_threads = args.num_threads - random_seed = args.seed - tensor_format = types.NFHWC if args.NHWC else types.NFCHW - tensor_dtype = types.FLOAT16 if args.fp16 else types.FLOAT - # Create Pipeline instance - pipe = Pipeline(batch_size=batch_size, num_threads=num_threads, device_id=args.local_rank, seed=random_seed, rocal_cpu=rocal_cpu, - tensor_layout=tensor_format, tensor_dtype=tensor_dtype) - # Use pipeline instance to make calls to reader, decoder & augmentation's - with pipe: - images = fn.readers.video(file_root=video_path, sequence_length=user_sequence_length, - random_shuffle=False, image_type=types.RGB) - crop_size = (512, 960) - output_images = fn.crop_mirror_normalize(images, - output_layout=tensor_format, - output_dtype=tensor_dtype, - crop=crop_size, - mean=[0, 0, 0], - std=[1, 1, 1]) - pipe.set_outputs(output_images) - # Build the pipeline - pipe.build() - # Dataloader - data_loader = ROCALVideoIterator(pipe, multiplier=pipe._multiplier, - offset=pipe._offset, display=display, sequence_length=user_sequence_length) - import timeit - start = timeit.default_timer() - # Enumerate over the Dataloader - for epoch in range(int(args.num_epochs)): - print("EPOCH:::::", epoch) - for i, it in enumerate(data_loader, 0): - if args.print_tensor: - print("**************", i, "*******************") - print("**************starts*******************") - print("\n IMAGES : \n", it) - print("**************ends*******************") - print("**************", i, "*******************") - data_loader.reset() - # Your statements here - stop = timeit.default_timer() - - print('\n Time: ', stop - start) - print("############################## VIDEO READER SUCCESS ############################") - - -if __name__ == '__main__': - main() diff --git a/tests/README.md b/tests/README.md index 5c0d87066..a01c7302f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -3,5 +3,5 @@ rocAL test suite to verify installation and functionality ## C++ API Test - -rocAL C++ API functionality tests \ No newline at end of file +* [C++ API functionality tests](cpp_api) +* [Python API functionality tests](python_api) \ No newline at end of file diff --git a/tests/cpp_api/CMakeLists.txt b/tests/cpp_api/CMakeLists.txt index b41c96906..6cbb6d74c 100644 --- a/tests/cpp_api/CMakeLists.txt +++ b/tests/cpp_api/CMakeLists.txt @@ -25,139 +25,139 @@ ################################################################################ cmake_minimum_required (VERSION 3.5) -# rocal_basic_test +# basic_test add_test( NAME - rocAL_basic_test_cpu + basic_test_cpu COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_basic_test" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/basic_test" + "${CMAKE_CURRENT_BINARY_DIR}/basic_test" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_basic_test" + --test-command "basic_test" ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 ) -add_test(NAME rocAL_basic_test_gpu - COMMAND rocal_basic_test +add_test(NAME basic_test_gpu + COMMAND basic_test ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) -add_test(NAME rocAL_basic_test_gray - COMMAND rocal_basic_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/basic_test) +add_test(NAME basic_test_gray + COMMAND basic_test ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 0 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) -add_test(NAME rocAL_basic_test_rgb - COMMAND rocal_basic_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/basic_test) +add_test(NAME basic_test_rgb + COMMAND basic_test ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/basic_test) -# TBD - rocAL_dataloader unit test options non-functional - NEEDS TO BE ADDED ONCE RESOLVED +# TBD - dataloader unit test options non-functional - NEEDS TO BE ADDED ONCE RESOLVED #add_test( # NAME -# rocAL_dataloader +# dataloader # COMMAND # "${CMAKE_CTEST_COMMAND}" -# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader" -# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader" +# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/dataloader" +# "${CMAKE_CURRENT_BINARY_DIR}/dataloader" # --build-generator "${CMAKE_GENERATOR}" -# --test-command "rocal_dataloader" +# --test-command "dataloader" # ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet #) -# rocal_dataloader_mt +# dataloader_multithread add_test( NAME rocAL_dataloader_mt_cpu COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_mt" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/dataloader_multithread" + "${CMAKE_CURRENT_BINARY_DIR}/dataloader_multithread" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_dataloader_mt" + --test-command "dataloader_multithread" ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 0 ) add_test(NAME rocAL_dataloader_mt_gpu - COMMAND rocal_dataloader_mt + COMMAND dataloader_multithread ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dataloader_multithread) -# TBD - rocAL_dataloader_tf unit test non-functional +# TBD - dataloader_tf unit test non-functional #add_test( # NAME -# rocAL_dataloader_tf +# dataloader_tf # COMMAND # "${CMAKE_CTEST_COMMAND}" -# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_tf" -# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_tf" +# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/dataloader_tf" +# "${CMAKE_CURRENT_BINARY_DIR}/dataloader_tf" # --build-generator "${CMAKE_GENERATOR}" -# --test-command "rocal_dataloader_tf" +# --test-command "dataloader_tf" # ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet #) -# rocal_performance_tests +# performance_tests # TBD - peformance test needs to run with default options add_test( NAME rocAL_performance_tests_cpu COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/performance_tests" + "${CMAKE_CURRENT_BINARY_DIR}/performance_tests" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_performance_tests" + --test-command "performance_tests" ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 0 ) add_test(NAME rocAL_performance_tests_gpu - COMMAND rocal_performance_tests + COMMAND performance_tests ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/performance_tests) -# rocal_performance_tests_with_depth +# performance_tests_with_depth add_test( NAME - rocAL_performance_tests_with_depth_cpu + performance_tests_with_depth_cpu COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests_with_depth" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/performance_tests_with_depth" + "${CMAKE_CURRENT_BINARY_DIR}/performance_tests_with_depth" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_performance_tests_with_depth" + --test-command "performance_tests_with_depth" ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 0 ) -add_test(NAME rocAL_performance_tests_with_depth_gpu - COMMAND rocal_performance_tests_with_depth +add_test(NAME performance_tests_with_depth_gpu + COMMAND performance_tests_with_depth ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/performance_tests_with_depth) -# rocal_unittests +# unit_tests add_test( NAME - rocAL_unittests_cpu + unit_tests_cpu COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_unittests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/unit_tests" + "${CMAKE_CURRENT_BINARY_DIR}/unit_tests" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_unittests" + --test-command "unit_tests" 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 0 1 ) -add_test(NAME rocAL_unittests_gpu - COMMAND rocal_unittests +add_test(NAME unit_tests_gpu + COMMAND unit_tests 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) -add_test(NAME rocAL_unittests_gray - COMMAND rocal_unittests + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unit_tests) +add_test(NAME unit_tests_gray + COMMAND unit_tests 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 0 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unit_tests) -# rocal_video_unittests +# video_tests add_test( NAME - rocAL_video_unittests + video_tests COMMAND "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_video_unittests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_video_unittests" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/video_tests" + "${CMAKE_CURRENT_BINARY_DIR}/video_tests" --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_video_unittests" + --test-command "video_tests" ${CMAKE_SOURCE_DIR}/data/videos/AMD_driving_virtual_20.mp4 ) diff --git a/tests/cpp_api_tests/rocAL_basic_test/CMakeLists.txt b/tests/cpp_api/basic_test/CMakeLists.txt similarity index 99% rename from tests/cpp_api_tests/rocAL_basic_test/CMakeLists.txt rename to tests/cpp_api/basic_test/CMakeLists.txt index bcb2b7b57..24067caf0 100644 --- a/tests/cpp_api_tests/rocAL_basic_test/CMakeLists.txt +++ b/tests/cpp_api/basic_test/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project(rocal_basic_test) +project(basic_test) set(CMAKE_CXX_STANDARD 14) diff --git a/tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp b/tests/cpp_api/basic_test/basic_test.cpp similarity index 97% rename from tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp rename to tests/cpp_api/basic_test/basic_test.cpp index a7a91e7ba..cadf09dad 100644 --- a/tests/cpp_api/rocAL_basic_test/rocal_basic_test.cpp +++ b/tests/cpp_api/basic_test/basic_test.cpp @@ -48,7 +48,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - std::cout << "Usage: rocal_basic_test decode_width decode_height decode_shard_counts \n"; + std::cout << "Usage: basic_test decode_width decode_height decode_shard_counts \n"; return -1; } int argIdx = 0; diff --git a/tests/cpp_api/rocAL_dataloader/CMakeLists.txt b/tests/cpp_api/dataloader/CMakeLists.txt similarity index 99% rename from tests/cpp_api/rocAL_dataloader/CMakeLists.txt rename to tests/cpp_api/dataloader/CMakeLists.txt index 2e3e0b25e..f533ce803 100644 --- a/tests/cpp_api/rocAL_dataloader/CMakeLists.txt +++ b/tests/cpp_api/dataloader/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required (VERSION 3.5) -project(rocal_dataloader) +project(dataloader) set(CMAKE_CXX_STANDARD 14) diff --git a/tests/cpp_api_tests/rocAL_dataloader/README.md b/tests/cpp_api/dataloader/README.md similarity index 66% rename from tests/cpp_api_tests/rocAL_dataloader/README.md rename to tests/cpp_api/dataloader/README.md index 92fd56615..d6ed8ae1d 100644 --- a/tests/cpp_api_tests/rocAL_dataloader/README.md +++ b/tests/cpp_api/dataloader/README.md @@ -1,12 +1,12 @@ -# rocal_dataloader application +# dataloader application This application demonstrates a basic usage of rocAL's C API to load RAW images from the disk and modify them in different possible ways and displays the output images. -

+

## Build Instructions ### Pre-requisites * Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher * ROCm Performance Primitives (RPP) @@ -20,5 +20,5 @@ This application demonstrates a basic usage of rocAL's C API to load RAW images ```` ### running the application ```` - rocal_dataloader + ./dataloader ```` diff --git a/tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp b/tests/cpp_api/dataloader/dataloader.cpp similarity index 100% rename from tests/cpp_api/rocAL_dataloader/rocAL_dataloader.cpp rename to tests/cpp_api/dataloader/dataloader.cpp diff --git a/tests/cpp_api_tests/rocAL_dataloader_mt/CMakeLists.txt b/tests/cpp_api/dataloader_multithread/CMakeLists.txt similarity index 94% rename from tests/cpp_api_tests/rocAL_dataloader_mt/CMakeLists.txt rename to tests/cpp_api/dataloader_multithread/CMakeLists.txt index da0f6c6ef..b2277ba8c 100644 --- a/tests/cpp_api_tests/rocAL_dataloader_mt/CMakeLists.txt +++ b/tests/cpp_api/dataloader_multithread/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required (VERSION 3.5) -project (rocal_dataloader_mt) +project (dataloader_multithread) set(CMAKE_CXX_STANDARD 14) @@ -65,7 +65,7 @@ elseif ("${BACKEND}" STREQUAL "HIP") list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH} ${ROCM_PATH}/hip) find_package(HIP QUIET) if(HIP_FOUND) - message("-- ${White}rocAL_dataloader_mt -- Using HIP -- Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER} ${ColourReset}) + message("-- ${White}dataloader_multithread -- Using HIP -- Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER} ${ColourReset}) set(ENABLE_HIP 1) set(ENABLE_OPENCL 0) include_directories(${HIP_PATH}/include) @@ -82,7 +82,7 @@ endif() include_directories (${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) link_directories (${ROCM_PATH}/lib) -add_executable(${PROJECT_NAME} ./rocAL_dataloader_mt.cpp) +add_executable(${PROJECT_NAME} ./dataloader_multithread.cpp) if(OpenCV_FOUND) if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 3 ) message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") diff --git a/tests/cpp_api/rocAL_dataloader_mt/README.md b/tests/cpp_api/dataloader_multithread/README.md similarity index 56% rename from tests/cpp_api/rocAL_dataloader_mt/README.md rename to tests/cpp_api/dataloader_multithread/README.md index c60f54596..f89d75e31 100644 --- a/tests/cpp_api/rocAL_dataloader_mt/README.md +++ b/tests/cpp_api/dataloader_multithread/README.md @@ -1,12 +1,12 @@ -# rocAL_dataloader_mt application +# dataloader multithreaded application This application demonstrates a basic usage of rocAL's C API to use sharded data_loader in a multithreaded application. -

+

## Build Instructions ### Pre-requisites * Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher * ROCm Performance Primitives (RPP) @@ -20,5 +20,5 @@ This application demonstrates a basic usage of rocAL's C API to use sharded data ```` ### running the application ```` - rocAL_dataloader_mt =1)/(cpu:0)> + ./dataloader_multithread =1)/(cpu:0)> ```` diff --git a/tests/cpp_api_tests/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp b/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp similarity index 98% rename from tests/cpp_api_tests/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp rename to tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp index 5a00fd03f..c5e35bc9f 100644 --- a/tests/cpp_api_tests/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp +++ b/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp @@ -196,7 +196,7 @@ int main(int argc, const char **argv) { const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { printf( - "Usage: rocal_dataloader_mt 1(gpu)/cpu=0> num_shards, \ + "Usage: dataloader_multithread 1(gpu)/cpu=0> num_shards, \ decode_width decode_height batch_size shuffle display_on_off dec_mode<0(tjpeg)/1(opencv)/2(hwdec)>\n"); return -1; } diff --git a/tests/cpp_api_tests/rocAL_unittests/CMakeLists.txt b/tests/cpp_api/dataloader_tf/CMakeLists.txt similarity index 99% rename from tests/cpp_api_tests/rocAL_unittests/CMakeLists.txt rename to tests/cpp_api/dataloader_tf/CMakeLists.txt index 59de69611..2e632a782 100644 --- a/tests/cpp_api_tests/rocAL_unittests/CMakeLists.txt +++ b/tests/cpp_api/dataloader_tf/CMakeLists.txt @@ -25,7 +25,8 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project (rocal_unittests) +project(dataloader_tf) + set(CMAKE_CXX_STANDARD 14) # ROCm Path @@ -45,6 +46,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) find_package(OpenCV QUIET) find_package(AMDRPP QUIET) + include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) link_directories(${ROCM_PATH}/lib) file(GLOB My_Source_Files ./*.cpp) diff --git a/tests/cpp_api_tests/rocAL_dataloader_tf/README.md b/tests/cpp_api/dataloader_tf/README.md similarity index 72% rename from tests/cpp_api_tests/rocAL_dataloader_tf/README.md rename to tests/cpp_api/dataloader_tf/README.md index 268875bc0..eb0db5c67 100644 --- a/tests/cpp_api_tests/rocAL_dataloader_tf/README.md +++ b/tests/cpp_api/dataloader_tf/README.md @@ -1,11 +1,10 @@ -# rocal_dataloader_tf application +# dataloader tensorflow application This application demonstrates a basic usage of rocAL's C API to load TfRecords from the disk and modify them in different possible ways and displays the output images. ## Build Instructions ### Pre-requisites * Ubuntu 16.04/18.04 Linux -* rocAL library (Part of the MIVisionX toolkit) * [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher * Google protobuf 3.11.1 or higher * ROCm Performance Primitives (RPP) @@ -20,5 +19,5 @@ This application demonstrates a basic usage of rocAL's C API to load TfRecords f ```` ### running the application ```` - rocal_dataloader + ./dataloader_tf ```` diff --git a/tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp b/tests/cpp_api/dataloader_tf/dataloader_tf.cpp similarity index 98% rename from tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp rename to tests/cpp_api/dataloader_tf/dataloader_tf.cpp index 6fc4d6b6e..60068b56d 100644 --- a/tests/cpp_api/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp +++ b/tests/cpp_api/dataloader_tf/dataloader_tf.cpp @@ -49,7 +49,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_dataloader_tf display_on_off \n"); + printf("Usage: dataloader_tf display_on_off \n"); return -1; } int argIdx = 0; diff --git a/tests/cpp_api_tests/rocAL_external_source/CMakeLists.txt b/tests/cpp_api/external_source/CMakeLists.txt similarity index 98% rename from tests/cpp_api_tests/rocAL_external_source/CMakeLists.txt rename to tests/cpp_api/external_source/CMakeLists.txt index 935d7de34..6b0b6589d 100644 --- a/tests/cpp_api_tests/rocAL_external_source/CMakeLists.txt +++ b/tests/cpp_api/external_source/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project (rocal_external_source) +project (external_source) set(CMAKE_CXX_STANDARD 14) # ROCm Path diff --git a/tests/cpp_api/rocAL_external_source/README.md b/tests/cpp_api/external_source/README.md similarity index 74% rename from tests/cpp_api/rocAL_external_source/README.md rename to tests/cpp_api/external_source/README.md index acaf18f52..e89ecea2a 100644 --- a/tests/cpp_api/rocAL_external_source/README.md +++ b/tests/cpp_api/external_source/README.md @@ -1,4 +1,4 @@ -# rocal_external_source application +# external source application This application demonstrates a basic usage of rocAL's C++ API to load images from external source and add augmentations and displays the output images. @@ -24,5 +24,5 @@ This application demonstrates a basic usage of rocAL's C++ API to load images fr ### running the application ````bash - rocal_external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode + external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode ```` diff --git a/tests/cpp_api_tests/rocAL_external_source/rocal_external_source.cpp b/tests/cpp_api/external_source/external_source.cpp similarity index 99% rename from tests/cpp_api_tests/rocAL_external_source/rocal_external_source.cpp rename to tests/cpp_api/external_source/external_source.cpp index 3c3f24cc3..5c66f8b2e 100644 --- a/tests/cpp_api_tests/rocAL_external_source/rocal_external_source.cpp +++ b/tests/cpp_api/external_source/external_source.cpp @@ -63,7 +63,7 @@ int main(int argc, const char **argv) { const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { printf( - "Usage: rocal_external_source " + "Usage: external_source " " decode_width decode_height batch_size " "gray_scale/rgb/rgbplanar display_on_off external_source_mode\n"); return -1; diff --git a/tests/cpp_api/rocAL_basic_test/CMakeLists.txt b/tests/cpp_api/performance_tests/CMakeLists.txt similarity index 99% rename from tests/cpp_api/rocAL_basic_test/CMakeLists.txt rename to tests/cpp_api/performance_tests/CMakeLists.txt index bcb2b7b57..4fb5f91a8 100644 --- a/tests/cpp_api/rocAL_basic_test/CMakeLists.txt +++ b/tests/cpp_api/performance_tests/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project(rocal_basic_test) +project (performance_tests) set(CMAKE_CXX_STANDARD 14) diff --git a/tests/cpp_api_tests/rocAL_performance_tests/README.md b/tests/cpp_api/performance_tests/README.md similarity index 70% rename from tests/cpp_api_tests/rocAL_performance_tests/README.md rename to tests/cpp_api/performance_tests/README.md index e808e7bc4..d065a9134 100644 --- a/tests/cpp_api_tests/rocAL_performance_tests/README.md +++ b/tests/cpp_api/performance_tests/README.md @@ -6,7 +6,7 @@ This application is used to run performance tests on the rocAL API for graphs of ### Pre-requisites * Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher * ROCm Performance Primitives (RPP) @@ -19,5 +19,5 @@ This application is used to run performance tests on the rocAL API for graphs of ```` ### running the application ```` -rocAL_performance_tests [test image folder] [image width] [image height] [test case] [batch size] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] +performance_tests [test image folder] [image width] [image height] [test case] [batch size] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] ```` diff --git a/tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp b/tests/cpp_api/performance_tests/performance_tests.cpp similarity index 98% rename from tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp rename to tests/cpp_api/performance_tests/performance_tests.cpp index 0ebfe69d6..37b1f1a99 100644 --- a/tests/cpp_api/rocAL_performance_tests/rocAL_performance_tests.cpp +++ b/tests/cpp_api/performance_tests/performance_tests.cpp @@ -51,7 +51,7 @@ int test(int test_case, const char* path, int rgb, int processing_device, int wi int main(int argc, const char** argv) { // check command-line usage const int MIN_ARG_COUNT = 2; - printf("Usage: rocal_performance_tests \n"); + printf("Usage: performance_tests \n"); if (argc < MIN_ARG_COUNT) return -1; diff --git a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/CMakeLists.txt b/tests/cpp_api/performance_tests_with_depth/CMakeLists.txt similarity index 98% rename from tests/cpp_api_tests/rocAL_performance_tests_with_depth/CMakeLists.txt rename to tests/cpp_api/performance_tests_with_depth/CMakeLists.txt index 7276c54b8..6c6483468 100644 --- a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/CMakeLists.txt +++ b/tests/cpp_api/performance_tests_with_depth/CMakeLists.txt @@ -26,7 +26,7 @@ cmake_minimum_required (VERSION 3.5) -project (rocal_performance_tests_with_depth) +project (performance_tests_with_depth) set(CMAKE_CXX_STANDARD 14) diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/README.md b/tests/cpp_api/performance_tests_with_depth/README.md similarity index 78% rename from tests/cpp_api/rocAL_performance_tests_with_depth/README.md rename to tests/cpp_api/performance_tests_with_depth/README.md index b1c190e26..092f55000 100644 --- a/tests/cpp_api/rocAL_performance_tests_with_depth/README.md +++ b/tests/cpp_api/performance_tests_with_depth/README.md @@ -19,5 +19,5 @@ This is very similar to the rocAL Performance Tests app except it takes an extra ```` ### running the application ```` -rocAL_performance_tests_with_depth [test image folder] [image width] [image height] [test case] [batch size] [graph depth] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] +performance_tests_with_depth [test image folder] [image width] [image height] [test case] [batch size] [graph depth] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] ```` diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp b/tests/cpp_api/performance_tests_with_depth/performance_tests_with_depth.cpp similarity index 100% rename from tests/cpp_api/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp rename to tests/cpp_api/performance_tests_with_depth/performance_tests_with_depth.cpp diff --git a/tests/cpp_api/rocAL_dataloader/README.md b/tests/cpp_api/rocAL_dataloader/README.md deleted file mode 100644 index 92fd56615..000000000 --- a/tests/cpp_api/rocAL_dataloader/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# rocal_dataloader application -This application demonstrates a basic usage of rocAL's C API to load RAW images from the disk and modify them in different possible ways and displays the output images. -

- -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* ROCm Performance Primitives (RPP) - -### build - ```` - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib - mkdir build - cd build - cmake ../ - make - ```` -### running the application - ```` - rocal_dataloader - ```` diff --git a/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt b/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt deleted file mode 100644 index da0f6c6ef..000000000 --- a/tests/cpp_api/rocAL_dataloader_mt/CMakeLists.txt +++ /dev/null @@ -1,132 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required (VERSION 3.5) - -project (rocal_dataloader_mt) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -if(NOT DEFINED BACKEND) - set(BACKEND "HIP") # set default backend to HIP -endif() - -if("${BACKEND}" STREQUAL "OPENCL") - find_package(OpenCL QUIET) - if(OpenCL_FOUND) - set(ENABLE_OPENCL 1) - set(ENABLE_HIP 0) - include_directories($${OpenCL_INCLUDE_DIRS} ${OpenCL_INCLUDE_DIRS}/Headers) - target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES}) - else() - message("-- ${Yellow}NOTE: OpenCL Not Found -- runVX built for CPU only${ColourReset}") - endif() -elseif ("${BACKEND}" STREQUAL "HIP") - list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH} ${ROCM_PATH}/hip) - find_package(HIP QUIET) - if(HIP_FOUND) - message("-- ${White}rocAL_dataloader_mt -- Using HIP -- Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER} ${ColourReset}) - set(ENABLE_HIP 1) - set(ENABLE_OPENCL 0) - include_directories(${HIP_PATH}/include) - link_directories(${HIP_PATH}/lib) - message("-- ${Green}rali_dataloader_mt built with HIP Support${ColourReset}") - else() - message("-- ${Yellow}NOTE: HIP Not Found -- rali_dataloader_mt built for CPU only${ColourReset}") - endif() -else() - message("-- ${Yellow}NOTE: GPU Support Not Found or Turned OFF -- rali_dataloader_mt app built for CPU only${ColourReset}") -endif() - - -include_directories (${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories (${ROCM_PATH}/lib) - -add_executable(${PROJECT_NAME} ./rocAL_dataloader_mt.cpp) -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 3 ) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=1) - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message("-- WARNING: OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) - endif() -else() - message("-- WARNING: OpenCV Not Found -- No Display Support") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall -pthread") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp b/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp deleted file mode 100644 index 5a00fd03f..000000000 --- a/tests/cpp_api/rocAL_dataloader_mt/rocAL_dataloader_mt.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include -#include -#include -using namespace cv; - -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define cvDestroyWindow destroyWindow -#else -#include -#endif - -#include "rocal_api.h" -#include "rocal_api_types.h" - -#define PRINT_NAMES_AND_LABELS 0 // uncomment for printing names and labels -// #define ROCAL_MEMCPY_TO_HOST 0 //For HOST 0 / GPU 1 -#define DISPLAY 0 -using namespace std::chrono; -std::mutex g_mtx; // mutex for critical section - -int thread_func(const char *path, int gpu_mode, RocalImageColor color_format, int shard_id, int num_shards, int dec_width, int dec_height, int batch_size, bool shuffle, bool display, int dec_mode) { - std::unique_lock lck(g_mtx, std::defer_lock); - std::cout << ">>> Running on " << (gpu_mode >= 0 ? "GPU" : "CPU") << std::endl; - std::cout << ">>> Running on shard_id: " << shard_id << std::endl; - color_format = RocalImageColor::ROCAL_COLOR_RGB24; - int gpu_id = (gpu_mode < 0) ? 0 : gpu_mode; - RocalDecoderType dec_type = (RocalDecoderType)dec_mode; - std::cout << ">>> Running on decoder mode - dec_mode<0(tjpeg)/1(opencv)/2(hwdec) : " << dec_type << std::endl; - lck.lock(); - // looks like OpenVX has some issue loading kernels from multiple threads at the same time - auto handle = rocalCreate(batch_size, (gpu_mode < 0) ? RocalProcessMode::ROCAL_PROCESS_CPU : RocalProcessMode::ROCAL_PROCESS_GPU, gpu_id, 1); - lck.unlock(); - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal context" - << "<" << shard_id << num_shards << " >" << std::endl; - return -1; - } - std::cout << "ROCAL created context for " - << "<" << shard_id << num_shards << " >" << std::endl; - // create JPEG data loader based on numshards and shard_id - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - RocalTensor decoded_output; - if (dec_width <= 0 || dec_height <= 0) - decoded_output = rocalJpegFileSourceSingleShard(handle, path, color_format, shard_id, num_shards, false, shuffle, false); - else - decoded_output = rocalJpegFileSourceSingleShard(handle, path, color_format, shard_id, num_shards, false, - shuffle, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, dec_width, dec_height, dec_type); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "rocalJpegFileSourceSingleShard<" << shard_id << " , " << num_shards << ">" - << " could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - // create meta data reader - rocalCreateLabelReader(handle, path); - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - rocalResize(handle, decoded_output, 224, 224, true); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - return -1; - } - - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; - - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int n = rocalGetAugmentationBranchCount(handle); - int h = n * rocalGetOutputHeight(handle) * batch_size; - int w = rocalGetOutputWidth(handle); - int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || - (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) - ? 3 - : 1); - std::cout << "output width " << w << " output height " << h << " color planes " << p << " n " << n << std::endl; - const unsigned number_of_cols = 1; // no augmented case - // printf("Allocated output tensor of size(flat) %d\n", h*w*p+256); - auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h, w * number_of_cols, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - int col_counter = 0; - - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int counter = 0; - std::vector names; - names.resize(batch_size); - int image_name_length[batch_size]; - if (DISPLAY) - cv::namedWindow("output", CV_WINDOW_AUTOSIZE); - int iter_cnt = 0; - - while (!rocalIsEmpty(handle) /*&& (iter_cnt < 100)*/) { - // std::cout << "processing iter: " << iter_cnt << std::endl; - if (rocalRun(handle) != 0) - break; - // copy output to host as image - rocalCopyToOutput(handle, mat_input.data, h * w * p); - RocalTensorList labels = rocalGetImageLabels(handle); - unsigned img_name_size = rocalGetImageNameLen(handle, image_name_length); - char img_name[img_name_size]; - rocalGetImageName(handle, img_name); -#if PRINT_NAMES_AND_LABELS - std::string imageNamesStr(img_name); - int pos = 0; - int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); - for (int i = 0; i < batch_size; i++) { - names[i] = imageNamesStr.substr(pos, image_name_length[i]); - pos += image_name_length[i]; - std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - "; - } - std::cout << std::endl; -#endif - iter_cnt++; - - if (!display) - continue; - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - if (DISPLAY) - cv::imshow("output.png", mat_output); - else - cv::imwrite("output.png", mat_output); - - col_counter = (col_counter + 1) % number_of_cols; - } - - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "For shard_id: " << shard_id << std::endl; - std::cout << "Load time: " - << " " << rocal_timing.load_time << std::endl; - std::cout << "Decode time: " - << " " << rocal_timing.decode_time << std::endl; - std::cout << "Process time: " - << " " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time: " - << " " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - return 0; -} - -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf( - "Usage: rocal_dataloader_mt 1(gpu)/cpu=0> num_shards, \ - decode_width decode_height batch_size shuffle display_on_off dec_mode<0(tjpeg)/1(opencv)/2(hwdec)>\n"); - return -1; - } - int argIdx = 0; - const char *path = argv[++argIdx]; - bool display = 1; // Display the images - // int aug_depth = 1;// how deep is the augmentation tree - int decode_width = 1024; - int decode_height = 1024; - int inputBatchSize = 16; - int num_shards = 2; - bool shuffle = 0; - int num_gpus = 0; - int dec_mode = 0; - - if (argc >= argIdx + MIN_ARG_COUNT) - num_gpus = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - num_shards = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - inputBatchSize = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - shuffle = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - display = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - dec_mode = atoi(argv[++argIdx]); - - // gpu mode needs either OPENCL or HIP enabled -#if !(ENABLE_HIP || ENABLE_OPENCL) - num_gpus = 0; -#endif - std::cout << "#GPUs :" << num_gpus << std::endl; - - // launch threads process shards - std::thread loader_threads[num_shards]; - auto gpu_id = num_gpus ? 0 : -1; - int th_id; - for (th_id = 0; th_id < num_shards; th_id++) { - loader_threads[th_id] = std::thread(thread_func, path, gpu_id, RocalImageColor::ROCAL_COLOR_RGB24, th_id, num_shards, decode_width, decode_height, inputBatchSize, - shuffle, display, dec_mode); - if (num_gpus) gpu_id = (gpu_id + 1) % num_gpus; - } - for (auto &th : loader_threads) { - th.join(); - } -} diff --git a/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt b/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt deleted file mode 100644 index 2b5b286fa..000000000 --- a/tests/cpp_api/rocAL_dataloader_tf/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project(rocal_dataloader_tf) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_dataloader_tf/README.md b/tests/cpp_api/rocAL_dataloader_tf/README.md deleted file mode 100644 index 268875bc0..000000000 --- a/tests/cpp_api/rocAL_dataloader_tf/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# rocal_dataloader_tf application -This application demonstrates a basic usage of rocAL's C API to load TfRecords from the disk and modify them in different possible ways and displays the output images. - -## Build Instructions - -### Pre-requisites -* Ubuntu 16.04/18.04 Linux -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* Google protobuf 3.11.1 or higher -* ROCm Performance Primitives (RPP) - -### build - ```` - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib - mkdir build - cd build - cmake ../ - make - ```` -### running the application - ```` - rocal_dataloader - ```` diff --git a/tests/cpp_api/rocAL_external_source/CMakeLists.txt b/tests/cpp_api/rocAL_external_source/CMakeLists.txt deleted file mode 100644 index 935d7de34..000000000 --- a/tests/cpp_api/rocAL_external_source/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project (rocal_external_source) -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp b/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp deleted file mode 100644 index 3c3f24cc3..000000000 --- a/tests/cpp_api/rocAL_external_source/rocal_external_source.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* -MIT License - -Copyright (c) 2023 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 -#include -#include -#include -#include - -#include "rocal_api.h" - -using namespace cv; -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#endif - -#define DISPLAY -using namespace std::chrono; - -template -void convert_float_to_uchar_buffer(T *input_float_buffer, unsigned char *output_uchar_buffer, size_t data_size) { - for (size_t i = 0; i < data_size; i++) { - output_uchar_buffer[i] = (unsigned char)(*(input_float_buffer + i) * 255); - } -} - -const std::array, 3> color_mappings = { - {std::make_pair(ROCAL_COLOR_U8, 1), - std::make_pair(ROCAL_COLOR_RGB24, 3), - std::make_pair(ROCAL_COLOR_RGB_PLANAR, 3)} - }; - -int main(int argc, const char **argv) { - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf( - "Usage: rocal_external_source " - " decode_width decode_height batch_size " - "gray_scale/rgb/rgbplanar display_on_off external_source_mode\n"); - return -1; - } - int argIdx = 0; - const char *folder_path = argv[++argIdx]; - bool display = 1; // Display the images - int rgb = 1; // process color images - int decode_width = 224; // Decoding width - int decode_height = 224; // Decoding height - int input_batch_size = 2; // Batch size - bool processing_device = 0; // CPU Processing - int mode = 0; // File mode - - if (argc >= argIdx + MIN_ARG_COUNT) processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) input_batch_size = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) display = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) mode = atoi(argv[++argIdx]); - - std::cerr << "\n Mode:: " << mode << std::endl; - std::cerr << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; - RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; - color_format = color_mappings[rgb].first; - int channels = color_mappings[rgb].second; - - auto handle = rocalCreate(input_batch_size, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cerr << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - rocalSetSeed(0); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor input1; - RocalTensorOutputType tensor_output_type = RocalTensorOutputType::ROCAL_UINT8; - std::vector srcsize_height, srcsize_width; - uint32_t max_height = 0, max_width = 0; - DIR *_src_dir; - struct dirent *_entity; - std::vector file_names; - std::vector input_buffer; - if ((_src_dir = opendir(folder_path)) == nullptr) { - std::cerr << "\n ERROR: Failed opening the directory at " << folder_path; - exit(0); - } - - while ((_entity = readdir(_src_dir)) != nullptr) { - if (_entity->d_type != DT_REG) continue; - - std::string file_path = folder_path; - file_path.append(_entity->d_name); - file_names.push_back(file_path); - } - if (mode != 0) { - if (mode == 1) { - // Mode 1 is Raw compressed - // srcsize_height and srcsize_width resized based on total file count - srcsize_height.resize(file_names.size()); - srcsize_width.resize(file_names.size()); - for (uint32_t i = 0; i < file_names.size(); i++) { - FILE *_current_fPtr; - _current_fPtr = fopen(file_names[i].c_str(), "rb"); // Open the file, - if (!_current_fPtr) // Check if it is ready for reading - return 0; - fseek(_current_fPtr, 0, - SEEK_END); // Take the file read pointer to the end - size_t _current_file_size = ftell( - _current_fPtr); // Check how many bytes are there between and the - // current read pointer position (end of the file) - unsigned char *input_data = static_cast( - malloc(sizeof(unsigned char) * _current_file_size)); - if (_current_file_size == 0) { // If file is empty continue - fclose(_current_fPtr); - _current_fPtr = nullptr; - return 0; - } - - fseek(_current_fPtr, 0, - SEEK_SET); // Take the file pointer back to the start - size_t actual_read_size = fread(input_data, sizeof(unsigned char), - _current_file_size, _current_fPtr); - input_buffer.push_back(input_data); - srcsize_height[i] = actual_read_size; // It stored the actual file size - } - } else if (mode == 2) { // Raw un compressed - srcsize_height.resize(file_names.size()); - srcsize_width.resize(file_names.size()); - for (uint32_t i = 0; i < file_names.size(); i++) { - Mat image; - image = imread(file_names[i], 1); - if (image.empty()) { - std::cout << "Could not read the image: " << file_names[i] << std::endl; - return 1; - } - srcsize_height[i] = image.rows; - srcsize_width[i] = image.cols; - max_height = std::max(max_height, srcsize_height[i]); - max_width = std::max(max_width, srcsize_width[i]); - } - unsigned long long image_dim_max = (unsigned long long)max_height * (unsigned long long)max_width * 3; - unsigned char *complete_image_buffer = (unsigned char *)malloc(sizeof(unsigned char) * file_names.size() * image_dim_max); - uint32_t elements_in_row_max = max_width * 3; - unsigned char *temp_buffer, *temp_image; - for (uint32_t i = 0; i < file_names.size(); i++) { - temp_image = temp_buffer = complete_image_buffer + (i * image_dim_max); - Mat image = imread(file_names[i], 1); - if (image.empty()) { - std::cout << "Could not read the image: " << file_names[i] << std::endl; - return 1; - } - cvtColor(image, image, cv::COLOR_BGR2RGB); - unsigned char *ip_image = image.data; - uint32_t elements_in_row = srcsize_width[i] * 3; - for (uint32_t j = 0; j < srcsize_height[i]; j++) { - memcpy(temp_buffer, ip_image, elements_in_row * sizeof(unsigned char)); - ip_image += elements_in_row; - temp_buffer += elements_in_row_max; - } - input_buffer.push_back(temp_image); - } - } - } - if (max_height != 0 && max_width != 0) { - input1 = rocalJpegExternalFileSource( - handle, color_format, false, false, false, - ROCAL_USE_USER_GIVEN_SIZE, max_width, max_height, - RocalDecoderType::ROCAL_DECODER_TJPEG, RocalExternalSourceMode(mode)); - } else { - input1 = rocalJpegExternalFileSource( - handle, color_format, false, false, false, - ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height, - RocalDecoderType::ROCAL_DECODER_TJPEG, RocalExternalSourceMode(mode)); - } - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cerr << "JPEG source could not initialize : " - << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - // uncomment the following to add augmentation if needed - int resize_w = decode_width, resize_h = decode_height; - // just do one augmentation to test - rocalResize(handle, input1, resize_w, resize_h, true); // Remove this later - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cerr << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cerr << err_msg << std::endl; - } - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cerr << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - cv::Mat mat_color; - const unsigned number_of_cols = 1; // no augmented case - int col_counter = 0; - printf("Going to process images\n"); - printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int index = 0; - bool eos = false; - int total_images = file_names.size(); - int counter = 0; - std::vector names; - std::vector labels; - bool set_labels = true; - names.resize(input_batch_size); - labels.resize(total_images); - RocalTensorList output_tensor_list; - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? ((tensor_output_type == RocalTensorOutputType::ROCAL_FP32) ? CV_32FC3 : CV_8UC3) : CV_8UC1); - std::vector ROI_xywh; - ROI_xywh.resize(input_batch_size); - while (static_cast(rocalGetRemainingImages(handle)) >= input_batch_size) { - std::vector input_images; - std::vector input_batch_buffer; - std::vector label_buffer; - for (int i = 0; i < input_batch_size; i++) { - if (mode == 0) { - input_images.push_back(file_names.back()); - file_names.pop_back(); - if ((file_names.size()) == 0) { - eos = true; - } - label_buffer.push_back(labels.back()); - labels.pop_back(); - } else { - if (mode == 1) { - input_batch_buffer.push_back(input_buffer.back()); - input_buffer.pop_back(); - ROI_xywh[i].h = srcsize_height.back(); - srcsize_height.pop_back(); - label_buffer.push_back(labels.back()); - labels.pop_back(); - } else { - input_batch_buffer.push_back(input_buffer.back()); - input_buffer.pop_back(); - ROI_xywh[i].w = srcsize_width.back(); - srcsize_width.pop_back(); - ROI_xywh[i].h = srcsize_height.back(); - srcsize_height.pop_back(); - label_buffer.push_back(labels.back()); - labels.pop_back(); - } - if ((file_names.size()) == 0 || input_buffer.size() == 0) { - eos = true; - } - } - } - if (index + 1 <= (total_images / input_batch_size)) { - std::cerr << "\n************************** Gonna process Batch *************************" << index; - std::cerr << "\n Mode ********************* " << mode; - if (mode == 0) { - rocalExternalSourceFeedInput(handle, input_images, set_labels, {}, ROI_xywh, - decode_width, decode_height, channels, - RocalExternalSourceMode(0), - RocalTensorLayout(0), eos); - } else if (mode == 1) { - rocalExternalSourceFeedInput(handle, {}, set_labels, input_batch_buffer, - ROI_xywh, decode_width, decode_height, - channels, RocalExternalSourceMode(mode), - RocalTensorLayout(0), eos); - } else if (mode == 2) { - rocalExternalSourceFeedInput(handle, {}, set_labels, input_batch_buffer, - ROI_xywh, max_width, max_height, - channels, RocalExternalSourceMode(mode), - RocalTensorLayout(0), eos); - } - } - if (rocalRun(handle) != 0) { - std::cerr << "rocalRun(handle) != 0 --- breaking"; - break; - } - - if (!display) continue; - // Dump the output image - output_tensor_list = rocalGetOutputTensors(handle); - std::vector compression_params; - compression_params.push_back(IMWRITE_PNG_COMPRESSION); - compression_params.push_back(9); - - cv::Mat mat_input; - cv::Mat mat_output; - int h = 0, w = 0 ; - for (uint64_t idx = 0; idx < output_tensor_list->size(); idx++) { - if (output_tensor_list->at(idx)->layout() == RocalTensorLayout::ROCAL_NHWC) { - h = output_tensor_list->at(idx)->dims().at(1) * output_tensor_list->at(idx)->dims().at(0); - w = output_tensor_list->at(idx)->dims().at(2); - } - - mat_input = cv::Mat(h, w, cv_color_format); - mat_output = cv::Mat(h, w, cv_color_format); - unsigned char *out_buffer = nullptr; - if (output_tensor_list->at(idx)->data_type() == RocalTensorOutputType::ROCAL_FP32) { - float *out_f_buffer = nullptr; - if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { - out_f_buffer = (float *)malloc(output_tensor_list->at(idx)->data_size()); - output_tensor_list->at(idx)->copy_data(out_f_buffer); - } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) - out_f_buffer = (float *)output_tensor_list->at(idx)->buffer(); - - out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 4); - convert_float_to_uchar_buffer(out_f_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 4); - // if(out_f_buffer != nullptr) free(out_f_buffer); - } - if (output_tensor_list->at(idx)->data_type() == RocalTensorOutputType::ROCAL_FP16) { - half *out_f16_buffer = nullptr; - if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { - out_f16_buffer = (half *)malloc(output_tensor_list->at(idx)->data_size()); - output_tensor_list->at(idx)->copy_data(out_f16_buffer); - } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) - out_f16_buffer = (half *)output_tensor_list->at(idx)->buffer(); - - out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 2); - convert_float_to_uchar_buffer(out_f16_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 2); - // if(out_f16_buffer != nullptr) free(out_f16_buffer); - } else { - if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_GPU) { - out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size()); - output_tensor_list->at(idx)->copy_data(out_buffer); - } else if (output_tensor_list->at(idx)->backend() == RocalTensorBackend::ROCAL_CPU) - out_buffer = (unsigned char *)(output_tensor_list->at(idx)->buffer()); - } - - mat_input.data = (unsigned char *)out_buffer; - - mat_input.copyTo(mat_output(cv::Rect(0, 0, w, h))); - std::string outName = "external_source_output"; - std::string out_filename = outName + ".png"; // in case the user specifies non png filename - if (display) - out_filename = outName + std::to_string(index) + std::to_string(idx) + ".png"; // in case the user specifies non png filename - - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - cv::imwrite(out_filename, mat_color, compression_params); - } else { - cv::imwrite(out_filename, mat_output, compression_params); - } - // if(out_buffer != nullptr) free(out_buffer); - } - mat_input.release(); - mat_output.release(); - - cv::waitKey(1); - - uint pipeline_type = 1; // External Source Reader Support given for the classification pipeline only - switch (pipeline_type) { - case 1: // classification pipeline - { - if(set_labels) - { - auto labels_tensor_list = rocalGetImageLabels(handle); - int *labels_ptr = static_cast(label_buffer.data()); - for (size_t i = 0; i < label_buffer.size(); i++) { - labels_tensor_list->at(i)->set_mem_handle(labels_ptr); - std::cerr << ">>>>> LABELS : " << labels_ptr[0] << "\t"; - labels_ptr++; - } - } - else - std::cerr<<"\n labels are not set"; - } break; - default: { - std::cerr << "Not a valid pipeline type ! Exiting!\n"; - return -1; - } - } - col_counter = (col_counter + 1) % number_of_cols; - index++; - counter += input_batch_size; - } - - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cerr << std::endl; - std::cerr << "Load time " << rocal_timing.load_time << std::endl; - std::cerr << "Decode time " << rocal_timing.decode_time << std::endl; - std::cerr << "Process time " << rocal_timing.process_time << std::endl; - std::cerr << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cerr << ">>>>> " << counter - << " images/frames Processed. Total Elapsed Time " << dur / 1000000 - << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - return 0; -} diff --git a/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt b/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt deleted file mode 100644 index 0d235c805..000000000 --- a/tests/cpp_api/rocAL_performance_tests/CMakeLists.txt +++ /dev/null @@ -1,98 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project (rocal_performance_tests) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/cpp_api/rocAL_performance_tests/README.md b/tests/cpp_api/rocAL_performance_tests/README.md deleted file mode 100644 index e808e7bc4..000000000 --- a/tests/cpp_api/rocAL_performance_tests/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# rocAL Performance Tests -This application is used to run performance tests on the rocAL API for graphs of depth size 1. - - -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* ROCm Performance Primitives (RPP) - -### build - ```` - mkdir build - cd build - cmake ../ - make - ```` -### running the application - ```` -rocAL_performance_tests [test image folder] [image width] [image height] [test case] [batch size] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] - ```` diff --git a/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt b/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt deleted file mode 100644 index 7276c54b8..000000000 --- a/tests/cpp_api/rocAL_performance_tests_with_depth/CMakeLists.txt +++ /dev/null @@ -1,76 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ - -cmake_minimum_required (VERSION 3.5) - -project (rocal_performance_tests_with_depth) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/rocAL_unittests/README.md b/tests/cpp_api/rocAL_unittests/README.md deleted file mode 100644 index dd4247fde..000000000 --- a/tests/cpp_api/rocAL_unittests/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# rocAL Unit Tests -This application can be used to verify the functionality of the API offered by rocAL. - -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.4+](https://github.com/opencv/opencv/releases/tag/3.4.0) -* ROCm Performance Primitives (RPP) -* Python3 -* Pillow - -Install Pillow library using `python3 -m pip install Pillow` - -### Build -```` -mkdir build -cd build -cmake ../ -make -```` -## Running the application - -``` -./rocAL_unittests - -Usage: ./rocAL_unittests reader-type pipeline-type=1(classification)2(detection)3(keypoints) output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all) -``` - -### Output verification - -The bash script `testAllScript.sh` can be used to run and dump the outputs for all test cases in rocAL and run the python script to verify the correctness of the generated outputs with the golden outputs. - -Input data is available in the following link : [MIVisionX-data](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data) - -`export ROCAL_DATA_PATH=` - -``` -./testAllScripts.sh -``` - -Device Type -* Option 0 - For only HOST backend -* Option 1 - For only HIP backend -* Option 2 - For both HOST and HIP backend - -Color Format -* Option 0 - For only Greyscale inputs -* Option 1 - For only RGB inputs -* Option 2 - For both Greyscale and RGB inputs diff --git a/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp b/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp deleted file mode 100644 index d02e91d3a..000000000 --- a/tests/cpp_api/rocAL_unittests/rocAL_unittests.cpp +++ /dev/null @@ -1,814 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; - -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#endif - -#define DISPLAY 0 -// #define RANDOMBBOXCROP - -using namespace std::chrono; - -std::string get_interpolation_type(unsigned int val, RocalResizeInterpolationType &interpolation_type) { - switch (val) { - case 0: { - interpolation_type = ROCAL_NEAREST_NEIGHBOR_INTERPOLATION; - return "NearestNeighbor"; - } - case 2: { - interpolation_type = ROCAL_CUBIC_INTERPOLATION; - return "Bicubic"; - } - case 3: { - interpolation_type = ROCAL_LANCZOS_INTERPOLATION; - return "Lanczos"; - } - case 4: { - interpolation_type = ROCAL_GAUSSIAN_INTERPOLATION; - return "Gaussian"; - } - case 5: { - interpolation_type = ROCAL_TRIANGULAR_INTERPOLATION; - return "Triangular"; - } - default: { - interpolation_type = ROCAL_LINEAR_INTERPOLATION; - return "Bilinear"; - } - } -} - -std::string get_scaling_mode(unsigned int val, RocalResizeScalingMode &scale_mode) { - switch (val) { - case 1: { - scale_mode = ROCAL_SCALING_MODE_STRETCH; - return "Stretch"; - } - case 2: { - scale_mode = ROCAL_SCALING_MODE_NOT_SMALLER; - return "NotSmaller"; - } - case 3: { - scale_mode = ROCAL_SCALING_MODE_NOT_LARGER; - return "Notlarger"; - } - default: { - scale_mode = ROCAL_SCALING_MODE_DEFAULT; - return "Default"; - } - } -} - -int test(int test_case, int reader_type, const char *path, const char *outName, int rgb, int gpu, int width, int height, int num_of_classes, int display_all, int resize_interpolation_type, int resize_scaling_mode); -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_unittests reader-type output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all)\n"); - return -1; - } - - int argIdx = 0; - int reader_type = atoi(argv[++argIdx]); - const char *path = argv[++argIdx]; - const char *outName = argv[++argIdx]; - int width = atoi(argv[++argIdx]); - int height = atoi(argv[++argIdx]); - int display_all = 0; - - int rgb = 1; // process color images - bool gpu = 1; - int test_case = 3; // For Rotate - int num_of_classes = 0; - int resize_interpolation_type = 1; // For Bilinear interpolations - int resize_scaling_mode = 0; // For Default scaling mode - - if (argc >= argIdx + MIN_ARG_COUNT) - test_case = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - gpu = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - num_of_classes = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - display_all = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - resize_interpolation_type = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - resize_scaling_mode = atoi(argv[++argIdx]); - - test(test_case, reader_type, path, outName, rgb, gpu, width, height, num_of_classes, display_all, resize_interpolation_type, resize_scaling_mode); - - return 0; -} - -int test(int test_case, int reader_type, const char *path, const char *outName, int rgb, int gpu, int width, int height, int num_of_classes, int display_all, int resize_interpolation_type, int resize_scaling_mode) { - size_t num_threads = 1; - unsigned int input_batch_size = 2; - int decode_max_width = width; - int decode_max_height = height; - int pipeline_type = -1; - std::cout << ">>> test case " << test_case << std::endl; - std::cout << ">>> Running on " << (gpu ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 - : RocalImageColor::ROCAL_COLOR_U8; - - auto handle = rocalCreate(input_batch_size, - gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, - 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>> Getting the path for MIVisionX-data <<<<<<<<<<<<<<<<*/ - - std::string rocal_data_path; - if (std::getenv("ROCAL_DATA_PATH")) - rocal_data_path = std::getenv("ROCAL_DATA_PATH"); - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - rocalSetSeed(0); - - // Creating uniformly distributed random objects to override some of the default augmentation parameters - RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); - RocalIntParam mirror = rocalCreateIntParameter(1); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - -#if defined RANDOMBBOXCROP - bool all_boxes_overlap = true; - bool no_crop = false; -#endif - - RocalTensor decoded_output; - RocalTensorLayout output_tensor_layout = (rgb != 0) ? RocalTensorLayout::ROCAL_NHWC : RocalTensorLayout::ROCAL_NCHW; - RocalTensorOutputType output_tensor_dtype = RocalTensorOutputType::ROCAL_UINT8; - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - switch (reader_type) { - case 1: // image_partial decode - { - std::cout << ">>>>>>> Running PARTIAL DECODE" << std::endl; - pipeline_type = 1; - rocalCreateLabelReader(handle, path); - std::vector area = {0.08, 1}; - std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; - decoded_output = rocalFusedJpegCrop(handle, path, color_format, num_threads, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 2: // coco detection - { - std::cout << ">>>>>>> Running COCO READER" << std::endl; - pipeline_type = 2; - if (strcmp(rocal_data_path.c_str(), "") == 0) { - std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; - exit(0); - } - // setting the default json path to ROCAL_DATA_PATH coco sample train annotation - std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img/annotations/instances_train2017.json"; - rocalCreateCOCOReader(handle, json_path.c_str(), true); - if (decode_max_height <= 0 || decode_max_width <= 0) - decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false); - else - decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 3: // coco detection partial - { - std::cout << ">>>>>>> Running COCO READER PARTIAL" << std::endl; - pipeline_type = 2; - if (strcmp(rocal_data_path.c_str(), "") == 0) { - std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; - exit(0); - } - // setting the default json path to ROCAL_DATA_PATH coco sample train annotation - std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img/annotations/instances_train2017.json"; - rocalCreateCOCOReader(handle, json_path.c_str(), true); -#if defined RANDOMBBOXCROP - rocalRandomBBoxCrop(handle, all_boxes_overlap, no_crop); -#endif - std::vector area = {0.08, 1}; - std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; - decoded_output = rocalJpegCOCOFileSourcePartial(handle, path, json_path.c_str(), color_format, num_threads, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 4: // tf classification - { - std::cout << ">>>>>>> Running TF CLASSIFICATION READER" << std::endl; - pipeline_type = 1; - char key1[25] = "image/encoded"; - char key2[25] = "image/class/label"; - char key8[25] = "image/filename"; - rocalCreateTFReader(handle, path, true, key2, key8); - decoded_output = rocalJpegTFRecordSource(handle, path, color_format, num_threads, false, key1, key8, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 5: // tf detection - { - std::cout << ">>>>>>> Running TF DETECTION READER" << std::endl; - pipeline_type = 2; - char key1[25] = "image/encoded"; - char key2[25] = "image/object/class/label"; - char key3[25] = "image/object/class/text"; - char key4[25] = "image/object/bbox/xmin"; - char key5[25] = "image/object/bbox/ymin"; - char key6[25] = "image/object/bbox/xmax"; - char key7[25] = "image/object/bbox/ymax"; - char key8[25] = "image/filename"; - rocalCreateTFReaderDetection(handle, path, true, key2, key3, key4, key5, key6, key7, key8); - decoded_output = rocalJpegTFRecordSource(handle, path, color_format, num_threads, false, key1, key8, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 6: // caffe classification - { - std::cout << ">>>>>>> Running CAFFE CLASSIFICATION READER" << std::endl; - pipeline_type = 1; - rocalCreateCaffeLMDBLabelReader(handle, path); - decoded_output = rocalJpegCaffeLMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 7: // caffe detection - { - std::cout << ">>>>>>> Running CAFFE DETECTION READER" << std::endl; - pipeline_type = 2; - rocalCreateCaffeLMDBReaderDetection(handle, path); - decoded_output = rocalJpegCaffeLMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 8: // caffe2 classification - { - std::cout << ">>>>>>> Running CAFFE2 CLASSIFICATION READER" << std::endl; - pipeline_type = 1; - rocalCreateCaffe2LMDBLabelReader(handle, path, true); - decoded_output = rocalJpegCaffe2LMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 9: // caffe2 detection - { - std::cout << ">>>>>>> Running CAFFE2 DETECTION READER" << std::endl; - pipeline_type = 2; - rocalCreateCaffe2LMDBReaderDetection(handle, path, true); - decoded_output = rocalJpegCaffe2LMDBRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 10: // coco reader keypoints - { - std::cout << ">>>>>>> Running COCO KEYPOINTS READER" << std::endl; - pipeline_type = 3; - if (strcmp(rocal_data_path.c_str(), "") == 0) { - std::cout << "\n ROCAL_DATA_PATH env variable has not been set. "; - exit(0); - } - // setting the default json path to ROCAL_DATA_PATH coco sample train annotation - std::string json_path = rocal_data_path + "/rocal_data/coco/coco_10_img_keypoints/annotations/person_keypoints_val2017.json"; - float sigma = 3.0; - rocalCreateCOCOReaderKeyPoints(handle, json_path.c_str(), true, sigma, (unsigned)width, (unsigned)height); - if (decode_max_height <= 0 || decode_max_width <= 0) - decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false); - else - decoded_output = rocalJpegCOCOFileSource(handle, path, json_path.c_str(), color_format, num_threads, false, true, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - case 11: // mxnet reader - { - std::cout << ">>>>>>> Running MXNET READER" << std::endl; - pipeline_type = 1; - rocalCreateMXNetReader(handle, path, true); - decoded_output = rocalMXNetRecordSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - default: { - std::cout << ">>>>>>> Running IMAGE READER" << std::endl; - pipeline_type = 1; - rocalCreateLabelReader(handle, path); - if (decode_max_height <= 0 || decode_max_width <= 0) - decoded_output = rocalJpegFileSource(handle, path, color_format, num_threads, false, true); - else - decoded_output = rocalJpegFileSource(handle, path, color_format, num_threads, false, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_max_width, decode_max_height); - } break; - } - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - int resize_w = width, resize_h = height; // height and width - - RocalTensor input = decoded_output; - // RocalTensor input = rocalResize(handle, decoded_output, resize_w, resize_h, false); // uncomment when processing images of different size - RocalTensor output; - - if ((test_case == 48 || test_case == 49 || test_case == 50) && rgb == 0) { - std::cout << "Not a valid option! Exiting!\n"; - return -1; - } - switch (test_case) { - case 0: { - std::cout << ">>>>>>> Running " - << "rocalResize" << std::endl; - resize_w = 400; - resize_h = 400; - std::string interpolation_type_name, scaling_node_name; - RocalResizeInterpolationType interpolation_type; - RocalResizeScalingMode scale_mode; - interpolation_type_name = get_interpolation_type(resize_interpolation_type, interpolation_type); - scaling_node_name = get_scaling_mode(resize_scaling_mode, scale_mode); - std::cerr << " \n Interpolation_type_name " << interpolation_type_name; - std::cerr << " \n Scaling_node_name " << scaling_node_name << std::endl; - if (scale_mode != ROCAL_SCALING_MODE_DEFAULT && interpolation_type != ROCAL_LINEAR_INTERPOLATION) { // (Reference output available for bilinear interpolation for this - std::cerr << " \n Running " << scaling_node_name << " scaling mode with Bilinear interpolation for comparison \n"; - interpolation_type = ROCAL_LINEAR_INTERPOLATION; - } - if (scale_mode == ROCAL_SCALING_MODE_STRETCH) // For reference Output comparison - output = rocalResize(handle, input, resize_w, 0, true, scale_mode, {}, 0, 0, interpolation_type); - else - output = rocalResize(handle, input, resize_w, resize_h, true, scale_mode, {}, 0, 0, interpolation_type); - } break; - case 1: { - std::cout << ">>>>>>> Running " - << "rocalCropResize" << std::endl; - output = rocalCropResize(handle, input, resize_w, resize_h, true); - } break; - case 2: { - std::cout << ">>>>>>> Running " - << "rocalRotate" << std::endl; - output = rocalRotate(handle, input, true); - } break; - case 3: { - std::cout << ">>>>>>> Running " - << "rocalBrightness" << std::endl; - output = rocalBrightness(handle, input, true); - } break; - case 4: { - std::cout << ">>>>>>> Running " - << "rocalGamma" << std::endl; - output = rocalGamma(handle, input, true); - } break; - case 5: { - std::cout << ">>>>>>> Running " - << "rocalContrast" << std::endl; - output = rocalContrast(handle, input, true); - } break; - case 6: { - std::cout << ">>>>>>> Running " - << "rocalFlip" << std::endl; - output = rocalFlip(handle, input, true); - } break; - case 7: { - std::cout << ">>>>>>> Running " - << "rocalBlur" << std::endl; - output = rocalBlur(handle, input, true); - } break; - case 8: { - std::cout << ">>>>>>> Running " - << "rocalBlend" << std::endl; - RocalTensor output_1 = rocalRotate(handle, input, false); - output = rocalBlend(handle, input, output_1, true); - } break; - case 9: { - std::cout << ">>>>>>> Running " - << "rocalWarpAffine" << std::endl; - output = rocalWarpAffine(handle, input, true); - } break; - case 10: { - std::cout << ">>>>>>> Running " - << "rocalFishEye" << std::endl; - output = rocalFishEye(handle, input, true); - } break; - case 11: { - std::cout << ">>>>>>> Running " - << "rocalVignette" << std::endl; - output = rocalVignette(handle, input, true); - } break; - case 12: { - std::cout << ">>>>>>> Running " - << "rocalJitter" << std::endl; - output = rocalJitter(handle, input, true); - } break; - case 13: { - std::cout << ">>>>>>> Running " - << "rocalSnPNoise" << std::endl; - output = rocalSnPNoise(handle, input, true); - } break; - case 14: { - std::cout << ">>>>>>> Running " - << "rocalSnow" << std::endl; - output = rocalSnow(handle, input, true); - } break; - case 15: { - std::cout << ">>>>>>> Running " - << "rocalRain" << std::endl; - output = rocalRain(handle, input, true); - } break; - case 16: { - std::cout << ">>>>>>> Running " - << "rocalColorTemp" << std::endl; - output = rocalColorTemp(handle, input, true); - } break; - case 17: { - std::cout << ">>>>>>> Running " - << "rocalFog" << std::endl; - output = rocalFog(handle, input, true); - } break; - case 18: { - std::cout << ">>>>>>> Running " - << "rocalLensCorrection" << std::endl; - output = rocalLensCorrection(handle, input, true); - } break; - case 19: { - std::cout << ">>>>>>> Running " - << "rocalPixelate" << std::endl; - output = rocalPixelate(handle, input, true); - } break; - case 20: { - std::cout << ">>>>>>> Running " - << "rocalExposure" << std::endl; - output = rocalExposure(handle, input, true); - } break; - case 21: { - std::cout << ">>>>>>> Running " - << "rocalHue" << std::endl; - output = rocalHue(handle, input, true); - } break; - case 22: { - std::cout << ">>>>>>> Running " - << "rocalSaturation" << std::endl; - output = rocalSaturation(handle, input, true); - } break; - case 23: { - std::cout << ">>>>>>> Running " - << "rocalCopy" << std::endl; - output = rocalCopy(handle, input, true); - } break; - case 24: { - std::cout << ">>>>>>> Running " - << "rocalColorTwist" << std::endl; - output = rocalColorTwist(handle, input, true); - } break; - case 25: { - std::cout << ">>>>>>> Running " - << "rocalCropMirrorNormalize" << std::endl; - std::vector mean = {128, 128, 128}; - std::vector std_dev = {1.2, 1.2, 1.2}; - output = rocalCropMirrorNormalize(handle, input, 224, 224, 0, 0, mean, std_dev, true, mirror, output_tensor_layout, output_tensor_dtype); - } break; - case 26: { - std::cout << ">>>>>>> Running " - << "rocalCrop" << std::endl; - output = rocalCrop(handle, input, true); - } break; - case 27: { - std::cout << ">>>>>>> Running " - << "rocalResizeCropMirror" << std::endl; - output = rocalResizeCropMirror(handle, input, resize_w, resize_h, true); - } break; - - case 30: { - std::cout << ">>>>>>> Running " - << "rocalCropResizeFixed" << std::endl; - output = rocalCropResizeFixed(handle, input, resize_w, resize_h, true, 0.25, 1.2, 0.6, 0.4); - } break; - case 31: { - std::cout << ">>>>>>> Running " - << "rocalRotateFixed" << std::endl; - output = rocalRotateFixed(handle, input, 45, true); - } break; - case 32: { - std::cout << ">>>>>>> Running " - << "rocalBrightnessFixed" << std::endl; - output = rocalBrightnessFixed(handle, input, 1.90, 20, true); - } break; - case 33: { - std::cout << ">>>>>>> Running " - << "rocalGammaFixed" << std::endl; - output = rocalGammaFixed(handle, input, 0.5, true); - } break; - case 34: { - std::cout << ">>>>>>> Running " - << "rocalContrastFixed" << std::endl; - output = rocalContrastFixed(handle, input, 30, 80, true); - } break; - case 35: { - std::cout << ">>>>>>> Running " - << "rocalBlurFixed" << std::endl; - output = rocalBlurFixed(handle, input, 5, true); - } break; - case 36: { - std::cout << ">>>>>>> Running " - << "rocalBlendFixed" << std::endl; - RocalTensor output_1 = rocalRotateFixed(handle, input, 45, false); - output = rocalBlendFixed(handle, input, output_1, 0.5, true); - } break; - case 37: { - std::cout << ">>>>>>> Running " - << "rocalWarpAffineFixed" << std::endl; - output = rocalWarpAffineFixed(handle, input, 1, 1, 0.5, 0.5, 7, 7, true); - } break; - case 38: { - std::cout << ">>>>>>> Running " - << "rocalVignetteFixed" << std::endl; - output = rocalVignetteFixed(handle, input, 50, true); - } break; - case 39: { - std::cout << ">>>>>>> Running " - << "rocalJitterFixed" << std::endl; - output = rocalJitterFixed(handle, input, 3, true); - } break; - case 40: { - std::cout << ">>>>>>> Running " - << "rocalSnPNoiseFixed" << std::endl; - output = rocalSnPNoiseFixed(handle, input, 0.2, 0.2, 0.2, 0.5, true, 0); - } break; - case 41: { - std::cout << ">>>>>>> Running " - << "rocalSnowFixed" << std::endl; - output = rocalSnowFixed(handle, input, 0.2, true); - } break; - case 42: { - std::cout << ">>>>>>> Running " - << "rocalRainFixed" << std::endl; - output = rocalRainFixed(handle, input, 0.5, 2, 16, 0.25, true); - } break; - case 43: { - std::cout << ">>>>>>> Running " - << "rocalColorTempFixed" << std::endl; - output = rocalColorTempFixed(handle, input, 70, true); - } break; - case 44: { - std::cout << ">>>>>>> Running " - << "rocalFogFixed" << std::endl; - output = rocalFogFixed(handle, input, 0.5, true); - } break; - case 45: { - std::cout << ">>>>>>> Running " - << "rocalLensCorrectionFixed" << std::endl; - output = rocalLensCorrectionFixed(handle, input, 2.9, 1.2, true); - } break; - case 46: { - std::cout << ">>>>>>> Running " - << "rocalExposureFixed" << std::endl; - output = rocalExposureFixed(handle, input, 1, true); - } break; - case 47: { - std::cout << ">>>>>>> Running " - << "rocalFlipFixed" << std::endl; - output = rocalFlipFixed(handle, input, 1, 0, true); - } break; - case 48: { - std::cout << ">>>>>>> Running " - << "rocalHueFixed" << std::endl; - output = rocalHueFixed(handle, input, 150, true); - } break; - case 49: { - std::cout << ">>>>>>> Running " - << "rocalSaturationFixed" << std::endl; - output = rocalSaturationFixed(handle, input, 0.3, true); - } break; - case 50: { - std::cout << ">>>>>>> Running " - << "rocalColorTwistFixed" << std::endl; - output = rocalColorTwistFixed(handle, input, 0.2, 10.0, 100.0, 0.25, true); - } break; - case 51: { - std::cout << ">>>>>>> Running " - << "rocalCropFixed" << std::endl; - output = rocalCropFixed(handle, input, 224, 224, 1, true, 0, 0, 0); - } break; - case 52: { - std::cout << ">>>>>>> Running " - << "rocalCropCenterFixed" << std::endl; - output = rocalCropCenterFixed(handle, input, 224, 224, 2, true); - } break; - case 53: { - std::cout << ">>>>>>> Running " - << "rocalResizeCropMirrorFixed" << std::endl; - output = rocalResizeCropMirrorFixed(handle, input, 400, 400, true, 200, 200, mirror); - } break; - case 54: { - std::cout << ">>>>>>> Running " - << "rocalSSDRandomCrop" << std::endl; - output = rocalSSDRandomCrop(handle, input, true); - } break; - case 55: { - std::cout << ">>>>>>> Running " - << "rocalCropMirrorNormalizeFixed_center crop" << std::endl; - std::vector mean = {128, 128, 128}; - std::vector std_dev = {1.2, 1.2, 1.2}; - output = rocalCropMirrorNormalize(handle, input, 224, 224, 0.5, 0.5, mean, std_dev, true, mirror); - } break; - case 56: { - std::vector mean = {128, 128, 128}; - std::vector std_dev = {1.2, 1.2, 1.2}; - std::cout << ">>>>>>> Running " - << " Resize Mirror Normalize " << std::endl; - output = rocalResizeMirrorNormalize(handle, input, 400, 400, mean, std_dev, true, ROCAL_SCALING_MODE_DEFAULT, - {}, 0, 0, ROCAL_LINEAR_INTERPOLATION, mirror); - } break; - - default: - std::cout << "Not a valid option! Exiting!\n"; - return -1; - } - - // Calling the API to verify and build the augmentation graph - rocalVerify(handle); - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); - return -1; - } - - auto number_of_outputs = rocalGetAugmentationBranchCount(handle); - std::cout << "\n\nAugmented copies count " << number_of_outputs << "\n"; - - if (number_of_outputs != 1) { - std::cout << "More than 1 output set in the pipeline"; - return -1; - } - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * input_batch_size; - int w = rocalGetOutputWidth(handle); - int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); - const unsigned number_of_cols = 1; // 1920 / w; - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h, w, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - int col_counter = 0; - if (DISPLAY) - cv::namedWindow("output", CV_WINDOW_AUTOSIZE); - printf("Going to process images\n"); - printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int index = 0; - - while (rocalGetRemainingImages(handle) >= input_batch_size) { - index++; - if (rocalRun(handle) != 0) - break; - int image_name_length[input_batch_size]; - switch (pipeline_type) { - case 1: { // classification pipeline - RocalTensorList labels = rocalGetImageLabels(handle); - int *label_id = reinterpret_cast(labels->at(0)->buffer()); // The labels are present contiguously in memory - int img_size = rocalGetImageNameLen(handle, image_name_length); - char img_name[img_size]; - int label_one_hot_encoded[input_batch_size * num_of_classes]; - rocalGetImageName(handle, img_name); - if (num_of_classes != 0) { - rocalGetOneHotImageLabels(handle, label_one_hot_encoded, num_of_classes, RocalOutputMemType::ROCAL_MEMCPY_HOST); - } - std::cerr << "\nPrinting image names of batch: " << img_name << "\n"; - for (unsigned int i = 0; i < input_batch_size; i++) { - std::cerr << "\t Printing label_id : " << label_id[i] << std::endl; - if(num_of_classes != 0) - { - std::cout << "One Hot Encoded labels:"<<"\t"; - for (int j = 0; j < num_of_classes; j++) - { - int idx_value = label_one_hot_encoded[(i*num_of_classes)+j]; - if(idx_value == 0) - std::cout << idx_value << "\t"; - else - { - std::cout << idx_value << "\t"; - } - } - } - std::cout << "\n"; - } - } break; - case 2: { // detection pipeline - int img_size = rocalGetImageNameLen(handle, image_name_length); - char img_name[img_size]; - rocalGetImageName(handle, img_name); - std::cerr << "\nPrinting image names of batch: " << img_name; - RocalTensorList bbox_labels = rocalGetBoundingBoxLabel(handle); - RocalTensorList bbox_coords = rocalGetBoundingBoxCords(handle); - for (unsigned i = 0; i < bbox_labels->size(); i++) { - int *labels_buffer = reinterpret_cast(bbox_labels->at(i)->buffer()); - float *bbox_buffer = reinterpret_cast(bbox_coords->at(i)->buffer()); - std::cerr << "\n>>>>> BBOX LABELS : "; - for (unsigned j = 0; j < bbox_labels->at(i)->dims().at(0); j++) - std::cerr << labels_buffer[j] << " "; - std::cerr << "\n>>>>> BBOX : " << bbox_coords->at(i)->dims().at(0) << " : \n"; - for (unsigned j = 0, j4 = 0; j < bbox_coords->at(i)->dims().at(0); j++, j4 = j * 4) - std::cerr << bbox_buffer[j4] << " " << bbox_buffer[j4 + 1] << " " << bbox_buffer[j4 + 2] << " " << bbox_buffer[j4 + 3] << "\n"; - } - int img_sizes_batch[input_batch_size * 2]; - rocalGetImageSizes(handle, img_sizes_batch); - for (int i = 0; i < (int)input_batch_size; i++) { - std::cout << "\nwidth:" << img_sizes_batch[i * 2]; - std::cout << "\nHeight:" << img_sizes_batch[(i * 2) + 1]; - } - } break; - case 3: { // keypoints pipeline - int size = input_batch_size; - RocalJointsData *joints_data; - rocalGetJointsDataPtr(handle, &joints_data); - for (int i = 0; i < size; i++) { - std::cout << "ImageID: " << joints_data->image_id_batch[i] << std::endl; - std::cout << "AnnotationID: " << joints_data->annotation_id_batch[i] << std::endl; - std::cout << "ImagePath: " << joints_data->image_path_batch[i] << std::endl; - std::cout << "Center: " << joints_data->center_batch[i][0] << " " << joints_data->center_batch[i][1] << std::endl; - std::cout << "Scale: " << joints_data->scale_batch[i][0] << " " << joints_data->scale_batch[i][1] << std::endl; - std::cout << "Score: " << joints_data->score_batch[i] << std::endl; - std::cout << "Rotation: " << joints_data->rotation_batch[i] << std::endl; - - for (int k = 0; k < 17; k++) { - std::cout << "x : " << joints_data->joints_batch[i][k][0] << " , y : " << joints_data->joints_batch[i][k][1] << " , v : " << joints_data->joints_visibility_batch[i][k][0] << std::endl; - } - } - } break; - default: { - std::cout << "Not a valid pipeline type ! Exiting!\n"; - return -1; - } - } - auto last_colot_temp = rocalGetIntValue(color_temp_adj); - rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); - - rocalCopyToOutput(handle, mat_input.data, h * w * p); - - std::vector compression_params; - compression_params.push_back(IMWRITE_PNG_COMPRESSION); - compression_params.push_back(9); - - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - std::string out_filename = std::string(outName) + ".png"; // in case the user specifies non png filename - if (display_all) - out_filename = std::string(outName) + std::to_string(index) + ".png"; // in case the user specifies non png filename - - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - if (DISPLAY) - cv::imshow("output", mat_output); - else - cv::imwrite(out_filename, mat_color, compression_params); - } else { - if (DISPLAY) - cv::imshow("output", mat_output); - else - cv::imwrite(out_filename, mat_output, compression_params); - } - col_counter = (col_counter + 1) % number_of_cols; - } - - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - if (!output) - return -1; - return 0; -} diff --git a/tests/cpp_api/rocAL_unittests/testAllScripts.sh b/tests/cpp_api/rocAL_unittests/testAllScripts.sh deleted file mode 100755 index b41bd95b3..000000000 --- a/tests/cpp_api/rocAL_unittests/testAllScripts.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash -cwd=$(pwd) -if [ -d build ];then - sudo rm -rf ./build/* -else - mkdir build -fi -cd build || exit -cmake .. -make -j"$(nproc)" - -if [[ $ROCAL_DATA_PATH == "" ]] -then - echo "Need to export ROCAL_DATA_PATH" - exit -fi - -# Path to inputs and outputs available in MIVisionX-data -image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ -tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ -caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ -caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ -caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ -caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ -mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ -output_path=../rocal_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ -golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ - -display=0 -device=0 -width=640 -height=480 -device_name="host" -rgb_name=("gray" "rgb") -rgb=1 -dev_start=0 -dev_end=1 -rgb_start=0 -rgb_end=1 - -if [ "$#" -gt 0 ]; then - if [ "$1" -eq 0 ]; then # For only HOST backend - dev_start=0 - dev_end=0 - elif [ "$1" -eq 1 ]; then # For only HIP backend - dev_start=1 - dev_end=1 - elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend - dev_start=0 - dev_end=1 - fi -fi - -if [ "$#" -gt 1 ]; then - if [ "$2" -eq 0 ]; then # For only Greyscale inputs - rgb_start=0 - rgb_end=0 - elif [ "$2" -eq 1 ]; then # For only RGB inputs - rgb_start=1 - rgb_end=1 - elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs - rgb_start=0 - rgb_end=1 - fi -fi - -mkdir "$output_path" - -for ((device=dev_start;device<=dev_end;device++)) -do - if [ $device -eq 1 ] - then - device_name="hip" - echo "Running HIP Backend..." - else - echo "Running HOST Backend..." - fi - for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) - do - # FileSource Reader - ./rocal_unittests 0 "$image_path" "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" $width $height 45 $device $rgb 0 $display - ./rocal_unittests 0 "$image_path" "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" $width $height 46 $device $rgb 0 $display - ./rocal_unittests 0 "$image_path" "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" $width $height 47 $device $rgb 0 $display - - # FileSource Reader + partial decoder - ./rocal_unittests 1 "$image_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 41 $device $rgb 0 $display - ./rocal_unittests 1 "$image_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 42 $device $rgb 0 $display - ./rocal_unittests 1 "$image_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 40 $device $rgb 0 $display - - # coco detection - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" $width $height 33 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" $width $height 34 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" $width $height 38 $device $rgb 0 $display - - # coco detection + partial decoder - ./rocal_unittests 3 "$coco_detection_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 41 $device $rgb 0 $display - ./rocal_unittests 3 "$coco_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 42 $device $rgb 0 $display - ./rocal_unittests 3 "$coco_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 40 $device $rgb 0 $display - - # tf classification - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" $width $height 36 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" $width $height 37 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" $width $height 35 $device $rgb 0 $display - - # tf detection - ./rocal_unittests 5 "$tf_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" $width $height 40 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" $width $height 43 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" $width $height 44 $device $rgb 0 $display - - # caffe classification - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" $width $height 31 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" $width $height 32 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" $width $height 48 $device $rgb 0 $display - - # caffe detection - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" $width $height 49 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" $width $height 50 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" $width $height 42 $device $rgb 0 $display - - # caffe2 classification - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" $width $height 52 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" $width $height 53 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" $width $height 41 $device $rgb 0 $display - - # caffe2 detection - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" $width $height 10 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropCenterCMN_${rgb_name[$rgb]}_${device_name}" $width $height 55 $device $rgb 0 $display - - # mxnet - ./rocal_unittests 11 "$mxnet_path" "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" $width $height 39 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display - - # CMN - ./rocal_unittests 0 "$image_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display - - # crop - ./rocal_unittests 0 "$image_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 51 $device $rgb 0 $display - - # resize - # Last two parameters are interpolation type and scaling mode - ./rocal_unittests 0 "$image_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" $width $height 0 $device $rgb 0 $display 1 0 - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" $width $height 0 $device $rgb 0 $display 1 1 - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" $width $height 0 $device $rgb 0 $display 1 2 - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" $width $height 0 $device $rgb 0 $display 1 3 - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" $width $height 0 $device $rgb 0 $display 2 0 - # ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" $width $height 0 $device $rgb 0 $display 0 0 - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" $width $height 0 $device $rgb 0 $display 3 0 - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" $width $height 0 $device $rgb 0 $display 5 0 - ./rocal_unittests 11 "$mxnet_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" $width $height 0 $device $rgb 0 $display 4 0 - - done -done - -pwd - -# Run python script to compare rocAL outputs with golden ouptuts -python3 "$cwd"/pixel_comparison/image_comparison.py "$golden_output_path" "$output_path" diff --git a/tests/cpp_api/rocAL_video_unittests/README.md b/tests/cpp_api/rocAL_video_unittests/README.md deleted file mode 100644 index af791c77d..000000000 --- a/tests/cpp_api/rocAL_video_unittests/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# rocAL Video Unit Tests -This application can be used to verify the functionality of the video API offered by rocAL. - -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, version - `18.04` / `20.04` -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) -* [FFmpeg n4.4.2](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2) -* ROCm Performance Primitives (RPP) - -### Running the application -Executing the below command will build and run the application for the specified test case. - -```` -./testScript.sh -```` - -The arguments passed to the Video Pipeline can be modified in the bash script [testScript.sh](./testScript.sh). - -The outputs will be dumped inside the build/output_frames folder. - -The sample video files and folder are available in the In the following path : [video and sequence samples](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples). - -The data samples can be downloaded from the MIVisionX-data repository. - -``` -git clone https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data.git -``` - -## Description - -### Test Cases - -The following test cases are supported in this unittest: -1. Video Reader - Reads the video file/folder and returns a sequence of frames. -2. Video Reader Resize (reader followed by resize augmentation) - Reads the video file/folder and returns a sequence of re-sized frames. -3. Sequence Reader - Reads the folder of images and returns a sequence of images. - -### Arguments used in test script - -INPUT_PATH : Input passed by the user. It can be a video file path, folder path containing videos or a text file. - - NOTE: - - * Inputs for cases 1 and 2 - Video file / folder containing videos - * Input for case 3 - Folder containing sequence of images [sample folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence) - -READER_CASE : Value passed can be 1/2/3 depending upon the selected reader (default value : 1). - -SAVE_FRAMES : Saves the output frames or avi files in the build/output_frames folder. - -DEVICE : CPU:0/GPU:1 device is supported. - -HARDWARE_DECODE_MODE : Uses Hardware decoder if set to true. - -SHUFFLE : Shuffles the sequences if set to true. - -BATCH SIZE : Number of sequences in a batch. - -SEQUENCE LENGTH : Number of frames in a sequence. - -STEP : The frame interval between sequences. - -STRIDE : The frame interval between frames within a sequence. - -RESIZE_WIDTH : Resize width value. - -RESIZE_HEIGHT : Resize height value. - -FILELIST_FRAMENUM : If set to true the inputs from text file will be considered as frame numbers otherwise they will be considered as timestamps. - -ENABLE_METADATA : If set to true, prints the labels and names of the associated frames in the sequence. - -ENABLE_FRAME_NUMBER : If set to true, prints the starting frame number of the sequences. - -ENABLE_TIMESTAMPS : If set to true, prints the timestamp of each frame in the sequences. - -ENABLE_SEQUENCE_REARRANGE : If set to true, the frames in each sequence will be rearranged in the order specified by the user. The order should contain values in the range of [0, sequence_length) - -## Test case examples - -**Example 1: Video Reader** - -> ./testScript.sh <[path/to/test_frame_num.mp4](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/blob/main/rocal_data/video_and_sequence_samples/test_frame/test_frame_num.mp4)> 1 - -Arguments to be modified in testScript.sh to get the following output: - -- BATCH_SIZE=2 -- SEQUENCE_LENGTH= 3 -- STEP=3 -- STRIDE=5 - -![video_reader.png](./samples/video_reader.png) - -To test with VideoReaderResize pass reader_case as 2: -> ./testScript.sh 2 - -Also RESIZE_WIDTH and RESIZE_HEIGHT can be changed in testScript.sh - -
- -**Example 2: Sequence Reader** - -> ./testScript.sh <[path/to/sequence_folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence)> 3 - -![sequence_reader.png](./samples/sequence_reader.png) - -NOTE : - -The input to the sequence reader should be a directory of images. - -The output of Sequence Reader may be different from the Video Reader because the names of the images from the input directory are sorted in lexicographic order and then split into sequences. - -
- -**Example 3: Sequence Rearrange** - -> ./testScript.sh 1 - -Arguments to be modified in testScript.sh to enable sequence rearrange: - -ENABLE_SEQUENCE_REARRANGE=1 - -![sequence_rearrange.png](./samples/sequence_rearrange.png) - -New Sequence order : (2, 1, 1, 0), The order can be changed directly in rocAL_video_unittests.cpp file. The values specified in the order can only be in the range [0,sequence_length) - -**NOTE**: - -The outputs frames will be dumped inside the build/output_frames folder. The above images are for illustration purpose only. diff --git a/tests/cpp_api/rocAL_unittests/CMakeLists.txt b/tests/cpp_api/unit_tests/CMakeLists.txt similarity index 99% rename from tests/cpp_api/rocAL_unittests/CMakeLists.txt rename to tests/cpp_api/unit_tests/CMakeLists.txt index 59de69611..a76fde8e5 100644 --- a/tests/cpp_api/rocAL_unittests/CMakeLists.txt +++ b/tests/cpp_api/unit_tests/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project (rocal_unittests) +project (unit_tests) set(CMAKE_CXX_STANDARD 14) # ROCm Path diff --git a/tests/cpp_api_tests/rocAL_unittests/README.md b/tests/cpp_api/unit_tests/README.md similarity index 82% rename from tests/cpp_api_tests/rocAL_unittests/README.md rename to tests/cpp_api/unit_tests/README.md index dd4247fde..95bbaa96c 100644 --- a/tests/cpp_api_tests/rocAL_unittests/README.md +++ b/tests/cpp_api/unit_tests/README.md @@ -23,9 +23,9 @@ make ## Running the application ``` -./rocAL_unittests +./unit_tests -Usage: ./rocAL_unittests reader-type pipeline-type=1(classification)2(detection)3(keypoints) output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all) +Usage: ./unit_tests reader-type pipeline-type=1(classification)2(detection)3(keypoints) output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all) ``` ### Output verification diff --git a/tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py b/tests/cpp_api/unit_tests/pixel_comparison/image_comparison.py similarity index 100% rename from tests/cpp_api/rocAL_unittests/pixel_comparison/image_comparison.py rename to tests/cpp_api/unit_tests/pixel_comparison/image_comparison.py diff --git a/tests/cpp_api/unit_tests/testAllScripts.sh b/tests/cpp_api/unit_tests/testAllScripts.sh new file mode 100755 index 000000000..dc3e4a82f --- /dev/null +++ b/tests/cpp_api/unit_tests/testAllScripts.sh @@ -0,0 +1,177 @@ +#!/bin/bash +cwd=$(pwd) +if [ -d build ];then + sudo rm -rf ./build/* +else + mkdir build +fi +cd build || exit +cmake .. +make -j"$(nproc)" + +if [[ $ROCAL_DATA_PATH == "" ]] +then + echo "Need to export ROCAL_DATA_PATH" + exit +fi + +# Path to inputs and outputs available in MIVisionX-data +image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ +tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ +tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ +caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ +caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ +caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ +caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ +mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ +output_path=../rocal_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ +golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ + +display=0 +device=0 +width=640 +height=480 +device_name="host" +rgb_name=("gray" "rgb") +rgb=1 +dev_start=0 +dev_end=1 +rgb_start=0 +rgb_end=1 + +if [ "$#" -gt 0 ]; then + if [ "$1" -eq 0 ]; then # For only HOST backend + dev_start=0 + dev_end=0 + elif [ "$1" -eq 1 ]; then # For only HIP backend + dev_start=1 + dev_end=1 + elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend + dev_start=0 + dev_end=1 + fi +fi + +if [ "$#" -gt 1 ]; then + if [ "$2" -eq 0 ]; then # For only Greyscale inputs + rgb_start=0 + rgb_end=0 + elif [ "$2" -eq 1 ]; then # For only RGB inputs + rgb_start=1 + rgb_end=1 + elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs + rgb_start=0 + rgb_end=1 + fi +fi + +mkdir "$output_path" + +for ((device=dev_start;device<=dev_end;device++)) +do + if [ $device -eq 1 ] + then + device_name="hip" + echo "Running HIP Backend..." + else + echo "Running HOST Backend..." + fi + for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) + do + # FileSource Reader + ./unit_tests 0 "$image_path" "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" $width $height 45 $device $rgb 0 $display + ./unit_tests 0 "$image_path" "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" $width $height 46 $device $rgb 0 $display + ./unit_tests 0 "$image_path" "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" $width $height 47 $device $rgb 0 $display + + # FileSource Reader + partial decoder + ./unit_tests 1 "$image_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 41 $device $rgb 0 $display + ./unit_tests 1 "$image_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 42 $device $rgb 0 $display + ./unit_tests 1 "$image_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 40 $device $rgb 0 $display + + # coco detection + ./unit_tests 2 "$coco_detection_path" "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" $width $height 33 $device $rgb 0 $display + ./unit_tests 2 "$coco_detection_path" "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" $width $height 34 $device $rgb 0 $display + ./unit_tests 2 "$coco_detection_path" "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" $width $height 38 $device $rgb 0 $display + + # coco detection + partial decoder + ./unit_tests 3 "$coco_detection_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 41 $device $rgb 0 $display + ./unit_tests 3 "$coco_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 42 $device $rgb 0 $display + ./unit_tests 3 "$coco_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 40 $device $rgb 0 $display + + # tf classification + ./unit_tests 4 "$tf_classification_path" "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" $width $height 36 $device $rgb 0 $display + ./unit_tests 4 "$tf_classification_path" "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" $width $height 37 $device $rgb 0 $display + ./unit_tests 4 "$tf_classification_path" "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" $width $height 35 $device $rgb 0 $display + + # tf detection + ./unit_tests 5 "$tf_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" $width $height 40 $device $rgb 0 $display + ./unit_tests 5 "$tf_detection_path" "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" $width $height 43 $device $rgb 0 $display + ./unit_tests 5 "$tf_detection_path" "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" $width $height 44 $device $rgb 0 $display + + # caffe classification + ./unit_tests 6 "$caffe_classification_path" "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" $width $height 31 $device $rgb 0 $display + ./unit_tests 6 "$caffe_classification_path" "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" $width $height 32 $device $rgb 0 $display + ./unit_tests 6 "$caffe_classification_path" "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" $width $height 48 $device $rgb 0 $display + + # caffe detection + ./unit_tests 7 "$caffe_detection_path" "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" $width $height 49 $device $rgb 0 $display + ./unit_tests 7 "$caffe_detection_path" "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" $width $height 50 $device $rgb 0 $display + ./unit_tests 7 "$caffe_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" $width $height 42 $device $rgb 0 $display + + # caffe2 classification + ./unit_tests 8 "$caffe2_classification_path" "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" $width $height 52 $device $rgb 0 $display + ./unit_tests 8 "$caffe2_classification_path" "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" $width $height 53 $device $rgb 0 $display + ./unit_tests 8 "$caffe2_classification_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" $width $height 41 $device $rgb 0 $display + + # caffe2 detection + ./unit_tests 9 "$caffe2_detection_path" "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" $width $height 10 $device $rgb 0 $display + ./unit_tests 9 "$caffe2_detection_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display + ./unit_tests 9 "$caffe2_detection_path" "${output_path}CropCenterCMN_${rgb_name[$rgb]}_${device_name}" $width $height 55 $device $rgb 0 $display + + # mxnet + ./unit_tests 11 "$mxnet_path" "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" $width $height 39 $device $rgb 0 $display + ./unit_tests 11 "$mxnet_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display + ./unit_tests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display + + # CMN + ./unit_tests 0 "$image_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 25 $device $rgb 0 $display + ./unit_tests 2 "$coco_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" $width $height 25 $device $rgb 0 $display + ./unit_tests 4 "$tf_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 25 $device $rgb 0 $display + ./unit_tests 5 "$tf_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 25 $device $rgb 0 $display + ./unit_tests 6 "$caffe_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 25 $device $rgb 0 $display + ./unit_tests 7 "$caffe_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 25 $device $rgb 0 $display + ./unit_tests 8 "$caffe2_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 25 $device $rgb 0 $display + ./unit_tests 9 "$caffe2_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 25 $device $rgb 0 $display + ./unit_tests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display + + # crop + ./unit_tests 0 "$image_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 51 $device $rgb 0 $display + ./unit_tests 2 "$coco_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" $width $height 51 $device $rgb 0 $display + ./unit_tests 4 "$tf_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 51 $device $rgb 0 $display + ./unit_tests 5 "$tf_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 51 $device $rgb 0 $display + ./unit_tests 6 "$caffe_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 51 $device $rgb 0 $display + ./unit_tests 7 "$caffe_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 51 $device $rgb 0 $display + ./unit_tests 8 "$caffe2_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 51 $device $rgb 0 $display + ./unit_tests 9 "$caffe2_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 51 $device $rgb 0 $display + ./unit_tests 11 "$mxnet_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 51 $device $rgb 0 $display + + # resize + # Last two parameters are interpolation type and scaling mode + ./unit_tests 0 "$image_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" $width $height 0 $device $rgb 0 $display 1 0 + ./unit_tests 2 "$coco_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" $width $height 0 $device $rgb 0 $display 1 1 + ./unit_tests 4 "$tf_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" $width $height 0 $device $rgb 0 $display 1 2 + ./unit_tests 5 "$tf_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" $width $height 0 $device $rgb 0 $display 1 3 + ./unit_tests 6 "$caffe_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" $width $height 0 $device $rgb 0 $display 2 0 + # ./unit_tests 7 "$caffe_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" $width $height 0 $device $rgb 0 $display 0 0 + ./unit_tests 8 "$caffe2_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" $width $height 0 $device $rgb 0 $display 3 0 + ./unit_tests 9 "$caffe2_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" $width $height 0 $device $rgb 0 $display 5 0 + ./unit_tests 11 "$mxnet_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" $width $height 0 $device $rgb 0 $display 4 0 + + done +done + +pwd + +# Run python script to compare rocAL outputs with golden ouptuts +python3 "$cwd"/pixel_comparison/image_comparison.py "$golden_output_path" "$output_path" diff --git a/tests/cpp_api_tests/rocAL_unittests/rocAL_unittests.cpp b/tests/cpp_api/unit_tests/unit_tests.cpp similarity index 99% rename from tests/cpp_api_tests/rocAL_unittests/rocAL_unittests.cpp rename to tests/cpp_api/unit_tests/unit_tests.cpp index d02e91d3a..212b8e765 100644 --- a/tests/cpp_api_tests/rocAL_unittests/rocAL_unittests.cpp +++ b/tests/cpp_api/unit_tests/unit_tests.cpp @@ -106,7 +106,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_unittests reader-type output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all)\n"); + printf("Usage: unit_tests reader-type output_image_name test_case gpu=1/cpu=0 rgb=1/grayscale=0 one_hot_labels=num_of_classes/0 display_all=0(display_last_only)1(display_all)\n"); return -1; } diff --git a/tests/cpp_api/rocAL_video_unittests/CMakeLists.txt b/tests/cpp_api/video_tests/CMakeLists.txt similarity index 98% rename from tests/cpp_api/rocAL_video_unittests/CMakeLists.txt rename to tests/cpp_api/video_tests/CMakeLists.txt index 81bec5c67..65cb4c109 100644 --- a/tests/cpp_api/rocAL_video_unittests/CMakeLists.txt +++ b/tests/cpp_api/video_tests/CMakeLists.txt @@ -25,7 +25,7 @@ ################################################################################ cmake_minimum_required(VERSION 3.5) -project (rocal_video_unittests) +project (video_tests) set(CMAKE_CXX_STANDARD 14) diff --git a/tests/cpp_api_tests/rocAL_video_unittests/README.md b/tests/cpp_api/video_tests/README.md similarity index 97% rename from tests/cpp_api_tests/rocAL_video_unittests/README.md rename to tests/cpp_api/video_tests/README.md index af791c77d..42a2486c5 100644 --- a/tests/cpp_api_tests/rocAL_video_unittests/README.md +++ b/tests/cpp_api/video_tests/README.md @@ -125,7 +125,7 @@ ENABLE_SEQUENCE_REARRANGE=1 ![sequence_rearrange.png](./samples/sequence_rearrange.png) -New Sequence order : (2, 1, 1, 0), The order can be changed directly in rocAL_video_unittests.cpp file. The values specified in the order can only be in the range [0,sequence_length) +New Sequence order : (2, 1, 1, 0), The order can be changed directly in video_tests.cpp file. The values specified in the order can only be in the range [0,sequence_length) **NOTE**: diff --git a/tests/cpp_api/rocAL_video_unittests/samples/sequence_reader.png b/tests/cpp_api/video_tests/samples/sequence_reader.png similarity index 100% rename from tests/cpp_api/rocAL_video_unittests/samples/sequence_reader.png rename to tests/cpp_api/video_tests/samples/sequence_reader.png diff --git a/tests/cpp_api/rocAL_video_unittests/samples/sequence_rearrange.png b/tests/cpp_api/video_tests/samples/sequence_rearrange.png similarity index 100% rename from tests/cpp_api/rocAL_video_unittests/samples/sequence_rearrange.png rename to tests/cpp_api/video_tests/samples/sequence_rearrange.png diff --git a/tests/cpp_api/rocAL_video_unittests/samples/video_reader.png b/tests/cpp_api/video_tests/samples/video_reader.png similarity index 100% rename from tests/cpp_api/rocAL_video_unittests/samples/video_reader.png rename to tests/cpp_api/video_tests/samples/video_reader.png diff --git a/tests/cpp_api/rocAL_video_unittests/testScript.sh b/tests/cpp_api/video_tests/testScript.sh similarity index 86% rename from tests/cpp_api/rocAL_video_unittests/testScript.sh rename to tests/cpp_api/video_tests/testScript.sh index 728c90c3e..38f632d11 100755 --- a/tests/cpp_api/rocAL_video_unittests/testScript.sh +++ b/tests/cpp_api/video_tests/testScript.sh @@ -51,12 +51,12 @@ FILELIST_FRAMENUM=1 # enables file number or timestamps parsing for tex ENABLE_METADATA=0 # outputs labels and names of the associated frames ENABLE_FRAME_NUMBER=0 # outputs the starting frame numbers of the sequences in the batch ENABLE_TIMESTAMPS=0 # outputs timestamps of the frames in the batch -ENABLE_SEQUENCE_REARRANGE=0 # rearranges the frames in the sequence NOTE: The order needs to be set in the rocAL_video_unittests.cpp +ENABLE_SEQUENCE_REARRANGE=0 # rearranges the frames in the sequence NOTE: The order needs to be set in the video_tests.cpp -echo ./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ +echo ./video_tests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ $RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ $ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE -./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ +./video_tests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ $RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ $ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE diff --git a/tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp b/tests/cpp_api/video_tests/video_tests.cpp similarity index 97% rename from tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp rename to tests/cpp_api/video_tests/video_tests.cpp index dae9a3128..16996446f 100644 --- a/tests/cpp_api/rocAL_video_unittests/rocAL_video_unittests.cpp +++ b/tests/cpp_api/video_tests/video_tests.cpp @@ -67,7 +67,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_video_unittests \n"); + printf("Usage: video_tests \n"); return -1; } diff --git a/tests/cpp_api_tests/CMakeLists.txt b/tests/cpp_api_tests/CMakeLists.txt deleted file mode 100644 index b41c96906..000000000 --- a/tests/cpp_api_tests/CMakeLists.txt +++ /dev/null @@ -1,163 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required (VERSION 3.5) - -# rocal_basic_test -add_test( - NAME - rocAL_basic_test_cpu - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_basic_test" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_basic_test" - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 -) -add_test(NAME rocAL_basic_test_gpu - COMMAND rocal_basic_test - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 0 224 224 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) -add_test(NAME rocAL_basic_test_gray - COMMAND rocal_basic_test - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 0 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) -add_test(NAME rocAL_basic_test_rgb - COMMAND rocal_basic_test - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_basic_test) - -# TBD - rocAL_dataloader unit test options non-functional - NEEDS TO BE ADDED ONCE RESOLVED -#add_test( -# NAME -# rocAL_dataloader -# COMMAND -# "${CMAKE_CTEST_COMMAND}" -# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader" -# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader" -# --build-generator "${CMAKE_GENERATOR}" -# --test-command "rocal_dataloader" -# ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet -#) - -# rocal_dataloader_mt -add_test( - NAME - rocAL_dataloader_mt_cpu - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_mt" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_dataloader_mt" - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 0 -) -add_test(NAME rocAL_dataloader_mt_gpu - COMMAND rocal_dataloader_mt - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_mt) - -# TBD - rocAL_dataloader_tf unit test non-functional -#add_test( -# NAME -# rocAL_dataloader_tf -# COMMAND -# "${CMAKE_CTEST_COMMAND}" -# --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_dataloader_tf" -# "${CMAKE_CURRENT_BINARY_DIR}/rocAL_dataloader_tf" -# --build-generator "${CMAKE_GENERATOR}" -# --test-command "rocal_dataloader_tf" -# ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet -#) - -# rocal_performance_tests -# TBD - peformance test needs to run with default options -add_test( - NAME - rocAL_performance_tests_cpu - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_performance_tests" - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 0 -) -add_test(NAME rocAL_performance_tests_gpu - COMMAND rocal_performance_tests - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 16 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests) - -# rocal_performance_tests_with_depth -add_test( - NAME - rocAL_performance_tests_with_depth_cpu - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_performance_tests_with_depth" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_performance_tests_with_depth" - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 0 -) -add_test(NAME rocAL_performance_tests_with_depth_gpu - COMMAND rocal_performance_tests_with_depth - ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet 224 224 1 1 1 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_performance_tests_with_depth) - -# rocal_unittests -add_test( - NAME - rocAL_unittests_cpu - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_unittests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_unittests" - 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 0 1 -) -add_test(NAME rocAL_unittests_gpu - COMMAND rocal_unittests - 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) -add_test(NAME rocAL_unittests_gray - COMMAND rocal_unittests - 0 ${CMAKE_SOURCE_DIR}/data/images/AMD-tinyDataSet test 224 224 1 1 0 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/rocAL_unittests) - -# rocal_video_unittests -add_test( - NAME - rocAL_video_unittests - COMMAND - "${CMAKE_CTEST_COMMAND}" - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/rocAL_video_unittests" - "${CMAKE_CURRENT_BINARY_DIR}/rocAL_video_unittests" - --build-generator "${CMAKE_GENERATOR}" - --test-command "rocal_video_unittests" - ${CMAKE_SOURCE_DIR}/data/videos/AMD_driving_virtual_20.mp4 -) diff --git a/tests/cpp_api_tests/rocAL_basic_test/rocal_basic_test.cpp b/tests/cpp_api_tests/rocAL_basic_test/rocal_basic_test.cpp deleted file mode 100644 index a7a91e7ba..000000000 --- a/tests/cpp_api_tests/rocAL_basic_test/rocal_basic_test.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include - -#include "rocal_api.h" -#define TEST_2 - -#include "opencv2/opencv.hpp" -using namespace cv; -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define cvDestroyWindow destroyWindow -#endif -#define DISPLAY 0 -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - std::cout << "Usage: rocal_basic_test decode_width decode_height decode_shard_counts \n"; - return -1; - } - int argIdx = 0; - const char *folderPath1 = argv[++argIdx]; - const char *label_text_file_path = argv[++argIdx]; - int rgb = 1; // process color images - int decode_width = 0; - int decode_height = 0; - int test_case = 0; - bool processing_device = 0; - size_t decode_shard_counts = 1; - - if (argc >= argIdx + MIN_ARG_COUNT) - test_case = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_shard_counts = atoi(argv[++argIdx]); - - int inputBatchSize = 4; - - std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; - - auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor decoded_output; - - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - if (decode_height <= 0 || decode_width <= 0) - decoded_output = rocalJpegFileSource(handle, folderPath1, color_format, decode_shard_counts, false, false); - else - decoded_output = rocalJpegFileSource(handle, folderPath1, color_format, decode_shard_counts, false, false, false, - ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height); - if (strcmp(label_text_file_path, "") == 0) - rocalCreateLabelReader(handle, folderPath1); - else - rocalCreateTextFileBasedLabelReader(handle, label_text_file_path); - rocalCropResizeFixed(handle, decoded_output, 224, 224, true, 0.9, 1.1, 0.1, 0.1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - } - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; - int w = rocalGetOutputWidth(handle); - int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); - std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); - - const int total_tests = 4; - int test_id = -1; - int ImageNameLen[inputBatchSize]; - int run_len[] = {2 * inputBatchSize, 4 * inputBatchSize, 1 * inputBatchSize, 50 * inputBatchSize}; - - std::vector names; - names.resize(inputBatchSize); - - while (++test_id < total_tests) { - std::cout << "#### Started test id " << test_id << "\n"; - std::cout << "Available images = " << rocalGetRemainingImages(handle) << std::endl; - int process_image_count = ((test_case == 0) ? rocalGetRemainingImages(handle) : run_len[test_id]); - std::cout << ">>>>> Going to process " << process_image_count << " images , press a key" << std::endl; - if (DISPLAY) - cv::waitKey(0); - const unsigned number_of_cols = process_image_count / inputBatchSize; - cv::Mat mat_output(h, w * number_of_cols, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - auto win_name = "output"; - if (DISPLAY) - cv::namedWindow(win_name, CV_WINDOW_AUTOSIZE); - - int col_counter = 0; - int counter = 0; - - while ((test_case == 0) ? !rocalIsEmpty(handle) : (counter < run_len[test_id])) { - if (rocalRun(handle) != 0) - break; - - rocalCopyToOutput(handle, mat_input.data, h * w * p); - - counter += inputBatchSize; - RocalTensorList labels = rocalGetImageLabels(handle); - - unsigned imagename_size = rocalGetImageNameLen(handle, ImageNameLen); - char imageNames[imagename_size]; - rocalGetImageName(handle, imageNames); - std::string imageNamesStr(imageNames); - - int pos = 0; - int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); - for (int i = 0; i < inputBatchSize; i++) { - names[i] = imageNamesStr.substr(pos, ImageNameLen[i]); - pos += ImageNameLen[i]; - std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - " << std::endl; - } - std::cout << std::endl; - - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - if (DISPLAY) - cv::imshow(win_name, mat_output); - else - cv::imwrite("output.png", mat_output); - } else { - if (DISPLAY) - cv::imshow(win_name, mat_output); - else - cv::imwrite("output.png", mat_output); - } - // The delay here simulates possible latency between runs due to training - if (DISPLAY) - cv::waitKey(200); - col_counter = (col_counter + 1) % number_of_cols; - } - std::cout << ">>>>> Done test id " << test_id << " processed " << counter << " images ,press a key \n"; - if (DISPLAY) - cv::waitKey(0); - std::cout << "#### Going to reset\n"; - rocalResetLoaders(handle); - mat_input.release(); - mat_output.release(); - mat_color.release(); - if (DISPLAY) - cvDestroyWindow(win_name); - std::cout << "#### Done reset\n"; - } - - rocalRelease(handle); - - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_dataloader/CMakeLists.txt b/tests/cpp_api_tests/rocAL_dataloader/CMakeLists.txt deleted file mode 100644 index 2e3e0b25e..000000000 --- a/tests/cpp_api_tests/rocAL_dataloader/CMakeLists.txt +++ /dev/null @@ -1,98 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required (VERSION 3.5) - -project(rocal_dataloader) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/cpp_api_tests/rocAL_dataloader/rocAL_dataloader.cpp b/tests/cpp_api_tests/rocAL_dataloader/rocAL_dataloader.cpp deleted file mode 100644 index 540efd196..000000000 --- a/tests/cpp_api_tests/rocAL_dataloader/rocAL_dataloader.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define cvDestroyWindow destroyWindow -#endif - -#define DISPLAY -using namespace std::chrono; - -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf("Usage: image_augmentation decode_width decode_height batch_size display_on_off \n"); - return -1; - } - int argIdx = 0; - const char *folderPath1 = argv[++argIdx]; - bool display = 0; // Display the images - // int aug_depth = 1;// how deep is the augmentation tree - int decode_width = 32; - int decode_height = 32; - int inputBatchSize = 4; - bool processing_device = 1; - - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - inputBatchSize = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - display = atoi(argv[++argIdx]); - - std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; - // The cifar10 dataloader only supports ROCAL_COLOR_RGB_PLANAR - RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; - - auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - // Creating uniformly distributed random objects to override some of the default augmentation parameters - // RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand( 0.3, 0.5 ); - // RocalIntParam color_temp_adj = rocalCreateIntParameter(0); - - // Creating a custom random object to set a limited number of values to randomize the rotation angle - // create Cifar10 meta data reader - // rocalCreateTextCifar10LabelReader(handle, folderPath1, "data_batch"); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - // create Cifar10 meta data reader - rocalCreateTextCifar10LabelReader(handle, folderPath1, "data_batch"); - RocalTensor input0; - input0 = rocalRawCIFAR10Source(handle, folderPath1, color_format, false, decode_width, decode_height, "data_batch_", false); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "rawCIFAR10 source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } -#if 0 - const size_t num_values = 3; - float values[num_values] = {0,10,135}; - double frequencies[num_values] = {1, 5, 5}; - - RocalFloatParam rand_angle = rocalCreateFloatRand( values , frequencies, num_values); - // Creating successive blur nodes to simulate a deep branch of augmentations - RocalTensor input2 = rocalCropResize(handle, input0, resize_w, resize_h, false, rand_crop_area); - for(int i = 0 ; i < aug_depth; i++) - { - input2 = rocalBlurFixed(handle, input2, 17.25, (i == (aug_depth -1)) ? true:false ); - } - - RocalTensor input4 = rocalColorTemp(handle, input0, false, color_temp_adj); - - RocalTensor input5 = rocalWarpAffine(handle, input4, false); - - RocalTensor input6 = rocalJitter(handle, input5, false); - - rocalVignette(handle, input6, true); - - RocalTensor input7 = rocalPixelate(handle, input0, false); - - RocalTensor input8 = rocalSnow(handle, input0, false); - - RocalTensor input9 = rocalBlend(handle, input7, input8, false); - - RocalTensor input10 = rocalLensCorrection(handle, input9, false); - - rocalExposure(handle, input10, true); -#else - // uncomment the following to add augmentation if needed - // just do one augmentation to test - rocalRain(handle, input0, true); -#endif - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - } - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; - - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int n = rocalGetAugmentationBranchCount(handle); - int h = n * rocalGetOutputHeight(handle) * inputBatchSize; - int w = rocalGetOutputWidth(handle); - int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || - (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) - ? 3 - : 1); - std::cout << "output width " << w << " output height " << h << " color planes " << p << " n " << n << std::endl; - const unsigned number_of_cols = 1; // no augmented case - auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h, w * number_of_cols, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - int col_counter = 0; - - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int counter = 0; - std::vector names; - int image_name_length[inputBatchSize]; - names.resize(inputBatchSize); - int iter_cnt = 0; - while (!rocalIsEmpty(handle) && (iter_cnt < 100)) { - if (rocalRun(handle) != 0) - break; - rocalCopyToOutput(handle, mat_input.data, h * w * p); - counter += inputBatchSize; - RocalTensorList labels = rocalGetImageLabels(handle); - unsigned img_name_size = rocalGetImageNameLen(handle, image_name_length); - char img_name[img_name_size]; - rocalGetImageName(handle, img_name); - std::string image_name(img_name); - int pos = 0; - int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); - for (int i = 0; i < inputBatchSize; i++) { - names[i] = image_name.substr(pos, image_name_length[i]); - pos += image_name_length[i]; - std::cout << "name: " << names[i] << " label: " << labels_buffer[i] << " - "; - } - std::cout << std::endl; - iter_cnt++; - - if (!display) - continue; - - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - - if (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - // convert planar to packed for OPENCV - for (int j = 0; j < n; j++) { - int const single_h = rocalGetOutputHeight(handle); - for (int n = 0; n < inputBatchSize; n++) { - unsigned channel_size = w * single_h * p; - unsigned char *interleavedp = mat_output.data + channel_size * n; - unsigned char *planarp = mat_input.data + channel_size * n; - for (int i = 0; i < (w * single_h); i++) { - interleavedp[i * 3 + 0] = planarp[i + 0 * w * single_h]; - interleavedp[i * 3 + 1] = planarp[i + 1 * w * single_h]; - interleavedp[i * 3 + 2] = planarp[i + 2 * w * single_h]; - } - } - } - cv::imwrite("output.png", mat_output); - } - // Cifar10 dataloader only supports ROCAL_COLOR_RGB_PLANAR - cv::waitKey(1); - col_counter = (col_counter + 1) % number_of_cols; - } - - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_dataloader_mt/README.md b/tests/cpp_api_tests/rocAL_dataloader_mt/README.md deleted file mode 100644 index c60f54596..000000000 --- a/tests/cpp_api_tests/rocAL_dataloader_mt/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# rocAL_dataloader_mt application -This application demonstrates a basic usage of rocAL's C API to use sharded data_loader in a multithreaded application. -

- -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* ROCm Performance Primitives (RPP) - -### build - ```` - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib - mkdir build - cd build - cmake ../ - make - ```` -### running the application - ```` - rocAL_dataloader_mt =1)/(cpu:0)> - ```` diff --git a/tests/cpp_api_tests/rocAL_dataloader_tf/CMakeLists.txt b/tests/cpp_api_tests/rocAL_dataloader_tf/CMakeLists.txt deleted file mode 100644 index 2b5b286fa..000000000 --- a/tests/cpp_api_tests/rocAL_dataloader_tf/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project(rocal_dataloader_tf) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api_tests/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp b/tests/cpp_api_tests/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp deleted file mode 100644 index 6fc4d6b6e..000000000 --- a/tests/cpp_api_tests/rocAL_dataloader_tf/rocAL_dataloader_tf.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define cvDestroyWindow destroyWindow -#endif - -#define DISPLAY 0 -using namespace std::chrono; - -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_dataloader_tf display_on_off \n"); - return -1; - } - int argIdx = 0; - const char *folderPath1 = argv[++argIdx]; - bool display = 0; // Display the images - // int aug_depth = 1;// how deep is the augmentation tree - int rgb = 0; // process gray images - int decode_width = 28; // mnist data_set - int decode_height = 28; - int inputBatchSize = 16; - bool processing_device = 1; - - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - inputBatchSize = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - display = atoi(argv[++argIdx]); - - std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; - RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_U8; - if (rgb == 0) - color_format = RocalImageColor::ROCAL_COLOR_U8; - else if (rgb == 1) - color_format = RocalImageColor::ROCAL_COLOR_RGB24; - else if (rgb == 2) - color_format = RocalImageColor::ROCAL_COLOR_RGB_PLANAR; - - auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor decoded_output; - // hardcoding the following for mnist tfrecords - std::string feature_map_image = "image/encoded"; - std::string feature_map_filename = "image/filename"; - std::string feature_map_label = "image/class/label"; - - rocalCreateTFReader(handle, folderPath1, 1, feature_map_label.c_str(), feature_map_filename.c_str()); - decoded_output = rocalJpegTFRecordSource(handle, folderPath1, color_format, 1, false, feature_map_image.c_str(), feature_map_filename.c_str(), false, false, ROCAL_USE_USER_GIVEN_SIZE, decode_width, decode_height); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - -#if 0 - const size_t num_values = 3; - float values[num_values] = {0,10,135}; - double frequencies[num_values] = {1, 5, 5}; - - RocalFloatParam rand_angle = rocalCreateFloatRand( values , frequencies, num_values); - // Creating successive blur nodes to simulate a deep branch of augmentations - RocalTensor input2 = rocalCropResize(handle, decoded_output, resize_w, resize_h, false, rand_crop_area);; - for(int i = 0 ; i < aug_depth; i++) - { - input2 = rocalBlurFixed(handle, input2, 17.25, (i == (aug_depth -1)) ? true:false ); - } - - - RocalTensor input4 = rocalColorTemp(handle, decoded_output, false, color_temp_adj); - - RocalTensor input5 = rocalWarpAffine(handle, input4, false); - - RocalTensor input6 = rocalJitter(handle, input5, false); - - rocalVignette(handle, input6, true); - - - - RocalTensor input7 = rocalPixelate(handle, decoded_output, false); - - RocalTensor input8 = rocalSnow(handle, decoded_output, false); - - RocalTensor input9 = rocalBlend(handle, input7, input8, false); - - RocalTensor image10 = rocalLensCorrection(handle, input9, false); - - rocalExposure(handle, image10, true); -#else - // uncomment the following to add augmentation if needed - // just do one augmentation to test - rocalResize(handle, decoded_output, 300, 300, true); -#endif - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - } - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; - - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int n = rocalGetAugmentationBranchCount(handle); - int h = n * rocalGetOutputHeight(handle) * inputBatchSize; - int w = rocalGetOutputWidth(handle); - int p = (((color_format == RocalImageColor::ROCAL_COLOR_RGB24) || - (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR)) - ? 3 - : 1); - printf("After get output dims\n"); - std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; - const unsigned number_of_cols = 1; // no augmented case - printf("Before memalloc\n"); - - auto cv_color_format = ((p == 3) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h, w * number_of_cols, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - int col_counter = 0; - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int counter = 0; - std::vector names; - names.resize(inputBatchSize); - int ImageNameLen[inputBatchSize]; - - int iter_cnt = 0; - while (!rocalIsEmpty(handle) && (iter_cnt < 100)) { - // if ((iter_cnt %16) == 0) - printf("Processing iter: %d\n", iter_cnt); - if (rocalRun(handle) != 0) { - std::cout << "rocalRun Failed" << std::endl; - break; - } - - rocalCopyToOutput(handle, mat_input.data, h * w * p); - counter += inputBatchSize; - - RocalTensorList labels = rocalGetImageLabels(handle); - unsigned img_name_size = rocalGetImageNameLen(handle, ImageNameLen); - char img_name[img_name_size]; - rocalGetImageName(handle, img_name); - std::string imageNamesStr(img_name); - int pos = 0; - int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); - for (int i = 0; i < inputBatchSize; i++) { - names[i] = imageNamesStr.substr(pos, ImageNameLen[i]); - pos += ImageNameLen[i]; - std::cout << "\n name: " << names[i] << " label: " << labels_buffer[i] << std::endl; - } - std::cout << std::endl; - - iter_cnt++; - if (!display) - continue; - - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::Mat mat_color; - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - if (DISPLAY) - cv::imshow("output", mat_output); - else - cv::imwrite("output.png", mat_output); - } else if (color_format == RocalImageColor::ROCAL_COLOR_RGB_PLANAR) { - // convert planar to packed for OPENCV - for (int j = 0; j < n; j++) { - int const kWidth = w; - int const kHeight = rocalGetOutputHeight(handle); - int single_h = kHeight / inputBatchSize; - for (int n = 0; n < inputBatchSize; n++) { - unsigned channel_size = kWidth * single_h * p; - unsigned char *interleavedp = mat_output.data + channel_size * n; - unsigned char *planarp = mat_input.data + channel_size * n; - for (int i = 0; i < (kWidth * single_h); i++) { - interleavedp[i * 3 + 0] = planarp[i + 0 * kWidth * single_h]; - interleavedp[i * 3 + 1] = planarp[i + 1 * kWidth * single_h]; - interleavedp[i * 3 + 2] = planarp[i + 2 * kWidth * single_h]; - } - } - } - if (DISPLAY) - cv::imshow("output", mat_output); - else - cv::imwrite("output.png", mat_output); - } else { - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); - if (DISPLAY) - cv::imshow("output", mat_output); - else - cv::imwrite("output.png", mat_output); - } - if (DISPLAY) - cv::waitKey(1); - col_counter = (col_counter + 1) % number_of_cols; - } - - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_external_source/README.md b/tests/cpp_api_tests/rocAL_external_source/README.md deleted file mode 100644 index acaf18f52..000000000 --- a/tests/cpp_api_tests/rocAL_external_source/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# rocal_external_source application - -This application demonstrates a basic usage of rocAL's C++ API to load images from external source and add augmentations and displays the output images. - -## Build Instructions - -### Pre-requisites - -* Ubuntu Linux, [version `18.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* ROCm Performance Primitives (RPP) - -### build - - ````bash - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/rpp/lib - mkdir build - cd build - cmake ../ - make - ```` - -### running the application - - ````bash - rocal_external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode - ```` diff --git a/tests/cpp_api_tests/rocAL_performance_tests/CMakeLists.txt b/tests/cpp_api_tests/rocAL_performance_tests/CMakeLists.txt deleted file mode 100644 index 0d235c805..000000000 --- a/tests/cpp_api_tests/rocAL_performance_tests/CMakeLists.txt +++ /dev/null @@ -1,98 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project (rocal_performance_tests) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/cpp_api_tests/rocAL_performance_tests/rocAL_performance_tests.cpp b/tests/cpp_api_tests/rocAL_performance_tests/rocAL_performance_tests.cpp deleted file mode 100644 index 0ebfe69d6..000000000 --- a/tests/cpp_api_tests/rocAL_performance_tests/rocAL_performance_tests.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define cvDestroyWindow destroyWindow -#endif - -#define DISPLAY -using namespace std::chrono; - -int test(int test_case, const char* path, int rgb, int processing_device, int width, int height, int batch_size, int shards, int shuffle); -int main(int argc, const char** argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - printf("Usage: rocal_performance_tests \n"); - if (argc < MIN_ARG_COUNT) - return -1; - - int argIdx = 0; - const char* path = argv[++argIdx]; - int width = atoi(argv[++argIdx]); - int height = atoi(argv[++argIdx]); - - int rgb = 1; // process color images - bool processing_device = 1; - int test_case = 0; - int batch_size = 10; - int shards = 4; - int shuffle = 0; - - if (argc >= argIdx + MIN_ARG_COUNT) - test_case = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - batch_size = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - shards = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - shuffle = atoi(argv[++argIdx]); - - test(test_case, path, rgb, processing_device, width, height, batch_size, shards, shuffle); - - return 0; -} - -int test(int test_case, const char* path, int rgb, int processing_device, int width, int height, int batch_size, int shards, int shuffle) { - size_t num_threads = shards; - int inputBatchSize = batch_size; - int decode_max_width = 0; - int decode_max_height = 0; - std::cout << ">>> test case " << test_case << std::endl; - std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; - printf(">>> Batch size = %d -- shard count = %lu\n", inputBatchSize, num_threads); - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; - - auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal context\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - rocalSetSeed(0); - - // Creating uniformly distributed random objects to override some of the default augmentation parameters - RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); - RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); - - // Creating a custom random object to set a limited number of values to randomize the rotation angle - const size_t num_values = 3; - float values[num_values] = {0, 10, 135}; - double frequencies[num_values] = {1, 5, 5}; - RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, - sizeof(values) / sizeof(values[0])); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor tensor0; - RocalTensor tensor0_b; - - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - if (decode_max_height <= 0 || decode_max_width <= 0) - tensor0 = rocalJpegFileSource(handle, path, color_format, num_threads, false, shuffle, true); - else - tensor0 = rocalJpegFileSource(handle, path, color_format, num_threads, false, shuffle, false, - ROCAL_USE_USER_GIVEN_SIZE, decode_max_width, decode_max_height); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - int resize_w = width, resize_h = height; - - switch (test_case) { - case 0: { - std::cout << ">>>>>>> Running " - << "rocalResize" << std::endl; - rocalResize(handle, tensor0, resize_w, resize_h, true); - } break; - case 1: { - std::cout << ">>>>>>> Running " - << "rocalCropResize" << std::endl; - rocalCropResize(handle, tensor0, resize_w, resize_h, true, rand_crop_area); - } break; - case 2: { - std::cout << ">>>>>>> Running " - << "rocalRotate" << std::endl; - rocalRotate(handle, tensor0, true, rand_angle); - } break; - case 3: { - std::cout << ">>>>>>> Running " - << "rocalBrightness" << std::endl; - rocalBrightness(handle, tensor0, true); - } break; - case 4: { - std::cout << ">>>>>>> Running " - << "rocalGamma" << std::endl; - rocalGamma(handle, tensor0, true); - } break; - case 5: { - std::cout << ">>>>>>> Running " - << "rocalContrast" << std::endl; - rocalContrast(handle, tensor0, true); - } break; - case 6: { - std::cout << ">>>>>>> Running " - << "rocalFlip" << std::endl; - rocalFlip(handle, tensor0, true); - } break; - case 7: { - std::cout << ">>>>>>> Running " - << "rocalBlur" << std::endl; - rocalBlur(handle, tensor0, true); - } break; - case 8: { - std::cout << ">>>>>>> Running " - << "rocalBlend" << std::endl; - tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); - rocalBlend(handle, tensor0, tensor0_b, true); - } break; - case 9: { - std::cout << ">>>>>>> Running " - << "rocalWarpAffine" << std::endl; - rocalWarpAffine(handle, tensor0, true); - } break; - case 10: { - std::cout << ">>>>>>> Running " - << "rocalFishEye" << std::endl; - rocalFishEye(handle, tensor0, true); - } break; - case 11: { - std::cout << ">>>>>>> Running " - << "rocalVignette" << std::endl; - rocalVignette(handle, tensor0, true); - } break; - case 12: { - std::cout << ">>>>>>> Running " - << "rocalJitter" << std::endl; - rocalJitter(handle, tensor0, true); - } break; - case 13: { - std::cout << ">>>>>>> Running " - << "rocalSnPNoise" << std::endl; - rocalSnPNoise(handle, tensor0, true); - } break; - case 14: { - std::cout << ">>>>>>> Running " - << "rocalSnow" << std::endl; - rocalSnow(handle, tensor0, true); - } break; - case 15: { - std::cout << ">>>>>>> Running " - << "rocalRain" << std::endl; - rocalRain(handle, tensor0, true); - } break; - case 16: { - std::cout << ">>>>>>> Running " - << "rocalColorTemp" << std::endl; - rocalColorTemp(handle, tensor0, true, color_temp_adj); - } break; - case 17: { - std::cout << ">>>>>>> Running " - << "rocalFog" << std::endl; - rocalFog(handle, tensor0, true); - } break; - case 18: { - std::cout << ">>>>>>> Running " - << "rocalLensCorrection" << std::endl; - rocalLensCorrection(handle, tensor0, true); - } break; - case 19: { - std::cout << ">>>>>>> Running " - << "rocalPixelate" << std::endl; - rocalPixelate(handle, tensor0, true); - } break; - case 20: { - std::cout << ">>>>>>> Running " - << "rocalExposure" << std::endl; - rocalExposure(handle, tensor0, true); - } break; - case 21: { - std::cout << ">>>>>>> Running " - << "rocalHue" << std::endl; - rocalHue(handle, tensor0, true); - } break; - case 22: { - std::cout << ">>>>>>> Running " - << "rocalSaturation" << std::endl; - rocalSaturation(handle, tensor0, true); - } break; - case 23: { - std::cout << ">>>>>>> Running " - << "rocalCopy" << std::endl; - rocalCopy(handle, tensor0, true); - } break; - case 24: { - std::cout << ">>>>>>> Running " - << "rocalColorTwist" << std::endl; - rocalColorTwist(handle, tensor0, true); - } break; - case 25: { - std::cout << ">>>>>>> Running " - << "rocalCropMirrorNormalize" << std::endl; - std::vector mean; - std::vector std_dev; - rocalCropMirrorNormalize(handle, tensor0, 200, 200, 50, 50, mean, std_dev, true); - } break; - case 26: { - std::cout << ">>>>>>> Running " - << "rocalCrop " << std::endl; - rocalCrop(handle, tensor0, true); - } break; - case 27: { - std::cout << ">>>>>>> Running " - << "rocalResizeCropMirror" << std::endl; - rocalResizeCropMirror(handle, tensor0, resize_w, resize_h, true); - } break; - case 28: { - std::cout << ">>>>>>> Running " - << "No-Op" << std::endl; - rocalNop(handle, tensor0, true); - } break; - default: - std::cout << "Not a valid option! Exiting!\n"; - return -1; - } - - // Calling the API to verify and build the augmentation graph - rocalVerify(handle); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); - return -1; - } - - printf("Augmented copies count %lu\n", rocalGetAugmentationBranchCount(handle)); - - printf("Going to process images\n"); - // printf("Remaining images %d \n", rocalGetRemainingImages(handle)); - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - - int i = 0; - while (i++ < 100 && !rocalIsEmpty(handle)) { - if (rocalRun(handle) != 0) - break; - - // auto last_colot_temp = rocalGetIntValue(color_temp_adj); - // rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); - - // rocalCopyToOutput(handle, mat_input.data, h * w * p); - } - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << "Total time " << dur << std::endl; - std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - - rocalRelease(handle); - - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/README.md b/tests/cpp_api_tests/rocAL_performance_tests_with_depth/README.md deleted file mode 100644 index b1c190e26..000000000 --- a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# rocAL Performance Tests with Depth -This application can be used to run performance tests on rocAL graphs with depth greater than 1. -This is very similar to the rocAL Performance Tests app except it takes an extra parameter to specify depth. - -## Build Instructions - -### Pre-requisites -* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) -* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher -* ROCm Performance Primitives (RPP) - -### build - ```` - mkdir build - cd build - cmake ../ - make - ```` -### running the application - ```` -rocAL_performance_tests_with_depth [test image folder] [image width] [image height] [test case] [batch size] [graph depth] [0 for CPU, 1 for GPU] [0 for grayscale, 1 for RGB] - ```` diff --git a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp b/tests/cpp_api_tests/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp deleted file mode 100644 index 082af2bb6..000000000 --- a/tests/cpp_api_tests/rocAL_performance_tests_with_depth/rocAL_performance_tests_with_depth.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; - -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#endif - -#define DISPLAY 0 -using namespace std::chrono; - -int test(int test_case, const char* path, int rgb, int gpu, int width, int height, int batch_size, int graph_depth); -int main(int argc, const char** argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - printf("Usage: image_augmentation test_case batch_size graph_depth gpu=1/cpu=0 rgb=1/grayscale =0 \n"); - if (argc < MIN_ARG_COUNT) - return -1; - - int argIdx = 0; - const char* path = argv[++argIdx]; - int width = atoi(argv[++argIdx]); - int height = atoi(argv[++argIdx]); - - int rgb = 1; // process color images - bool gpu = 1; - int test_case = 0; - int batch_size = 10; - int graph_depth = 1; - - if (argc >= argIdx + MIN_ARG_COUNT) - test_case = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - batch_size = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - graph_depth = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - gpu = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - test(test_case, path, rgb, gpu, width, height, batch_size, graph_depth); - - return 0; -} - -int test(int test_case, const char* path, int rgb, int gpu, int width, int height, int batch_size, int graph_depth) { - size_t num_threads = 1; - int inputBatchSize = 1; - int decode_max_width = width; - int decode_max_height = height; - std::cout << ">>> test case " << test_case << std::endl; - std::cout << ">>> Running on " << (gpu ? "GPU" : "CPU") << " , " << (rgb ? " Color " : " Grayscale ") << std::endl; - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 - : RocalImageColor::ROCAL_COLOR_U8; - - auto handle = rocalCreate(inputBatchSize, - gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, - 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - - /*>>>>>>>>>>>>>>>> Creating Rocal parameters <<<<<<<<<<<<<<<<*/ - - rocalSetSeed(0); - - // Creating uniformly distributed random objects to override some of the default augmentation parameters - RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); - RocalIntParam color_temp_adj = rocalCreateIntParameter(-50); - - // Creating a custom random object to set a limited number of values to randomize the rotation angle - const size_t num_values = 3; - float values[num_values] = {0, 10, 135}; - double frequencies[num_values] = {1, 5, 5}; - RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, - sizeof(values) / sizeof(values[0])); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor input_image; - RocalTensor tensor0; - RocalTensor tensor0_b; - - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - if (decode_max_height <= 0 || decode_max_width <= 0) - input_image = rocalJpegFileSource(handle, path, color_format, num_threads, false, true); - else - input_image = rocalJpegFileSource(handle, path, color_format, num_threads, false, true, false, - ROCAL_USE_USER_GIVEN_SIZE, decode_max_width, decode_max_height); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - int resize_w = width, resize_h = height; - - switch (test_case) { - case 0: { - std::cout << ">>>>>>> Running " - << "rocalResize" << std::endl; - - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalResize(handle, tensor0, resize_w, resize_h, true); - } - } - } break; - case 1: { - std::cout << ">>>>>>> Running " - << "rocalCropResize" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalCropResize(handle, tensor0, resize_w, resize_h, true, rand_crop_area); - } - } - } break; - case 2: { - std::cout << ">>>>>>> Running " - << "rocalCropResizeFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalCropResizeFixed(handle, tensor0, resize_w, resize_h, true, 0.25, 1.2, 0.6, 0.4); - } - } - } break; - case 3: { - std::cout << ">>>>>>> Running " - << "rocalRotate" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalRotate(handle, tensor0, true, rand_angle); - } - } - } break; - case 4: { - std::cout << ">>>>>>> Running " - << "rocalRotateFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalRotateFixed(handle, tensor0, 45, true, resize_w, resize_h); - } - } - } break; - case 5: { - std::cout << ">>>>>>> Running " - << "rocalBrightness" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalBrightness(handle, tensor0, true); - } - } - } break; - case 6: { - std::cout << ">>>>>>> Running " - << "rocalBrightnessFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalBrightnessFixed(handle, tensor0, 4, 50, true); - } - } - } break; - case 7: { - std::cout << ">>>>>>> Running " - << "rocalGamma" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalGamma(handle, tensor0, true); - } - } - } break; - case 8: { - std::cout << ">>>>>>> Running " - << "rocalGammaFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalGammaFixed(handle, tensor0, 0.5, true); - } - } - } break; - case 9: { - std::cout << ">>>>>>> Running " - << "rocalContrast" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalContrast(handle, tensor0, true); - } - } - } break; - case 10: { - std::cout << ">>>>>>> Running " - << "rocalContrastFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalContrastFixed(handle, tensor0, 30, 380, true); - } - } - } break; - case 11: { - std::cout << ">>>>>>> Running " - << "rocalFlip horizontal" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalFlip(handle, tensor0, true); - } - } - } break; - case 12: { - std::cout << ">>>>>>> Running " - << "rocalFlip vertical" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalFlip(handle, tensor0, true); - } - } - } break; - case 13: { - std::cout << ">>>>>>> Running " - << "rocalBlur" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalBlur(handle, tensor0, true); - } - } - } break; - case 14: { - std::cout << ">>>>>>> Running " - << "rocalBlurFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalBlurFixed(handle, tensor0, 17.25, true); - } - } - } break; - case 15: { - std::cout << ">>>>>>> Running " - << "rocalBlend" << std::endl; - - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalBlend(handle, tensor0, tensor0_b, true); - } - } - } break; - case 16: { - std::cout << ">>>>>>> Running " - << "rocalBlendFixed" << std::endl; - tensor0 = input_image; - tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - tensor0_b = rocalRotateFixed(handle, tensor0, 30, false); - for (int k = 0; k < graph_depth; k++) { - rocalBlendFixed(handle, tensor0, tensor0_b, 0.5, true); - } - } - } break; - - case 17: { - std::cout << ">>>>>>> Running " - << "rocalWarpAffine" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalWarpAffine(handle, tensor0, true); - } - } - } break; - case 18: { - std::cout << ">>>>>>> Running " - << "rocalWarpAffineFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalWarpAffineFixed(handle, tensor0, true, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5); - } - } - } break; - case 19: { - std::cout << ">>>>>>> Running " - << "rocalFishEye" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalFishEye(handle, tensor0, true); - } - } - } break; - case 20: { - std::cout << ">>>>>>> Running " - << "rocalVignette" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalVignette(handle, tensor0, true); - } - } - } break; - case 21: { - std::cout << ">>>>>>> Running " - << "rocalVignetteFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalVignetteFixed(handle, tensor0, 40, true); - } - } - } break; - case 22: { - std::cout << ">>>>>>> Running " - << "rocalJitter" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalJitter(handle, tensor0, true); - } - } - } break; - case 23: { - std::cout << ">>>>>>> Running " - << "rocalJitterFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalJitterFixed(handle, tensor0, 3, true); - } - } - } break; - case 24: { - std::cout << ">>>>>>> Running " - << "rocalSnPNoise" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalSnPNoise(handle, tensor0, true); - } - } - } break; - case 25: { - std::cout << ">>>>>>> Running " - << "rocalSnPNoiseFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalSnPNoiseFixed(handle, tensor0, true, 0.2, 0.2, 0.2, 0.5, 0); - } - } - } break; - case 26: { - std::cout << ">>>>>>> Running " - << "rocalSnow" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalSnow(handle, tensor0, true); - } - } - } break; - case 27: { - std::cout << ">>>>>>> Running " - << "rocalSnowFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalSnowFixed(handle, tensor0, 0.5, true); - } - } - } break; - case 28: { - std::cout << ">>>>>>> Running " - << "rocalRain" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalRain(handle, tensor0, true); - } - } - } break; - case 29: { - std::cout << ">>>>>>> Running " - << "rocalRainFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalRainFixed(handle, tensor0, 0.5, 2, 16, 0.25, true); - } - } - } break; - case 30: { - std::cout << ">>>>>>> Running " - << "rocalColorTemp" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalColorTemp(handle, tensor0, true, color_temp_adj); - } - } - } break; - case 31: { - std::cout << ">>>>>>> Running " - << "rocalColorTempFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalColorTempFixed(handle, tensor0, 70, true); - } - } - } break; - case 32: { - std::cout << ">>>>>>> Running " - << "rocalFog" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalFog(handle, tensor0, true); - } - } - } break; - case 33: { - std::cout << ">>>>>>> Running " - << "rocalFogFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalFogFixed(handle, tensor0, true, 2.5); - } - } - } break; - case 34: { - std::cout << ">>>>>>> Running " - << "rocalLensCorrection" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalLensCorrection(handle, tensor0, true); - } - } - } break; - case 35: { - std::cout << ">>>>>>> Running " - << "rocalLensCorrectionFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalLensCorrectionFixed(handle, tensor0, 2.9, 1.5, true); - } - } - } break; - case 36: { - std::cout << ">>>>>>> Running " - << "rocalPixelate" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalPixelate(handle, tensor0, true); - } - } - } break; - case 37: { - std::cout << ">>>>>>> Running " - << "rocalExposure" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalExposure(handle, tensor0, true); - } - } - } break; - case 38: { - std::cout << ">>>>>>> Running " - << "rocalExposureFixed" << std::endl; - for (int j = 0; j < batch_size; j++) { - tensor0 = input_image; - for (int k = 0; k < graph_depth; k++) { - tensor0 = rocalExposureFixed(handle, tensor0, 1, true); - } - } - } break; - default: - std::cout << "Not a valid option! Exiting!\n"; - return -1; - } - - // Calling the API to verify and build the augmentation graph - rocalVerify(handle); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph " << rocalGetErrorMessage(handle); - return -1; - } - - printf("Augmented copies count %lu\n", rocalGetAugmentationBranchCount(handle)); - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle); - int w = rocalGetOutputWidth(handle); - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h, w, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - if (DISPLAY) - cv::namedWindow("output", CV_WINDOW_AUTOSIZE); - printf("Going to process images\n"); - printf("Remaining images %lu \n", rocalGetRemainingImages(handle)); - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - - int i = 0; - while (i++ < 1000) { - if (rocalRun(handle) != 0) - break; - - auto last_colot_temp = rocalGetIntValue(color_temp_adj); - rocalUpdateIntParameter(last_colot_temp + 1, color_temp_adj); - - // rocalCopyToOutput(handle, mat_input.data, h * w * p); - } - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_unittests/pixel_comparison/image_comparison.py b/tests/cpp_api_tests/rocAL_unittests/pixel_comparison/image_comparison.py deleted file mode 100644 index f2aa93c62..000000000 --- a/tests/cpp_api_tests/rocAL_unittests/pixel_comparison/image_comparison.py +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright (c) 2023 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. - -from PIL import Image -import os -import sys -import datetime -import logging - - -def compare_pixels(img1, img2, aug_name, width, height, image_offset=0): - pixel_difference = [0, 0, 0, 0, 0, 0] - if "rgb" in aug_name: - pixels1 = img1.load() - pixels2 = img2.load() - channel = 3 - else: - pixels1 = img1.convert("L").load() - pixels2 = img2.convert("L").load() - channel = 1 - total_valid_pixel_count = width * height * channel - for wt in range(width): - for ht in range(height): - ht = ht + image_offset - if pixels1[wt, ht] != pixels2[wt, ht]: - if channel == 1: - diff_val = abs(pixels1[wt, ht] - pixels2[wt, ht]) - diff_val = min(diff_val, 5) - pixel_difference[diff_val] += 1 - else: - for ch in range(channel): - diff_val = abs( - pixels1[wt, ht][ch] - pixels2[wt, ht][ch]) - diff_val = min(diff_val, 5) - pixel_difference[diff_val] += 1 - else: - pixel_difference[0] += channel - return pixel_difference, total_valid_pixel_count - - -def main(): - timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S_") - handlers = [ - logging.FileHandler("./rocal_unittest_log_file_" + timestamp + ".log"), - logging.StreamHandler(), - ] - logging.basicConfig(level=logging.INFO, handlers=handlers) - if len(sys.argv) < 3: - print("Please pass ref_output_folder_path rocal_ouput_folder_path") - logging.error( - "Please pass ref_output_folder_path rocal_ouput_folder_path") - exit(0) - - # Open the two images - ref_output_path = sys.argv[1] - rocal_output_path = sys.argv[2] - - if not (os.path.exists(ref_output_path) and os.path.exists(rocal_output_path)): - logging.error("Path does not Exists") - exit() - - total_case_count = 0 - passed_case_count = 0 - failed_case_count = 0 - failed_case_list = [] - golden_output_dir_list = os.listdir(ref_output_path) - rocal_output_dir_list = os.listdir(rocal_output_path) - randomized_augmentation = ["Snow", "Rain", "Jitter", "SNPNoise"] - golden_file_path = "" - for aug_name in rocal_output_dir_list: - temp = aug_name.split(".") - file_name_split = temp[0].split("_") - if len(file_name_split) > 3: - file_name_split.pop() - golden_file_path = "_".join(file_name_split) + ".png" - else: - golden_file_path = aug_name - - # For randomized augmentation - if file_name_split[0] in randomized_augmentation: - total_case_count = total_case_count + 1 - augmentation_name = aug_name.split(".")[0] - logging.info("Running %s", augmentation_name) - passed_case_count = passed_case_count + 1 - logging.info("PASSED ") - elif golden_file_path in golden_output_dir_list: - total_case_count = total_case_count + 1 - ref_file_path = ref_output_path + golden_file_path - rocal_file_path = rocal_output_path + aug_name - if os.path.exists(rocal_file_path) and os.path.exists(ref_file_path): - logging.info("Running %s ", aug_name.split(".")[0]) - img1 = Image.open(ref_file_path) - img2 = Image.open(rocal_file_path) - - # Check if the images have the same dimensions - if img1.size != img2.size: - logging.info( - "Golden output and augmentation outputs are having different sizes. Exiting!") - exit() - - # Compare the pixel values for each image - pixel_diff = None - total_count = 0 - if "larger" in aug_name: - resize_width = 400 - resize_height = 300 - image_offset = 400 - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, resize_width, resize_height) - pixel_diff2, total_count2 = compare_pixels( - img1, img2, aug_name, resize_width, resize_height, image_offset) - pixel_diff = [x + y for x, - y in zip(pixel_diff, pixel_diff2)] - total_count = total_count + total_count2 - elif "smaller" in aug_name: - resize_width = 533 - resize_height = 400 - image_offset = 2400 - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, resize_width, resize_height) - pixel_diff2, total_count2 = compare_pixels( - img1, img2, aug_name, resize_width, resize_height, image_offset) - pixel_diff = [x + y for x, - y in zip(pixel_diff, pixel_diff2)] - total_count = total_count + total_count2 - else: - pixel_diff, total_count = compare_pixels( - img1, img2, aug_name, img1.size[0], img1.size[1]) - total_pixel_diff = 0 - for pix_diff in range(1, 6): - total_pixel_diff += pixel_diff[pix_diff] - mismatch_percentage = round( - (total_pixel_diff / total_count) * 100, 2) - if ((total_pixel_diff == 0) or (mismatch_percentage < 5.0 and pixel_diff[1] == total_pixel_diff) or # Ignore test cases with single pixel differences less than 5% of total pixel count - (mismatch_percentage < 0.5 and ("Blend" in aug_name or "Rotate" in aug_name) and "hip" in aug_name)): # Ignore mismatch in rotate augmentation less than 0.5% of total pixel count - passed_case_count = passed_case_count + 1 - logging.info("PASSED") - else: - failed_case_list.append(golden_file_path) - failed_case_count = failed_case_count + 1 - logging.info("FAILED") - logging.info("Printing pixel mismatch %s", pixel_diff) - logging.info("Mismatach percentage %0.2f", - mismatch_percentage) - for pix_diff in range(1, 6): - logging.info("Percentage of %d pixel mismatch %0.2f", pix_diff, round( - (pixel_diff[pix_diff] / total_pixel_diff) * 100, 2)) - else: - logging.info( - "Skipping the testcase as file not found %s", rocal_file_path) - else: - logging.info("File not found in ref_output_folder %s", - golden_file_path) - if len(failed_case_list) != 0: - logging.info("Failing cases: {}".format(", ".join(failed_case_list))) - logging.info( - "Total case passed --> {} / {} ".format(passed_case_count, total_case_count)) - logging.info( - "Total case failed --> {} / {} ".format(failed_case_count, total_case_count)) - - -if __name__ == "__main__": - main() diff --git a/tests/cpp_api_tests/rocAL_unittests/testAllScripts.sh b/tests/cpp_api_tests/rocAL_unittests/testAllScripts.sh deleted file mode 100755 index b41bd95b3..000000000 --- a/tests/cpp_api_tests/rocAL_unittests/testAllScripts.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash -cwd=$(pwd) -if [ -d build ];then - sudo rm -rf ./build/* -else - mkdir build -fi -cd build || exit -cmake .. -make -j"$(nproc)" - -if [[ $ROCAL_DATA_PATH == "" ]] -then - echo "Need to export ROCAL_DATA_PATH" - exit -fi - -# Path to inputs and outputs available in MIVisionX-data -image_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -coco_detection_path=${ROCAL_DATA_PATH}/rocal_data/coco/coco_10_img/train_10images_2017/ -tf_classification_path=${ROCAL_DATA_PATH}/rocal_data/tf/classification/ -tf_detection_path=${ROCAL_DATA_PATH}/rocal_data/tf/detection/ -caffe_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe/classification/ -caffe_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe/detection/ -caffe2_classification_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/classification/ -caffe2_detection_path=${ROCAL_DATA_PATH}/rocal_data/caffe2/detection/ -mxnet_path=${ROCAL_DATA_PATH}/rocal_data/mxnet/ -output_path=../rocal_unittest_output_folder_$(date +%Y-%m-%d_%H-%M-%S)/ -golden_output_path=${ROCAL_DATA_PATH}/rocal_data/GoldenOutputsTensor/ - -display=0 -device=0 -width=640 -height=480 -device_name="host" -rgb_name=("gray" "rgb") -rgb=1 -dev_start=0 -dev_end=1 -rgb_start=0 -rgb_end=1 - -if [ "$#" -gt 0 ]; then - if [ "$1" -eq 0 ]; then # For only HOST backend - dev_start=0 - dev_end=0 - elif [ "$1" -eq 1 ]; then # For only HIP backend - dev_start=1 - dev_end=1 - elif [ "$1" -eq 2 ]; then # For both HOST and HIP backend - dev_start=0 - dev_end=1 - fi -fi - -if [ "$#" -gt 1 ]; then - if [ "$2" -eq 0 ]; then # For only Greyscale inputs - rgb_start=0 - rgb_end=0 - elif [ "$2" -eq 1 ]; then # For only RGB inputs - rgb_start=1 - rgb_end=1 - elif [ "$2" -eq 2 ]; then # For both RGB and Greyscale inputs - rgb_start=0 - rgb_end=1 - fi -fi - -mkdir "$output_path" - -for ((device=dev_start;device<=dev_end;device++)) -do - if [ $device -eq 1 ] - then - device_name="hip" - echo "Running HIP Backend..." - else - echo "Running HOST Backend..." - fi - for ((rgb=rgb_start;rgb<=rgb_end;rgb++)) - do - # FileSource Reader - ./rocal_unittests 0 "$image_path" "${output_path}LensCorrection_${rgb_name[$rgb]}_${device_name}" $width $height 45 $device $rgb 0 $display - ./rocal_unittests 0 "$image_path" "${output_path}Exposure_${rgb_name[$rgb]}_${device_name}" $width $height 46 $device $rgb 0 $display - ./rocal_unittests 0 "$image_path" "${output_path}Flip_${rgb_name[$rgb]}_${device_name}" $width $height 47 $device $rgb 0 $display - - # FileSource Reader + partial decoder - ./rocal_unittests 1 "$image_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 41 $device $rgb 0 $display - ./rocal_unittests 1 "$image_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 42 $device $rgb 0 $display - ./rocal_unittests 1 "$image_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_FileReader_partial" $width $height 40 $device $rgb 0 $display - - # coco detection - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Gamma_${rgb_name[$rgb]}_${device_name}" $width $height 33 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Contrast_${rgb_name[$rgb]}_${device_name}" $width $height 34 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Vignette_${rgb_name[$rgb]}_${device_name}" $width $height 38 $device $rgb 0 $display - - # coco detection + partial decoder - ./rocal_unittests 3 "$coco_detection_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 41 $device $rgb 0 $display - ./rocal_unittests 3 "$coco_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 42 $device $rgb 0 $display - ./rocal_unittests 3 "$coco_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}_coco_partial" $width $height 40 $device $rgb 0 $display - - # tf classification - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blend_${rgb_name[$rgb]}_${device_name}" $width $height 36 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}WarpAffine_${rgb_name[$rgb]}_${device_name}" $width $height 37 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Blur_${rgb_name[$rgb]}_${device_name}" $width $height 35 $device $rgb 0 $display - - # tf detection - ./rocal_unittests 5 "$tf_detection_path" "${output_path}SNPNoise_${rgb_name[$rgb]}_${device_name}" $width $height 40 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}ColorTemp_${rgb_name[$rgb]}_${device_name}" $width $height 43 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Fog_${rgb_name[$rgb]}_${device_name}" $width $height 44 $device $rgb 0 $display - - # caffe classification - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Rotate_${rgb_name[$rgb]}_${device_name}" $width $height 31 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Brightness_${rgb_name[$rgb]}_${device_name}" $width $height 32 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Hue_${rgb_name[$rgb]}_${device_name}" $width $height 48 $device $rgb 0 $display - - # caffe detection - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Saturation_${rgb_name[$rgb]}_${device_name}" $width $height 49 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}ColorTwist_${rgb_name[$rgb]}_${device_name}" $width $height 50 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Rain_${rgb_name[$rgb]}_${device_name}" $width $height 42 $device $rgb 0 $display - - # caffe2 classification - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropCenter_${rgb_name[$rgb]}_${device_name}" $width $height 52 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}ResizeCropMirror_${rgb_name[$rgb]}_${device_name}" $width $height 53 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Snow_${rgb_name[$rgb]}_${device_name}" $width $height 41 $device $rgb 0 $display - - # caffe2 detection - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}FishEye_${rgb_name[$rgb]}_${device_name}" $width $height 10 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropCenterCMN_${rgb_name[$rgb]}_${device_name}" $width $height 55 $device $rgb 0 $display - - # mxnet - ./rocal_unittests 11 "$mxnet_path" "${output_path}Jitter_${rgb_name[$rgb]}_${device_name}" $width $height 39 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}Pixelate_${rgb_name[$rgb]}_${device_name}" $width $height 19 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display - - # CMN - ./rocal_unittests 0 "$image_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_coco" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 25 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}CropMirrorNormalize_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 25 $device $rgb 0 $display - - # crop - ./rocal_unittests 0 "$image_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_FileReader" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_coco" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfClassification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_tfDetection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeClassification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffeDetection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Classification" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_caffe2Detection" $width $height 51 $device $rgb 0 $display - ./rocal_unittests 11 "$mxnet_path" "${output_path}Crop_${rgb_name[$rgb]}_${device_name}_mxnet" $width $height 51 $device $rgb 0 $display - - # resize - # Last two parameters are interpolation type and scaling mode - ./rocal_unittests 0 "$image_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_default_FileReader" $width $height 0 $device $rgb 0 $display 1 0 - ./rocal_unittests 2 "$coco_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_stretch_coco" $width $height 0 $device $rgb 0 $display 1 1 - ./rocal_unittests 4 "$tf_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notsmaller_tfClassification" $width $height 0 $device $rgb 0 $display 1 2 - ./rocal_unittests 5 "$tf_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bilinear_notlarger_tfDetection" $width $height 0 $device $rgb 0 $display 1 3 - ./rocal_unittests 6 "$caffe_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_bicubic_default_caffeClassification" $width $height 0 $device $rgb 0 $display 2 0 - # ./rocal_unittests 7 "$caffe_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_nearestneighbor_default_caffeDetection" $width $height 0 $device $rgb 0 $display 0 0 - ./rocal_unittests 8 "$caffe2_classification_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_lanczos_default_caffe2Classification" $width $height 0 $device $rgb 0 $display 3 0 - ./rocal_unittests 9 "$caffe2_detection_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_triangular_default_caffe2Detection" $width $height 0 $device $rgb 0 $display 5 0 - ./rocal_unittests 11 "$mxnet_path" "${output_path}Resize_${rgb_name[$rgb]}_${device_name}_gaussian_default_mxnet" $width $height 0 $device $rgb 0 $display 4 0 - - done -done - -pwd - -# Run python script to compare rocAL outputs with golden ouptuts -python3 "$cwd"/pixel_comparison/image_comparison.py "$golden_output_path" "$output_path" diff --git a/tests/cpp_api_tests/rocAL_video_unittests/CMakeLists.txt b/tests/cpp_api_tests/rocAL_video_unittests/CMakeLists.txt deleted file mode 100644 index 81bec5c67..000000000 --- a/tests/cpp_api_tests/rocAL_video_unittests/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2018 - 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ -cmake_minimum_required(VERSION 3.5) - -project (rocal_video_unittests) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") - -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) - -include_directories(${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/lib/) -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - endif() -else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") -endif() - -target_link_libraries(${PROJECT_NAME} rocal) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api_tests/rocAL_video_unittests/rocAL_video_unittests.cpp b/tests/cpp_api_tests/rocAL_video_unittests/rocAL_video_unittests.cpp deleted file mode 100644 index dae9a3128..000000000 --- a/tests/cpp_api_tests/rocAL_video_unittests/rocAL_video_unittests.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* -MIT License - -Copyright (c) 2020 - 2023 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 - -#include -#include -#include -#include -#include -#include - -#include "opencv2/opencv.hpp" -#include "rocal_api.h" -using namespace cv; - -#if USE_OPENCV_4 -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#endif - -using namespace std::chrono; - -bool IsPathExist(const char *s) { - struct stat buffer; - return (stat(s, &buffer) == 0); -} - -int check_extension(std::string file_name) { - // store the position of last '.' in the file name - int position = file_name.find_last_of("."); - // store the characters after the '.' from the file_name string - std::string result = file_name.substr(position + 1); - if ((result.compare("txt") == 0) || (result.size() == 0) || (result.compare("mp4") == 0)) - return -1; - return 0; -} - -int main(int argc, const char **argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf("Usage: rocal_video_unittests \n"); - return -1; - } - - int argIdx = 0; - const char *source_path = argv[++argIdx]; - int reader_case = 0; - bool save_frames = 1; // Saves the frames - int rgb = 1; // process color images - unsigned resize_width = 0; - unsigned resize_height = 0; - bool processing_device = 1; - size_t shard_count = 1; - bool shuffle = false; - unsigned input_batch_size = 1; - unsigned sequence_length = 1; - unsigned ouput_frames_per_sequence = 1; - unsigned frame_step = 1; - unsigned frame_stride = 1; - bool file_list_frame_num = true; - bool enable_metadata = false; - bool enable_framenumbers = false; - bool enable_timestamps = true; - bool enable_sequence_rearrange = false; - bool is_output = true; - unsigned hardware_decode_mode = 0; - if (argc >= argIdx + MIN_ARG_COUNT) - reader_case = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - hardware_decode_mode = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - input_batch_size = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - ouput_frames_per_sequence = sequence_length = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - frame_step = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - frame_stride = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - save_frames = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - shuffle = atoi(argv[++argIdx]) ? true : false; - if (argc >= argIdx + MIN_ARG_COUNT) - resize_width = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - resize_height = atoi(argv[++argIdx]); - if (argc >= argIdx + MIN_ARG_COUNT) - file_list_frame_num = atoi(argv[++argIdx]) ? true : false; - if (argc >= argIdx + MIN_ARG_COUNT) - enable_metadata = atoi(argv[++argIdx]) ? true : false; - if (argc >= argIdx + MIN_ARG_COUNT) - enable_framenumbers = atoi(argv[++argIdx]) ? true : false; - if (argc >= argIdx + MIN_ARG_COUNT) - enable_timestamps = atoi(argv[++argIdx]) ? true : false; - if (argc >= argIdx + MIN_ARG_COUNT) - enable_sequence_rearrange = atoi(argv[++argIdx]) ? true : false; - - auto decoder_mode = ((hardware_decode_mode == 1) ? RocalDecodeDevice::ROCAL_HW_DECODE : RocalDecodeDevice::ROCAL_SW_DECODE); - if (!IsPathExist(source_path)) { - std::cout << "\nThe folder/file path does not exist\n"; - return -1; - } - if (enable_sequence_rearrange) { - is_output = false; - } - std::cerr << "Batch size : " << input_batch_size << std::endl; - std::cerr << "Sequence length : " << sequence_length << std::endl; - std::cerr << "Frame step : " << frame_step << std::endl; - std::cerr << "Frame stride : " << frame_stride << std::endl; - if (reader_case == 2) { - std::cerr << "Resize Width : " << resize_width << std::endl; - std::cerr << "Resize height : " << resize_height << std::endl; - } - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; - RocalContext handle; - handle = rocalCreate(input_batch_size, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the Rocal contex\n"; - return -1; - } - if (reader_case == 3) { - if (check_extension(source_path) < 0) { - std::cerr << "\n[ERR] Text file/ Video File passed as input to SEQUENCE READER\n"; - return -1; - } - if (enable_metadata) { - std::cout << "METADATA cannot be enabled for SEQUENCE READER"; - enable_metadata = false; - } - if (enable_framenumbers) - enable_framenumbers = false; - if (enable_timestamps) - enable_timestamps = false; - } else if (enable_metadata) { - std::cout << "\n>>>> META DATA READER\n"; - rocalCreateVideoLabelReader(handle, source_path, sequence_length, frame_step, frame_stride, file_list_frame_num); - } - - RocalTensor input1; - switch (reader_case) { - default: { - std::cout << "\n>>>> VIDEO READER\n"; - input1 = rocalVideoFileSource(handle, source_path, color_format, decoder_mode, shard_count, sequence_length, shuffle, is_output, false, frame_step, frame_stride, file_list_frame_num); - break; - } - case 2: { - std::cout << "\n>>>> VIDEO READER RESIZE\n"; - if (resize_width == 0 || resize_height == 0) { - std::cerr << "\n[ERR]Resize width and height are passed as NULL values\n"; - return -1; - } - input1 = rocalVideoFileResize(handle, source_path, color_format, decoder_mode, shard_count, sequence_length, resize_width, resize_height, shuffle, is_output, false, frame_step, frame_stride, file_list_frame_num); - break; - } - case 3: { - std::cout << "\n>>>> SEQUENCE READER\n"; - enable_framenumbers = enable_timestamps = 0; - input1 = rocalSequenceReader(handle, source_path, color_format, shard_count, sequence_length, is_output, shuffle, false, frame_step, frame_stride); - break; - } - } - if (enable_sequence_rearrange) { - std::cout << "\n>>>> ENABLE SEQUENCE REARRANGE\n"; - std::vector new_order = {0, 0, 1, 1, 0}; // The integers in new order should range only from 0 to sequence_length - 1 - ouput_frames_per_sequence = new_order.size(); - input1 = rocalSequenceRearrange(handle, input1, new_order, true); - } - RocalIntParam color_temp_adj = rocalCreateIntParameter(0); - - // Calling the API to verify and build the augmentation graph - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cerr << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - } - - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cerr << "[ERR]Could not verify the augmentation graph" << std::endl; - return -1; - } - std::cout << "\nRemaining images " << rocalGetRemainingImages(handle) << std::endl; - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - if (save_frames) - mkdir("output_frames", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // Create directory in which images will be stored - int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * input_batch_size * ouput_frames_per_sequence; - int w = rocalGetOutputWidth(handle); - int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); - int single_image_height = h / (input_batch_size * ouput_frames_per_sequence); - std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color, mat_output; - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int counter = 0; - int color_temp_increment = 1; - int count = 0; - while (!rocalIsEmpty(handle)) { - count++; - if (rocalRun(handle) != 0) - break; - - if (rocalGetIntValue(color_temp_adj) <= -99 || rocalGetIntValue(color_temp_adj) >= 99) - color_temp_increment *= -1; - - rocalUpdateIntParameter(rocalGetIntValue(color_temp_adj) + color_temp_increment, color_temp_adj); - rocalCopyToOutput(handle, mat_input.data, h * w * p); - counter += input_batch_size; - if (save_frames) { - std::string batch_path = "output_frames/" + std::to_string(count); - int status = mkdir(batch_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (status) continue; - for (unsigned b = 0; b < input_batch_size; b++) // Iterates over each sequence in the batch - { - std::string seq_path = batch_path + "/seq_" + std::to_string(b); - std::string save_video_path = seq_path + "_output_video.avi"; - - int frame_width = static_cast(w); // get the width of frames of the video - int frame_height = static_cast(single_image_height); // get the height of frames of the video - Size frame_size(frame_width, frame_height); - int frames_per_second = 10; - - // Create and initialize the VideoWriter object - VideoWriter video_writer(save_video_path, VideoWriter::fourcc('M', 'J', 'P', 'G'), - frames_per_second, frame_size, true); - // If the VideoWriter object is not initialized successfully, exit the program - if (video_writer.isOpened() == false) { - std::cout << "Cannot save the video to a file" << std::endl; - return -1; - } - - for (unsigned i = 0; i < ouput_frames_per_sequence; i++) // Iterates over the frames in each sequence - { - std::string save_image_path = seq_path + "_output_" + std::to_string(i) + ".png"; - mat_output = mat_input(cv::Rect(0, ((b * single_image_height * ouput_frames_per_sequence) + (i * single_image_height)), w, single_image_height)); - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - cv::imwrite(save_image_path, mat_color); - video_writer.write(mat_color); - } else { - cv::imwrite(save_image_path, mat_output); - video_writer.write(mat_output); - } - } - video_writer.release(); - } - } - if (enable_metadata) { - int image_name_length[input_batch_size]; - RocalTensorList labels = rocalGetImageLabels(handle); - int img_size = rocalGetImageNameLen(handle, image_name_length); - char img_name[img_size]; - rocalGetImageName(handle, img_name); - - std::cout << "\nPrinting image names of batch: " << img_name << "\n"; - std::cout << "\t Printing label_id : "; - int *label_id = reinterpret_cast(labels->at(0)->buffer()); - for (unsigned i = 0; i < input_batch_size; i++) { - std::cout << label_id[i] << "\t"; - } - std::cout << std::endl; - } - if (enable_framenumbers || enable_timestamps) { - unsigned int start_frame_num[input_batch_size]; - float frame_timestamps[input_batch_size * sequence_length]; - rocalGetSequenceStartFrameNumber(handle, start_frame_num); - if (enable_timestamps) { - rocalGetSequenceFrameTimestamps(handle, frame_timestamps); - } - for (unsigned i = 0; i < input_batch_size; i++) { - if (enable_framenumbers) - std::cout << "\nFrame number : " << start_frame_num[i] << std::endl; - if (enable_timestamps) - for (unsigned j = 0; j < sequence_length; j++) - std::cout << "T" << j << " : " << frame_timestamps[(i * sequence_length) + j] << "\t"; - std::cout << "\n"; - } - } - } - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - return 0; -} diff --git a/tests/cpp_api_tests/rocAL_video_unittests/samples/sequence_reader.png b/tests/cpp_api_tests/rocAL_video_unittests/samples/sequence_reader.png deleted file mode 100644 index b55c66e8e3264850ba4e0460e80bf2f32e00b760..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12447 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 YSmxL6iLnrZ7B5FwWkvky|2+x+U!@Jp!vFvP diff --git a/tests/cpp_api_tests/rocAL_video_unittests/testScript.sh b/tests/cpp_api_tests/rocAL_video_unittests/testScript.sh deleted file mode 100755 index 728c90c3e..000000000 --- a/tests/cpp_api_tests/rocAL_video_unittests/testScript.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -################ AVAILABLE READERS ###################### -## DEFAULT : VideoReader ## -## READER_CASE 2 : VideoReaderResize ## -## READER_CASE 3 : SequenceReader ## -######################################################### -INPUT_PATH=$1 -READER_CASE=$2 - -if [ -z "$INPUT_PATH" ] - then - echo "No input argument supplied" - exit -fi - -# Handles relative input path -if [ ! -d "$INPUT_PATH" & [[ "$INPUT_PATH" != /* ]] -then - CWD=$(pwd) - INPUT_PATH="$CWD/$INPUT_PATH" -fi - -if [ -z "$READER_CASE" ] - then - READER_CASE=1 -fi - -# Building video unit test -sudo rm -rvf build* -mkdir build -cd build || exit -cmake .. -make - -# Arguments used in video unit test -SAVE_FRAMES=1 # (save_frames:on/off) -RGB=1 # (rgb:1/gray:0) -DEVICE=0 # (cpu:0/gpu:1) -HARDWARE_DECODE_MODE=0 # (hardware_decode_mode:on/off) -SHUFFLE=0 # (shuffle:on/off) - -BATCH_SIZE=1 # Number of sequences per batch -SEQUENCE_LENGTH=3 # Number of frames per sequence -STEP=3 # Frame interval from one sequence to another sequence -STRIDE=1 # Frame interval within frames in a sequences -RESIZE_WIDTH=1280 # width with which frames should be resized (applicable only for READER_CASE 2) -RESIZE_HEIGHT=720 # height with which frames should be resized (applicable only for READER_CASE 2) - -FILELIST_FRAMENUM=1 # enables file number or timestamps parsing for text file input -ENABLE_METADATA=0 # outputs labels and names of the associated frames -ENABLE_FRAME_NUMBER=0 # outputs the starting frame numbers of the sequences in the batch -ENABLE_TIMESTAMPS=0 # outputs timestamps of the frames in the batch -ENABLE_SEQUENCE_REARRANGE=0 # rearranges the frames in the sequence NOTE: The order needs to be set in the rocAL_video_unittests.cpp - -echo ./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ -$RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ -$ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE - -./rocal_video_unittests "$INPUT_PATH" $READER_CASE $DEVICE $HARDWARE_DECODE_MODE $BATCH_SIZE $SEQUENCE_LENGTH $STEP $STRIDE \ -$RGB $SAVE_FRAMES $SHUFFLE $RESIZE_WIDTH $RESIZE_HEIGHT $FILELIST_FRAMENUM \ -$ENABLE_METADATA $ENABLE_FRAME_NUMBER $ENABLE_TIMESTAMPS $ENABLE_SEQUENCE_REARRANGE diff --git a/tests/python_api/readers_test_file.sh b/tests/python_api/readers_test_file.sh index d5ddd4a9a..4a1051da9 100755 --- a/tests/python_api/readers_test_file.sh +++ b/tests/python_api/readers_test_file.sh @@ -94,30 +94,30 @@ ver=$(python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2 #################################################################################################################################### # USER TO MAKE CHANGES HERE FOR TEST # Make the respective " Pipeline " to test equal to 1 -rocAL_api_python_unittest=1 +unit_test=1 coco_pipeline=1 caffe_reader=1 caffe2_reader=1 -rocAL_api_tf_classification_reader=1 -rocAL_api_tf_detection_pipeline=1 -rocAL_api_video_pipeline=1 +tf_classification_reader=1 +tf_detection_pipeline=1 +video_pipeline=1 #################################################################################################################################### #################################################################################################################################### -if [[ rocAL_api_python_unittest -eq 1 ]]; then +if [[ unit_test -eq 1 ]]; then # Mention dataset_path data_dir=$ROCAL_DATA_PATH/rocal_data/images_jpg/labels_folder/ - # rocAL_api_python_unittest.py + # unit_test.py # By default : cpu backend, NCHW format , fp32 # Please pass image_folder augmentation_nanme in addition to other common args # Refer rocAL_api_python_unitest.py for all augmentation names - python"$ver" rocAL_api_python_unittest.py \ + python"$ver" unit_test.py \ --image-dataset-path $data_dir \ --augmentation-name snow \ --batch-size $batch_size \ @@ -274,16 +274,16 @@ fi #################################################################################################################################### -if [[ rocAL_api_tf_classification_reader -eq 1 ]]; then +if [[ tf_classification_reader -eq 1 ]]; then # Mention dataset_path # Classification data_dir=$ROCAL_DATA_PATH/rocal_data/tf/classification/ - # rocAL_api_tf_classification_reader.py + # tf_classification_reader.py # By default : cpu backend, NCHW format , fp32 # use --classification for Classification / --no-classification for Detection - python"$ver" rocAL_api_tf_classification_reader.py \ + python"$ver" tf_classification_reader.py \ --image-dataset-path $data_dir \ --classification \ --batch-size $batch_size \ @@ -300,16 +300,16 @@ fi #################################################################################################################################### -if [[ rocAL_api_tf_detection_pipeline -eq 1 ]]; then +if [[ tf_detection_pipeline -eq 1 ]]; then # Mention dataset_path # Detection data_dir=$ROCAL_DATA_PATH/rocal_data/tf/detection/ - # rocAL_api_tf_detection_pipeline.py + # tf_detection_pipeline.py # By default : cpu backend, NCHW format , fp32 # use --classification for Classification / --no-classification for Detection - python"$ver" rocAL_api_tf_detection_pipeline.py \ + python"$ver" tf_detection_pipeline.py \ --image-dataset-path $data_dir \ --no-classification \ --batch-size 100 \ @@ -326,15 +326,15 @@ fi #################################################################################################################################### -if [[ rocAL_api_video_pipeline -eq 1 ]]; then +if [[ video_pipeline -eq 1 ]]; then # Mention dataset_path # Detection data_dir=$ROCAL_DATA_PATH/rocal_data/video_and_sequence_samples/labelled_videos/ - # rocAL_api_video_pipeline.py + # video_pipeline.py # By default : cpu backend, NCHW format , fp32 - python"$ver" rocAL_api_video_pipeline.py \ + python"$ver" video_pipeline.py \ --video-path $data_dir \ --$backend_arg \ --batch-size 10 \ From 6672d48aef1463af14504193554f38eb8101e1ba Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 09:13:05 -0700 Subject: [PATCH 06/21] readme and link clean up --- CHANGELOG.md | 8 +++---- CMakeLists.txt | 2 +- README.md | 14 ++++++------ apps/README.md | 2 +- .../image_augmentation/image_augmentation.cpp | 2 +- copyright.txt | 2 +- docker/README.md | 2 +- docker/rocal-on-rhel-09.dockerfile | 4 ++-- ...buntu-20-with-pytorch-with-mesa.dockerfile | 4 ++-- docker/rocal-on-ubuntu-20.dockerfile | 2 +- docker/rocal-on-ubuntu-22.dockerfile | 2 +- docker/rocal-with-pytorch.dockerfile | 2 +- docker/rocal-with-tensorflow.dockerfile | 2 +- docs/README.md | 13 +++++------ docs/examples.md | 4 ++-- docs/how-to/using-with-python.rst | 12 +++++----- docs/user_guide/ch1.md | 2 +- docs/user_guide/ch2.md | 2 +- docs/user_guide/ch3.md | 16 +++++++------- docs/user_guide/ch5.md | 22 +++++++++---------- docs/user_guide/ch6.md | 16 +++++++------- rocAL-setup.py | 2 +- rocAL_pybind/README.md | 7 +++--- .../performance_tests_with_depth/README.md | 2 +- tests/cpp_api/unit_tests/README.md | 4 ++-- tests/cpp_api/video_tests/README.md | 12 +++++----- 26 files changed, 81 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ef3d92ae..d76038692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ## Online Documentation -[rocAL Documentation](https://github.com/ROCmSoftwarePlatform/rocAL) +[rocAL Documentation](https://github.com/ROCm/rocAL) ## rocAL 1.0.0 (unreleased) @@ -28,12 +28,12 @@ * Linux distribution + Ubuntu - `20.04` / `22.04` -* ROCm: rocm-core - `5.4.0.50400-72` +* ROCm: rocm-core - `6.0.60002-1` * Protobuf - [V3.12.4](https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.4) * OpenCV - [4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) -* RPP - [1.2.0](https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp/releases/tag/1.2.0) +* RPP - [1.4.0](https://github.com/ROCms/rpp/releases/tag/1.4.0) * FFMPEG - [n4.4.2](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2) -* MIVisionX - [master](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX) +* MIVisionX - [master](https://github.com/ROCm/MIVisionX) * Dependencies for all the above packages * rocAL Setup Script - `V1.0.2` diff --git a/CMakeLists.txt b/CMakeLists.txt index ee15be3a9..93766916f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ set(CPACK_PACKAGE_CONTACT "rocAL Support ") set(CPACK_PACKAGE_VENDOR "AMD Radeon") set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/docs/data/rocAL_logo.png") set(CPACK_PACKAGE_GROUP "Development/Tools") -set(CPACK_PACKAGE_HOMEPAGE "https://github.com/ROCmSoftwarePlatform/rocAL") +set(CPACK_PACKAGE_HOMEPAGE "https://github.com/ROCm/rocAL") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "AMD rocAL is a comprehensive Augmentation Library The AMD ROCm Augmentation Library (rocAL) is designed to efficiently decode and process images \ diff --git a/README.md b/README.md index 21d95b031..b524f3515 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,8 @@ rocAL can be currently used to perform the following operations either with rand + RedHat - `8` / `9` + SLES - `15-SP4` * [ROCm](https://rocmdocs.amd.com/en/latest/deploy/linux/installer/install.html) with --usecase=graphics,rocm -* [AMD RPP](https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp) - MIVisionX Component -* [AMD OpenVX™](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` - MIVisionX Components +* [AMD RPP](https://github.com/ROCm/rpp) - MIVisionX Component +* [AMD OpenVX™](https://github.com/ROCm/MIVisionX/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` - MIVisionX Components * [Turbo JPEG](https://libjpeg-turbo.org/) - Version 2.0.6.2 from `https://github.com/rrawther/libjpeg-turbo.git` * [Half-precision floating-point](https://half.sourceforge.net) library - Version `1.12.0` or higher * [Google Protobuf](https://developers.google.com/protocol-buffers) - Version `3.12.4` or higher @@ -131,7 +131,7 @@ For the convenience of the developer, we here provide the setup script which wil + Clone rocAL source code ``` - git clone https://github.com/ROCmSoftwarePlatform/rocAL.git + git clone https://github.com/ROCm/rocAL.git cd rocAL ``` **Note:** rocAL supports **CPU** and two **GPU** backends: **OPENCL**/**HIP**: @@ -153,7 +153,7 @@ For the convenience of the developer, we here provide the setup script which wil sudo make install ``` - + run tests - [test option instructions](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/wiki/CTest) + + run tests - [test option instructions](https://github.com/ROCm/MIVisionX/wiki/CTest) ``` make test ``` @@ -174,13 +174,13 @@ For the convenience of the developer, we here provide the setup script which wil + RedHat - `8` / `9` + SLES - `15-SP4` * ROCm: rocm-core - `5.7.0.50700-6` -* RPP - [1.2.0](https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp/releases/tag/1.2.0) -* MIVisionX - [master](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX) +* RPP - [1.2.0](https://github.com/ROCm/rpp/releases/tag/1.2.0) +* MIVisionX - [master](https://github.com/ROCm/MIVisionX) * Protobuf - [V3.12.4](https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.4) * OpenCV - [4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) * FFMPEG - [n4.4.2](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2) * RapidJSON- [master](https://github.com/Tencent/rapidjson) * PyBind11 - [v2.10.4](https://github.com/pybind/pybind11) -* CuPy - [v12.2.0](https://github.com/ROCmSoftwarePlatform/cupy/releases/tag/v12.0.0) +* CuPy - [v12.2.0](https://github.com/ROCm/cupy/releases/tag/v12.0.0) * rocAL Setup Script - `V1.0.2` * Dependencies for all the above packages diff --git a/apps/README.md b/apps/README.md index f0bc10718..4205215fe 100644 --- a/apps/README.md +++ b/apps/README.md @@ -3,7 +3,7 @@ rocAL has several applications built on top of AMD optimized libraries that can be used as prototypes or used as models to develop products. ## Prerequisites -* [rocAL](https://github.com/ROCmSoftwarePlatform/rocAL) +* [rocAL](https://github.com/ROCm/rocAL) ## Image Augmentation diff --git a/apps/image_augmentation/image_augmentation.cpp b/apps/image_augmentation/image_augmentation.cpp index a21b89393..73154d35a 100644 --- a/apps/image_augmentation/image_augmentation.cpp +++ b/apps/image_augmentation/image_augmentation.cpp @@ -213,7 +213,7 @@ int main(int argc, const char** argv) { AMD_ROCm_Black_resize = cv::imread("../../../samples/images/rocm-black-resize.png"); int fontFace = CV_FONT_HERSHEY_DUPLEX; int thickness = 1.3; - std::string bufferName = "MIVisionX Image Augmentation"; + std::string bufferName = "rocAL Image Augmentation"; int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; int w = rocalGetOutputWidth(handle); diff --git a/copyright.txt b/copyright.txt index c6c3df3a2..f0c87eebd 100644 --- a/copyright.txt +++ b/copyright.txt @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: rocAL -Source: https://github.com/ROCmSoftwarePlatform/rocAL.git +Source: https://github.com/ROCm/rocAL.git Files: * Copyright: 2022 - 2023 Advanced Micro Devices, Inc. diff --git a/docker/README.md b/docker/README.md index 91399d4e5..aa204cffe 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,6 +1,6 @@ # rocAL Docker -Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. [Read More](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/wiki/Docker) +Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. [Read More](https://github.com/ROCm/MIVisionX/wiki/Docker) ## Build - dockerfiles diff --git a/docker/rocal-on-rhel-09.dockerfile b/docker/rocal-on-rhel-09.dockerfile index fbfd4a760..7e8028255 100644 --- a/docker/rocal-on-rhel-09.dockerfile +++ b/docker/rocal-on-rhel-09.dockerfile @@ -26,12 +26,12 @@ RUN apt-get update -y && apt-get -y install autoconf automake libbz2-dev libssl- RUN apt-get -y install sqlite3 libsqlite3-dev libtool build-essential RUN git clone -b v3.21.9 https://github.com/protocolbuffers/protobuf.git && cd protobuf && git submodule update --init --recursive && \ ./autogen.sh && ./configure && make -j8 && make check -j8 && sudo make install && sudo ldconfig && cd -RUN git clone -b 0.99 https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp.git && cd rpp && mkdir build && cd build && \ +RUN git clone -b 0.99 https://github.com/ROCm/rpp.git && cd rpp && mkdir build && cd build && \ cmake -DBACKEND=HIP ../ && make -j4 && sudo make install && cd ENV ROCAL_WORKSPACE=/workspace WORKDIR $ROCAL_WORKSPACE # Install MIVisionX -RUN git clone https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX.git && \ +RUN git clone https://github.com/ROCm/MIVisionX.git && \ mkdir build && cd build && cmake -DBACKEND=HIP ../MIVisionX && make -j8 && make install \ No newline at end of file diff --git a/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile b/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile index 0267782c0..66f5319a9 100644 --- a/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile +++ b/docker/rocal-on-ubuntu-20-with-pytorch-with-mesa.dockerfile @@ -58,9 +58,9 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ cmake ../ && make -j4 && sudo make install && cd ../../ && \ pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ - pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCm/hipify_torch.git && \ env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ - git clone https://github.com/ROCmSoftwarePlatform/cupy.git && cd cupy && git submodule update --init && \ + git clone https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ pip install -e . --no-cache-dir -vvvv # install MIVisionX diff --git a/docker/rocal-on-ubuntu-20.dockerfile b/docker/rocal-on-ubuntu-20.dockerfile index 99af654ef..e2954678d 100644 --- a/docker/rocal-on-ubuntu-20.dockerfile +++ b/docker/rocal-on-ubuntu-20.dockerfile @@ -54,7 +54,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ cmake ../ && make -j4 && sudo make install && cd ../../ && \ pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ - pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCm/hipify_torch.git && \ env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ git clone -b rocm6.1_internal_testing https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ pip install -e . --no-cache-dir -vvvv diff --git a/docker/rocal-on-ubuntu-22.dockerfile b/docker/rocal-on-ubuntu-22.dockerfile index 20f1b010b..2d4c97d06 100644 --- a/docker/rocal-on-ubuntu-22.dockerfile +++ b/docker/rocal-on-ubuntu-22.dockerfile @@ -57,7 +57,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ cmake ../ && make -j4 && sudo make install && cd ../../ && \ pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ - pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCm/hipify_torch.git && \ env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ git clone -b rocm6.1_internal_testing https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ pip install -e . --no-cache-dir -vvvv diff --git a/docker/rocal-with-pytorch.dockerfile b/docker/rocal-with-pytorch.dockerfile index aee91ccbf..547b79854 100644 --- a/docker/rocal-with-pytorch.dockerfile +++ b/docker/rocal-with-pytorch.dockerfile @@ -45,7 +45,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ cmake ../ && make -j4 && sudo make install && cd ../../ && \ pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ - pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCm/hipify_torch.git && \ env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ git clone -b rocm6.1_internal_testing https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ pip install -e . --no-cache-dir -vvvv diff --git a/docker/rocal-with-tensorflow.dockerfile b/docker/rocal-with-tensorflow.dockerfile index 3bc795ff6..337367c43 100644 --- a/docker/rocal-with-tensorflow.dockerfile +++ b/docker/rocal-with-tensorflow.dockerfile @@ -45,7 +45,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 python3-pip git g+ cmake ../ && make -j4 && sudo make install && cd ../../ && \ pip install pytest==3.1 && git clone -b v2.10.4 https://github.com/pybind/pybind11 && cd pybind11 && mkdir build && cd build && \ cmake -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON ../ && make -j4 && sudo make install && cd ../../ && \ - pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCmSoftwarePlatform/hipify_torch.git && \ + pip install numpy==1.24.2 scipy==1.9.3 cython==0.29.* git+https://github.com/ROCm/hipify_torch.git && \ env CC=$MPI_HOME/bin/mpicc python -m pip install mpi4py && \ git clone -b rocm6.1_internal_testing https://github.com/ROCm/cupy.git && cd cupy && git submodule update --init && \ pip install -e . --no-cache-dir -vvvv diff --git a/docs/README.md b/docs/README.md index ede6f142f..7fa4f21bb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,11 +24,11 @@ These pipelines are programmable by the user using both C++ and Python APIs. ## Prerequisites -Refer [rocAL Prerequisites](https://github.com/ROCmSoftwarePlatform/rocAL#prerequisites) +Refer [rocAL Prerequisites](https://github.com/ROCm/rocAL#prerequisites) ## Build instructions -Refer [rocAL build instructions](https://github.com/ROCmSoftwarePlatform/rocAL#build-instructions) +Refer [rocAL build instructions](https://github.com/ROCm/rocAL#build-instructions) ## rocAL Python @@ -81,12 +81,11 @@ amd.rocal.types are enums exported from C++ API to python. Some examples include * From the above classes, any hybrid iterator pipeline can be created by adding augmentations. * see example [PyTorch Simple Example](./examples). Requires PyTorch. -### installing rocAL python plugin (Python 3.6) +### installing rocAL python plugin (Python 3.9+) * Build and install RPP -* Build and install MIVisionX which installs rocAL c++ lib -* Go to the [rocal_pybind](https://github.com/ROCm/rocAL/tree/develop/rocAL_pybind) folder -* sudo ./run.sh +* Build and install MIVisionX +* Build and install [rocAL](https://github.com/ROCm/rocAL/) ### Steps to run MLPerf Resnet50 classification training with rocAL on a system with MI50+ and ROCm @@ -110,7 +109,7 @@ git clone -b mlperf-v1.1-rocal https://github.com/rrawther/MLPerf-mGPU ### MIVisionX Pytorch Docker -* Refer to the [docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX#docker) page for prerequisites and information on building the docker +* Refer to the [docker](https://github.com/ROCm/MIVisionX#docker) page for prerequisites and information on building the docker * Step 1: Run the docker image* ``` bash diff --git a/docs/examples.md b/docs/examples.md index 065c48b28..7e9089c38 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -2,6 +2,6 @@ Use the links below to see more examples: -- [Image Processing](https://github.com/ROCmSoftwarePlatform/rocAL/tree/master/docs/examples/image_processing) +- [Image Processing](https://github.com/ROCm/rocAL/tree/master/docs/examples/image_processing) -- [Pytorch](https://github.com/ROCmSoftwarePlatform/rocAL/tree/master/docs/examples/pytorch) +- [Pytorch](https://github.com/ROCm/rocAL/tree/master/docs/examples/pytorch) diff --git a/docs/how-to/using-with-python.rst b/docs/how-to/using-with-python.rst index e4b7abd33..9e9f9e9cb 100644 --- a/docs/how-to/using-with-python.rst +++ b/docs/how-to/using-with-python.rst @@ -95,7 +95,7 @@ Given below is an example of a file reader, which takes a folder of images as in ## 4.1.2 Defining the Pipeline -To define a pipeline, see https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/amd/rocal/pipeline.py#L29. +To define a pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/amd/rocal/pipeline.py#L29. ``` class Pipeline(object): @@ -189,7 +189,7 @@ Building the Pipeline Building the pipeline ensures that all operators are validated with the corresponding inputs and outputs. <<<<<<< HEAD:docs/user_guide/ch4.md -To build the pipeline, see https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L166 +To build the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L166 ======= To build the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L166` >>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst @@ -208,7 +208,7 @@ Running the Pipeline To run/use the pipeline, simply create a data loader using the pipeline and iterate through it to get the next batch of images with labels. <<<<<<< HEAD:docs/user_guide/ch4.md -To run the pipeline, see https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L168 +To run the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L168 ======= To run the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L168` @@ -240,7 +240,7 @@ Performing Augmentations rocAL not only reads images from the disk and batches them into tensors, it can also perform various augmentations on those images. <<<<<<< HEAD:docs/user_guide/ch4.md -To read images, decode them, and rotate them in the pipeline, see https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L77 +To read images, decode them, and rotate them in the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L77 ======= To read images, decode them, and rotate them in the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L77` >>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst @@ -270,7 +270,7 @@ To run the pipeline, see: show_images(images) <<<<<<< HEAD:docs/user_guide/ch4.md -All the rocAL data types are defined under [amd.rocal.types](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/blob/master/rocAL/rocAL_pybind/amd/rocal/types.py). Import this library in the application to access the various data types such as rocAL status, processing mode, tensor output type, image size evaluation policy, image color, tensor layout, decode device, resize scaling mode, and resize interpolation type. +All the rocAL data types are defined under [amd.rocal.types](https://github.com/ROCm/MIVisionX/blob/master/rocAL/rocAL_pybind/amd/rocal/types.py). Import this library in the application to access the various data types such as rocAL status, processing mode, tensor output type, image size evaluation policy, image color, tensor layout, decode device, resize scaling mode, and resize interpolation type. ======= rocAL Data Types @@ -284,7 +284,7 @@ Here are some of the commonly used rocAL data types: * Processing modes: Values (GPU/CPU). Use the rocal_cpu argument in the pipeline to set the processing mode. <<<<<<< HEAD:docs/user_guide/ch4.md -To see the usage of the above-mentioned data types, see https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/amd/rocal/pipeline.py#L97 +To see the usage of the above-mentioned data types, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/amd/rocal/pipeline.py#L97 ======= * rocal_cpu = True: This performs data loading on the CPU. If GPUs are heavily used for training, it is viable to create the data-loading pipeline using CPU. * rocal_cpu = False: This performs data loading on the available GPU as specified using the device_id argument in the pipeline. diff --git a/docs/user_guide/ch1.md b/docs/user_guide/ch1.md index 97f08d2c7..7ad19e5c6 100644 --- a/docs/user_guide/ch1.md +++ b/docs/user_guide/ch1.md @@ -80,4 +80,4 @@ rocAL operators offer the flexibility to run on CPU or GPU for building hybrid p | Image_random_crop | Decodes and randomly crops JPEG images | | Image_slice | Decodes and slices JPEG images | -To see examples demonstrating the usage of decoders and readers, [click here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/rocAL/rocAL_pybind/examples) +To see examples demonstrating the usage of decoders and readers, [click here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples) diff --git a/docs/user_guide/ch2.md b/docs/user_guide/ch2.md index e4aa6367e..87aa1e19f 100644 --- a/docs/user_guide/ch2.md +++ b/docs/user_guide/ch2.md @@ -18,4 +18,4 @@ Figure 2. rocAL Master-Graph Architecture RPP is a comprehensive high-performance computer vision library optimized for the AMD CPU and GPU with HIP and OpenCL backends. It is available under the AMD ROCm software platform. It provides low-level functionality for all rocAL operators for single, image, and tensor datatypes. RPP provides an extensive library for vision augmentations that includes vision functions, color augmentations, filter augmentations, geometric distortions, and a few more features. -For more information on RPP along with the list of supported kernels, see https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp. +For more information on RPP along with the list of supported kernels, see https://github.com/ROCm/rpp. diff --git a/docs/user_guide/ch3.md b/docs/user_guide/ch3.md index aa64b032a..aa86daa49 100644 --- a/docs/user_guide/ch3.md +++ b/docs/user_guide/ch3.md @@ -5,8 +5,8 @@ This chapter provides information about the installation of rocAL and related pa ## 3.1 Prerequisites * Linux distribution -* [AMD RPP](https://github.com/GPUOpen-ProfessionalCompute-Libraries/rpp) -* [AMD OpenVX™](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` +* [AMD RPP](https://github.com/ROCm/rpp) +* [AMD OpenVX™](https://github.com/ROCm/MIVisionX/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` * [Turbo JPEG](https://libjpeg-turbo.org/) - Version `2.0` or higher * [Half-precision floating-point](https://half.sourceforge.net) library - Version `1.12.0` or higher * [Google Protobuf](https://developers.google.com/protocol-buffers) - Version `3.12.4` or higher @@ -20,23 +20,23 @@ To see the list of supported platforms for rocAL, see the ROCm Installation Guid ## 3.3 Installing rocAL -rocAL is shipped along with MIVisionX. To build and install the rocAL C++ library, follow the instructions given [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX#build--install-mivisionx) +rocAL is shipped along with MIVisionX. To build and install the rocAL C++ library, follow the instructions given [here](https://github.com/ROCm/MIVisionX#build--install-mivisionx) ## 3.4 Installing rocAL Python Package The rocAL Python package (rocal_pybind) is a separate redistributable wheel. rocal_pybind, which is created using Pybind11, enables data transfer between rocAL C++ API and Python API. With the help of rocal_pybind.so wrapper library, the rocAL functionality, which is primarily in C/C++, can be effectively used in Python. The Python package supports PyTorch, TensorFlow, Caffe2, and data readers available for various formats such as FileReader, COCO Reader, TFRecord Reader, and CaffeReader. -To build and install the Python package, see [rocAL python](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/rocAL/rocAL_pybind). +To build and install the Python package, see [rocAL python](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind). ## 3.5 Installing rocAL Using Framework Dockers To test the rocAL Python APIs using PyTorch or TensorFlow, we recommend building a docker with rocAL and ROCm using any of the links below: -- [rocAL PyTorch docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/pytorch) -- [rocAL TensorFlow docker](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/docker/tensorflow) +- [rocAL PyTorch docker](https://github.com/ROCm/MIVisionX/tree/master/docker/pytorch) +- [rocAL TensorFlow docker](https://github.com/ROCm/MIVisionX/tree/master/docker/tensorflow) To use rocAL on Ubuntu, use the following dockers: -- [rocAL on ubuntu20](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/blob/master/docker/mivisionx-on-ubuntu20.dockerfile) -- [rocAL on Ubuntu22](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/blob/master/docker/mivisionx-on-ubuntu22.dockerfile) +- [rocAL on ubuntu20](https://github.com/ROCm/MIVisionX/blob/master/docker/mivisionx-on-ubuntu20.dockerfile) +- [rocAL on Ubuntu22](https://github.com/ROCm/MIVisionX/blob/master/docker/mivisionx-on-ubuntu22.dockerfile) diff --git a/docs/user_guide/ch5.md b/docs/user_guide/ch5.md index ebdf3845a..149b4897d 100644 --- a/docs/user_guide/ch5.md +++ b/docs/user_guide/ch5.md @@ -14,7 +14,7 @@ Build a rocAL PyTorch docker by following the steps here. Follow these steps: -1. Import libraries for [rocAL](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/docs/examples/pytorch/test_training.py#L28). +1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L28). ``` from amd.rocal.plugin.pytorch import ROCALClassificationIterator @@ -23,7 +23,7 @@ import amd.rocal.fn as fn import amd.rocal.types as types ``` -2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the [pipeline](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/docs/examples/pytorch/test_training.py#L38). +2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the [pipeline](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L38). ``` def trainPipeline(data_path, batch_size, num_classes, one_hot, local_rank, world_size, num_thread, crop, rocal_cpu, fp16): @@ -61,7 +61,7 @@ import torch.nn.functional as F import torch.optim as optim ``` -4. Call the training pipeline with rocAL classification data [loader](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/docs/examples/pytorch/test_training.py#L78). +4. Call the training pipeline with rocAL classification data [loader](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L78). ``` Def get_pytorch_train_loader(self): @@ -72,7 +72,7 @@ Def get_pytorch_train_loader(self): train_loader = ROCALClassificationIterator(pipe_train, device=”cpu” if self.rocal_cpu else “cuda”, device_id = self.local_rank) ``` -5. Run the [training](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/docs/examples/pytorch/test_training.py#L179). +5. Run the [training](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L179). ``` # Training loop @@ -88,9 +88,9 @@ Def get_pytorch_train_loader(self): inputs, labels = inputs.to(device), labels.to(device) ``` -6. Run the training as shown [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). +6. Run the training as shown [here](https://github.com/ROCm/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). -To see a sample training script, click [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). +To see a sample training script, click [here](https://github.com/ROCm/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). ## 5.2 TensorFlow Integration @@ -104,7 +104,7 @@ Build a rocAL TensorFlow docker by following the steps here. Follow these steps: -1. Import libraries for [rocAL](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L22). +1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L22). ``` from amd.rocal.plugin.tf import ROCALIterator @@ -113,7 +113,7 @@ import amd.rocal.fn as fn import amd.rocal.types as types ``` -2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses fn.decoders.image to decode the raw [images](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L128). +2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses fn.decoders.image to decode the raw [images](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L128). ``` trainPipe = Pipeline(batch_size=TRAIN_BATCH_SIZE, num_threads=1, rocal_cpu=RUN_ON_HOST, tensor_layout = types.NHWC) @@ -140,7 +140,7 @@ trainPipe = Pipeline(batch_size=TRAIN_BATCH_SIZE, num_threads=1, rocal_cpu=RUN_O trainPipe.build() ``` -3. Import libraries for [TensorFlow](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L174). +3. Import libraries for [TensorFlow](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L174). ``` import tensorflow.compat.v1 as tf @@ -159,6 +159,6 @@ Run the training Session train_label_one_hot_list = get_label_one_hot(train_label_ndArray) ``` -4. Run the training as shown [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). +4. Run the training as shown [here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). -To see a sample training script, click [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). +To see a sample training script, click [here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). diff --git a/docs/user_guide/ch6.md b/docs/user_guide/ch6.md index f3f481945..5c164cc03 100644 --- a/docs/user_guide/ch6.md +++ b/docs/user_guide/ch6.md @@ -14,21 +14,21 @@ Returns: The context for the pipeline Arguments: -- RocalProcessMode: Defines whether rocal data loading should be on the CPU or [GPU](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api_types.h#L91) +- RocalProcessMode: Defines whether rocal data loading should be on the CPU or [GPU](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api_types.h#L91) ``` RocalProcessMode:: ROCAL_PROCESS_GPU RocalProcessMode::ROCAL_PROCESS_CPU ``` -- RocalTensorOutputType: Defines whether the output of rocal tensor is FP32 or [FP16](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api_types.h#L124) +- RocalTensorOutputType: Defines whether the output of rocal tensor is FP32 or [FP16](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api_types.h#L124) ``` RocalTensorOutputType::ROCAL_FP32 RocalTensorOutputType::ROCAL_FP16 ``` -[Example](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api.h#L41): +[Example](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api.h#L41): ``` extern "C" RocalContext ROCAL_API_CALL rocalCreate(size_t batch_size, RocalProcessMode affinity, int gpu_id = 0, size_t cpu_thread_count = 1, size_t prefetch_queue_depth = 3, RocalTensorOutputType output_tensor_data_type = RocalTensorOutputType::ROCAL_FP32); @@ -40,7 +40,7 @@ Use: To verify the graph for all the inputs and outputs Returns: A status code indicating the success or failure -[Example](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api.h#L47): +[Example](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api.h#L47): ``` extern "C" RocalStatus ROCAL_API_CALL rocalVerify(RocalContext context); @@ -52,7 +52,7 @@ Use: To process and run the built and verified graph Returns: A status code indicating the success or failure -[Example](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api.h#L52): +[Example](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api.h#L52): ``` extern "C" RocalStatus ROCAL_API_CALL rocalRun(RocalContext context); @@ -64,7 +64,7 @@ Use: To free all the resources allocated during the graph creation process Returns: A status code indicating the success or failure -[Example](https://github.com/ROCmSoftwarePlatform/rocAL/blob/master/rocAL/include/api/rocal_api.h#L57): +[Example](https://github.com/ROCm/rocAL/blob/master/rocAL/include/api/rocal_api.h#L57): ``` extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context); @@ -72,7 +72,7 @@ extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context) ## 6.1.5 Image Augmentation Using C++ API -The example below shows how to create a pipeline, read JPEG images, perform certain augmentations on them, and show the output using OpenCV by utilizing C++ [APIs](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/blob/develop/apps/image_augmentation/image_augmentation.cpp#L103). +The example below shows how to create a pipeline, read JPEG images, perform certain augmentations on them, and show the output using OpenCV by utilizing C++ [APIs](https://github.com/ROCm/MIVisionX/blob/develop/apps/image_augmentation/image_augmentation.cpp#L103). ``` Auto handle = rocalCreate(inputBatchSize, processing_device?RocalProcessMode::ROCAL_PROCESS_GPU:RocalProcessMode::ROCAL_PROCESS_CPU, 0,1); @@ -109,4 +109,4 @@ while (!rocalIsEmpty(handle)) } ``` -To see a sample image augmentation application in C++, click [here](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/develop/apps/image_augmentation). +To see a sample image augmentation application in C++, click [here](https://github.com/ROCm/MIVisionX/tree/develop/apps/image_augmentation). diff --git a/rocAL-setup.py b/rocAL-setup.py index 30f0e29d2..c0d74e94f 100644 --- a/rocAL-setup.py +++ b/rocAL-setup.py @@ -420,6 +420,6 @@ # MIVisionX os.system('sudo -v') os.system('(cd '+deps_dir+'; git clone -b '+mivisionxVersion+' https://github.com/ROCm/MIVisionX.git; cd MIVisionX; mkdir build-'+backend+'; cd build-'+backend+'; ' + - linuxCMake+' -DBACKEND='+backend+' -DROCAL=OFF ../; make -j4; sudo make install)') + linuxCMake+' -DBACKEND='+backend+' ../; make -j4; sudo make install)') print("\nrocAL Dependencies Installed with rocAL-setup.py V-"+__version__+"\n") diff --git a/rocAL_pybind/README.md b/rocAL_pybind/README.md index 057bf1a1e..84058228c 100644 --- a/rocAL_pybind/README.md +++ b/rocAL_pybind/README.md @@ -11,10 +11,10 @@ written primarily in C/C++ language can be used effectively in Python. * CMake Version 3.10 or higher * Python 3 * PIP3 - `sudo apt install python3-pip` -* [CuPy for rocm](https://github.com/ROCmSoftwarePlatform/cupy) +* [CuPy for rocm](https://github.com/ROCm/cupy) ## Install -rocAL_pybind installs during [MIVisionX build](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX#build--install-mivisionx) +rocAL_pybind installs during [rocAL build](https://github.com/ROCm/rocAL#build-instructions) #### Prerequisites @@ -24,4 +24,5 @@ pip3 install numpy opencv-python torch pillow ```` #### Run Test Scripts -* Test scripts and instructions to run them can be found [here](examples/) +* Test scripts and instructions to run them can be found [here](../tests/python_api/) +* Examples using python APIs can be found [here](../docs/examples/) diff --git a/tests/cpp_api/performance_tests_with_depth/README.md b/tests/cpp_api/performance_tests_with_depth/README.md index 092f55000..05352eb6b 100644 --- a/tests/cpp_api/performance_tests_with_depth/README.md +++ b/tests/cpp_api/performance_tests_with_depth/README.md @@ -6,7 +6,7 @@ This is very similar to the rocAL Performance Tests app except it takes an extra ### Pre-requisites * Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher * ROCm Performance Primitives (RPP) diff --git a/tests/cpp_api/unit_tests/README.md b/tests/cpp_api/unit_tests/README.md index 95bbaa96c..64353fe8e 100644 --- a/tests/cpp_api/unit_tests/README.md +++ b/tests/cpp_api/unit_tests/README.md @@ -5,7 +5,7 @@ This application can be used to verify the functionality of the API offered by r ### Pre-requisites * Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 3.4+](https://github.com/opencv/opencv/releases/tag/3.4.0) * ROCm Performance Primitives (RPP) * Python3 @@ -32,7 +32,7 @@ Usage: ./unit_tests reader-type pipeline-type=1(classification)2(detection)3(key The bash script `testAllScript.sh` can be used to run and dump the outputs for all test cases in rocAL and run the python script to verify the correctness of the generated outputs with the golden outputs. -Input data is available in the following link : [MIVisionX-data](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data) +Input data is available in the following link : [MIVisionX-data](https://github.com/ROCm/MIVisionX-data) `export ROCAL_DATA_PATH=` diff --git a/tests/cpp_api/video_tests/README.md b/tests/cpp_api/video_tests/README.md index 42a2486c5..c3fefbec9 100644 --- a/tests/cpp_api/video_tests/README.md +++ b/tests/cpp_api/video_tests/README.md @@ -5,7 +5,7 @@ This application can be used to verify the functionality of the video API offere ### Pre-requisites * Ubuntu Linux, version - `18.04` / `20.04` -* rocAL library (Part of the MIVisionX toolkit) +* rocAL library * [OpenCV 4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) * [FFmpeg n4.4.2](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2) * ROCm Performance Primitives (RPP) @@ -21,12 +21,12 @@ The arguments passed to the Video Pipeline can be modified in the bash script [t The outputs will be dumped inside the build/output_frames folder. -The sample video files and folder are available in the In the following path : [video and sequence samples](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples). +The sample video files and folder are available in the In the following path : [video and sequence samples](https://github.com/ROCm/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples). The data samples can be downloaded from the MIVisionX-data repository. ``` -git clone https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data.git +git clone https://github.com/ROCm/MIVisionX-data.git ``` ## Description @@ -45,7 +45,7 @@ INPUT_PATH : Input passed by the user. It can be a video file path, folder path NOTE: * Inputs for cases 1 and 2 - Video file / folder containing videos - * Input for case 3 - Folder containing sequence of images [sample folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence) + * Input for case 3 - Folder containing sequence of images [sample folder](https://github.com/ROCm/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence) READER_CASE : Value passed can be 1/2/3 depending upon the selected reader (default value : 1). @@ -83,7 +83,7 @@ ENABLE_SEQUENCE_REARRANGE : If set to true, the frames in each sequence will be **Example 1: Video Reader** -> ./testScript.sh <[path/to/test_frame_num.mp4](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/blob/main/rocal_data/video_and_sequence_samples/test_frame/test_frame_num.mp4)> 1 +> ./testScript.sh <[path/to/test_frame_num.mp4](https://github.com/ROCm/MIVisionX-data/blob/main/rocal_data/video_and_sequence_samples/test_frame/test_frame_num.mp4)> 1 Arguments to be modified in testScript.sh to get the following output: @@ -103,7 +103,7 @@ Also RESIZE_WIDTH and RESIZE_HEIGHT can be changed in testScript.sh **Example 2: Sequence Reader** -> ./testScript.sh <[path/to/sequence_folder](https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence)> 3 +> ./testScript.sh <[path/to/sequence_folder](https://github.com/ROCm/MIVisionX-data/tree/main/rocal_data/video_and_sequence_samples/sequence)> 3 ![sequence_reader.png](./samples/sequence_reader.png) From 39864255875af6819df16630d68afef28f13f5a7 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 09:16:30 -0700 Subject: [PATCH 07/21] move image_augmentation app with other cpp tests --- .../cpp_api/image_augmentation/CMakeLists.txt | 90 ++++++ tests/cpp_api/image_augmentation/README.md | 30 ++ .../image_augmentation/image_augmentation.cpp | 284 ++++++++++++++++++ 3 files changed, 404 insertions(+) create mode 100644 tests/cpp_api/image_augmentation/CMakeLists.txt create mode 100644 tests/cpp_api/image_augmentation/README.md create mode 100644 tests/cpp_api/image_augmentation/image_augmentation.cpp diff --git a/tests/cpp_api/image_augmentation/CMakeLists.txt b/tests/cpp_api/image_augmentation/CMakeLists.txt new file mode 100644 index 000000000..e25a3494e --- /dev/null +++ b/tests/cpp_api/image_augmentation/CMakeLists.txt @@ -0,0 +1,90 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2023 Advanced Micro Devices, Inc. +# +# 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. +# +################################################################################ + +cmake_minimum_required(VERSION 3.5) + +project(image_augmentation) + +set(CMAKE_CXX_STANDARD 14) + +# ROCm Path +set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") +# avoid setting the default installation path to /usr/local +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + +# Changes for RPATH Removal from Binaries: +# Since all public interface libraries are present in same folder +# RPATH/RUNPATH is not required +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) +set(CMAKE_SKIP_INSTALL_RPATH TRUE) + +# Add Default libdir +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(AMDRPP REQUIRED) +find_package(MIVisionX REQUIRED) +find_package(OpenCV QUIET) + + +# Application Includes & Libraries +include_directories(${MIVisionX_INCLUDE_DIRS} ${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) +link_directories(${ROCM_PATH}/${CMAKE_INSTALL_LIBDIR}) + +add_executable(${PROJECT_NAME} image_augmentation.cpp) + +# OpenCV 3/4 Support +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 3 ) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=1) + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message("-- WARNING: OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) + endif() +else() + message("-- WARNING: OpenCV Not Found -- No Display Support") + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) +endif() + +# Link Libraries & Set CXX Flags +# -mf16c -- Support F16C built-in functions and code generation. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c -Wall ") +target_link_libraries(${PROJECT_NAME} rocal ${OpenCV_LIBRARIES} ) + +# Install Application in ROCm Bin Directory +install(TARGETS ${PROJECT_NAME} DESTINATION ${ROCM_PATH}/${CMAKE_INSTALL_BINDIR}) diff --git a/tests/cpp_api/image_augmentation/README.md b/tests/cpp_api/image_augmentation/README.md new file mode 100644 index 000000000..02270a4b6 --- /dev/null +++ b/tests/cpp_api/image_augmentation/README.md @@ -0,0 +1,30 @@ +# Image Augmentation Application + +This application demonstrates the basic usage of rocAL's C API to load JPEG images from the disk and modify them in different possible ways and displays the output images. + +

+ +## Build Instructions + +### Pre-requisites + +* Linux distribution + + Ubuntu - `20.04` / `22.04` +* rocAL and it's dependencies +* Optional: OpenCV for display - [4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) + +### Build + +``` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib + mkdir build + cd build + cmake ../ + make +``` + +### Running the application + +``` + image_augmentation +``` diff --git a/tests/cpp_api/image_augmentation/image_augmentation.cpp b/tests/cpp_api/image_augmentation/image_augmentation.cpp new file mode 100644 index 000000000..73154d35a --- /dev/null +++ b/tests/cpp_api/image_augmentation/image_augmentation.cpp @@ -0,0 +1,284 @@ +/* +MIT License + +Copyright (c) 2018 - 2023 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 +#include +#include +#include +using namespace cv; + +#if USE_OPENCV_4 +#define CV_FONT_HERSHEY_DUPLEX FONT_HERSHEY_DUPLEX +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE +#define CV_RGB2BGR cv::COLOR_BGR2RGB +#else +#include +#endif + +#include "rocal_api.h" + +#define DISPLAY +using namespace std::chrono; + +int main(int argc, const char** argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + printf( + "Usage: image_augmentation \ + decode_width decode_height decoder_mode gray_scale/rgb display_on_off decode_shard_count \n"); + return -1; + } + int argIdx = 0; + const char* folderPath1 = argv[++argIdx]; + int decoder_mode = 0; // 0 means no video decode, 1 means hardware, 2 means software decoding + bool display = 1; // Display the images + int aug_depth = 1; // how deep is the augmentation tree + int rgb = 1; // process color images + int decode_width = 0; + int decode_height = 0; + bool processing_device = 1; + size_t shard_count = 2; + int shuffle = 0; + int decoder_type = 0; + const char *outName = "image_augmentation_app.png"; + + if (argc >= argIdx + MIN_ARG_COUNT) + processing_device = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_width = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decode_height = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decoder_mode = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + rgb = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + display = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + shard_count = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + shuffle = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + decoder_type = atoi(argv[++argIdx]); + + if (argc >= argIdx + MIN_ARG_COUNT) + outName = argv[++argIdx]; + + int inputBatchSize = 4; + + std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; + + RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; + + auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the rocAL contex\n"; + return -1; + } + + RocalDecoderType dec_type = (RocalDecoderType)decoder_type; + + /*>>>>>>>>>>>>>>>> Creating rocAL parameters <<<<<<<<<<<<<<<<*/ + + // Creating uniformly distributed random objects to override some of the default augmentation parameters + RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); + RocalIntParam color_temp_adj = rocalCreateIntParameter(0); + + // Creating a custom random object to set a limited number of values to randomize the rotation angle + const size_t num_values = 3; + float values[num_values] = {0, 10, 135}; + double frequencies[num_values] = {1, 5, 5}; + + RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, num_values); + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + RocalTensor input1; + + if (decoder_mode >= 2) { + unsigned sequence_length = 3; + unsigned frame_step = 3; + unsigned frame_stride = 1; + if (decode_height <= 0 || decode_width <= 0) { + std::cout << "Output width and height is needed for video decode\n"; + return -1; + } + input1 = rocalVideoFileSource(handle, folderPath1, color_format, (decoder_mode == 2)? ROCAL_SW_DECODE: ROCAL_HW_DECODE, shard_count, sequence_length, frame_step, frame_stride, shuffle, true, false); + } else if (decoder_mode == 1) { + std::vector area = {0.08, 1}; + std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; + input1 = rocalFusedJpegCrop(handle, folderPath1, color_format, shard_count, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_width, decode_height); + + } else { + // The jpeg file loader can automatically select the best size to decode all images to that size + // User can alternatively set the size or change the policy that is used to automatically find the size + if (dec_type == RocalDecoderType::ROCAL_DECODER_OPENCV) std::cout << "Using OpenCV decoder for Jpeg Source\n"; + if (decode_height <= 0 || decode_width <= 0) + input1 = rocalJpegFileSource(handle, folderPath1, color_format, shard_count, false, shuffle, false); + else + input1 = rocalJpegFileSource(handle, folderPath1, color_format, shard_count, false, shuffle, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_width, decode_height, dec_type); + } + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + RocalTensor tensor0; + int resize_w = 112, resize_h = 112; + if (decoder_mode >= 2) { + resize_h = decode_height; + resize_w = decode_width; + tensor0 = input1; + } else { + tensor0 = rocalResize(handle, input1, resize_w, resize_h, true); + } + RocalTensor tensor1 = rocalRain(handle, tensor0, false); + + RocalTensor tensor11 = rocalFishEye(handle, tensor1, false); + + rocalRotate(handle, tensor11, true, rand_angle); + + // Creating successive blur nodes to simulate a deep branch of augmentations + RocalTensor tensor2 = rocalCropResize(handle, tensor0, resize_w, resize_h, false, rand_crop_area); + for (int i = 0; i < aug_depth; i++) { + tensor2 = rocalBlurFixed(handle, tensor2, 17.25, (i == (aug_depth - 1)) ? true : false); + } + // Commenting few augmentations out until tensor support is added in rpp + // RocalTensor tensor4 = rocalColorTemp(handle, tensor0, true, color_temp_adj); + + // RocalTensor tensor6 = rocalJitter(handle, tensor5, true); + + // rocalVignette(handle, tensor5, true); + + // RocalTensor tensor7 = rocalPixelate(handle, tensor0, true); + + RocalTensor tensor8 = rocalSnow(handle, tensor0, true); + + RocalTensor tensor9 = rocalBlend(handle, tensor0, tensor8, true); + + RocalTensor tensor10 = rocalLensCorrection(handle, tensor9, true); + + rocalExposure(handle, tensor10, true); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Error while adding the augmentation nodes " << std::endl; + auto err_msg = rocalGetErrorMessage(handle); + std::cout << err_msg << std::endl; + } + // Calling the API to verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; + std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ + // initializations for logos and heading + cv::Mat AMD_Epyc_Black_resize, AMD_ROCm_Black_resize; + AMD_Epyc_Black_resize = cv::imread("../../../samples/images/amd-epyc-black-resize.png"); + AMD_ROCm_Black_resize = cv::imread("../../../samples/images/rocm-black-resize.png"); + int fontFace = CV_FONT_HERSHEY_DUPLEX; + int thickness = 1.3; + std::string bufferName = "rocAL Image Augmentation"; + + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; + int w = rocalGetOutputWidth(handle); + int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); + std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; + const unsigned number_of_cols = (decoder_mode >= 2) ? 1 : 10; + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h + AMD_ROCm_Black_resize.rows, w * number_of_cols, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + int col_counter = 0; + + // adding heading to output display + cv::Rect roi = Rect(0, 0, w * number_of_cols, AMD_Epyc_Black_resize.rows); + mat_output(roi).setTo(cv::Scalar(128, 128, 128)); + putText(mat_output, bufferName, Point(250, 70), fontFace, 1.2, cv::Scalar(66, 13, 9), thickness, 5); + + // adding logos to output display + cv::Mat mat_output_ROI = mat_output(cv::Rect(w * number_of_cols - AMD_Epyc_Black_resize.cols, 0, AMD_Epyc_Black_resize.cols, AMD_Epyc_Black_resize.rows)); + cv::Mat mat_output_ROI_1 = mat_output(cv::Rect(0, 0, AMD_ROCm_Black_resize.cols, AMD_ROCm_Black_resize.rows)); + AMD_Epyc_Black_resize.copyTo(mat_output_ROI); + AMD_ROCm_Black_resize.copyTo(mat_output_ROI_1); + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + int counter = 0; + int color_temp_increment = 1; + while (!rocalIsEmpty(handle)) { + if (rocalRun(handle) != 0) + break; + + if (rocalGetIntValue(color_temp_adj) <= -99 || rocalGetIntValue(color_temp_adj) >= 99) + color_temp_increment *= -1; + + rocalUpdateIntParameter(rocalGetIntValue(color_temp_adj) + color_temp_increment, color_temp_adj); + auto ouput_tensor_list = rocalGetOutputTensors(handle); + unsigned char* output = mat_input.data; + for (uint i = 0; i < ouput_tensor_list->size(); i++) { + ouput_tensor_list->at(i)->copy_data(output); + output += ouput_tensor_list->at(i)->data_size(); + } + counter += inputBatchSize; + if (!display) + continue; + + std::string out_filename = std::string(outName) + ".png"; + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, AMD_ROCm_Black_resize.rows, w, h))); + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); + cv::imwrite(out_filename, mat_color); + } else { + cv::imwrite(out_filename, mat_output); + } + cv::waitKey(1); + col_counter = (col_counter + 1) % number_of_cols; + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto dur = duration_cast(t2 - t1).count(); + auto rocal_timing = rocalGetTimingInfo(handle); + std::cout << "Load time " << rocal_timing.load_time << std::endl; + std::cout << "Decode time " << rocal_timing.decode_time << std::endl; + std::cout << "Process time " << rocal_timing.process_time << std::endl; + std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; + std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; + rocalRelease(handle); + mat_input.release(); + mat_output.release(); + return 0; +} From 501c1a6e4c0405b547a2a0cf1b43ad8028b2579d Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 09:52:37 -0700 Subject: [PATCH 08/21] update docs --- apps/README.md | 12 - apps/image_augmentation/CMakeLists.txt | 90 ------ apps/image_augmentation/README.md | 30 -- .../image_augmentation/image_augmentation.cpp | 284 ------------------ docs/examples.rst | 2 + docs/how-to/framework.rst | 39 +-- docs/how-to/overview.rst | 2 +- docs/how-to/using-with-cpp.rst | 4 +- docs/how-to/using-with-python.rst | 28 +- docs/install/install.rst | 2 +- docs/user_guide/ch1.md | 2 +- docs/user_guide/ch3.md | 16 +- docs/user_guide/ch5.md | 22 +- docs/user_guide/ch6.md | 4 +- 14 files changed, 45 insertions(+), 492 deletions(-) delete mode 100644 apps/README.md delete mode 100644 apps/image_augmentation/CMakeLists.txt delete mode 100644 apps/image_augmentation/README.md delete mode 100644 apps/image_augmentation/image_augmentation.cpp diff --git a/apps/README.md b/apps/README.md deleted file mode 100644 index 4205215fe..000000000 --- a/apps/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Applications - -rocAL has several applications built on top of AMD optimized libraries that can be used as prototypes or used as models to develop products. - -## Prerequisites -* [rocAL](https://github.com/ROCm/rocAL) - -## Image Augmentation - -This sample [application](./image_augmentation#image-augmentation-application) demonstrates the basic usage of rocAL's C API to load JPEG images from the disk and modify them in different possible ways and displays the output images. - -

diff --git a/apps/image_augmentation/CMakeLists.txt b/apps/image_augmentation/CMakeLists.txt deleted file mode 100644 index e25a3494e..000000000 --- a/apps/image_augmentation/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -################################################################################ -# -# MIT License -# -# Copyright (c) 2023 Advanced Micro Devices, Inc. -# -# 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. -# -################################################################################ - -cmake_minimum_required(VERSION 3.5) - -project(image_augmentation) - -set(CMAKE_CXX_STANDARD 14) - -# ROCm Path -set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") -# avoid setting the default installation path to /usr/local -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocAL default installation path" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - -# Changes for RPATH Removal from Binaries: -# Since all public interface libraries are present in same folder -# RPATH/RUNPATH is not required -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) -set(CMAKE_SKIP_INSTALL_RPATH TRUE) - -# Add Default libdir -set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") -include(GNUInstallDirs) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) - -find_package(AMDRPP REQUIRED) -find_package(MIVisionX REQUIRED) -find_package(OpenCV QUIET) - - -# Application Includes & Libraries -include_directories(${MIVisionX_INCLUDE_DIRS} ${ROCM_PATH}/${CMAKE_INSTALL_INCLUDEDIR}/rocal) -link_directories(${ROCM_PATH}/${CMAKE_INSTALL_LIBDIR}) - -add_executable(${PROJECT_NAME} image_augmentation.cpp) - -# OpenCV 3/4 Support -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 3 ) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=1) - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() - else() - message("-- WARNING: OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) - endif() -else() - message("-- WARNING: OpenCV Not Found -- No Display Support") - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_OPENCV=0) -endif() - -# Link Libraries & Set CXX Flags -# -mf16c -- Support F16C built-in functions and code generation. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c -Wall ") -target_link_libraries(${PROJECT_NAME} rocal ${OpenCV_LIBRARIES} ) - -# Install Application in ROCm Bin Directory -install(TARGETS ${PROJECT_NAME} DESTINATION ${ROCM_PATH}/${CMAKE_INSTALL_BINDIR}) diff --git a/apps/image_augmentation/README.md b/apps/image_augmentation/README.md deleted file mode 100644 index 02270a4b6..000000000 --- a/apps/image_augmentation/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Image Augmentation Application - -This application demonstrates the basic usage of rocAL's C API to load JPEG images from the disk and modify them in different possible ways and displays the output images. - -

- -## Build Instructions - -### Pre-requisites - -* Linux distribution - + Ubuntu - `20.04` / `22.04` -* rocAL and it's dependencies -* Optional: OpenCV for display - [4.6.0](https://github.com/opencv/opencv/releases/tag/4.6.0) - -### Build - -``` - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib - mkdir build - cd build - cmake ../ - make -``` - -### Running the application - -``` - image_augmentation -``` diff --git a/apps/image_augmentation/image_augmentation.cpp b/apps/image_augmentation/image_augmentation.cpp deleted file mode 100644 index 73154d35a..000000000 --- a/apps/image_augmentation/image_augmentation.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* -MIT License - -Copyright (c) 2018 - 2023 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 -#include -#include -#include -using namespace cv; - -#if USE_OPENCV_4 -#define CV_FONT_HERSHEY_DUPLEX FONT_HERSHEY_DUPLEX -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#define CV_RGB2BGR cv::COLOR_BGR2RGB -#else -#include -#endif - -#include "rocal_api.h" - -#define DISPLAY -using namespace std::chrono; - -int main(int argc, const char** argv) { - // check command-line usage - const int MIN_ARG_COUNT = 2; - if (argc < MIN_ARG_COUNT) { - printf( - "Usage: image_augmentation \ - decode_width decode_height decoder_mode gray_scale/rgb display_on_off decode_shard_count \n"); - return -1; - } - int argIdx = 0; - const char* folderPath1 = argv[++argIdx]; - int decoder_mode = 0; // 0 means no video decode, 1 means hardware, 2 means software decoding - bool display = 1; // Display the images - int aug_depth = 1; // how deep is the augmentation tree - int rgb = 1; // process color images - int decode_width = 0; - int decode_height = 0; - bool processing_device = 1; - size_t shard_count = 2; - int shuffle = 0; - int decoder_type = 0; - const char *outName = "image_augmentation_app.png"; - - if (argc >= argIdx + MIN_ARG_COUNT) - processing_device = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_width = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decode_height = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decoder_mode = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - rgb = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - display = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - shard_count = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - shuffle = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - decoder_type = atoi(argv[++argIdx]); - - if (argc >= argIdx + MIN_ARG_COUNT) - outName = argv[++argIdx]; - - int inputBatchSize = 4; - - std::cout << ">>> Running on " << (processing_device ? "GPU" : "CPU") << std::endl; - - RocalImageColor color_format = (rgb != 0) ? RocalImageColor::ROCAL_COLOR_RGB24 : RocalImageColor::ROCAL_COLOR_U8; - - auto handle = rocalCreate(inputBatchSize, processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Could not create the rocAL contex\n"; - return -1; - } - - RocalDecoderType dec_type = (RocalDecoderType)decoder_type; - - /*>>>>>>>>>>>>>>>> Creating rocAL parameters <<<<<<<<<<<<<<<<*/ - - // Creating uniformly distributed random objects to override some of the default augmentation parameters - RocalFloatParam rand_crop_area = rocalCreateFloatUniformRand(0.3, 0.5); - RocalIntParam color_temp_adj = rocalCreateIntParameter(0); - - // Creating a custom random object to set a limited number of values to randomize the rotation angle - const size_t num_values = 3; - float values[num_values] = {0, 10, 135}; - double frequencies[num_values] = {1, 5, 5}; - - RocalFloatParam rand_angle = rocalCreateFloatRand(values, frequencies, num_values); - - /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - RocalTensor input1; - - if (decoder_mode >= 2) { - unsigned sequence_length = 3; - unsigned frame_step = 3; - unsigned frame_stride = 1; - if (decode_height <= 0 || decode_width <= 0) { - std::cout << "Output width and height is needed for video decode\n"; - return -1; - } - input1 = rocalVideoFileSource(handle, folderPath1, color_format, (decoder_mode == 2)? ROCAL_SW_DECODE: ROCAL_HW_DECODE, shard_count, sequence_length, frame_step, frame_stride, shuffle, true, false); - } else if (decoder_mode == 1) { - std::vector area = {0.08, 1}; - std::vector aspect_ratio = {3.0f / 4, 4.0f / 3}; - input1 = rocalFusedJpegCrop(handle, folderPath1, color_format, shard_count, false, area, aspect_ratio, 10, false, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_width, decode_height); - - } else { - // The jpeg file loader can automatically select the best size to decode all images to that size - // User can alternatively set the size or change the policy that is used to automatically find the size - if (dec_type == RocalDecoderType::ROCAL_DECODER_OPENCV) std::cout << "Using OpenCV decoder for Jpeg Source\n"; - if (decode_height <= 0 || decode_width <= 0) - input1 = rocalJpegFileSource(handle, folderPath1, color_format, shard_count, false, shuffle, false); - else - input1 = rocalJpegFileSource(handle, folderPath1, color_format, shard_count, false, shuffle, false, ROCAL_USE_USER_GIVEN_SIZE_RESTRICTED, decode_width, decode_height, dec_type); - } - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; - return -1; - } - - RocalTensor tensor0; - int resize_w = 112, resize_h = 112; - if (decoder_mode >= 2) { - resize_h = decode_height; - resize_w = decode_width; - tensor0 = input1; - } else { - tensor0 = rocalResize(handle, input1, resize_w, resize_h, true); - } - RocalTensor tensor1 = rocalRain(handle, tensor0, false); - - RocalTensor tensor11 = rocalFishEye(handle, tensor1, false); - - rocalRotate(handle, tensor11, true, rand_angle); - - // Creating successive blur nodes to simulate a deep branch of augmentations - RocalTensor tensor2 = rocalCropResize(handle, tensor0, resize_w, resize_h, false, rand_crop_area); - for (int i = 0; i < aug_depth; i++) { - tensor2 = rocalBlurFixed(handle, tensor2, 17.25, (i == (aug_depth - 1)) ? true : false); - } - // Commenting few augmentations out until tensor support is added in rpp - // RocalTensor tensor4 = rocalColorTemp(handle, tensor0, true, color_temp_adj); - - // RocalTensor tensor6 = rocalJitter(handle, tensor5, true); - - // rocalVignette(handle, tensor5, true); - - // RocalTensor tensor7 = rocalPixelate(handle, tensor0, true); - - RocalTensor tensor8 = rocalSnow(handle, tensor0, true); - - RocalTensor tensor9 = rocalBlend(handle, tensor0, tensor8, true); - - RocalTensor tensor10 = rocalLensCorrection(handle, tensor9, true); - - rocalExposure(handle, tensor10, true); - - if (rocalGetStatus(handle) != ROCAL_OK) { - std::cout << "Error while adding the augmentation nodes " << std::endl; - auto err_msg = rocalGetErrorMessage(handle); - std::cout << err_msg << std::endl; - } - // Calling the API to verify and build the augmentation graph - if (rocalVerify(handle) != ROCAL_OK) { - std::cout << "Could not verify the augmentation graph" << std::endl; - return -1; - } - - std::cout << "Remaining images " << rocalGetRemainingImages(handle) << std::endl; - std::cout << "Augmented copies count " << rocalGetAugmentationBranchCount(handle) << std::endl; - - /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ - // initializations for logos and heading - cv::Mat AMD_Epyc_Black_resize, AMD_ROCm_Black_resize; - AMD_Epyc_Black_resize = cv::imread("../../../samples/images/amd-epyc-black-resize.png"); - AMD_ROCm_Black_resize = cv::imread("../../../samples/images/rocm-black-resize.png"); - int fontFace = CV_FONT_HERSHEY_DUPLEX; - int thickness = 1.3; - std::string bufferName = "rocAL Image Augmentation"; - - int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; - int w = rocalGetOutputWidth(handle); - int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); - std::cout << "output width " << w << " output height " << h << " color planes " << p << std::endl; - const unsigned number_of_cols = (decoder_mode >= 2) ? 1 : 10; - auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); - cv::Mat mat_output(h + AMD_ROCm_Black_resize.rows, w * number_of_cols, cv_color_format); - cv::Mat mat_input(h, w, cv_color_format); - cv::Mat mat_color; - int col_counter = 0; - - // adding heading to output display - cv::Rect roi = Rect(0, 0, w * number_of_cols, AMD_Epyc_Black_resize.rows); - mat_output(roi).setTo(cv::Scalar(128, 128, 128)); - putText(mat_output, bufferName, Point(250, 70), fontFace, 1.2, cv::Scalar(66, 13, 9), thickness, 5); - - // adding logos to output display - cv::Mat mat_output_ROI = mat_output(cv::Rect(w * number_of_cols - AMD_Epyc_Black_resize.cols, 0, AMD_Epyc_Black_resize.cols, AMD_Epyc_Black_resize.rows)); - cv::Mat mat_output_ROI_1 = mat_output(cv::Rect(0, 0, AMD_ROCm_Black_resize.cols, AMD_ROCm_Black_resize.rows)); - AMD_Epyc_Black_resize.copyTo(mat_output_ROI); - AMD_ROCm_Black_resize.copyTo(mat_output_ROI_1); - - high_resolution_clock::time_point t1 = high_resolution_clock::now(); - int counter = 0; - int color_temp_increment = 1; - while (!rocalIsEmpty(handle)) { - if (rocalRun(handle) != 0) - break; - - if (rocalGetIntValue(color_temp_adj) <= -99 || rocalGetIntValue(color_temp_adj) >= 99) - color_temp_increment *= -1; - - rocalUpdateIntParameter(rocalGetIntValue(color_temp_adj) + color_temp_increment, color_temp_adj); - auto ouput_tensor_list = rocalGetOutputTensors(handle); - unsigned char* output = mat_input.data; - for (uint i = 0; i < ouput_tensor_list->size(); i++) { - ouput_tensor_list->at(i)->copy_data(output); - output += ouput_tensor_list->at(i)->data_size(); - } - counter += inputBatchSize; - if (!display) - continue; - - std::string out_filename = std::string(outName) + ".png"; - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, AMD_ROCm_Black_resize.rows, w, h))); - if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); - cv::imwrite(out_filename, mat_color); - } else { - cv::imwrite(out_filename, mat_output); - } - cv::waitKey(1); - col_counter = (col_counter + 1) % number_of_cols; - } - high_resolution_clock::time_point t2 = high_resolution_clock::now(); - auto dur = duration_cast(t2 - t1).count(); - auto rocal_timing = rocalGetTimingInfo(handle); - std::cout << "Load time " << rocal_timing.load_time << std::endl; - std::cout << "Decode time " << rocal_timing.decode_time << std::endl; - std::cout << "Process time " << rocal_timing.process_time << std::endl; - std::cout << "Transfer time " << rocal_timing.transfer_time << std::endl; - std::cout << ">>>>> " << counter << " images/frames Processed. Total Elapsed Time " << dur / 1000000 << " sec " << dur % 1000000 << " us " << std::endl; - rocalRelease(handle); - mat_input.release(); - mat_output.release(); - return 0; -} diff --git a/docs/examples.rst b/docs/examples.rst index 1baa5e5bf..10607f2a3 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -12,4 +12,6 @@ Use the links below to see more examples: * `Image Processing `_ * `Pytorch `_ +* `Tensorflow `_ +* `Jupyter Notebooks `_ diff --git a/docs/how-to/framework.rst b/docs/how-to/framework.rst index 9dc4923d8..eafc2eb34 100644 --- a/docs/how-to/framework.rst +++ b/docs/how-to/framework.rst @@ -27,7 +27,7 @@ Create Data-loading Pipeline Follow these steps: -1. Import libraries for `rocAL `_. +1. Import libraries for `rocAL `_. .. code-block:: python :caption: Import libraries @@ -38,7 +38,7 @@ Follow these steps: import amd.rocal.types as types -2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the `pipeline `_. +2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the `pipeline `_. .. code-block:: python :caption: Pipeline for PyTorch @@ -80,7 +80,7 @@ Follow these steps: import torch.optim as optim -4. Call the training pipeline with rocAL classification data `loader `_. +4. Call the training pipeline with rocAL classification data `loader `_. .. code-block:: python :caption: Call the training pipeline @@ -93,7 +93,7 @@ Follow these steps: train_loader = ROCALClassificationIterator(pipe_train, device=”cpu” if self.rocal_cpu else “cuda”, device_id = self.local_rank) -5. Run the `training script `_. +5. Run the `training script `_. .. code-block:: python :caption: Run the training pipeline @@ -130,7 +130,7 @@ Create Data-loading Pipeline Follow these steps: -1. Import libraries for `rocAL_pybind `_. +1. Import libraries for `rocAL_pybind `_. .. code-block:: python :caption: Import libraries @@ -141,7 +141,7 @@ Follow these steps: import amd.rocal.types as types -2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses ``fn.decoders.image`` to decode the raw `images `_. +2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses ``fn.decoders.image`` to decode the raw `images `_. .. code-block:: python :caption: Pipeline for TensorFlow @@ -170,7 +170,7 @@ Follow these steps: trainPipe.build() -3. Import libraries for `TensorFlow `_. +3. Import libraries for `TensorFlow `_. .. code-block:: python :caption: Import libraries for TensorFlow @@ -191,16 +191,16 @@ Follow these steps: train_label_one_hot_list = get_label_one_hot(train_label_ndArray) -4. To see and run a sample training script, refer to `rocAL TensorFlow example `_. +4. To see and run a sample training script, refer to `rocAL TensorFlow example `_. -.. _ml-perf: +.. __resnet50: -Run MLPerf Resnet50 classification training with rocAL +Run Resnet50 classification training with rocAL ======================================================= #. Ensure you have downloaded ``ILSVRC2012_img_val.tar`` (6.3GB) and ``ILSVRC2012_img_train.tar`` (138 GB) files and unzip into ``train`` and ``val`` folders -#. Build `MIVisionX Pytorch docker `_ +#. Build `rocAL Pytorch docker `_ * Run the docker image @@ -209,26 +209,13 @@ Run MLPerf Resnet50 classification training with rocAL sudo docker run -it -v :/data -v /:/dockerx -w /dockerx --privileged --device=/dev/kfd --device=/dev/dri --group-add video --shm-size=4g --ipc="host" --network=host .. note:: - Refer to the `docker `_ page for prerequisites and information on building the docker image. + Refer to the `docker `_ page for prerequisites and information on building the docker image. Optional: Map localhost directory on the docker image * Option to map the localhost directory with imagenet dataset folder to be accessed on the docker image. * Usage: ``-v {LOCAL_HOST_DIRECTORY_PATH}:{DOCKER_DIRECTORY_PATH}`` -#. Install rocAL ``python_pybind`` plugin as described above -#. Clone `MLPerf `_ repo and checkout ``mlperf-v1.1-rocal`` branch +#. To see and run a sample training script, refer to `rocAL Imagenet example `_. -.. code-block:: shell - - git clone -b mlperf-v1.1-rocal https://github.com/rrawther/MLPerf-mGPU - -#. Modify ``RN50_AMP_LARS_8GPUS_NCHW.sh`` or ``RN50_AMP_LARS_8GPUS_NHWC.sh`` to reflect correct path for imagenet directory -#. Run appropriate script as needed: - -.. code-block:: shell - - ./RN50_AMP_LARS_8GPUS_NCHW.sh - (or) - ./RN50_AMP_LARS_8GPUS_NHWC.sh diff --git a/docs/how-to/overview.rst b/docs/how-to/overview.rst index fc3d674ad..b134f0dde 100644 --- a/docs/how-to/overview.rst +++ b/docs/how-to/overview.rst @@ -109,4 +109,4 @@ Decoders Description ====================== ======================================== To see examples demonstrating the usage of decoders and readers, see -`MIVisionX rocAL Python Binding Examples `_. +`rocAL Python Examples `_. diff --git a/docs/how-to/using-with-cpp.rst b/docs/how-to/using-with-cpp.rst index 50704c60b..cb3a02188 100644 --- a/docs/how-to/using-with-cpp.rst +++ b/docs/how-to/using-with-cpp.rst @@ -92,7 +92,7 @@ See `rocalRelease example `_. +The example below shows how to create a pipeline, read JPEG images, perform certain augmentations on them, and show the output using OpenCV by utilizing `C++ API `_. .. code-block:: cpp :caption: Example Image Augmentation @@ -131,4 +131,4 @@ The example below shows how to create a pipeline, read JPEG images, perform cert } -To see a sample image augmentation application in C++, see `Image Augmentation `_. +To see a sample image augmentation application in C++, see `Image Augmentation `_. diff --git a/docs/how-to/using-with-python.rst b/docs/how-to/using-with-python.rst index 9e9f9e9cb..d5257ac69 100644 --- a/docs/how-to/using-with-python.rst +++ b/docs/how-to/using-with-python.rst @@ -188,11 +188,7 @@ Building the Pipeline Building the pipeline ensures that all operators are validated with the corresponding inputs and outputs. -<<<<<<< HEAD:docs/user_guide/ch4.md -To build the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L166 -======= -To build the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L166` ->>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst +To build the pipeline, see `https://github.com/ROCm/rocAL/blob/master/tests/python_api/unit_test.py#L166` .. code-block:: python :caption: Build the Pipeline @@ -207,14 +203,10 @@ Running the Pipeline To run/use the pipeline, simply create a data loader using the pipeline and iterate through it to get the next batch of images with labels. -<<<<<<< HEAD:docs/user_guide/ch4.md -To run the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L168 -======= -To run the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L168` +To run the pipeline, see `https://github.com/ROCm/rocAL/blob/master/tests/python_api/unit_test.py#L168` .. code-block:: python :caption: Run the Pipeline ->>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst # Dataloader data_loader = ROCALClassificationIterator(pipe,device=device) @@ -239,11 +231,7 @@ Performing Augmentations rocAL not only reads images from the disk and batches them into tensors, it can also perform various augmentations on those images. -<<<<<<< HEAD:docs/user_guide/ch4.md -To read images, decode them, and rotate them in the pipeline, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L77 -======= -To read images, decode them, and rotate them in the pipeline, see `https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/rocAL_api_python_unittest.py#L77` ->>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst +To read images, decode them, and rotate them in the pipeline, see `https://github.com/ROCm/rocAL/blob/master/tests/python_api/unit_test.py#L77` .. code-block:: python :caption: Perform Augmentations @@ -269,26 +257,18 @@ To run the pipeline, see: images, labels = pipe_out show_images(images) -<<<<<<< HEAD:docs/user_guide/ch4.md -All the rocAL data types are defined under [amd.rocal.types](https://github.com/ROCm/MIVisionX/blob/master/rocAL/rocAL_pybind/amd/rocal/types.py). Import this library in the application to access the various data types such as rocAL status, processing mode, tensor output type, image size evaluation policy, image color, tensor layout, decode device, resize scaling mode, and resize interpolation type. -======= rocAL Data Types ========================= -All the rocAL data types are defined under `amd.rocal.types `_. Import this library in the application to access the various data types such as rocAL status, processing mode, tensor output type, image size evaluation policy, image color, tensor layout, decode device, resize scaling mode, and resize interpolation type. ->>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst +All the rocAL data types are defined under `amd.rocal.types `_. Import this library in the application to access the various data types such as rocAL status, processing mode, tensor output type, image size evaluation policy, image color, tensor layout, decode device, resize scaling mode, and resize interpolation type. Here are some of the commonly used rocAL data types: * Processing modes: Values (GPU/CPU). Use the rocal_cpu argument in the pipeline to set the processing mode. -<<<<<<< HEAD:docs/user_guide/ch4.md -To see the usage of the above-mentioned data types, see https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/amd/rocal/pipeline.py#L97 -======= * rocal_cpu = True: This performs data loading on the CPU. If GPUs are heavily used for training, it is viable to create the data-loading pipeline using CPU. * rocal_cpu = False: This performs data loading on the available GPU as specified using the device_id argument in the pipeline. ->>>>>>> 80a9d60 (Documentation - reorg for diataxis (#102)):docs/how-to/using-with-python.rst * Tensor output types: Values (NCHW/NHWC). Example: diff --git a/docs/install/install.rst b/docs/install/install.rst index 7e6dca28d..b9fe216f4 100644 --- a/docs/install/install.rst +++ b/docs/install/install.rst @@ -24,7 +24,7 @@ Prerequisites * Install ROCm with `amdgpu-install `_ with ``--usecase=graphics,rocm --no-32`` * `RPP `_ * `AMD OpenVX™ `_ and AMD OpenVX™ Extensions: ``VX_RPP`` and ``AMD Media`` - MIVisionX Components -* `Turbo JPEG `_ - Version 2.0.6.2 from ``https://github.com/rrawther/libjpeg-turbo.git`` +* `Turbo JPEG `_ - Version 3.0.1 from ``https://github.com/libjpeg-turbo/libjpeg-turbo.git`` * `Half-precision floating-point `_ library - Version 1.12.0 or higher * `Google Protobuf `_ - Version 3.12.4 or higher * `LMBD Library `_ diff --git a/docs/user_guide/ch1.md b/docs/user_guide/ch1.md index 7ad19e5c6..422620071 100644 --- a/docs/user_guide/ch1.md +++ b/docs/user_guide/ch1.md @@ -80,4 +80,4 @@ rocAL operators offer the flexibility to run on CPU or GPU for building hybrid p | Image_random_crop | Decodes and randomly crops JPEG images | | Image_slice | Decodes and slices JPEG images | -To see examples demonstrating the usage of decoders and readers, [click here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples) +To see examples demonstrating the usage of decoders and readers, [click here](https://github.com/ROCm/rocAL/tree/master/rocAL/docs/examples) diff --git a/docs/user_guide/ch3.md b/docs/user_guide/ch3.md index aa86daa49..ad408c859 100644 --- a/docs/user_guide/ch3.md +++ b/docs/user_guide/ch3.md @@ -6,8 +6,8 @@ This chapter provides information about the installation of rocAL and related pa * Linux distribution * [AMD RPP](https://github.com/ROCm/rpp) -* [AMD OpenVX™](https://github.com/ROCm/MIVisionX/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` -* [Turbo JPEG](https://libjpeg-turbo.org/) - Version `2.0` or higher +* [AMD OpenVX™](https://github.com/ROCm/rocAL/tree/master/amd_openvx) and AMD OpenVX™ Extensions: `VX_RPP` and `AMD Media` +* [Turbo JPEG](https://libjpeg-turbo.org/) - Version `3.0` or higher * [Half-precision floating-point](https://half.sourceforge.net) library - Version `1.12.0` or higher * [Google Protobuf](https://developers.google.com/protocol-buffers) - Version `3.12.4` or higher * [LMBD Library](http://www.lmdb.tech/doc/) @@ -20,23 +20,23 @@ To see the list of supported platforms for rocAL, see the ROCm Installation Guid ## 3.3 Installing rocAL -rocAL is shipped along with MIVisionX. To build and install the rocAL C++ library, follow the instructions given [here](https://github.com/ROCm/MIVisionX#build--install-mivisionx) +To build and install the rocAL library, follow the instructions given [here](https://github.com/ROCm/rocAL#build-instructions) ## 3.4 Installing rocAL Python Package The rocAL Python package (rocal_pybind) is a separate redistributable wheel. rocal_pybind, which is created using Pybind11, enables data transfer between rocAL C++ API and Python API. With the help of rocal_pybind.so wrapper library, the rocAL functionality, which is primarily in C/C++, can be effectively used in Python. The Python package supports PyTorch, TensorFlow, Caffe2, and data readers available for various formats such as FileReader, COCO Reader, TFRecord Reader, and CaffeReader. -To build and install the Python package, see [rocAL python](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind). +To build and install the Python package, install the PyPackageInstall instruction [here](https://github.com/ROCm/rocAL#build-instructions) ## 3.5 Installing rocAL Using Framework Dockers To test the rocAL Python APIs using PyTorch or TensorFlow, we recommend building a docker with rocAL and ROCm using any of the links below: -- [rocAL PyTorch docker](https://github.com/ROCm/MIVisionX/tree/master/docker/pytorch) -- [rocAL TensorFlow docker](https://github.com/ROCm/MIVisionX/tree/master/docker/tensorflow) +- [rocAL PyTorch docker](https://github.com/ROCm/rocAL/tree/master/docker/rocal-with-pytorch.dockerfile) +- [rocAL TensorFlow docker](https://github.com/ROCm/rocAL/tree/master/docker/rocal-with-tensorflow.dockerfile) To use rocAL on Ubuntu, use the following dockers: -- [rocAL on ubuntu20](https://github.com/ROCm/MIVisionX/blob/master/docker/mivisionx-on-ubuntu20.dockerfile) -- [rocAL on Ubuntu22](https://github.com/ROCm/MIVisionX/blob/master/docker/mivisionx-on-ubuntu22.dockerfile) +- [rocAL on ubuntu20](https://github.com/ROCm/rocAL/blob/master/docker/rocAL-on-ubuntu20.dockerfile) +- [rocAL on Ubuntu22](https://github.com/ROCm/rocAL/blob/master/docker/rocAL-on-ubuntu22.dockerfile) diff --git a/docs/user_guide/ch5.md b/docs/user_guide/ch5.md index 149b4897d..144132a03 100644 --- a/docs/user_guide/ch5.md +++ b/docs/user_guide/ch5.md @@ -14,7 +14,7 @@ Build a rocAL PyTorch docker by following the steps here. Follow these steps: -1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L28). +1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/toynet_training/train.py#L28). ``` from amd.rocal.plugin.pytorch import ROCALClassificationIterator @@ -23,7 +23,7 @@ import amd.rocal.fn as fn import amd.rocal.types as types ``` -2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the [pipeline](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L38). +2. See a rocAL pipeline for PyTorch below. It reads data from the dataset using a fileReader and uses image_slice to decode the raw images. The other required augmentation operations are also defined in the [pipeline](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/toynet_training/train.py#L38). ``` def trainPipeline(data_path, batch_size, num_classes, one_hot, local_rank, world_size, num_thread, crop, rocal_cpu, fp16): @@ -61,7 +61,7 @@ import torch.nn.functional as F import torch.optim as optim ``` -4. Call the training pipeline with rocAL classification data [loader](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L78). +4. Call the training pipeline with rocAL classification data [loader](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/toynet_training/train.py#L78). ``` Def get_pytorch_train_loader(self): @@ -72,7 +72,7 @@ Def get_pytorch_train_loader(self): train_loader = ROCALClassificationIterator(pipe_train, device=”cpu” if self.rocal_cpu else “cuda”, device_id = self.local_rank) ``` -5. Run the [training](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/test_training.py#L179). +5. Run the [training](https://github.com/ROCm/rocAL/blob/master/docs/examples/pytorch/toynet_training/train.py#L179). ``` # Training loop @@ -88,9 +88,9 @@ Def get_pytorch_train_loader(self): inputs, labels = inputs.to(device), labels.to(device) ``` -6. Run the training as shown [here](https://github.com/ROCm/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). +6. Run the training as shown [here](https://github.com/ROCm/rocAL/tree/develop/rocAL/docs/examples/pytorch/toynet_training). -To see a sample training script, click [here](https://github.com/ROCm/MIVisionX/tree/develop/rocAL/docs/examples/pytorch). +To see a sample training script, click [here](https://github.com/ROCm/rocAL/tree/develop/rocAL/docs/examples/pytorch/toynet_training). ## 5.2 TensorFlow Integration @@ -104,7 +104,7 @@ Build a rocAL TensorFlow docker by following the steps here. Follow these steps: -1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L22). +1. Import libraries for [rocAL](https://github.com/ROCm/rocAL/blob/master/docs/examples/tf/pets_training/train.py#L22). ``` from amd.rocal.plugin.tf import ROCALIterator @@ -113,7 +113,7 @@ import amd.rocal.fn as fn import amd.rocal.types as types ``` -2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses fn.decoders.image to decode the raw [images](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L128). +2. See a rocAL pipeline for TensorFlow below. It reads data from the TFRecords using TFRecord Reader and uses fn.decoders.image to decode the raw [images](https://github.com/ROCm/rocAL/blob/master/examples/tf/pets_training/train.py#L128). ``` trainPipe = Pipeline(batch_size=TRAIN_BATCH_SIZE, num_threads=1, rocal_cpu=RUN_ON_HOST, tensor_layout = types.NHWC) @@ -140,7 +140,7 @@ trainPipe = Pipeline(batch_size=TRAIN_BATCH_SIZE, num_threads=1, rocal_cpu=RUN_O trainPipe.build() ``` -3. Import libraries for [TensorFlow](https://github.com/ROCm/rocAL/blob/master/rocAL_pybind/examples/tf_petsTrainingExample/train_withROCAL_withTFRecordReader.py#L174). +3. Import libraries for [TensorFlow](https://github.com/ROCm/rocAL/blob/master/examples/tf/pets_training/train.py#L174). ``` import tensorflow.compat.v1 as tf @@ -159,6 +159,6 @@ Run the training Session train_label_one_hot_list = get_label_one_hot(train_label_ndArray) ``` -4. Run the training as shown [here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). +4. Run the training as shown [here](https://github.com/ROCm/rocAL/tree/master/rocAL/examples/tf/pets_training/). -To see a sample training script, click [here](https://github.com/ROCm/MIVisionX/tree/master/rocAL/rocAL_pybind/examples/tf_petsTrainingExample). +To see a sample training script, click [here](https://github.com/ROCm/rocAL/tree/master/rocAL/examples/tf/pets_training/). diff --git a/docs/user_guide/ch6.md b/docs/user_guide/ch6.md index 5c164cc03..570aef275 100644 --- a/docs/user_guide/ch6.md +++ b/docs/user_guide/ch6.md @@ -72,7 +72,7 @@ extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context) ## 6.1.5 Image Augmentation Using C++ API -The example below shows how to create a pipeline, read JPEG images, perform certain augmentations on them, and show the output using OpenCV by utilizing C++ [APIs](https://github.com/ROCm/MIVisionX/blob/develop/apps/image_augmentation/image_augmentation.cpp#L103). +The example below shows how to create a pipeline, read JPEG images, perform certain augmentations on them, and show the output using OpenCV by utilizing C++ [APIs](https://github.com/ROCm/rocAL/blob/develop/tests/cpp_api/image_augmentation/image_augmentation.cpp#L103). ``` Auto handle = rocalCreate(inputBatchSize, processing_device?RocalProcessMode::ROCAL_PROCESS_GPU:RocalProcessMode::ROCAL_PROCESS_CPU, 0,1); @@ -109,4 +109,4 @@ while (!rocalIsEmpty(handle)) } ``` -To see a sample image augmentation application in C++, click [here](https://github.com/ROCm/MIVisionX/tree/develop/apps/image_augmentation). +To see a sample image augmentation application in C++, click [here](https://github.com/ROCm/rocAL/tree/develop/tests/cpp_api/image_augmentation). From a3801c93459b62eff3b8aa5600ed4d908fdabd05 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 10:28:46 -0700 Subject: [PATCH 09/21] fixes broken unit_test shell script for python --- tests/python_api/unit_tests.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/python_api/unit_tests.sh b/tests/python_api/unit_tests.sh index fdf6d1a07..431cb3a57 100755 --- a/tests/python_api/unit_tests.sh +++ b/tests/python_api/unit_tests.sh @@ -35,6 +35,9 @@ dev_end=1 rgb_start=0 rgb_end=1 +# python version +ver=$(python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";) + if [ "$#" -gt 0 ]; then if [ "$1" -eq 0 ]; then # For only HOST backend dev_start=0 From 1241dd7fe2655fb200bce562ce3c5156cb0f3744 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:08:11 -0700 Subject: [PATCH 10/21] output folder rename + adds readme to python tetss --- docs/examples/notebooks/tf_dataloader.ipynb | 4 +- tests/python_api/README.md | 64 +++++++++++++++---- tests/python_api/caffe2_reader.py | 8 +-- tests/python_api/caffe_reader.py | 8 +-- .../{coco_pipeline.py => coco_reader.py} | 4 +- tests/python_api/external_source_reader.py | 8 +-- tests/python_api/parse_config.py | 6 +- tests/python_api/pipeline.py | 4 +- .../pytorch_classification_reader.py | 4 +- tests/python_api/readers_test_file.sh | 16 ++--- tests/python_api/tf_classification_reader.py | 4 +- ...ion_pipeline.py => tf_detection_reader.py} | 4 +- tests/python_api/unit_test.py | 2 +- tests/python_api/video_pipeline.py | 6 +- 14 files changed, 90 insertions(+), 52 deletions(-) rename tests/python_api/{coco_pipeline.py => coco_reader.py} (99%) rename tests/python_api/{tf_detection_pipeline.py => tf_detection_reader.py} (98%) diff --git a/docs/examples/notebooks/tf_dataloader.ipynb b/docs/examples/notebooks/tf_dataloader.ipynb index dfdf74c30..5305cec9a 100644 --- a/docs/examples/notebooks/tf_dataloader.ipynb +++ b/docs/examples/notebooks/tf_dataloader.ipynb @@ -63,7 +63,7 @@ " \"image/class/label\": \"image/class/label\",\n", " \"image/filename\": \"image/filename\",\n", "}\n", - "path = \"OUTPUT_FOLDER/TF_READER/CLASSIFICATION/\"" + "path = \"output_folder/tf_reader/classification/\"" ] }, { @@ -171,7 +171,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.16" + "version": "3.10.12" } }, "nbformat": 4, diff --git a/tests/python_api/README.md b/tests/python_api/README.md index 3b2b5ad5e..015ede2f7 100644 --- a/tests/python_api/README.md +++ b/tests/python_api/README.md @@ -1,30 +1,40 @@ ## Set environmental variables `export ROCAL_DATA_PATH=/Absolute/Path/Of/MIVisionX-data/`` +### NOTE: Refer parse_config.py for more info on other args. This script is used with the `readers_test_file.sh` and `unit_tests.sh` -## Reader Pipeline tests: -* To test all the reader pipelines with a single script +## Reader Pipeline Tests: +* To test all the reader pipelines with a single script. The `readers_test_file.sh` tests the following cases: + * unit test + * coco reader + * caffe reader + * caffe2 reader + * tf classification reader + * tf detection reader * The default value of number of gpu's is "1" & display is "ON" by default -./readers_test_file.sh +`./readers_test_file.sh` ### Options: * To test a single reader / multiple reader pipelines: Use the same script `readers_test_file.sh` as above and make the respective " Pipeline " to test equal to "1" ``` unit_test = 1 -coco_pipeline = 0 +coco_reader = 0 ``` * Example : To run COCO Pipeline ``` unit_test=0 -coco_pipeline=1 +coco_reader=1 caffe_reader=0 caffe2_reader=0 tf_classification_reader=0 -tf_detection_pipeline=0 +tf_detection_reader=0 ``` -* To set number of GPUs/display/backend: +* To set options: + * Number of GPUs `-n` + * display `-d` + * backend `-b` ``` ./readers_test_file.sh -n -d ./readers_test_file.sh -n "1" -d "false" -b "cpu" @@ -35,7 +45,9 @@ tf_detection_pipeline=0 `./unit_tests.sh` -## Command line for individual files: +* This test also runs the `image_comaprison.py` script at the end to compare the results with the golden outputs from [MIVisionX-data](https://www.github.com/ROCm/MIVisionX-data). + +### Command line for individual files: * Test a single reader pipeline * Example: COCO Pipeline ``` @@ -54,14 +66,40 @@ tf_detection_pipeline=0 # Mention json path json_path=$ROCAL_DATA_PATH/coco/coco_10_img/annotations/instances_val2017.json - # coco_pipeline.py + # coco_reader.py # By default : cpu backend, NCHW format , fp32 # Annotation must be a json file # For printing all the arguments that can be passed from user - python$ver coco_pipeline.py -h + python$ver coco_reader.py -h + + python$ver coco_reader.py --image-dataset-path $data_dir --json-path $json_path --batch-size $batch_size --display --rocal-gpu --NHWC \ + --local-rank 0 --world-size $gpus_per_node --num-threads 1 --num-epochs 1 2>&1 | tee -a run.log.coco_reader.txt +``` +## Decoder Test: + +This test runs a simple decoder pipeline making use of a image file reader and resizing the given input images to 300x300. + +It uses the [AMD-TinyDataSet](../../data/images/AMD-tinyDataSet/) by default, unless otherwise specified by user. + +### Options: +```backend: +Input image folder: +``` + +* Usage: +```python3 decoder.py +python3 decoder.py gpu +``` + +## External source reader test: + +This test runs a pipeline making use of the external source reader in 3 different modes. +* Mode 0 - Filename +* Mode 1 - Raw compressed images +* Mode 2 - JPEG reader with OpenCV - python$ver coco_pipeline.py --image-dataset-path $data_dir --json-path $json_path --batch-size $batch_size --display --rocal-gpu --NHWC \ - --local-rank 0 --world-size $gpus_per_node --num-threads 1 --num-epochs 1 2>&1 | tee -a run.log.coco_pipeline.txt +* Usage: ``` -### [ NOTE: Refer parse_config.py for more info on other args] +python3 external_source_reader.py +``` \ No newline at end of file diff --git a/tests/python_api/caffe2_reader.py b/tests/python_api/caffe2_reader.py index 4caf647d9..e8b51cadf 100644 --- a/tests/python_api/caffe2_reader.py +++ b/tests/python_api/caffe2_reader.py @@ -38,7 +38,7 @@ def draw_patches(img, idx, bboxes=None, args=None): image = image.transpose([1, 2, 0]) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) if args.classification: - cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" + + cv2.imwrite("output_folder/caffe2_reader/classification/" + str(idx)+"_"+"train"+".png", image) else: if bboxes is not None: @@ -49,7 +49,7 @@ def draw_patches(img, idx, bboxes=None, args=None): thickness = 2 image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" + + cv2.imwrite("output_folder/caffe2_reader/detection/" + str(idx)+"_"+"train"+".png", image) @@ -70,9 +70,9 @@ def main(): print("num_classes:: ", num_classes) try: if args.classification: - path = "OUTPUT_FOLDER/CAFFE2_READER/CLASSIFICATION/" + path = "output_folder/caffe2_reader/classification/" else: - path = "OUTPUT_FOLDER/CAFFE2_READER/DETECTION/" + path = "output_folder/caffe2_reader/detection/" isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/caffe_reader.py b/tests/python_api/caffe_reader.py index 9cec39c82..16f820501 100644 --- a/tests/python_api/caffe_reader.py +++ b/tests/python_api/caffe_reader.py @@ -38,7 +38,7 @@ def draw_patches(img, idx, bboxes=None, args=None): image = image.transpose([1, 2, 0]) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) if args.classification: - cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" + + cv2.imwrite("output_folder/caffe_reader/classification/" + str(idx)+"_"+"train"+".png", image) else: if bboxes is not None: @@ -49,7 +49,7 @@ def draw_patches(img, idx, bboxes=None, args=None): thickness = 2 image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/CAFFE_READER/DETECTION/" + + cv2.imwrite("output_folder/caffe_reader/detection/" + str(idx)+"_"+"train"+".png", image) def main(): @@ -68,9 +68,9 @@ def main(): num_classes = len(next(os.walk(image_path))[1]) try: if args.classification: - path = "OUTPUT_FOLDER/CAFFE_READER/CLASSIFICATION/" + path = "output_folder/caffe_reader/classification/" else: - path = "OUTPUT_FOLDER/CAFFE_READER/DETECTION/" + path = "output_folder/caffe_reader/detection/" isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/coco_pipeline.py b/tests/python_api/coco_reader.py similarity index 99% rename from tests/python_api/coco_pipeline.py rename to tests/python_api/coco_reader.py index 79baaadd4..ce373abc0 100755 --- a/tests/python_api/coco_pipeline.py +++ b/tests/python_api/coco_reader.py @@ -138,7 +138,7 @@ def draw_patches(img, idx, bboxes, device, dtype, layout): image = cv2.UMat(image).get() image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/COCO_READER/" + + cv2.imwrite("output_folder/coco_reader/" + str(idx)+"_"+"train"+".png", image) @@ -157,7 +157,7 @@ def main(): tensor_format = types.NHWC if args.NHWC else types.NCHW tensor_dtype = types.FLOAT16 if args.fp16 else types.FLOAT try: - path = "OUTPUT_FOLDER/COCO_READER/" + path = "output_folder/coco_reader/" isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/external_source_reader.py b/tests/python_api/external_source_reader.py index a871d78e5..62f013e39 100644 --- a/tests/python_api/external_source_reader.py +++ b/tests/python_api/external_source_reader.py @@ -16,21 +16,21 @@ def main(): "/coco/coco_10_img/train_10images_2017/" device = "cpu" try: - path_mode0 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE0/" + path_mode0 = "output_folder/external_source_reader/mode0/" isExist = os.path.exists(path_mode0) if not isExist: os.makedirs(path_mode0) except OSError as error: print(error) try: - path_mode1 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE1/" + path_mode1 = "output_folder/external_source_reader/mode1/" isExist = os.path.exists(path_mode1) if not isExist: os.makedirs(path_mode1) except OSError as error: print(error) try: - path_mode2 = "OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE2/" + path_mode2 = "output_folder/external_source_reader/mode2/" isExist = os.path.exists(path_mode2) if not isExist: os.makedirs(path_mode2) @@ -44,7 +44,7 @@ def image_dump(img, idx, device="cpu", mode=0): img = (img).astype('uint8') if mode!=2: img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_IMAGES_PYTHON/EXTERNAL_SOURCE_READER/MODE" + str(mode) + "/"+ + cv2.imwrite("output_folder/external_source_reader/mode" + str(mode) + "/"+ str(idx)+"_"+"train"+".png", img) ##################### MODE 0 ######################### diff --git a/tests/python_api/parse_config.py b/tests/python_api/parse_config.py index afbacb1fd..ea919369e 100644 --- a/tests/python_api/parse_config.py +++ b/tests/python_api/parse_config.py @@ -105,10 +105,10 @@ def parse_args(): help='interpolation type used for resize and crop') python_unit_test.add_argument('--scaling-mode', '-sm', type=int, default=0, help='scaling mode type used for resize') - # coco_pipeline.py related options - coco_pipeline = parser.add_argument_group( + # coco_reader.py related options + coco_reader = parser.add_argument_group( 'coco-pipeline', 'coco-pipeline-related options') - coco_pipeline.add_argument('--json-path', '-json-path', type=str, + coco_reader.add_argument('--json-path', '-json-path', type=str, help='coco dataset json path') # caffe_reader.py related options caffe_pipeline = parser.add_argument_group( diff --git a/tests/python_api/pipeline.py b/tests/python_api/pipeline.py index 603dee8a4..a925f2877 100644 --- a/tests/python_api/pipeline.py +++ b/tests/python_api/pipeline.py @@ -39,7 +39,7 @@ def draw_patches(img, idx, device=True, layout="NCHW"): if layout == "NCHW": image = image.transpose([1, 2, 0]) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + + cv2.imwrite("output_folder/file_reader/" + str(idx)+"_"+"train"+".png", image * 255) @@ -48,7 +48,7 @@ def main(): print('Please pass image_folder cpu/gpu batch_size') exit(0) try: - path = "OUTPUT_FOLDER/FILE_READER/" + path = "output_folder/file_reader/" isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/pytorch_classification_reader.py b/tests/python_api/pytorch_classification_reader.py index 0ac21c72d..ceda16fb0 100644 --- a/tests/python_api/pytorch_classification_reader.py +++ b/tests/python_api/pytorch_classification_reader.py @@ -40,7 +40,7 @@ def draw_patches(img, idx, layout="nchw", dtype="fp32", device="cpu"): if dtype == "fp16": image = image.astype("uint8") image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/FILE_READER/" + str(idx) + + cv2.imwrite("output_folder/file_reader/" + str(idx) + "_" + "train" + ".png", image * 255) @@ -49,7 +49,7 @@ def main(): print("Please pass image_folder cpu/gpu batch_size") exit(0) try: - path = "OUTPUT_FOLDER/FILE_READER/" + path = "output_folder/file_reader/" isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/readers_test_file.sh b/tests/python_api/readers_test_file.sh index 4a1051da9..3790ea14d 100755 --- a/tests/python_api/readers_test_file.sh +++ b/tests/python_api/readers_test_file.sh @@ -95,11 +95,11 @@ ver=$(python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2 # USER TO MAKE CHANGES HERE FOR TEST # Make the respective " Pipeline " to test equal to 1 unit_test=1 -coco_pipeline=1 +coco_reader=1 caffe_reader=1 caffe2_reader=1 tf_classification_reader=1 -tf_detection_pipeline=1 +tf_detection_reader=1 video_pipeline=1 #################################################################################################################################### @@ -134,7 +134,7 @@ fi #################################################################################################################################### -if [[ coco_pipeline -eq 1 ]]; then +if [[ coco_reader -eq 1 ]]; then # Mention dataset_path data_dir=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/val_10images_2017/ @@ -143,11 +143,11 @@ if [[ coco_pipeline -eq 1 ]]; then # Mention json path json_path=$ROCAL_DATA_PATH/rocal_data/coco/coco_10_img/annotations/instances_val2017.json - # coco_pipeline.py + # coco_reader.py # By default : cpu backend, NCHW format , fp32 # Please pass annotation path in addition to other common args # Annotation must be a json file - python"$ver" coco_pipeline.py \ + python"$ver" coco_reader.py \ --image-dataset-path $data_dir \ --json-path $json_path \ --batch-size $batch_size \ @@ -300,16 +300,16 @@ fi #################################################################################################################################### -if [[ tf_detection_pipeline -eq 1 ]]; then +if [[ tf_detection_reader -eq 1 ]]; then # Mention dataset_path # Detection data_dir=$ROCAL_DATA_PATH/rocal_data/tf/detection/ - # tf_detection_pipeline.py + # tf_detection_reader.py # By default : cpu backend, NCHW format , fp32 # use --classification for Classification / --no-classification for Detection - python"$ver" tf_detection_pipeline.py \ + python"$ver" tf_detection_reader.py \ --image-dataset-path $data_dir \ --no-classification \ --batch-size 100 \ diff --git a/tests/python_api/tf_classification_reader.py b/tests/python_api/tf_classification_reader.py index 44fcd87a1..adae068fa 100644 --- a/tests/python_api/tf_classification_reader.py +++ b/tests/python_api/tf_classification_reader.py @@ -37,7 +37,7 @@ def draw_patches(img, idx, device_type, args=None): if not args.NHWC: img = img.transpose([0, 1, 2]) image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - cv2.imwrite("OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" + + cv2.imwrite("output_folder/tf_reader/classification/" + str(idx) + "_" + "train" + ".png", image) @@ -58,7 +58,7 @@ def main(): 'image/filename': 'image/filename' } try: - path = "OUTPUT_FOLDER/TF_READER/CLASSIFICATION/" + path = "output_folder/tf_reader/classification/" is_exist = os.path.exists(path) if not is_exist: os.makedirs(path) diff --git a/tests/python_api/tf_detection_pipeline.py b/tests/python_api/tf_detection_reader.py similarity index 98% rename from tests/python_api/tf_detection_pipeline.py rename to tests/python_api/tf_detection_reader.py index 8b9aa3920..beb477e68 100644 --- a/tests/python_api/tf_detection_pipeline.py +++ b/tests/python_api/tf_detection_reader.py @@ -66,7 +66,7 @@ def draw_patches(img, idx, bboxes, device_type, args=None): image = cv2.UMat(image).get() image = cv2.rectangle(image, (int(loc_[0]), int(loc_[1])), (int( (loc_[2])), int((loc_[3]))), color, thickness) - cv2.imwrite("OUTPUT_FOLDER/TF_READER/DETECTION/" + + cv2.imwrite("output_folder/tf_reader/detection/" + str(idx) + "_" + "train" + ".png", image) @@ -92,7 +92,7 @@ def main(): 'image/filename': 'image/filename' } try: - path = "OUTPUT_FOLDER/TF_READER/DETECTION" + path = "output_folder/tf_reader/detection" is_exist = os.path.exists(path) if not is_exist: os.makedirs(path) diff --git a/tests/python_api/unit_test.py b/tests/python_api/unit_test.py index bfd81590c..803a4b1a9 100644 --- a/tests/python_api/unit_test.py +++ b/tests/python_api/unit_test.py @@ -101,7 +101,7 @@ def main(): sys.exit(0) try: - path = "OUTPUT_FOLDER/FILE_READER/" + args.augmentation_name + path = "output_folder/file_reader/" + args.augmentation_name isExist = os.path.exists(path) if not isExist: os.makedirs(path) diff --git a/tests/python_api/video_pipeline.py b/tests/python_api/video_pipeline.py index 1a1556a9a..5f106ff21 100644 --- a/tests/python_api/video_pipeline.py +++ b/tests/python_api/video_pipeline.py @@ -103,10 +103,10 @@ def draw_frames(img, batch_idx, iter_idx, layout): image = image.transpose([1, 2, 0]) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) import os - if not os.path.exists("OUTPUT_FOLDER/VIDEO_READER"): - os.makedirs("OUTPUT_FOLDER/VIDEO_READER") + if not os.path.exists("output_folder/video_reader"): + os.makedirs("output_folder/video_reader") image = cv2.UMat(image).get() - cv2.imwrite("OUTPUT_FOLDER/VIDEO_READER/" + + cv2.imwrite("output_folder/video_reader/" + "iter_"+str(iter_idx)+"_batch_"+str(batch_idx)+".png", image) From d68a79678a4d9fd251fe46d91d227de741ec1338 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:09:47 -0700 Subject: [PATCH 11/21] fix decoder.py --- tests/python_api/decoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python_api/decoder.py b/tests/python_api/decoder.py index 073fa383c..f2d51124f 100644 --- a/tests/python_api/decoder.py +++ b/tests/python_api/decoder.py @@ -9,7 +9,7 @@ import cupy as cp seed = 1549361629 -image_dir = "../../../data/images/AMD-tinyDataSet/" +image_dir = "../../data/images/AMD-tinyDataSet/" batch_size = 4 gpu_id = 0 From e0ac87d9d3f8be88b029655f03ff5f0dd636b6b7 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:25:44 -0700 Subject: [PATCH 12/21] external_source_reader.py fix --- tests/python_api/external_source_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python_api/external_source_reader.py b/tests/python_api/external_source_reader.py index 62f013e39..772209254 100644 --- a/tests/python_api/external_source_reader.py +++ b/tests/python_api/external_source_reader.py @@ -13,7 +13,7 @@ def main(): batch_size = 3 data_dir = os.environ["ROCAL_DATA_PATH"] + \ - "/coco/coco_10_img/train_10images_2017/" + "rocal_data/coco/coco_10_img/train_10images_2017/" device = "cpu" try: path_mode0 = "output_folder/external_source_reader/mode0/" From 9c3b30e1ae0982a4d7db467da992946601b6ae99 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:26:47 -0700 Subject: [PATCH 13/21] external_source_reader.py readme update --- tests/python_api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python_api/README.md b/tests/python_api/README.md index 015ede2f7..cdffb1744 100644 --- a/tests/python_api/README.md +++ b/tests/python_api/README.md @@ -94,7 +94,7 @@ python3 decoder.py gpu ## External source reader test: -This test runs a pipeline making use of the external source reader in 3 different modes. +This test runs a pipeline making use of the external source reader in 3 different modes. It uses coco2017 images by default. * Mode 0 - Filename * Mode 1 - Raw compressed images * Mode 2 - JPEG reader with OpenCV From 8e828981442e74d4296a0f86c998370a841f60ea Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:37:09 -0700 Subject: [PATCH 14/21] add readerme for basic test cpp --- tests/cpp_api/basic_test/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/cpp_api/basic_test/README.md diff --git a/tests/cpp_api/basic_test/README.md b/tests/cpp_api/basic_test/README.md new file mode 100644 index 000000000..09676e2b0 --- /dev/null +++ b/tests/cpp_api/basic_test/README.md @@ -0,0 +1,24 @@ +# basic test +This application demonstrates a basic usage of rocAL's C API to load images from the disk and tests the functionality for getting image labels and displays the output images. +

+ +## Build Instructions + +### Pre-requisites +* Ubuntu Linux, [version `16.04` or later](https://www.microsoft.com/software-download/windows10) +* rocAL library +* [OpenCV 3.1](https://github.com/opencv/opencv/releases) or higher +* ROCm Performance Primitives (RPP) + +### build + ```` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rocm/lib + mkdir build + cd build + cmake ../ + make + ```` +### running the application + ``` + ./basic_test decode_width decode_height decode_shard_counts + ``` \ No newline at end of file From c57cbede72be4bac3c2de5aba7d75bba87913b56 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:40:07 -0700 Subject: [PATCH 15/21] dataloader cpp test update --- tests/cpp_api/dataloader/README.md | 2 +- tests/cpp_api/dataloader/dataloader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpp_api/dataloader/README.md b/tests/cpp_api/dataloader/README.md index d6ed8ae1d..13412750d 100644 --- a/tests/cpp_api/dataloader/README.md +++ b/tests/cpp_api/dataloader/README.md @@ -20,5 +20,5 @@ This application demonstrates a basic usage of rocAL's C API to load RAW images ```` ### running the application ```` - ./dataloader + ./dataloader decode_width decode_height batch_size display_on_off ```` diff --git a/tests/cpp_api/dataloader/dataloader.cpp b/tests/cpp_api/dataloader/dataloader.cpp index 540efd196..235a78dcb 100644 --- a/tests/cpp_api/dataloader/dataloader.cpp +++ b/tests/cpp_api/dataloader/dataloader.cpp @@ -49,7 +49,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf("Usage: image_augmentation decode_width decode_height batch_size display_on_off \n"); + printf("Usage: image_augmentation decode_width decode_height batch_size display_on_off \n"); return -1; } int argIdx = 0; From 3ba874ad8ca54c4ac472e1055ed317cb79470cc5 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:47:30 -0700 Subject: [PATCH 16/21] dataloader mutlithreaded updates --- tests/cpp_api/dataloader_multithread/README.md | 2 +- .../dataloader_multithread/dataloader_multithread.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/cpp_api/dataloader_multithread/README.md b/tests/cpp_api/dataloader_multithread/README.md index f89d75e31..2bc50c3c4 100644 --- a/tests/cpp_api/dataloader_multithread/README.md +++ b/tests/cpp_api/dataloader_multithread/README.md @@ -20,5 +20,5 @@ This application demonstrates a basic usage of rocAL's C API to use sharded data ```` ### running the application ```` - ./dataloader_multithread =1)/(cpu:0)> + ./dataloader_multithread =1)/(cpu:0)> ```` diff --git a/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp b/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp index c5e35bc9f..3334ce5c5 100644 --- a/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp +++ b/tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp @@ -195,9 +195,8 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf( - "Usage: dataloader_multithread 1(gpu)/cpu=0> num_shards, \ - decode_width decode_height batch_size shuffle display_on_off dec_mode<0(tjpeg)/1(opencv)/2(hwdec)>\n"); + std::cout << "Usage: dataloader_multithread " << + "num_shards decode_width decode_height batch_size shuffle display_on_off dec_mode<0(tjpeg)/1(opencv)/2(hwdec)>" << std::endl; return -1; } int argIdx = 0; From d24e2bbcc74a1336f0bbdc344e23c56bc064a943 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 11:52:52 -0700 Subject: [PATCH 17/21] tf dataloader cpp update --- tests/cpp_api/dataloader_tf/README.md | 2 +- tests/cpp_api/dataloader_tf/dataloader_tf.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpp_api/dataloader_tf/README.md b/tests/cpp_api/dataloader_tf/README.md index eb0db5c67..0b0bbec3a 100644 --- a/tests/cpp_api/dataloader_tf/README.md +++ b/tests/cpp_api/dataloader_tf/README.md @@ -19,5 +19,5 @@ This application demonstrates a basic usage of rocAL's C API to load TfRecords f ```` ### running the application ```` - ./dataloader_tf + ./dataloader_tf ```` diff --git a/tests/cpp_api/dataloader_tf/dataloader_tf.cpp b/tests/cpp_api/dataloader_tf/dataloader_tf.cpp index 60068b56d..71eb05d3b 100644 --- a/tests/cpp_api/dataloader_tf/dataloader_tf.cpp +++ b/tests/cpp_api/dataloader_tf/dataloader_tf.cpp @@ -49,7 +49,7 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - printf("Usage: dataloader_tf display_on_off \n"); + printf("Usage: dataloader_tf display_on_off \n"); return -1; } int argIdx = 0; From 9c63c14c15a0cc09b34532aec1e5ec1278271b64 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 12:25:49 -0700 Subject: [PATCH 18/21] cpp external source updates --- tests/cpp_api/external_source/README.md | 6 +++--- tests/cpp_api/external_source/external_source.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/cpp_api/external_source/README.md b/tests/cpp_api/external_source/README.md index e89ecea2a..3a06650ec 100644 --- a/tests/cpp_api/external_source/README.md +++ b/tests/cpp_api/external_source/README.md @@ -23,6 +23,6 @@ This application demonstrates a basic usage of rocAL's C++ API to load images fr ### running the application - ````bash - external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode - ```` + ``` + ./external_source decode_width decode_height batch_size gray_scale/rgb/rgbplanar display_on_off external_source_mode + ``` diff --git a/tests/cpp_api/external_source/external_source.cpp b/tests/cpp_api/external_source/external_source.cpp index 5c66f8b2e..6327cc9bf 100644 --- a/tests/cpp_api/external_source/external_source.cpp +++ b/tests/cpp_api/external_source/external_source.cpp @@ -63,7 +63,7 @@ int main(int argc, const char **argv) { const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { printf( - "Usage: external_source " + "Usage: external_source " " decode_width decode_height batch_size " "gray_scale/rgb/rgbplanar display_on_off external_source_mode\n"); return -1; From 54bdba432336cbcbabc644234e9cdc8a55e87e80 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 12:34:05 -0700 Subject: [PATCH 19/21] fixes path relative to image_augmentation app --- tests/cpp_api/image_augmentation/CMakeLists.txt | 2 +- tests/cpp_api/image_augmentation/README.md | 2 +- tests/cpp_api/image_augmentation/image_augmentation.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/cpp_api/image_augmentation/CMakeLists.txt b/tests/cpp_api/image_augmentation/CMakeLists.txt index e25a3494e..ec3fd8703 100644 --- a/tests/cpp_api/image_augmentation/CMakeLists.txt +++ b/tests/cpp_api/image_augmentation/CMakeLists.txt @@ -47,7 +47,7 @@ set(CMAKE_SKIP_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory") include(GNUInstallDirs) -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../../cmake) find_package(AMDRPP REQUIRED) find_package(MIVisionX REQUIRED) diff --git a/tests/cpp_api/image_augmentation/README.md b/tests/cpp_api/image_augmentation/README.md index 02270a4b6..8d0b58e69 100644 --- a/tests/cpp_api/image_augmentation/README.md +++ b/tests/cpp_api/image_augmentation/README.md @@ -26,5 +26,5 @@ This application demonstrates the basic usage of rocAL's C API to load JPEG imag ### Running the application ``` - image_augmentation +./image_augmentation ``` diff --git a/tests/cpp_api/image_augmentation/image_augmentation.cpp b/tests/cpp_api/image_augmentation/image_augmentation.cpp index 73154d35a..f67792e04 100644 --- a/tests/cpp_api/image_augmentation/image_augmentation.cpp +++ b/tests/cpp_api/image_augmentation/image_augmentation.cpp @@ -209,8 +209,8 @@ int main(int argc, const char** argv) { /*>>>>>>>>>>>>>>>>>>> Diplay using OpenCV <<<<<<<<<<<<<<<<<*/ // initializations for logos and heading cv::Mat AMD_Epyc_Black_resize, AMD_ROCm_Black_resize; - AMD_Epyc_Black_resize = cv::imread("../../../samples/images/amd-epyc-black-resize.png"); - AMD_ROCm_Black_resize = cv::imread("../../../samples/images/rocm-black-resize.png"); + AMD_Epyc_Black_resize = cv::imread("../../../../docs/data/amd-epyc-black-resize.png"); + AMD_ROCm_Black_resize = cv::imread("../../../../docs/data/rocm-black-resize.png"); int fontFace = CV_FONT_HERSHEY_DUPLEX; int thickness = 1.3; std::string bufferName = "rocAL Image Augmentation"; From 0cc9a99f53cce842893d409d64f5020ce9f513c7 Mon Sep 17 00:00:00 2001 From: LAkshmiKuamr23 Date: Fri, 29 Mar 2024 13:52:11 -0700 Subject: [PATCH 20/21] add missign images for apps --- docs/data/amd-epyc-black-resize.png | Bin 0 -> 6824 bytes docs/data/rocm-black-resize.png | Bin 0 -> 8045 bytes tests/cpp_api/performance_tests/README.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/data/amd-epyc-black-resize.png create mode 100644 docs/data/rocm-black-resize.png diff --git a/docs/data/amd-epyc-black-resize.png b/docs/data/amd-epyc-black-resize.png new file mode 100644 index 0000000000000000000000000000000000000000..a79b38ca95757366853480ceb2ee0d75abf14aff GIT binary patch literal 6824 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 literal 0 HcmV?d00001 diff --git a/docs/data/rocm-black-resize.png b/docs/data/rocm-black-resize.png new file mode 100644 index 0000000000000000000000000000000000000000..34829a6ad59ba284aed48cafe271d56275104079 GIT binary patch literal 8045 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 UI3S!e1}8w2 Date: Tue, 2 Apr 2024 09:50:17 -0700 Subject: [PATCH 21/21] readme update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b524f3515..caa9e926e 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ For the convenience of the developer, we here provide the setup script which wil ``` + run the below commands to build rocAL + **Note:** Use `-DPYTHONVERSION=3.x` with `cmake` for using a specific Python3 version if required. ``` mkdir build-hip cd build-hip