diff --git a/ai-solutions/android/03-ObjectDetection/GenerateDLC.ipynb b/ai-solutions/android/03-ObjectDetection/GenerateDLC.ipynb new file mode 100644 index 00000000..cfc14630 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/GenerateDLC.ipynb @@ -0,0 +1,376 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "721491e1", + "metadata": {}, + "source": [ + "## Steps for generating YoloNAS dlc\n", + "#### Note->Use python3.8 or above for generating onnx and python3.6 for generating dlc" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d1d3b4eb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: super-gradients==3.1.2 in /usr/local/lib/python3.8/site-packages (3.1.2)\n", + "Requirement already satisfied: torch>=1.9.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.13.1)\n", + "Requirement already satisfied: tqdm>=4.57.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (4.65.0)\n", + "Requirement already satisfied: boto3>=1.17.15 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.28.2)\n", + "Requirement already satisfied: jsonschema>=3.2.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (4.17.3)\n", + "Requirement already satisfied: Deprecated>=1.2.11 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.2.14)\n", + "Requirement already satisfied: opencv-python>=4.5.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (4.5.2.52)\n", + "Requirement already satisfied: scipy>=1.6.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.10.1)\n", + "Requirement already satisfied: matplotlib>=3.3.4 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (3.3.4)\n", + "Requirement already satisfied: psutil>=5.8.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (5.9.5)\n", + "Requirement already satisfied: tensorboard>=2.4.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (2.13.0)\n", + "Requirement already satisfied: setuptools>=21.0.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (57.5.0)\n", + "Requirement already satisfied: coverage~=5.3.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (5.3.1)\n", + "Requirement already satisfied: torchvision>=0.10.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (0.14.1)\n", + "Requirement already satisfied: sphinx~=4.0.2 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (4.0.3)\n", + "Requirement already satisfied: sphinx-rtd-theme in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.2.2)\n", + "Requirement already satisfied: torchmetrics==0.8 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (0.8.0)\n", + "Requirement already satisfied: hydra-core>=1.2.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.3.2)\n", + "Requirement already satisfied: omegaconf in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (2.3.0)\n", + "Requirement already satisfied: onnxruntime==1.13.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.13.1)\n", + "Requirement already satisfied: onnx==1.13.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.13.0)\n", + "Requirement already satisfied: pillow!=8.3,>=5.3.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (10.0.0)\n", + "Requirement already satisfied: pip-tools>=6.12.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (6.14.0)\n", + "Requirement already satisfied: pyparsing==2.4.5 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (2.4.5)\n", + "Requirement already satisfied: einops==0.3.2 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (0.3.2)\n", + "Requirement already satisfied: pycocotools==2.0.6 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (2.0.6)\n", + "Requirement already satisfied: protobuf==3.20.3 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (3.20.3)\n", + "Requirement already satisfied: treelib==1.6.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.6.1)\n", + "Requirement already satisfied: termcolor==1.1.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.1.0)\n", + "Requirement already satisfied: packaging>=20.4 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (21.0)\n", + "Requirement already satisfied: wheel>=0.38.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (0.40.0)\n", + "Requirement already satisfied: pygments>=2.7.4 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (2.15.1)\n", + "Requirement already satisfied: stringcase>=1.2.0 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.2.0)\n", + "Requirement already satisfied: numpy<=1.23 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (1.23.0)\n", + "Requirement already satisfied: rapidfuzz in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (3.1.1)\n", + "Requirement already satisfied: json-tricks==3.16.1 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (3.16.1)\n", + "Requirement already satisfied: onnx-simplifier<1.0,>=0.3.6 in /usr/local/lib/python3.8/site-packages (from super-gradients==3.1.2) (0.4.33)\n", + "Requirement already satisfied: typing-extensions>=3.6.2.1 in /usr/local/lib/python3.8/site-packages (from onnx==1.13.0->super-gradients==3.1.2) (4.7.1)\n", + "Requirement already satisfied: coloredlogs in /usr/local/lib/python3.8/site-packages (from onnxruntime==1.13.1->super-gradients==3.1.2) (15.0.1)\n", + "Requirement already satisfied: flatbuffers in /usr/local/lib/python3.8/site-packages (from onnxruntime==1.13.1->super-gradients==3.1.2) (23.5.26)\n", + "Requirement already satisfied: sympy in /usr/local/lib/python3.8/site-packages (from onnxruntime==1.13.1->super-gradients==3.1.2) (1.12)\n", + "Requirement already satisfied: pyDeprecate==0.3.* in /usr/local/lib/python3.8/site-packages (from torchmetrics==0.8->super-gradients==3.1.2) (0.3.2)\n", + "Requirement already satisfied: future in /usr/local/lib/python3.8/site-packages (from treelib==1.6.1->super-gradients==3.1.2) (0.18.3)\n", + "Requirement already satisfied: botocore<1.32.0,>=1.31.2 in /usr/local/lib/python3.8/site-packages (from boto3>=1.17.15->super-gradients==3.1.2) (1.31.2)\n", + "Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /usr/local/lib/python3.8/site-packages (from boto3>=1.17.15->super-gradients==3.1.2) (1.0.1)\n", + "Requirement already satisfied: s3transfer<0.7.0,>=0.6.0 in /usr/local/lib/python3.8/site-packages (from boto3>=1.17.15->super-gradients==3.1.2) (0.6.1)\n", + "Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.8/site-packages (from Deprecated>=1.2.11->super-gradients==3.1.2) (1.15.0)\n", + "Requirement already satisfied: antlr4-python3-runtime==4.9.* in /usr/local/lib/python3.8/site-packages (from hydra-core>=1.2.0->super-gradients==3.1.2) (4.9.3)\n", + "Requirement already satisfied: importlib-resources in /usr/local/lib/python3.8/site-packages (from hydra-core>=1.2.0->super-gradients==3.1.2) (5.12.0)\n", + "Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.8/site-packages (from jsonschema>=3.2.0->super-gradients==3.1.2) (23.1.0)\n", + "Requirement already satisfied: pkgutil-resolve-name>=1.3.10 in /usr/local/lib/python3.8/site-packages (from jsonschema>=3.2.0->super-gradients==3.1.2) (1.3.10)\n", + "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.8/site-packages (from jsonschema>=3.2.0->super-gradients==3.1.2) (0.19.3)\n", + "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.8/site-packages (from matplotlib>=3.3.4->super-gradients==3.1.2) (0.11.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.8/site-packages (from matplotlib>=3.3.4->super-gradients==3.1.2) (1.4.4)\n", + "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.8/site-packages (from matplotlib>=3.3.4->super-gradients==3.1.2) (2.8.2)\n", + "Requirement already satisfied: PyYAML>=5.1.0 in /usr/local/lib/python3.8/site-packages (from omegaconf->super-gradients==3.1.2) (6.0)\n", + "Requirement already satisfied: rich in /usr/local/lib/python3.8/site-packages (from onnx-simplifier<1.0,>=0.3.6->super-gradients==3.1.2) (13.4.2)\n", + "Requirement already satisfied: build in /usr/local/lib/python3.8/site-packages (from pip-tools>=6.12.1->super-gradients==3.1.2) (0.10.0)\n", + "Requirement already satisfied: click>=8 in /usr/local/lib/python3.8/site-packages (from pip-tools>=6.12.1->super-gradients==3.1.2) (8.1.5)\n", + "Requirement already satisfied: pip>=22.2 in /usr/local/lib/python3.8/site-packages (from pip-tools>=6.12.1->super-gradients==3.1.2) (23.1.2)\n", + "Requirement already satisfied: tomli in /usr/local/lib/python3.8/site-packages (from pip-tools>=6.12.1->super-gradients==3.1.2) (2.0.1)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: sphinxcontrib-applehelp in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.0.4)\n", + "Requirement already satisfied: sphinxcontrib-devhelp in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.0.2)\n", + "Requirement already satisfied: sphinxcontrib-jsmath in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.0.1)\n", + "Requirement already satisfied: sphinxcontrib-htmlhelp in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (2.0.1)\n", + "Requirement already satisfied: sphinxcontrib-serializinghtml in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.1.5)\n", + "Requirement already satisfied: sphinxcontrib-qthelp in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.0.3)\n", + "Requirement already satisfied: Jinja2>=2.3 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (3.1.2)\n", + "Requirement already satisfied: docutils<0.18,>=0.14 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (0.17.1)\n", + "Requirement already satisfied: snowballstemmer>=1.1 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (2.2.0)\n", + "Requirement already satisfied: babel>=1.3 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (2.12.1)\n", + "Requirement already satisfied: alabaster<0.8,>=0.7 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (0.7.13)\n", + "Requirement already satisfied: imagesize in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (1.4.1)\n", + "Requirement already satisfied: requests>=2.5.0 in /usr/local/lib/python3.8/site-packages (from sphinx~=4.0.2->super-gradients==3.1.2) (2.31.0)\n", + "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (1.0.0)\n", + "Requirement already satisfied: grpcio>=1.48.2 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (1.56.0)\n", + "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (2.21.0)\n", + "Requirement already satisfied: google-auth-oauthlib<1.1,>=0.5 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (1.0.0)\n", + "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (3.4.3)\n", + "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (0.7.1)\n", + "Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.8/site-packages (from tensorboard>=2.4.1->super-gradients==3.1.2) (2.3.6)\n", + "Requirement already satisfied: nvidia-cuda-runtime-cu11==11.7.99 in /usr/local/lib/python3.8/site-packages (from torch>=1.9.0->super-gradients==3.1.2) (11.7.99)\n", + "Requirement already satisfied: nvidia-cudnn-cu11==8.5.0.96 in /usr/local/lib/python3.8/site-packages (from torch>=1.9.0->super-gradients==3.1.2) (8.5.0.96)\n", + "Requirement already satisfied: nvidia-cublas-cu11==11.10.3.66 in /usr/local/lib/python3.8/site-packages (from torch>=1.9.0->super-gradients==3.1.2) (11.10.3.66)\n", + "Requirement already satisfied: nvidia-cuda-nvrtc-cu11==11.7.99 in /usr/local/lib/python3.8/site-packages (from torch>=1.9.0->super-gradients==3.1.2) (11.7.99)\n", + "Requirement already satisfied: sphinxcontrib-jquery<5,>=4 in /usr/local/lib/python3.8/site-packages (from sphinx-rtd-theme->super-gradients==3.1.2) (4.1)\n", + "Requirement already satisfied: six in /usr/local/lib/python3.8/site-packages (from absl-py>=0.4->tensorboard>=2.4.1->super-gradients==3.1.2) (1.16.0)\n", + "Requirement already satisfied: pytz>=2015.7 in /usr/local/lib/python3.8/site-packages (from babel>=1.3->sphinx~=4.0.2->super-gradients==3.1.2) (2023.3)\n", + "Requirement already satisfied: urllib3<1.27,>=1.25.4 in /usr/local/lib/python3.8/site-packages (from botocore<1.32.0,>=1.31.2->boto3>=1.17.15->super-gradients==3.1.2) (1.26.16)\n", + "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.8/site-packages (from google-auth<3,>=1.6.3->tensorboard>=2.4.1->super-gradients==3.1.2) (5.3.1)\n", + "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.8/site-packages (from google-auth<3,>=1.6.3->tensorboard>=2.4.1->super-gradients==3.1.2) (0.3.0)\n", + "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.8/site-packages (from google-auth<3,>=1.6.3->tensorboard>=2.4.1->super-gradients==3.1.2) (4.9)\n", + "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.8/site-packages (from google-auth-oauthlib<1.1,>=0.5->tensorboard>=2.4.1->super-gradients==3.1.2) (1.3.1)\n", + "Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.8/site-packages (from importlib-resources->hydra-core>=1.2.0->super-gradients==3.1.2) (3.15.0)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/site-packages (from Jinja2>=2.3->sphinx~=4.0.2->super-gradients==3.1.2) (2.1.3)\n", + "Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.8/site-packages (from markdown>=2.6.8->tensorboard>=2.4.1->super-gradients==3.1.2) (6.7.0)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.8/site-packages (from requests>=2.5.0->sphinx~=4.0.2->super-gradients==3.1.2) (3.1.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.8/site-packages (from requests>=2.5.0->sphinx~=4.0.2->super-gradients==3.1.2) (3.4)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.8/site-packages (from requests>=2.5.0->sphinx~=4.0.2->super-gradients==3.1.2) (2023.5.7)\n", + "Requirement already satisfied: pyproject_hooks in /usr/local/lib/python3.8/site-packages (from build->pip-tools>=6.12.1->super-gradients==3.1.2) (1.0.0)\n", + "Requirement already satisfied: humanfriendly>=9.1 in /usr/local/lib/python3.8/site-packages (from coloredlogs->onnxruntime==1.13.1->super-gradients==3.1.2) (10.0)\n", + "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.8/site-packages (from rich->onnx-simplifier<1.0,>=0.3.6->super-gradients==3.1.2) (3.0.0)\n", + "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.8/site-packages (from sympy->onnxruntime==1.13.1->super-gradients==3.1.2) (1.3.0)\n", + "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.8/site-packages (from markdown-it-py>=2.2.0->rich->onnx-simplifier<1.0,>=0.3.6->super-gradients==3.1.2) (0.1.2)\n", + "Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in /usr/local/lib/python3.8/site-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard>=2.4.1->super-gradients==3.1.2) (0.5.0)\n", + "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.8/site-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<1.1,>=0.5->tensorboard>=2.4.1->super-gradients==3.1.2) (3.2.2)\n", + "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n", + "\u001b[0m" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.8/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "[2023-07-13 17:15:54] INFO - crash_tips_setup.py - Crash tips is enabled. You can set your environment variable to CRASH_HANDLER=FALSE to disable it\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The console stream is logged into /root/sg_logs/console.log\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[2023-07-13 17:15:57] WARNING - __init__.py - Failed to import pytorch_quantization\n", + "[2023-07-13 17:15:57] WARNING - calibrator.py - Failed to import pytorch_quantization\n", + "[2023-07-13 17:15:57] WARNING - export.py - Failed to import pytorch_quantization\n", + "[2023-07-13 17:15:57] WARNING - selective_quantization_utils.py - Failed to import pytorch_quantization\n", + "[2023-07-13 17:15:58] INFO - checkpoint_utils.py - License Notification: YOLO-NAS pre-trained weights are subjected to the specific license terms and conditions detailed in \n", + "https://github.com/Deci-AI/super-gradients/blob/master/LICENSE.YOLONAS.md\n", + "By downloading the pre-trained weight files you agree to comply with these terms.\n" + ] + } + ], + "source": [ + "## Note- Use python3.8 or above for generating onnx\n", + "\n", + "!pip install super-gradients==3.1.2\n", + "\n", + "\n", + "## Downloading Model from git repo\n", + "import torch\n", + "# Load model with pretrained weights\n", + "from super_gradients.training import models\n", + "from super_gradients.common.object_names import Models\n", + "\n", + "model = models.get(Models.YOLO_NAS_S, pretrained_weights=\"coco\")\n", + "\n", + "# Prepare model for conversion\n", + "# Input size is in format of [Batch x Channels x Width x Height] where 640 is the standard COCO dataset dimensions\n", + "model.eval()\n", + "model.prep_model_for_conversion(input_size=[1, 3, 320, 320])\n", + "\n", + "# Create dummy_input\n", + "dummy_input = torch.randn([1, 3, 320, 320], device=\"cpu\")\n", + "\n", + "# Convert model to onnx\n", + "torch.onnx.export(model, dummy_input, \"yolo_nas_s.onnx\", opset_version=11)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "bb97b534", + "metadata": {}, + "source": [ + "#### Enable python3.6 environment, to use SNPE SDK and then convert onnx to dlc" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c466b9aa", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-07-13 17:16:03,073 - 235 - INFO - Successfully simplified the onnx model in child process\n", + "2023-07-13 17:16:03,547 - 235 - INFO - Successfully receive the simplified onnx model in main process\n", + "2023-07-13 17:16:06,272 - 235 - INFO - INFO_INITIALIZATION_SUCCESS: \n" + ] + } + ], + "source": [ + "%%bash\n", + "snpe-onnx-to-dlc -i yolo_nas_s.onnx -o app/src/main/assets/yolo_nas_s.dlc" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "b2675610", + "metadata": {}, + "source": [ + "## Quantizing MobileNetSSD" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "b01ac9cf", + "metadata": {}, + "outputs": [], + "source": [ + "##STEPS to preprocess images\n", + "\n", + "def preprocess(original_image):\n", + " resized_image = cv2.resize(original_image, (320, 320))\n", + " resized_image = resized_image/255\n", + " return resized_image\n", + "\n", + "import cv2\n", + "import numpy as np\n", + "import os\n", + "\n", + "##Please download Coco2014 dataset and give the path here\n", + "dataset_path = \"/workspace/val2014/\"\n", + "\n", + "!mkdir -p rawYoloNAS\n", + "\n", + "filenames=[]\n", + "for path in os.listdir(dataset_path)[:5]:\n", + " # check if current path is a file\n", + " if os.path.isfile(os.path.join(dataset_path, path)):\n", + " filenames.append(os.path.join(dataset_path, path))\n", + "\n", + "for filename in filenames:\n", + " original_image = cv2.imread(filename)\n", + " img = preprocess(original_image)\n", + " img = img.astype(np.float32)\n", + " img.tofile(\"rawYoloNAS/\"+filename.split(\"/\")[-1].split(\".\")[0]+\".raw\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "7370c51c", + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "find rawYoloNAS -name *.raw > YoloInputlist.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "40b37c70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "rawYoloNAS/COCO_val2014_000000000400.raw\n", + "rawYoloNAS/COCO_val2014_000000000042.raw\n", + "rawYoloNAS/COCO_val2014_000000000073.raw\n", + "rawYoloNAS/COCO_val2014_000000000074.raw\n", + "rawYoloNAS/COCO_val2014_000000000133.raw\n" + ] + } + ], + "source": [ + "%%bash\n", + "cat YoloInputlist.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "39b97591", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] InitializeStderr: DebugLog initialized.\n", + "[INFO] Processed command-line arguments\n", + "[INFO] Quantized parameters\n", + "[INFO] Generated activations\n", + "[INFO] Saved quantized dlc to: app/src/main/assets/Quant_yoloNas_s_320.dlc\n", + "[INFO] DebugLog shutting down.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0.1ms [ INFO ] Initializing logging in the backend. Callback: [0xc42410], Log Level: [3]\n", + " 0.1ms [ INFO ] No BackendExtensions lib provided;initializing NetRunBackend Interface\n", + " 875.4ms [ INFO ] cleaning up resources for input tensors\n", + " 875.5ms [ INFO ] cleaning up resources for output tensors\n", + " 1524.6ms [ INFO ] cleaning up resources for input tensors\n", + " 1524.6ms [ INFO ] cleaning up resources for output tensors\n", + " 2136.3ms [ INFO ] cleaning up resources for input tensors\n", + " 2136.3ms [ INFO ] cleaning up resources for output tensors\n", + " 2852.1ms [ INFO ] cleaning up resources for input tensors\n", + " 2852.1ms [ INFO ] cleaning up resources for output tensors\n", + " 3461.0ms [ INFO ] cleaning up resources for input tensors\n", + " 3461.0ms [ INFO ] cleaning up resources for output tensors\n" + ] + } + ], + "source": [ + "%%bash\n", + "snpe-dlc-quantize --input_dlc app/src/main/assets/yolo_nas_s.dlc --input_list YoloInputlist.txt --use_enhanced_quantizer --use_adjusted_weights_quantizer --axis_quant --output_dlc app/src/main/assets/Quant_yoloNas_s_320.dlc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a13d7629", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.17" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ai-solutions/android/03-ObjectDetection/README.md b/ai-solutions/android/03-ObjectDetection/README.md new file mode 100644 index 00000000..d9917ca0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/README.md @@ -0,0 +1,215 @@ +## Object Detection with YoloNAS / SSDMobilenetV2 / YoloX +The project is designed to utilize the [Qualcomm® Neural Processing SDK for AI ](https://developer.qualcomm.com/sites/default/files/docs/snpe/index.html), a deep learning software from Snapdragon platforms for Object Detection in Android. The Android application can be designed to use any built-in/connected camera to capture the objects and use Machine Learning model to get the prediction/inference and location of the respective objects. + +# Pre-requisites + +* Before starting the Android application, please follow the instructions for setting up Qualcomm Neural Processing SDK using the link provided. https://developer.qualcomm.com/sites/default/files/docs/snpe/setup.html +* Android device 6.0 and above which uses below mentioned Snapdragon processors/Snapdragon HDK with display can be used to test the application +* Download CocoDataset 2014 and give its path to Generate_DLC.ipynb. Change variable "dataset_path" in Quantization Section in notebook. + + +## List of Supported Devices + +- Snapdragon® SM8550 + +The above targets supports the application with CPU, GPU and DSP. For more information on the supported devices, please follow this link https://developer.qualcomm.com/docs/snpe/overview.html + +# Source Overview + +## Source Organization + +demo : Contains demo GIF + +app : Contains source files in standard Android app format + +app\src\main\assets : Contains Model binary DLC + +app\src\main\java\com\qc\objectdetectionYoloNas : Application java source code + +app\src\main\cpp : native source code + +sdk: Contains openCV sdk + +## DLC Generation + +Run jupyter notebook GenerateDLC.ipynb. This notebook will generate YoloNAS quantized dlc. + +YoloNAS model is trained on COCO dataset for 80 classes of everyday objects. +List of the classes can be found in dataset at : https://cocodataset.org/#explore + +## Code Implementation + +This application opens a camera preview, collects all the frames and converts them to bitmap. The network is built via Neural Network builder by passing model dlc name and runtime as the input. The bitmap is then given to the model for inference, which returns object prediction and localization of the respective object. + + +### Prerequisite for Camera Preview. + +Permission to obtain camera preview frames is granted in the following file: +```python +/app/src/main/AndroidManifest.xml + + ``` +In order to use camera2 APIs, add the below feature +```python + +``` +### Loading Model +Code snippet for neural network connection and loading model: +```java + snpe = snpeBuilder.setOutputLayers({}) + .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::BURST) + .setExecutionPriorityHint( + zdl::DlSystem::ExecutionPriorityHint_t::HIGH) + .setRuntimeProcessorOrder(runtimeList) + .setUseUserSuppliedBuffers(useUserSuppliedBuffers) + .setPlatformConfig(platformConfig) + .setInitCacheMode(useCaching) + .setCPUFallbackMode(true) + .setUnconsumedTensorsAsOutputs(true) + .build(); +``` +### Preprocessing +The bitmap image is passed as openCV Mat to native and then converted to BGR Mat. DLC models can work with specific image sizes. +Therefore, we need to resize the input image to the size accepted by the corresponding selected model DLC before passing image to DLC. +Below code reference for YoloNAS preprocessing. Similarly for other models based on model requirements, the preprocessing may change. +```java + cv::Mat img320; + //Resize and get the size from model itself (320x320 for YOLONAS) + cv::resize(img,img320,cv::Size(dims[2],dims[1]),cv::INTER_LINEAR); + + float inputScale = 0.00392156862745f; + + float * accumulator = reinterpret_cast (&dest_buffer[0]); + + //opencv read in BGRA by default + cvtColor(img320, img320, CV_BGRA2BGR); + int lim = img320.rows*img320.cols*3; + for(int idx = 0; idx=0.5 ) + { + int x1 = BBout_boxcoords[i * 4 + 0]; + int y1 = BBout_boxcoords[i * 4 + 1]; + int x2 = BBout_boxcoords[i * 4 + 2]; + int y2 = BBout_boxcoords[i * 4 + 3]; + Boxlist.push_back(BoxCornerEncoding(x1, y1, x2, y2,*it,classname)); + } + } + + std::vector reslist = NonMaxSuppression(Boxlist,0.20); +``` +then we just scale the coords for original image + +```python + float top,bottom,left,right; + left = reslist[k].y1 * ratio_1; //y1 + right = reslist[k].y2 * ratio_1; //y2 + + bottom = reslist[k].x1 * ratio_2; //x1 + top = reslist[k].x2 * ratio_2; //x2 +``` + +## Drawing bounding boxes + +```python + RectangleBox rbox = boxlist.get(j); + float y = rbox.left; + float y1 = rbox.right; + float x = rbox.top; + float x1 = rbox.bottom; + + String fps_textLabel = "FPS: "+String.valueOf(rbox.fps); + canvas.drawText(fps_textLabel,10,70,mTextColor); + + String processingTimeTextLabel= rbox.processing_time+"ms"; + + canvas.drawRect(x1, y, x, y1, mBorderColor); + canvas.drawText(rbox.label,x1+10, y+40, mTextColor); + canvas.drawText(processingTimeTextLabel,x1+10, y+90, mTextColor); +``` + +# Build and run with Android Studio + +## Build APK file with Android Studio + +1. Clone QIDK repo. + +2. Run below script, from the directory where it is present, to resolve dependencies of this project. + +* This will copy snpe-release.aar file from $SNPE_ROOT to "snpe-release" directory in Android project. + + **NOTE - If you are using SNPE version 2.11 or greater, please change following line in resolveDependencies.sh.** + ``` + From: cp $SNPE_ROOT/android/snpe-release.aar snpe-release + To : cp $SNPE_ROOT/lib/android/snpe-release.aar snpe-release + ``` +* Download opencv and paste to sdk directory, to enable OpenCv for android Java. + +```java + bash resolveDependencies.sh +``` + + +3. Run jupyter notebook GenerateDLC.ipynb to generate DLC(s) for quantized YOLO_NAS DLC. Also, **change the dataset_path with Coco Dataset Path**. +* This script generates required dlc(s) and paste them to appropriate location. + + +4. Do gradle sync +5. Compile the project. +6. Output APK file should get generated : app-debug.apk +7. Prepare the Qualcomm Innovators development kit to install the application (Do not run APK on emulator) + +8. If Unsigned or Signed DSP runtime is not getting detected, then please check the logcat logs for the FastRPC error. DSP runtime may not get detected due to SE Linux security policy. Please try out following commands to set permissive SE Linux policy. + +It is recommended to run below commands. +```java +adb disable-verity +adb reboot +adb root +adb remount +adb shell setenforce 0 +``` + +9. Install and test application : app-debug.apk +```java +adb install -r -t app-debug.apk +``` + +10. launch the application + +Following is the basic "Pose Detection" Android App + +1. On launch of application, from home screen user can select the model and runtime and then press start camera button. +2. On first launch of camera, user needs to provide camera permissions. +3. After camera launched, the selected model with runtime starts loading in the background. User will see a dialogue box till model is being loaded. +4. Once the model is loaded, it will start detecting objects and box will be seen around the object if respective object is detected on the screen +5. User can go back to home screen by pressing back button and select appropriate model and run-time and observe performance difference. + +Same results for the application are : + +## Demo of the application +![Screenshot](.//demo/ObjectDetectYoloNAS.gif) + +# References +1. SSD - Single shot Multi box detector - https://arxiv.org/pdf/1512.02325.pdf +2. https://github.com/Deci-AI/super-gradients +3. https://zenodo.org/record/7789328 + + +###### *Snapdragon and Qualcomm Neural Processing SDK are products of Qualcomm Technologies, Inc. and/or its subsidiaries.* diff --git a/ai-solutions/android/03-ObjectDetection/app/build.gradle b/ai-solutions/android/03-ObjectDetection/app/build.gradle new file mode 100644 index 00000000..4f8293a0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/build.gradle @@ -0,0 +1,68 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.qcom.aistack_objdetect" + minSdkVersion 24 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { +// cppFlags '' + cppFlags "-std=c++11 -frtti -fexceptions" + arguments "-DOpenCV_DIR=" + project(':sdk').projectDir + "/native/jni", + "-DANDROID_TOOLCHAIN=clang" +// "-DANDROID_STL=c++_shared", +// "-DANDROID_ARM_NEON=TRUE" + targets "objectdetectionYoloNas" + } + ndk { + abiFilters 'arm64-v8a' + } + } + } + + packagingOptions { + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + ndkVersion '21.4.7075529' + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(path: ':sdk') + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.1' + implementation 'com.android.support:design:26.0.0' + implementation 'com.android.support:support-v4:26.0.0' + + + +} diff --git a/ai-solutions/android/03-ObjectDetection/app/local.properties b/ai-solutions/android/03-ObjectDetection/app/local.properties new file mode 100644 index 00000000..0a5b4775 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Sat Jan 07 01:53:02 IST 2023 +sdk.dir=C\:\\Users\\shubgoya\\AppData\\Local\\Android\\Sdk diff --git a/ai-solutions/android/03-ObjectDetection/app/proguard-rules.pro b/ai-solutions/android/03-ObjectDetection/app/proguard-rules.pro new file mode 100644 index 00000000..6e7ffa99 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/AndroidManifest.xml b/ai-solutions/android/03-ObjectDetection/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..e387bd86 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/assets/ReadMe.txt b/ai-solutions/android/03-ObjectDetection/app/src/main/assets/ReadMe.txt new file mode 100644 index 00000000..aca5c44b --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/assets/ReadMe.txt @@ -0,0 +1 @@ +Generate model DLC and place here \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/CMakeLists.txt b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 00000000..adeaf8e0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,66 @@ + +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.18.1) + +# Declares and names the project. + +project("objectdetectionYoloNas") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +###OPENCV +#find_package(OpenCV REQUIRED) ##FAILED, cannot find libcpufeatures.so +#set(OpenCV_STATIC on) +#set(OpenCV_DIR C:/Users/shubgoya/Desktop/SNPEworkspace/github_workspace/HRNET_posenet/opencv45/native/jni) +find_package(OpenCV REQUIRED) +#INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS}) + + +###INCLUDE_DIRECTORIES +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc/zdl) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc/hpp) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library( # Sets the name of the library. + objectdetectionYoloNas + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + inference.cpp inference_helper.cpp objectdetectionYoloNas.cpp Model.h Model.cpp YOLONAS_Model.h YOLONAS_Model.cpp + SSDMobileNetV2_Model.h SSDMobileNetV2_Model.cpp YOLO_X_Model.h YOLO_X_Model.cpp) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log ) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + objectdetectionYoloNas + + # Links the target library to the log library + # included in the NDK. + ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/arm64-v8a/libSNPE.so + + ${log-lib} ${OpenCV_LIBS}) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.cpp new file mode 100644 index 00000000..c15814fc --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.cpp @@ -0,0 +1,14 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 8/30/2023. +// + +// #include "Model.h" diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.h new file mode 100644 index 00000000..06e5d491 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/Model.h @@ -0,0 +1,60 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 8/30/2023. +// + +#ifndef APP_MODEL_H +#define APP_MODEL_H + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "android/log.h" + + +#include +#include +#include + +#define LOG_TAG "SNPE_INF" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) + +// List of All the supported models by the current application +enum ModelName +{ + YOLONAS, + SSDMobilenetV2, + YoloX +}; + +class Model { + +public: + virtual void preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims) = 0; + virtual void postprocess(int orig_width, int orig_height, int &numberofobj, std::vector> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time) = 0; + virtual void msg() = 0; + + ModelName model_name=YOLONAS; //initialized + +}; + + +#endif //APP_MODEL_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.cpp new file mode 100644 index 00000000..72750b9e --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.cpp @@ -0,0 +1,111 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 9/11/2023. +// + +#include "SSDMobileNetV2_Model.h" + + +void SSDMobileNetV2_Model::preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims) +{ + LOGI("SSDMobileNetV2_Model preprocess"); + cv::Mat img320; + //Resize and get the size from model itself (320x320 for SSDMobileNetV2) + cv::resize(img,img320,cv::Size(dims[2],dims[1]),0,0,cv::INTER_LINEAR); + + //float inputScale = 0.00392156862745f; //normalization value, this is 1/255 + float inputScale = 1.070312500000f; //normalization value, this is 1/255 + + float * accumulator = reinterpret_cast (&dest_buffer[0]); + + cvtColor(img320, img320, CV_BGRA2RGB); + //LOGI("num of channels: %d",img320.channels()); + int lim = img320.rows*img320.cols*3; + for(int idx = 0; idx> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time) { + LOGI("SSDMobileNetV2_Model postprocess"); + std::vector Boxlist; + std::vector Classlist; + + //sanjeev temp sanity check for sometimes stability issue in SSDMobileNetV2 Model + if (BBout_boxcoords.size() == 0) + { + numberofobj=-1; + LOGE("sanjeev BBout_boxcoords is zero. Returning Error.."); + return; + } + + //Post Processing + for(int i =1;i<(21);i++) // [21 classes supported by SSDMobileNetV2] + { + + int row_index; + float max_element; + + std::string classname = classnamemapping[i]; + + for (int j=i; j<(67914); j+=21) // [67914 = 21 (no of classes) x 3234 (total boxes output by model)] + { + if (BBout_class[j] > 0.4) + { + max_element = BBout_class[j]; + row_index = j/21; + + float x1 = BBout_boxcoords[row_index * 4 + 0]; + float y1 = BBout_boxcoords[row_index * 4 + 1]; + float x2 = BBout_boxcoords[row_index * 4 + 2]; + float y2 = BBout_boxcoords[row_index * 4 + 3]; + + Boxlist.push_back(SSDMobileNetV2BoxCornerEncoding(x1, y1, x2, y2,max_element,classname)); + } + } + + } + + //LOGI("Boxlist size:: %d",Boxlist.size()); + std::vector reslist = NonMaxSuppression(Boxlist,0.20); + //LOGI("reslist ssize %d", reslist.size()); + + numberofobj = reslist.size(); + + //LOGI("numberofobj detected = %d", numberofobj); + + float ratio_2 = orig_width; + float ratio_1 = orig_height; + + //LOGI("ratio1 %f :: ratio_2 %f",ratio_1,ratio_2); + + for(int k=0;k singleboxcoords{top, bottom, left, right, milli_time}; + BB_coords.push_back(singleboxcoords); + BB_names.push_back(reslist[k].objlabel); + } + +} + +void SSDMobileNetV2_Model::msg() +{ + LOGI("SSDMobileNetV2_Model Class msg model_name = %d", model_name); +} \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.h new file mode 100644 index 00000000..379f2a70 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/SSDMobileNetV2_Model.h @@ -0,0 +1,133 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 9/11/2023. +// + +#ifndef APP_SSDMOBILENETV2_MODEL_H +#define APP_SSDMOBILENETV2_MODEL_H + +#include "Model.h" + +#include + +class SSDMobileNetV2BoxCornerEncoding { + +public: + float x1; + float y1; + float x2; + float y2; + float score; + std::string objlabel; + + SSDMobileNetV2BoxCornerEncoding(float a, float b, float c, float d,float sc, std::string name="person") + { + x1 = a; + y1 = b; + x2 = c; + y2 = d; + score = sc; + objlabel = name; + } +}; + + + +class SSDMobileNetV2_Model: public Model{ + + std::map classnamemapping = + { + {0, "BACKGROUND"},{ 1, "aeroplane"},{ 2, "bicycle"},{ 3, "bird"},{ 4, "boat"},{ 5, "bottle"},{ + 6, "bus"},{ 7, "car"},{ 8, "cat"},{ 9, "chair"},{ 10, "cow"},{ 11, "diningtable"},{ 12, "dog"},{ + 13, "horse"},{ 14, "motorbike"},{ 15, "person"},{ 16, "pottedplant"},{ 17, "sheep"},{ 18, "sofa"},{ 19, "train"},{ + 20, "tvmonitor"} + }; + +public: + + SSDMobileNetV2_Model() + { + model_name=SSDMobilenetV2; + } + + void preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims); + void postprocess(int orig_width, int orig_height, int &numberofobj, std::vector> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time); + void msg(); + + inline float ComputeIntersectionOverUnion(const SSDMobileNetV2BoxCornerEncoding &box_i,const SSDMobileNetV2BoxCornerEncoding &box_j) + { + const float box_i_y_min = std::min(box_i.y1, box_i.y2); + const float box_i_y_max = std::max(box_i.y1, box_i.y2); + const float box_i_x_min = std::min(box_i.x1, box_i.x2); + const float box_i_x_max = std::max(box_i.x1, box_i.x2); + const float box_j_y_min = std::min(box_j.y1, box_j.y2); + const float box_j_y_max = std::max(box_j.y1, box_j.y2); + const float box_j_x_min = std::min(box_j.x1, box_j.x2); + const float box_j_x_max = std::max(box_j.x1, box_j.x2); + + const float area_i = + (box_i_y_max - box_i_y_min) * (box_i_x_max - box_i_x_min); + const float area_j = + (box_j_y_max - box_j_y_min) * (box_j_x_max - box_j_x_min); + if (area_i <= 0 || area_j <= 0) return 0.0; + const float intersection_ymax = std::min(box_i_y_max, box_j_y_max); + const float intersection_xmax = std::min(box_i_x_max, box_j_x_max); + const float intersection_ymin = std::max(box_i_y_min, box_j_y_min); + const float intersection_xmin = std::max(box_i_x_min, box_j_x_min); + const float intersection_area = + std::max(intersection_ymax - intersection_ymin, 0.0) * + std::max(intersection_xmax - intersection_xmin, 0.0); + return intersection_area / (area_i + area_j - intersection_area); + } + + std::vector NonMaxSuppression(std::vector boxes, + const float iou_threshold) + { + + if (boxes.size()==0) { + return boxes; + } + + std::sort(boxes.begin(), boxes.end(), [] (const SSDMobileNetV2BoxCornerEncoding& left, const SSDMobileNetV2BoxCornerEncoding& right) { + if (left.score > right.score) { + return true; + } else { + return false; + } + }); + + + std::vector flag(boxes.size(), false); + for (unsigned int i = 0; i < boxes.size(); i++) { + if (flag[i]) { + continue; + } + + for (unsigned int j = i + 1; j < boxes.size(); j++) { + if (ComputeIntersectionOverUnion(boxes[i],boxes[j]) > iou_threshold) { + flag[j] = true; + } + } + } + + std::vector ret; + for (unsigned int i = 0; i < boxes.size(); i++) { + if (!flag[i]) + ret.push_back(boxes[i]); + } + + return ret; + } + +}; + + +#endif //APP_SSDMOBILENETV2_MODEL_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.cpp new file mode 100644 index 00000000..7fa9b630 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.cpp @@ -0,0 +1,90 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 8/30/2023. +// + +#include "YOLONAS_Model.h" + +void YOLONAS_Model::preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims) +{ + LOGI("YOLONAS_Model preprocess"); + cv::Mat img320; + //Resize and get the size from model itself (320x320 for YOLONAS) + cv::resize(img,img320,cv::Size(dims[2],dims[1]),cv::INTER_LINEAR); + + float inputScale = 0.00392156862745f; //normalization value, this is 1/255 + + float * accumulator = reinterpret_cast (&dest_buffer[0]); + + //opencv read in BGRA by default + cvtColor(img320, img320, CV_BGRA2BGR); + //LOGI("num of channels: %d",img320.channels()); + int lim = img320.rows*img320.cols*3; + for(int idx = 0; idx> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time) { + LOGI("YOLONAS_Model postprocess"); + std::vector Boxlist; + std::vector Classlist; + + //Post Processing + for(int i =0;i<(2100);i++) //TODO change value of 2100 to soft value + { + int start = i*80; + int end = (i+1)*80; + + auto it = max_element (BBout_class.begin()+start, BBout_class.begin()+end); + int index = distance(BBout_class.begin()+start, it); + + std::string classname = classnamemapping[index]; + if(*it>=0.5 ) + { + int x1 = BBout_boxcoords[i * 4 + 0]; + int y1 = BBout_boxcoords[i * 4 + 1]; + int x2 = BBout_boxcoords[i * 4 + 2]; + int y2 = BBout_boxcoords[i * 4 + 3]; + Boxlist.push_back(BoxCornerEncoding(x1, y1, x2, y2,*it,classname)); + } + } + + //LOGI("Boxlist size:: %d",Boxlist.size()); + std::vector reslist = NonMaxSuppression(Boxlist,0.20); + //LOGI("reslist ssize %d", reslist.size()); + + numberofobj = reslist.size(); + float ratio_2 = orig_width/320.0f; + float ratio_1 = orig_height/320.0f; + //LOGI("ratio1 %f :: ratio_2 %f",ratio_1,ratio_2); + + for(int k=0;k singleboxcoords{top, bottom, left, right, milli_time}; + BB_coords.push_back(singleboxcoords); + BB_names.push_back(reslist[k].objlabel); + } +} + +void YOLONAS_Model::msg() +{ + LOGI("YOLONAS_Model Class msg model_name = %d",model_name); +} \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.h new file mode 100644 index 00000000..853af371 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLONAS_Model.h @@ -0,0 +1,142 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 8/30/2023. +// + +#ifndef APP_YOLONAS_MODEL_H +#define APP_YOLONAS_MODEL_H + +#include "Model.h" + +#include + +class BoxCornerEncoding { + +public: + int x1; + int y1; + int x2; + int y2; + float score; + std::string objlabel; + + BoxCornerEncoding(int a, int b, int c, int d,int sc, std::string name="person") + { + x1 = a; + y1 = b; + x2 = c; + y2 = d; + score = sc; + objlabel = name; + } +}; + + +class YOLONAS_Model: public Model{ + + + std::map classnamemapping = + { + {0, "person"},{ 1, "bicycle"},{ 2, "car"},{ 3, "motorcycle"},{ 4, "airplane"},{ 5, "bus"},{ + 6, "train"},{ 7, "truck"},{ 8, "boat"},{ 9, "traffic"},{ 10, "fire"},{ 11, "stop"},{ 12, "parking"},{ + 13, "bench"},{ 14, "bird"},{ 15, "cat"},{ 16, "dog"},{ 17, "horse"},{ 18, "sheep"},{ 19, "cow"},{ + 20, "elephant"},{ 21, "bear"},{ 22, "zebra"},{ 23, "giraffe"},{ 24, "backpack"},{ 25, "umbrella"},{ + 26, "handbag"},{ 27, "tie"},{ 28, "suitcase"},{ 29, "frisbee"},{ 30, "skis"},{ 31, "snowboard"},{ + 32, "sports"},{ 33, "kite"},{ 34, "baseball"},{ 35, "baseball"},{ 36, "skateboard"},{ 37, "surfboard"},{ + 38, "tennis"},{ 39, "bottle"},{ 40, "wine"},{ 41, "cup"},{ 42, "fork"},{ 43, "knife"},{ 44, "spoon"},{ + 45, "bowl"},{ 46, "banana"},{ 47, "apple"},{ 48, "sandwich"},{ 49, "orange"},{ 50, "broccoli"},{ + 51, "carrot"},{ 52, "hot"},{ 53, "pizza"},{ 54, "donut"},{ 55, "cake"},{ 56, "chair"},{ 57, "couch"},{ + 58, "potted"},{ 59, "bed"},{ 60, "dining"},{ 61, "toilet"},{ 62, "tv"},{ 63, "laptop"},{ 64, "mouse"},{ + 65, "remote"},{ 66, "keyboard"},{ 67, "cell"},{ 68, "microwave"},{ 69, "oven"},{ 70, "toaster"},{ + 71, "sink"},{ 72, "refrigerator"},{ 73, "book"},{ 74, "clock"},{ 75, "vase"},{ 76, "scissors"},{ + 77, "teddy"},{ 78, "hair"},{ 79, "toothbrush"} + }; + +public: + + YOLONAS_Model() + { + model_name=YOLONAS; + } + + void preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims); + void postprocess(int orig_width, int orig_height, int &numberofobj, std::vector> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time); + void msg(); + + inline float ComputeIntersectionOverUnion(const BoxCornerEncoding &box_i,const BoxCornerEncoding &box_j) + { + const float box_i_y_min = std::min(box_i.y1, box_i.y2); + const float box_i_y_max = std::max(box_i.y1, box_i.y2); + const float box_i_x_min = std::min(box_i.x1, box_i.x2); + const float box_i_x_max = std::max(box_i.x1, box_i.x2); + const float box_j_y_min = std::min(box_j.y1, box_j.y2); + const float box_j_y_max = std::max(box_j.y1, box_j.y2); + const float box_j_x_min = std::min(box_j.x1, box_j.x2); + const float box_j_x_max = std::max(box_j.x1, box_j.x2); + + const float area_i = + (box_i_y_max - box_i_y_min) * (box_i_x_max - box_i_x_min); + const float area_j = + (box_j_y_max - box_j_y_min) * (box_j_x_max - box_j_x_min); + if (area_i <= 0 || area_j <= 0) return 0.0; + const float intersection_ymax = std::min(box_i_y_max, box_j_y_max); + const float intersection_xmax = std::min(box_i_x_max, box_j_x_max); + const float intersection_ymin = std::max(box_i_y_min, box_j_y_min); + const float intersection_xmin = std::max(box_i_x_min, box_j_x_min); + const float intersection_area = + std::max(intersection_ymax - intersection_ymin, 0.0) * + std::max(intersection_xmax - intersection_xmin, 0.0); + return intersection_area / (area_i + area_j - intersection_area); + } + + std::vector NonMaxSuppression(std::vector boxes, + const float iou_threshold) + { + + if (boxes.size()==0) { + return boxes; + } + + std::sort(boxes.begin(), boxes.end(), [] (const BoxCornerEncoding& left, const BoxCornerEncoding& right) { + if (left.score > right.score) { + return true; + } else { + return false; + } + }); + + + std::vector flag(boxes.size(), false); + for (unsigned int i = 0; i < boxes.size(); i++) { + if (flag[i]) { + continue; + } + + for (unsigned int j = i + 1; j < boxes.size(); j++) { + if (ComputeIntersectionOverUnion(boxes[i],boxes[j]) > iou_threshold) { + flag[j] = true; + } + } + } + + std::vector ret; + for (unsigned int i = 0; i < boxes.size(); i++) { + if (!flag[i]) + ret.push_back(boxes[i]); + } + + return ret; + } + +}; + + +#endif //APP_YOLONAS_MODEL_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.cpp new file mode 100644 index 00000000..315a0919 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.cpp @@ -0,0 +1,145 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 9/20/2023. +// + +#include "YOLO_X_Model.h" + + +void YOLO_X_Model::preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims) +{ + LOGI("YOLO_X_Model preprocess"); + cv::Mat img640; + //Resize and get the size from model itself (640x640 for YoloX) + cv::resize(img,img640,cv::Size(dims[2],dims[1]),cv::INTER_LINEAR); + + //float inputScale = 0.00392156862745f; //normalization value, this is 1/255 + float inputScale = 0.998046875000f; //normalization value, this is 1/255 + + float * accumulator = reinterpret_cast (&dest_buffer[0]); + + //opencv read in BGRA by default + cvtColor(img640, img640, CV_BGRA2BGR); + //LOGI("num of channels: %d",img640.channels()); + int lim = img640.rows*img640.cols*3; + for(int idx = 0; idx> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time) { + + //YoloX Model has only single tensor output (BBout_class) that includes classes, boxes as well as score + + LOGI("YOLO_X_Model postprocess"); + std::vector Boxlist; + std::vector Classlist; + + std::vector img_size = {640, 640}; + bool p6=false; + + struct Point { + float32_t x,y; + }; + + std::vector grids; + std::vector expanded_strides; + std::vector strides = !p6 ? std::vector{8, 16, 32} : std::vector{8, 16, 32, 64}; + + std::vector hsizes, wsizes; + for (const int stride : strides) { + hsizes.push_back(img_size[0] / stride); + wsizes.push_back(img_size[1] / stride); + } + + for (size_t i=0; i(x), static_cast(y)}; + grids.push_back(point); + expanded_strides.push_back(stride); + } + } + } + + for (size_t i=0; i<8400; i++) { + + BBout_class[i*85+0] = (BBout_class[i*85+0] + grids[i].x) * expanded_strides[i]; + BBout_class[i*85+1] = (BBout_class[i*85+1] + grids[i].y) * expanded_strides[i]; + BBout_class[i*85+2] = std::exp(BBout_class[i*85+2]) * expanded_strides[i]; + BBout_class[i*85+3] = std::exp(BBout_class[i*85+3]) * expanded_strides[i]; + + } + + for(int i =0;i<(8400);i++) // Total tensor output rows + { + int start = i*85+5; // each row contains classes from indexes 5 to 85 + int end = (i+1)*85; + + float score = BBout_class[start-1]; // each row contains score at index 4 + + if(score>=0.2 ) + { + + auto it = max_element (BBout_class.begin()+start, BBout_class.begin()+end); + int index = distance(BBout_class.begin()+start, it); + + std::string classname = classnamemapping[index]; + + // each row contains box co-ordinates from index 0 to 3 + float x1 = BBout_class[start-5]; + float y1 = BBout_class[start-4]; + float x2 = BBout_class[start-3]; + float y2 = BBout_class[start-2]; + Boxlist.push_back(YOLO_X_BoxCornerEncoding(x1, y1, x2, y2,score,classname)); + } + } + + //LOGI("Boxlist size:: %d",Boxlist.size()); + std::vector reslist_temp = Yolo_X_Rescale_boxes(Boxlist,orig_width,orig_height); + + std::vector reslist = NonMaxSuppression(reslist_temp,0.20); + //LOGI("reslist ssize %d", reslist.size()); + + + numberofobj = reslist.size(); + float ratio_2 = orig_width/640.0f; + float ratio_1 = orig_height/640.0f; + //LOGI("ratio1 %f :: ratio_2 %f",ratio_1,ratio_2); + + for(int k=0;k singleboxcoords{top, bottom, left, right, milli_time}; + BB_coords.push_back(singleboxcoords); + BB_names.push_back(reslist[k].objlabel); + } +} + +void YOLO_X_Model::msg() +{ + LOGI("YOLO_X_Model Class msg model_name = %d", model_name); +} \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.h new file mode 100644 index 00000000..63acc3fc --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/YOLO_X_Model.h @@ -0,0 +1,165 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by gsanjeev on 9/20/2023. +// + +#ifndef APP_YOLO_X_MODEL_H +#define APP_YOLO_X_MODEL_H + +#include "Model.h" + +#include + +class YOLO_X_BoxCornerEncoding { + +public: + float x1; + float y1; + float x2; + float y2; + float score; + std::string objlabel; + + YOLO_X_BoxCornerEncoding(float a, float b, float c, float d,float sc, std::string name="person") + { + x1 = a; + y1 = b; + x2 = c; + y2 = d; + score = sc; + objlabel = name; + } +}; + + +class YOLO_X_Model: public Model{ + + + std::map classnamemapping = + { + {0, "person"},{ 1, "bicycle"},{ 2, "car"},{ 3, "motorcycle"},{ 4, "airplane"},{ 5, "bus"},{ + 6, "train"},{ 7, "truck"},{ 8, "boat"},{ 9, "traffic"},{ 10, "fire"},{ 11, "stop"},{ 12, "parking"},{ + 13, "bench"},{ 14, "bird"},{ 15, "cat"},{ 16, "dog"},{ 17, "horse"},{ 18, "sheep"},{ 19, "cow"},{ + 20, "elephant"},{ 21, "bear"},{ 22, "zebra"},{ 23, "giraffe"},{ 24, "backpack"},{ 25, "umbrella"},{ + 26, "handbag"},{ 27, "tie"},{ 28, "suitcase"},{ 29, "frisbee"},{ 30, "skis"},{ 31, "snowboard"},{ + 32, "sports"},{ 33, "kite"},{ 34, "baseball"},{ 35, "baseball"},{ 36, "skateboard"},{ 37, "surfboard"},{ + 38, "tennis"},{ 39, "bottle"},{ 40, "wine"},{ 41, "cup"},{ 42, "fork"},{ 43, "knife"},{ 44, "spoon"},{ + 45, "bowl"},{ 46, "banana"},{ 47, "apple"},{ 48, "sandwich"},{ 49, "orange"},{ 50, "broccoli"},{ + 51, "carrot"},{ 52, "hot"},{ 53, "pizza"},{ 54, "donut"},{ 55, "cake"},{ 56, "chair"},{ 57, "couch"},{ + 58, "potted"},{ 59, "bed"},{ 60, "dining"},{ 61, "toilet"},{ 62, "tv"},{ 63, "laptop"},{ 64, "mouse"},{ + 65, "remote"},{ 66, "keyboard"},{ 67, "cell"},{ 68, "microwave"},{ 69, "oven"},{ 70, "toaster"},{ + 71, "sink"},{ 72, "refrigerator"},{ 73, "book"},{ 74, "clock"},{ 75, "vase"},{ 76, "scissors"},{ + 77, "teddy"},{ 78, "hair"},{ 79, "toothbrush"} + }; + +public: + + YOLO_X_Model() + { + model_name=YoloX; + } + + void preprocess(std::vector &dest_buffer, cv::Mat &img, std::vector dims); + void postprocess(int orig_width, int orig_height, int &numberofobj, std::vector> &BB_coords, std::vector &BB_names, std::vector &BBout_boxcoords, std::vector &BBout_class, float milli_time); + void msg(); + + inline float ComputeIntersectionOverUnion(const YOLO_X_BoxCornerEncoding &box_i,const YOLO_X_BoxCornerEncoding &box_j) + { + const float box_i_y_min = std::min(box_i.y1, box_i.y2); + const float box_i_y_max = std::max(box_i.y1, box_i.y2); + const float box_i_x_min = std::min(box_i.x1, box_i.x2); + const float box_i_x_max = std::max(box_i.x1, box_i.x2); + const float box_j_y_min = std::min(box_j.y1, box_j.y2); + const float box_j_y_max = std::max(box_j.y1, box_j.y2); + const float box_j_x_min = std::min(box_j.x1, box_j.x2); + const float box_j_x_max = std::max(box_j.x1, box_j.x2); + + const float area_i = + (box_i_y_max - box_i_y_min) * (box_i_x_max - box_i_x_min); + const float area_j = + (box_j_y_max - box_j_y_min) * (box_j_x_max - box_j_x_min); + if (area_i <= 0 || area_j <= 0) return 0.0; + const float intersection_ymax = std::min(box_i_y_max, box_j_y_max); + const float intersection_xmax = std::min(box_i_x_max, box_j_x_max); + const float intersection_ymin = std::max(box_i_y_min, box_j_y_min); + const float intersection_xmin = std::max(box_i_x_min, box_j_x_min); + const float intersection_area = + std::max(intersection_ymax - intersection_ymin, 0.0) * + std::max(intersection_xmax - intersection_xmin, 0.0); + return intersection_area / (area_i + area_j - intersection_area); + } + + std::vector NonMaxSuppression(std::vector boxes, + const float iou_threshold) + { + + if (boxes.size()==0) { + return boxes; + } + + std::sort(boxes.begin(), boxes.end(), [] (const YOLO_X_BoxCornerEncoding& left, const YOLO_X_BoxCornerEncoding& right) { + if (left.score > right.score) { + return true; + } else { + return false; + } + }); + + + std::vector flag(boxes.size(), false); + for (unsigned int i = 0; i < boxes.size(); i++) { + if (flag[i]) { + continue; + } + + for (unsigned int j = i + 1; j < boxes.size(); j++) { + if (ComputeIntersectionOverUnion(boxes[i],boxes[j]) > iou_threshold) { + flag[j] = true; + } + } + } + + std::vector ret; + for (unsigned int i = 0; i < boxes.size(); i++) { + if (!flag[i]) + ret.push_back(boxes[i]); + } + + return ret; + } + + std::vector Yolo_X_Rescale_boxes(std::vector boxes, + int img_width, int img_height){ + + std::vector ret; + for (unsigned int i = 0; i < boxes.size(); i++) { + + float x1=boxes[i].x1 - 0.5f * boxes[i].x2; + float y1=boxes[i].y1 - 0.5f * boxes[i].y2; + float x2=boxes[i].x1 + 0.5f * boxes[i].x2; + float y2=boxes[i].y1 + 0.5f * boxes[i].y2; + + boxes[i].x1 =x1; + boxes[i].y1 =y1; + boxes[i].x2 =x2; + boxes[i].y2 =y2; + + ret.push_back(boxes[i]); + } + + return ret; + + } + +}; + + +#endif //APP_YOLO_X_MODEL_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CheckRuntime.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CheckRuntime.hpp new file mode 100644 index 00000000..07538cd0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CheckRuntime.hpp @@ -0,0 +1,17 @@ +//============================================================================== +// +// Copyright (c) 2017-2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CHECKRUNTIME_H +#define CHECKRUNTIME_H + +#include "SNPE/SNPEFactory.hpp" + +zdl::DlSystem::Runtime_t checkRuntime(zdl::DlSystem::Runtime_t runtime); +bool checkGLCLInteropSupport(); + +#endif diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CreateUserBuffer.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CreateUserBuffer.hpp new file mode 100644 index 00000000..68f25407 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/CreateUserBuffer.hpp @@ -0,0 +1,43 @@ +//============================================================================== +// +// Copyright (c) 2017-2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#include"inference.h" +#include +#include +#include +#include "SNPE/SNPE.hpp" +#include "DlSystem/IUserBuffer.hpp" +#include "DlSystem/UserBufferMap.hpp" + +typedef unsigned int GLuint; + +// Helper function to fill a single entry of the UserBufferMap with the given user-backed buffer +void createUserBuffer(zdl::DlSystem::UserBufferMap& userBufferMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + const char * name, + const bool isTfNBuffer, + int bitWidth); + + +// Create a UserBufferMap of the SNPE network outputs +void createOutputBufferMap(zdl::DlSystem::UserBufferMap& outputMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + const bool isTfNBuffer, + int bitWidth); + +// Create a UserBufferMap of the SNPE network inputs +void createInputBufferMap(zdl::DlSystem::UserBufferMap& inputMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + const bool isTfNBuffer, + int bitWidth); diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadContainer.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadContainer.hpp new file mode 100644 index 00000000..85bf622a --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadContainer.hpp @@ -0,0 +1,19 @@ +//============================================================================== +// +// Copyright (c) 2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef LOADCONTAINER_H +#define LOADCONTAINER_H + +#include + +#include "DlContainer/IDlContainer.hpp" + +std::unique_ptr loadContainerFromFile(std::string containerPath); +std::unique_ptr loadContainerFromBuffer(const uint8_t * buffer, const size_t size); + +#endif diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadInputTensor.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadInputTensor.hpp new file mode 100644 index 00000000..7aec3b24 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/LoadInputTensor.hpp @@ -0,0 +1,27 @@ +//============================================================================== +// +// Copyright (c) 2017-2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef LOADINPUTTENSOR_H +#define LOADINPUTTENSOR_H + +#include +#include +#include + +#include "SNPE/SNPE.hpp" +#include "DlSystem/ITensorFactory.hpp" +#include "DlSystem/TensorMap.hpp" +#include "../../Model.h" + + +bool loadInputUserBuffer(std::unordered_map>& applicationBuffers, + std::unique_ptr& snpe, + cv::Mat &model_input, + zdl::DlSystem::UserBufferMap& inputMap, + int bitWidth, Model *modelobj); +#endif diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/SetBuilderOptions.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/SetBuilderOptions.hpp new file mode 100644 index 00000000..e3db3df0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/SetBuilderOptions.hpp @@ -0,0 +1,26 @@ +//============================================================================== +// +// Copyright (c) 2017-2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SETBUILDEROPTIONS_H +#define SETBUILDEROPTIONS_H + +#include "DlSystem/RuntimeList.hpp" +#include "SNPE/SNPE.hpp" +#include "DlSystem/DlEnums.hpp" +//#include "DlSystem/UDLFunc.hpp" +#include "DlContainer/IDlContainer.hpp" +#include "DlSystem/PlatformConfig.hpp" + +std::unique_ptr setBuilderOptions(std::unique_ptr & container, + zdl::DlSystem::Runtime_t runtime, + zdl::DlSystem::RuntimeList runtimeList, + bool useUserSuppliedBuffers, + bool useCaching, + ModelName modelName); + +#endif //SETBUILDEROPTIONS_H \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/Util.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/Util.hpp new file mode 100644 index 00000000..346e7ac0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/Util.hpp @@ -0,0 +1,41 @@ +//============================================================================== +// +// Copyright (c) 2017-2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include +#include + +#include "DlSystem/ITensorFactory.hpp" +#include "DlSystem/TensorShape.hpp" + +template Container& split(Container& result, const typename Container::value_type & s, typename Container::value_type::value_type delimiter ) +{ + result.clear(); + std::istringstream ss( s ); + while (!ss.eof()) + { + typename Container::value_type field; + getline( ss, field, delimiter ); + if (field.empty()) continue; + result.push_back( field ); + } + return result; +} + + +cv::Mat get_affine_transform(int dst_w, int dst_h, int inv, double center[], double scale[]); +//void getcenterscale(int image_width, int image_height, double center[2], double scale[2]); +void getcenterscale(int image_width, int image_height, double center[2], double scale[2],float bottom, float left, float top, float right); +float** getCoords(std::vector buff, double center[], double scale[]); + +#endif + diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/inference.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/inference.h new file mode 100644 index 00000000..a74eaea3 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/hpp/inference.h @@ -0,0 +1,74 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +// +// Created by shubpate on 12/11/2021. +// + +#ifndef NATIVEINFERENCE_INFERENCE_H +#define NATIVEINFERENCE_INFERENCE_H + +#include "zdl/DlSystem/TensorShape.hpp" +#include "zdl/DlSystem/TensorMap.hpp" +#include "zdl/DlSystem/TensorShapeMap.hpp" +#include "zdl/DlSystem/IUserBufferFactory.hpp" +#include "zdl/DlSystem/IUserBuffer.hpp" +#include "zdl/DlSystem/UserBufferMap.hpp" +#include "zdl/DlSystem/IBufferAttributes.hpp" + +#include "zdl/DlSystem/StringList.hpp" + +#include "zdl/SNPE/SNPE.hpp" +#include "zdl/SNPE/SNPEFactory.hpp" +#include "zdl/DlSystem/DlVersion.hpp" +#include "zdl/DlSystem/DlEnums.hpp" +#include "zdl/DlSystem/String.hpp" +#include "zdl/DlContainer/IDlContainer.hpp" +#include "zdl/SNPE/SNPEBuilder.hpp" + +#include "zdl/DlSystem/ITensor.hpp" +#include "zdl/DlSystem/ITensorFactory.hpp" + +#include +#include "android/log.h" +#include + +#include "../../Model.h" + +#define LOG_TAG "SNPE_INF" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) + +/*class BoxCornerEncoding { + +public: + int x1; + int y1; + int x2; + int y2; + float score; + std::string objlabel; + + BoxCornerEncoding(int a, int b, int c, int d,int sc, std::string name="person") + { + x1 = a; + y1 = b; + x2 = c; + y2 = d; + score = sc; + objlabel = name; + } +};*/ + +std::string build_network_BB(const uint8_t * dlc_buffer, const size_t dlc_size, const char runtime_arg, ModelName modelName); +bool SetAdspLibraryPath(std::string nativeLibPath); + +bool executeDLC(cv::Mat &img, int orig_width, int orig_height, int &numberofhuman, std::vector> &BB_coords, std::vector &BB_names, Model *modelobj); + +#endif //NATIVEINFERENCE_INFERENCE_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.h new file mode 100644 index 00000000..9a084071 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.h @@ -0,0 +1,102 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef _DIAGLOG_IDIAGLOG_H_ +#define _DIAGLOG_IDIAGLOG_H_ + +#include "DiagLog/Options.h" +#include "DlSystem/SnpeApiExportDefine.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE IDiagLog handle + */ +typedef void* Snpe_IDiagLog_Handle_t; + +/** + * @brief . + * + * Sets the options after initialization occurs. + * + * @param[in] handle : Handle to access IDiagLog + * @param[in] loggingOptions : The options to set up diagnostic logging. + * + * @return Error code if the options could not be set. Ensure logging is not started/ + * SNPE_SUCCESS otherwise + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IDiagLog_SetOptions(Snpe_IDiagLog_Handle_t handle, Snpe_Options_Handle_t loggingOptionsHandle); + +/** + * @brief . + * + * Gets the curent options for the diag logger. + * + * @param[in] handle : Handle to access IDiagLog + * @return Handle to access DiagLog options. + */ +SNPE_API +Snpe_Options_Handle_t Snpe_IDiagLog_GetOptions(Snpe_IDiagLog_Handle_t handle); + +/** + * @brief . + * + * @param[in] handle : Handle to access IDiagLog + * @param[in] mask : Allows for setting the log mask once diag logging has started + * @return SNPE_SUCCESS if the level was set successfully. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IDiagLog_SetDiagLogMask(Snpe_IDiagLog_Handle_t handle, const char* mask) ; + +/** + * @brief . + * + * Enables logging. + * + * Logging should be started prior to the instantiation of other SNPE_APIs + * to ensure all events are captured. + * + * @param[in] handle : Handle to access IDiagLog + * @return SNPE_SUCCESS if diagnostic logging started successfully. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IDiagLog_Start(Snpe_IDiagLog_Handle_t handle); + +/** + * @brief Disables logging. + * + * @param[in] handle : Handle to access IDiagLog + * + * @return SNPE_SUCCESS if logging stopped successfully. Error code otherwise. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IDiagLog_Stop(Snpe_IDiagLog_Handle_t handle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DIAGLOG_IDIAGLOG_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.hpp new file mode 100644 index 00000000..64b81eba --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/IDiagLog.hpp @@ -0,0 +1,133 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include +#include + +#include "Options.hpp" +#include "DlSystem/String.hpp" + +#include "DiagLog/IDiagLog.h" + + +namespace DiagLog{ +class IDiagLog : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static Snpe_ErrorCode_t InvalidDeleteCall(Snpe_IDiagLog_Handle_t ){ + return SNPE_ERRORCODE_CAPI_DELETE_FAILURE; + } + + static constexpr DeleteFunctionType DeleteFunction{InvalidDeleteCall}; + + class OptionsInternal : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_Options_Delete}; + public: + OptionsInternal() + : BaseType(Snpe_Options_Create()) + { } + + explicit OptionsInternal(const Options& options) + : BaseType(Snpe_Options_Create()) + { + setDiagLogMask(options.DiagLogMask.c_str()); + setLogFileDirectory(options.LogFileDirectory.c_str()); + setLogFileName(options.LogFileName.c_str()); + setLogFileRotateCount(options.LogFileRotateCount); + setLogFileReplace(options.LogFileReplace); + } + + const char* getDiagLogMask() const{ + return Snpe_Options_GetDiagLogMask(handle()); + } + void setDiagLogMask(const char* diagLogMask){ + Snpe_Options_SetDiagLogMask(handle(), diagLogMask); + } + + const char* getLogFileDirectory() const{ + return Snpe_Options_GetLogFileDirectory(handle()); + } + void setLogFileDirectory(const char* logFileDirectory){ + Snpe_Options_SetLogFileDirectory(handle(), logFileDirectory); + } + + const char* getLogFileName() const{ + return Snpe_Options_GetLogFileName(handle()); + } + void setLogFileName(const char* logFileName){ + Snpe_Options_SetLogFileName(handle(), logFileName); + } + + uint32_t getLogFileRotateCount() const{ + return Snpe_Options_GetLogFileRotateCount(handle()); + } + void setLogFileRotateCount(uint32_t logFileRotateCount){ + Snpe_Options_SetLogFileRotateCount(handle(), logFileRotateCount); + } + + bool getLogFileReplace() const{ + return Snpe_Options_GetLogFileReplace(handle()); + } + void setLogFileReplace(bool logFileReplace){ + Snpe_Options_SetLogFileReplace(handle(), logFileReplace); + } + + explicit operator Options() const{ + return { + getDiagLogMask(), + getLogFileDirectory(), + getLogFileName(), + getLogFileRotateCount(), + getLogFileReplace() + }; + } + + }; + + + +public: + bool setOptions(const Options& loggingOptions){ + OptionsInternal optionsInternal(loggingOptions); + return SNPE_SUCCESS == Snpe_IDiagLog_SetOptions(handle(), getHandle(optionsInternal)); + } + Options getOptions() const{ + OptionsInternal optionsInternal(moveHandle(Snpe_IDiagLog_GetOptions(handle()))); + return Options(optionsInternal); + } + + bool setDiagLogMask(const std::string& mask){ + return SNPE_SUCCESS == Snpe_IDiagLog_SetDiagLogMask(handle(), mask.c_str()); + } + bool setDiagLogMask(const DlSystem::String& mask){ + return setDiagLogMask(static_cast(mask)); + } + + bool start(void){ + return SNPE_SUCCESS == Snpe_IDiagLog_Start(handle()); + } + bool stop(void){ + return SNPE_SUCCESS == Snpe_IDiagLog_Stop(handle()); + } + +}; + +} // ns DiagLog + +ALIAS_IN_ZDL_NAMESPACE(DiagLog, IDiagLog) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.h new file mode 100644 index 00000000..ad641cca --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.h @@ -0,0 +1,164 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef _DIAGLOG_OPTIONS_H_ +#define _DIAGLOG_OPTIONS_H_ + +#include + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE Options handle + */ +typedef void* Snpe_Options_Handle_t; + + +SNPE_API +Snpe_Options_Handle_t Snpe_Options_Create(); + +/** + * Destroys/frees a Options + * + * @param[in] handle : Handle to access Options object + * @return indication of success/failures + */ +SNPE_API +Snpe_ErrorCode_t Snpe_Options_Delete(Snpe_Options_Handle_t handle); + +/** + * Gets DiagLogMask + * diagLogMask: Enables diag logging only on the specified area mask + * + * @param[in] handle : Handle to access Options object + * @return diagLogMask as a const char* + */ +SNPE_API +const char* Snpe_Options_GetDiagLogMask(Snpe_Options_Handle_t handle); + +/** + * Sets DiagLogMask + * diagLogMask: Enables diag logging only on the specified area mask + * + * @param[in] handle : Handle to access Options object + * @param[in] diagLogMask : specific area where logging needs to be enabed + */ +SNPE_API +void Snpe_Options_SetDiagLogMask(Snpe_Options_Handle_t handle, const char* diagLogMask); + +/** + * Gets logFileDirectory + * logFileDirectory: The path to the directory where log files will be written. + * The path may be relative or absolute. Relative paths are interpreted + * + * @param[in] handle : Handle to access Options object + * @return logFileDirectory as a const char* + */ +SNPE_API +const char* Snpe_Options_GetLogFileDirectory(Snpe_Options_Handle_t handle); + +/** + * Sets logFileDirectory + * logFileDirectory: The path to the directory where log files will be written. + * The path may be relative or absolute. Relative paths are interpreted + * + * @param[in] handle : Handle to access Options object + * @param[in] logFileDirectory : path for saving the log files + */ +SNPE_API +void Snpe_Options_SetLogFileDirectory(Snpe_Options_Handle_t handle, const char* logFileDirectory); + + +/** + * Gets logFileName + * logFileName: The name used for log files. If this value is empty then BaseName will be + * used as the default file name. + * + * @param[in] handle : Handle to access Options object + * @return logFileName as a const char* + */ +SNPE_API +const char* Snpe_Options_GetLogFileName(Snpe_Options_Handle_t handle); + +/** + * Sets logFileName + * logFileName: The name used for log files. If this value is empty then BaseName will be + * used as the default file name. + * + * @param[in] handle : Handle to access Options object + * @param[in] logFileName : name of log file + */ +SNPE_API +void Snpe_Options_SetLogFileName(Snpe_Options_Handle_t handle, const char* logFileName); + +/** + * Gets the maximum number of log files to create. If set to 0 no log rotation + * will be used and the log file name specified will be used each time, overwriting + * any existing log file that may exist. + * + * @param[in] handle : Handle to access options object. + * @return max log files to create + */ +SNPE_API +uint32_t Snpe_Options_GetLogFileRotateCount(Snpe_Options_Handle_t handle); + +/** + * Sets the maximum number of log files to create. If set to 0 no log rotation + * will be used and the log file name specified will be used each time, overwriting + * any existing log file that may exist. + * + * @param[in] handle : Handle to access options object. + * @param[in] logFileRotateCount : max log files to create + */ +SNPE_API +void Snpe_Options_SetLogFileRotateCount(Snpe_Options_Handle_t handle, uint32_t logFileRotateCount); + +/** + * If the log file already exists, control whether it will be replaced + * + * @param[in] handle : Handle to access options object + * @return 1 if log file will be replaced, 0 otherwise + */ +SNPE_API +int Snpe_Options_GetLogFileReplace(Snpe_Options_Handle_t handle); + +/** + * If the log file already exists, control whether it will be replaced + * + * @param[in] handle : Handle to access options object + * @param[in] logFileReplace : 1 if log file to be replaced, 0 otherwise + */ +SNPE_API +void Snpe_Options_SetLogFileReplace(Snpe_Options_Handle_t handle, int logFileReplace); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DIAGLOG_OPTIONS_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.hpp new file mode 100644 index 00000000..c9ad48b6 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DiagLog/Options.hpp @@ -0,0 +1,50 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include +#include + +#include "DiagLog/IDiagLog.h" + + +namespace DiagLog { + +class Options +{ +public: + Options( + std::string diagLogMask = "", + std::string logFileDirectory = "diaglogs", + std::string logFileName = "DiagLog", + uint32_t logFileRotateCount = 20, + bool logFileReplace = true + ) + : DiagLogMask(std::move(diagLogMask)), + LogFileDirectory(std::move(logFileDirectory)), + LogFileName(std::move(logFileName)), + LogFileRotateCount(logFileRotateCount), + LogFileReplace(logFileReplace) + { + // Solves the empty string problem with multiple std libs + DiagLogMask.reserve(1); + } + + std::string DiagLogMask; + std::string LogFileDirectory; + std::string LogFileName; + uint32_t LogFileRotateCount; + + bool LogFileReplace; +}; + +} // ns DiagLog + +ALIAS_IN_ZDL_NAMESPACE(DiagLog, Options) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/DlContainer.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/DlContainer.h new file mode 100644 index 00000000..6ce7cd25 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/DlContainer.h @@ -0,0 +1,185 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_CONTAINER_DLCONTAINER_H +#define DL_CONTAINER_DLCONTAINER_H + +#ifdef __cplusplus +#include // uint8_t +#include // size_t +#else +#include +#include +#endif + +#include "DlSystem/DlError.h" +#include "DlSystem/StringList.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE DlcRecord handle + */ +typedef void* Snpe_DlcRecord_Handle_t; + +/** + * Constructs a DlcRecord and returns a handle to it + * + * @return the handle to the created DlcRecord + */ +SNPE_API +Snpe_DlcRecord_Handle_t Snpe_DlcRecord_Create(); + +/** + * Constructs a DlcRecord with a provided name and returns a handle to it + * + * @param[in] name : the name of the record + * + * @return the handle to the created DlcRecord + */ +SNPE_API +Snpe_DlcRecord_Handle_t Snpe_DlcRecord_CreateName(const char* name); + + +/** + * Destroys/frees a DlcRecord + * + * @param[in] dlcRecordHandle : Handle to access DlcRecord + * + * @return indication of success/failures + */ +SNPE_API +Snpe_ErrorCode_t Snpe_DlcRecord_Delete(Snpe_DlcRecord_Handle_t dlcRecordHandle); + +/** + * Gets the size of a DlcRecord in bytes + * + * @param[in] dlcRecordHandle : Handle to access DlcRecord + * + * @return the size of the DlcRecord in bytes + */ +SNPE_API +size_t Snpe_DlcRecord_Size(Snpe_DlcRecord_Handle_t dlcRecordHandle); + +/** + * Gets a pointer to the start of the DlcRecord's data + * + * @param[in] dlcRecordHandle : Handle to access DlcRecord + * + * @return uint8_t pointer to the DlcRecord's data + */ +SNPE_API +uint8_t* Snpe_DlcRecord_Data(Snpe_DlcRecord_Handle_t dlcRecordHandle); + +/** + * Gets the name of the DlcRecord + * + * @param[in] dlcRecordHandle : Handle to access DlcRecord + * + * @return the record's name + */ +SNPE_API +const char* Snpe_DlcRecord_Name(Snpe_DlcRecord_Handle_t dlcRecordHandle); + +/** + * A typedef to indicate a SNPE DlContainer handle + */ +typedef void* Snpe_DlContainer_Handle_t; + +/** + * Destroys/frees a DlContainer + * + * @param[in] dlContainerHandle : Handle to access DlContainer + * + * @return indication of success/failures + */ +SNPE_API +Snpe_ErrorCode_t Snpe_DlContainer_Delete(Snpe_DlContainer_Handle_t dlContainerHandle); + + +/** + * Initializes a container from a container archive file. + * + * @param[in] filename Container archive file path. + * + * @return Status of container open call + */ +SNPE_API +Snpe_DlContainer_Handle_t Snpe_DlContainer_Open(const char* filename); + +/** + * Initializes a container from a byte buffer. + * + * @param[in] buffer Byte buffer holding the contents of an archive + * file. + * + * @param[in] size Size of the byte buffer. + * + * @return A Snpe_DlContainer_Handle_t to access the dlContainer + */ +SNPE_API +Snpe_DlContainer_Handle_t Snpe_DlContainer_OpenBuffer(const uint8_t* buffer, const size_t size); + +/** + * Get the record catalog for a container. + * + * @param[in] dlContainerHandle : Handle to access DlContainer + * + * @return A Snpe_StringListHandle_t that holds the record names of the DlContainer + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_DlContainer_GetCatalog(Snpe_DlContainer_Handle_t dlContainerHandle); + +/** + * Get a record from a container by name. + * + * @param[in] dlContainerHandle : Handle to access DlContainer + * @param[in] recordName : Name of the record to fetch. + * + * @return A Snpe_DlcRecordHandle_t that owns the record read from the DlContainer + */ +SNPE_API +Snpe_DlcRecord_Handle_t Snpe_DlContainer_GetRecord(Snpe_DlContainer_Handle_t dlContainerHandle, const char* recordName); + +/** + * Save the container to an archive on disk. This function will save the + * container if the filename is different from the file that it was opened + * from, or if at least one record was modified since the container was + * opened. + * + * It will truncate any existing file at the target path. + * + * @param[in] dlContainerHandle : Handle to access DlContainer + * @param[in] filename : Container archive file path. + * + * @return indication of success/failure + */ +SNPE_API +Snpe_ErrorCode_t Snpe_DlContainer_Save(Snpe_DlContainer_Handle_t dlContainerHandle, const char* filename); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_CONTAINER_DLCONTAINER_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/IDlContainer.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/IDlContainer.hpp new file mode 100644 index 00000000..482dbd02 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlContainer/IDlContainer.hpp @@ -0,0 +1,146 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include +#include +#include +#include + +#include "Wrapper.hpp" +#include "DlSystem/String.hpp" + +#include "DlContainer/DlContainer.h" +#include "DlSystem/StringList.hpp" + + + +namespace DlContainer { + +struct DlcRecord +{ + std::string name; + std::vector data; + + DlcRecord() + : name{}, + data{} + { } + + DlcRecord( DlcRecord&& other ) noexcept + : name(std::move(other.name)), + data(std::move(other.data)) + { } + DlcRecord(const std::string& new_name) + : name(new_name), + data() + { + if(name.empty()) { + name.reserve(1); + } + } + DlcRecord(const DlcRecord&) = delete; +}; + + +class IDlContainer : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_DlContainer_Delete}; + + template + void getCatalog_(std::set& catalog) const{ + DlSystem::StringList sl(moveHandle(Snpe_DlContainer_GetCatalog(handle()))); + for(auto s : sl){ + catalog.emplace(s); + } + } + + + class DlcRecordInternal : public Wrapper { + friend BaseType; + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_DlcRecord_Delete}; + public: + DlcRecordInternal() + : BaseType(Snpe_DlcRecord_Create()) + { } + explicit DlcRecordInternal(const std::string& name) + : BaseType(Snpe_DlcRecord_CreateName(name.c_str())) + { } + + uint8_t* getData(){ + return Snpe_DlcRecord_Data(handle()); + } + size_t size() const{ + return Snpe_DlcRecord_Size(handle()); + } + const char* getName(){ + return Snpe_DlcRecord_Name(handle()); + } + }; + + +public: + static std::unique_ptr open(const std::string& filename) noexcept{ + return makeUnique(Snpe_DlContainer_Open(filename.c_str())); + } + + static std::unique_ptr open(const uint8_t* buffer, const size_t size) noexcept{ + return makeUnique(Snpe_DlContainer_OpenBuffer(buffer, size)); + + } + static std::unique_ptr open(const std::vector& buffer) noexcept{ + return open(buffer.data(), buffer.size()); + } + static std::unique_ptr open(const DlSystem::String &filename) noexcept{ + return open(static_cast(filename)); + } + + + void getCatalog(std::set& catalog) const{ + return getCatalog_(catalog); + } + void getCatalog(std::set& catalog) const{ + return getCatalog_(catalog); + } + + bool getRecord(const std::string& name, DlcRecord& record) const{ + auto h = Snpe_DlContainer_GetRecord(handle(), name.c_str()); + if(!h) return false; + DlcRecordInternal internal(moveHandle(h)); + auto data = internal.getData(); + + record.name.assign(internal.getName()); + record.data.assign(data, data+internal.size()); + return true; + } + + bool getRecord(const DlSystem::String& name, DlcRecord& record) const{ + return getRecord(static_cast(name), record); + } + + bool save(const std::string& filename){ + return Snpe_DlContainer_Save(handle(), filename.c_str()); + } + + bool save(const DlSystem::String& filename){ + return save(static_cast(filename)); + } +}; + + +} // ns DlContainer + +ALIAS_IN_ZDL_NAMESPACE(DlContainer, DlcRecord) +ALIAS_IN_ZDL_NAMESPACE(DlContainer, IDlContainer) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.h new file mode 100644 index 00000000..85a0f4d3 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.h @@ -0,0 +1,267 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _DL_ENUMS_H_ +#define _DL_ENUMS_H_ + +#include "DlSystem/SnpeApiExportDefine.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Enumeration of supported target runtimes. + */ +typedef enum +{ + /// Special value indicating the property is unset. + SNPE_RUNTIME_UNSET = -1, + /// Run the processing on Snapdragon CPU. + /// Data: float 32bit + /// Math: float 32bit + SNPE_RUNTIME_CPU_FLOAT32 = 0, + /// Default legacy enum to retain backward compatibility. + /// CPU = CPU_FLOAT32 + SNPE_RUNTIME_CPU = SNPE_RUNTIME_CPU_FLOAT32, + + /// Run the processing on the Adreno GPU. + /// Data: float 16bit + /// Math: float 32bit + SNPE_RUNTIME_GPU_FLOAT32_16_HYBRID = 1, + /// Default legacy enum to retain backward compatibility. + /// GPU = GPU_FLOAT32_16_HYBRID + SNPE_RUNTIME_GPU = SNPE_RUNTIME_GPU_FLOAT32_16_HYBRID, + + /// Run the processing on the Hexagon DSP. + /// Data: 8bit fixed point Tensorflow style format + /// Math: 8bit fixed point Tensorflow style format + SNPE_RUNTIME_DSP_FIXED8_TF = 2, + /// Default legacy enum to retain backward compatibility. + /// DSP = DSP_FIXED8_TF + SNPE_RUNTIME_DSP = SNPE_RUNTIME_DSP_FIXED8_TF, + + /// Run the processing on the Adreno GPU. + /// Data: float 16bit + /// Math: float 16bit + SNPE_RUNTIME_GPU_FLOAT16 = 3, + + /// Run the processing on Snapdragon AIX+HVX. + /// Data: 8bit fixed point Tensorflow style format + /// Math: 8bit fixed point Tensorflow style format + SNPE_RUNTIME_AIP_FIXED8_TF = 5, + SNPE_RUNTIME_AIP_FIXED_TF = SNPE_RUNTIME_AIP_FIXED8_TF +} Snpe_Runtime_t; + +/** + * Enumeration of runtime available check options. + */ +typedef enum +{ + /// Perform standard runtime available check + SNPE_RUNTIME_CHECK_OPTION_DEFAULT = 2, + /// Perform standard runtime available check + SNPE_RUNTIME_CHECK_OPTION_NORMAL_CHECK = 0, + /// Perform basic runtime available check, may be runtime specific + SNPE_RUNTIME_CHECK_OPTION_BASIC_CHECK = 1, + /// Perform unsignedPD runtime available check + SNPE_RUNTIME_CHECK_OPTION_UNSIGNEDPD_CHECK = 2, +} Snpe_RuntimeCheckOption_t; + +/** + * Enumeration of various performance profiles that can be requested. + */ +typedef enum +{ + /// Run in a standard mode. + /// This mode will be deprecated in the future and replaced with BALANCED. + SNPE_PERFORMANCE_PROFILE_DEFAULT = 0, + /// Run in a balanced mode. + SNPE_PERFORMANCE_PROFILE_BALANCED = 0, + + /// Run in high performance mode + SNPE_PERFORMANCE_PROFILE_HIGH_PERFORMANCE = 1, + + /// Run in a power sensitive mode, at the expense of performance. + SNPE_PERFORMANCE_PROFILE_POWER_SAVER = 2, + + /// Use system settings. SNPE makes no calls to any performance related APIs. + SNPE_PERFORMANCE_PROFILE_SYSTEM_SETTINGS = 3, + + /// Run in sustained high performance mode + SNPE_PERFORMANCE_PROFILE_SUSTAINED_HIGH_PERFORMANCE = 4, + + /// Run in burst mode + SNPE_PERFORMANCE_PROFILE_BURST = 5, + + /// Run in lower clock than POWER_SAVER, at the expense of performance. + SNPE_PERFORMANCE_PROFILE_LOW_POWER_SAVER = 6, + + /// Run in higher clock and provides better performance than POWER_SAVER. + SNPE_PERFORMANCE_PROFILE_HIGH_POWER_SAVER = 7, + + /// Run in lower balanced mode + SNPE_PERFORMANCE_PROFILE_LOW_BALANCED = 8, + + /// Run in lowest clock at the expense of performance + SNPE_PERFORMANCE_PROFILE_EXTREME_POWER_SAVER = 9, + +} Snpe_PerformanceProfile_t; + +/** + * Enumeration of various profilngLevels that can be requested. + */ +typedef enum +{ + /// No profiling. + /// Collects no runtime stats in the DiagLog + SNPE_PROFILING_LEVEL_OFF = 0, + + /// Basic profiling + /// Collects some runtime stats in the DiagLog + SNPE_PROFILING_LEVEL_BASIC = 1, + + /// Detailed profiling + /// Collects more runtime stats in the DiagLog, including per-layer statistics + /// Performance may be impacted + SNPE_PROFILING_LEVEL_DETAILED = 2, + + /// Moderate profiling + /// Collects more runtime stats in the DiagLog, no per-layer statistics + SNPE_PROFILING_LEVEL_MODERATE = 3, + + /// Linting profiling + /// HTP exclusive profiling level that collects in-depth performance metrics + /// for each op in the graph including main thread execution time and time spent + /// on parallel background ops + SNPE_PROFILING_LEVEL_LINTING = 4 + +} Snpe_ProfilingLevel_t; + +/** + * Enumeration of various execution priority hints. + */ +typedef enum +{ + /// Normal priority + SNPE_EXECUTION_PRIORITY_NORMAL = 0, + + /// Higher than normal priority + SNPE_EXECUTION_PRIORITY_HIGH = 1, + + /// Lower priority + SNPE_EXECUTION_PRIORITY_LOW = 2, + + /// Between Normal and High priority + SNPE_EXECUTION_PRIORITY_NORMAL_HIGH = 3 + +} Snpe_ExecutionPriorityHint_t; + +/** + * Enumeration that lists the supported image encoding formats. + */ +typedef enum +{ + /// For unknown image type. Also used as a default value for ImageEncoding_t. + SNPE_IMAGE_ENCODING_UNKNOWN = 0, + + /// The RGB format consists of 3 bytes per pixel: one byte for + /// Red, one for Green, and one for Blue. The byte ordering is + /// endian independent and is always in RGB byte order. + SNPE_IMAGE_ENCODING_RGB = 1, + + /// The ARGB32 format consists of 4 bytes per pixel: one byte for + /// Red, one for Green, one for Blue, and one for the alpha channel. + /// The alpha channel is ignored. The byte ordering depends on the + /// underlying CPU. For little endian CPUs, the byte order is BGRA. + /// For big endian CPUs, the byte order is ARGB. + SNPE_IMAGE_ENCODING_ARGB32 = 2, + + /// The RGBA format consists of 4 bytes per pixel: one byte for + /// Red, one for Green, one for Blue, and one for the alpha channel. + /// The alpha channel is ignored. The byte ordering is endian independent + /// and is always in RGBA byte order. + SNPE_IMAGE_ENCODING_RGBA = 3, + + /// The GRAYSCALE format is for 8-bit grayscale. + SNPE_IMAGE_ENCODING_GRAYSCALE = 4, + + /// NV21 is the Android version of YUV. The Chrominance is down + /// sampled and has a subsampling ratio of 4:2:0. Note that this + /// image format has 3 channels, but the U and V channels + /// are subsampled. For every four Y pixels there is one U and one V pixel. @newpage + SNPE_IMAGE_ENCODING_NV21 = 5, + + /// The BGR format consists of 3 bytes per pixel: one byte for + /// Red, one for Green and one for Blue. The byte ordering is + /// endian independent and is always BGR byte order. + SNPE_IMAGE_ENCODING_BGR = 6 +} Snpe_ImageEncoding_t; + +/** + * Enumeration that lists the supported LogLevels that can be set by users. + */ +typedef enum +{ + /// Enumeration variable to be used by user to set logging level to FATAL. + SNPE_LOG_LEVEL_FATAL = 0, + + /// Enumeration variable to be used by user to set logging level to ERROR. + SNPE_LOG_LEVEL_ERROR = 1, + + /// Enumeration variable to be used by user to set logging level to WARN. + SNPE_LOG_LEVEL_WARN = 2, + + /// Enumeration variable to be used by user to set logging level to INFO. + SNPE_LOG_LEVEL_INFO = 3, + + /// Enumeration variable to be used by user to set logging level to VERBOSE. + SNPE_LOG_LEVEL_VERBOSE = 4 +} Snpe_LogLevel_t; + +/** + * Enumeration that list the supported data types for buffers + */ +typedef enum +{ + /// Unspecified + SNPE_IO_BUFFER_DATATYPE_UNSPECIFIED = 0, + + /// 32-bit floating point + SNPE_IO_BUFFER_DATATYPE_FLOATING_POINT_32 = 1, + + /// 16-bit floating point + SNPE_IO_BUFFER_DATATYPE_FLOATING_POINT_16 = 2, + + /// 8-bit fixed point + SNPE_IO_BUFFER_DATATYPE_FIXED_POINT_8 = 3, + + /// 16-bit fixed point + SNPE_IO_BUFFER_DATATYPE_FIXED_POINT_16 = 4 +} Snpe_IOBufferDataType_t; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DL_ENUMS_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.hpp new file mode 100644 index 00000000..9158f594 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlEnums.hpp @@ -0,0 +1,266 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +namespace DlSystem { +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * Enumeration of supported target runtimes. + */ +enum class Runtime_t +{ + /// Special value indicating the property is unset. + UNSET = -1, + /// Run the processing on Snapdragon CPU. + /// Data: float 32bit + /// Math: float 32bit + CPU_FLOAT32 = 0, + /// Default legacy enum to retain backward compatibility. + /// CPU = CPU_FLOAT32 + CPU = CPU_FLOAT32, + + /// Run the processing on the Adreno GPU. + /// Data: float 16bit + /// Math: float 32bit + GPU_FLOAT32_16_HYBRID = 1, + /// Default legacy enum to retain backward compatibility. + /// GPU = GPU_FLOAT32_16_HYBRID + GPU = GPU_FLOAT32_16_HYBRID, + + /// Run the processing on the Hexagon DSP. + /// Data: 8bit fixed point Tensorflow style format + /// Math: 8bit fixed point Tensorflow style format + DSP_FIXED8_TF = 2, + /// Default legacy enum to retain backward compatibility. + /// DSP = DSP_FIXED8_TF + DSP = DSP_FIXED8_TF, + + /// Run the processing on the Adreno GPU. + /// Data: float 16bit + /// Math: float 16bit + GPU_FLOAT16 = 3, + + /// Run the processing on Snapdragon AIX+HVX. + /// Data: 8bit fixed point Tensorflow style format + /// Math: 8bit fixed point Tensorflow style format + AIP_FIXED8_TF = 5, + AIP_FIXED_TF = AIP_FIXED8_TF, + + /// Any new enums should be added above this line + NUM_RUNTIME_TARGETS +}; + +/** + * Enumeration of runtime available check options. + */ +enum class RuntimeCheckOption_t +{ + /// Perform standard runtime available check + NORMAL_CHECK = 0, + /// Perform basic runtime available check, may be runtime specific + BASIC_CHECK = 1, + /// Perform unsignedPD runtime available check + UNSIGNEDPD_CHECK = 2, + /// Perform standard runtime available check + DEFAULT = 2, + /// Any new enums should be added above this line + NUM_RUNTIMECHECK_OPTIONS +}; + +/** + * Enumeration of various performance profiles that can be requested. + */ +enum class PerformanceProfile_t +{ + /// Run in a standard mode. + /// This mode will be deprecated in the future and replaced with BALANCED. + DEFAULT = 0, + /// Run in a balanced mode. + BALANCED = 0, + + /// Run in high performance mode + HIGH_PERFORMANCE = 1, + + /// Run in a power sensitive mode, at the expense of performance. + POWER_SAVER = 2, + + /// Use system settings. SNPE makes no calls to any performance related APIs. + SYSTEM_SETTINGS = 3, + + /// Run in sustained high performance mode + SUSTAINED_HIGH_PERFORMANCE = 4, + + /// Run in burst mode + BURST = 5, + + /// Run in lower clock than POWER_SAVER, at the expense of performance. + LOW_POWER_SAVER = 6, + + /// Run in higher clock and provides better performance than POWER_SAVER. + HIGH_POWER_SAVER = 7, + + /// Run in lower balanced mode + LOW_BALANCED = 8, + + /// Run in lowest clock at the expense of performance + EXTREME_POWER_SAVER = 9, + + /// Any new enums should be added above this line + NUM_PERF_PROFILES +}; + +/** + * Enumeration of various profilngLevels that can be requested. + */ +enum class ProfilingLevel_t +{ + /// No profiling. + /// Collects no runtime stats in the DiagLog + OFF = 0, + + /// Basic profiling + /// Collects some runtime stats in the DiagLog + BASIC = 1, + + /// Detailed profiling + /// Collects more runtime stats in the DiagLog, including per-layer statistics + /// Performance may be impacted + DETAILED = 2, + + /// Moderate profiling + /// Collects more runtime stats in the DiagLog, no per-layer statistics + MODERATE = 3, + + /// Linting profiling + /// HTP exclusive profiling level that collects in-depth performance metrics + /// for each op in the graph including main thread execution time and time spent + /// on parallel background ops + LINTING = 4 +}; + +/** + * Enumeration of various execution priority hints. + */ +enum class ExecutionPriorityHint_t +{ + /// Normal priority + NORMAL = 0, + + /// Higher than normal priority + HIGH = 1, + + /// Lower priority + LOW = 2, + + /// Between Normal and High priority + NORMAL_HIGH = 3, + + /// Any new enums should be added above this line + NUM_EXECUTION_PRIORITY_HINTS +}; + +/** @} */ /* end_addtogroup c_plus_plus_apis C++*/ + +/** + * Enumeration that lists the supported image encoding formats. + */ +enum class ImageEncoding_t +{ + /// For unknown image type. Also used as a default value for ImageEncoding_t. + UNKNOWN = 0, + + /// The RGB format consists of 3 bytes per pixel: one byte for + /// Red, one for Green, and one for Blue. The byte ordering is + /// endian independent and is always in RGB byte order. + RGB = 1, + + /// The ARGB32 format consists of 4 bytes per pixel: one byte for + /// Red, one for Green, one for Blue, and one for the alpha channel. + /// The alpha channel is ignored. The byte ordering depends on the + /// underlying CPU. For little endian CPUs, the byte order is BGRA. + /// For big endian CPUs, the byte order is ARGB. + ARGB32 = 2, + + /// The RGBA format consists of 4 bytes per pixel: one byte for + /// Red, one for Green, one for Blue, and one for the alpha channel. + /// The alpha channel is ignored. The byte ordering is endian independent + /// and is always in RGBA byte order. + RGBA = 3, + + /// The GRAYSCALE format is for 8-bit grayscale. + GRAYSCALE = 4, + + /// NV21 is the Android version of YUV. The Chrominance is down + /// sampled and has a subsampling ratio of 4:2:0. Note that this + /// image format has 3 channels, but the U and V channels + /// are subsampled. For every four Y pixels there is one U and one V pixel. @newpage + NV21 = 5, + + /// The BGR format consists of 3 bytes per pixel: one byte for + /// Red, one for Green and one for Blue. The byte ordering is + /// endian independent and is always BGR byte order. + BGR = 6 +}; + +/** + * Enumeration that lists the supported LogLevels that can be set by users. + */ +enum class LogLevel_t +{ + /// Enumeration variable to be used by user to set logging level to FATAL. + LOG_FATAL = 0, + + /// Enumeration variable to be used by user to set logging level to ERROR. + LOG_ERROR = 1, + + /// Enumeration variable to be used by user to set logging level to WARN. + LOG_WARN = 2, + + /// Enumeration variable to be used by user to set logging level to INFO. + LOG_INFO = 3, + + /// Enumeration variable to be used by user to set logging level to VERBOSE. + LOG_VERBOSE = 4, + + /// Any new enums should be added above this line + NUM_LOG_LEVELS +}; + +enum class IOBufferDataType_t : int +{ + UNSPECIFIED = 0, + FLOATING_POINT_32 = 1, + FLOATING_POINT_16 = 2, + FIXED_POINT_8 = 3, + FIXED_POINT_16 = 4, + INT_32 = 5, + UINT_32 = 6, + INT_8 = 7, + UINT_8 = 8, + INT_16 = 9, + UINT_16 = 10, + BOOL_8 = 11, + INT_64 = 12, + UINT_64 = 13 +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, Runtime_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, RuntimeCheckOption_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, PerformanceProfile_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ProfilingLevel_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ExecutionPriorityHint_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ImageEncoding_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, LogLevel_t) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, IOBufferDataType_t) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.h new file mode 100644 index 00000000..f8c216ea --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.h @@ -0,0 +1,299 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _DL_ERROR_H_ +#define _DL_ERROR_H_ + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "SnpeApiExportDefine.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Enumeration of error codes + */ +typedef enum +{ + /// Indicate success: SNPE_SUCCESS = 0 + SNPE_SUCCESS = 0, + + // C API Error Codes + // This is a temporary place for them. We still have to figure out how to manage + // passing error codes from the C API to C++ if we want to use things like SetLastError + SNPE_ERRORCODE_CAPI_CREATE_FAILURE = 10, + SNPE_ERRORCODE_CAPI_HANDLEGEN_FAILURE = 11, + SNPE_ERRORCODE_CAPI_DELETE_FAILURE = 12, + SNPE_ERRORCODE_CAPI_BAD_HANDLE = 13, + SNPE_ERRORCODE_CAPI_BAD_ARGUMENT = 14, + SNPE_ERRORCODE_CAPI_BAD_ALLOC = 15, + + // System config errors + SNPE_ERRORCODE_CONFIG_MISSING_PARAM = 100, + SNPE_ERRORCODE_CONFIG_INVALID_PARAM = 101, + SNPE_ERRORCODE_CONFIG_MISSING_FILE = 102, + SNPE_ERRORCODE_CONFIG_NNCONFIG_NOT_SET = 103, + SNPE_ERRORCODE_CONFIG_NNCONFIG_INVALID = 104, + SNPE_ERRORCODE_CONFIG_WRONG_INPUT_NAME = 105, + SNPE_ERRORCODE_CONFIG_INCORRECT_INPUT_DIMENSIONS = 106, + SNPE_ERRORCODE_CONFIG_DIMENSIONS_MODIFICATION_NOT_SUPPORTED = 107, + SNPE_ERRORCODE_CONFIG_BOTH_OUTPUT_LAYER_TENSOR_NAMES_SET = 108, + + SNPE_ERRORCODE_CONFIG_NNCONFIG_ONLY_TENSOR_SUPPORTED = 120, + SNPE_ERRORCODE_CONFIG_NNCONFIG_ONLY_USER_BUFFER_SUPPORTED = 121, + + // DlSystem errors + SNPE_ERRORCODE_DLSYSTEM_MISSING_BUFFER = 200, + SNPE_ERRORCODE_DLSYSTEM_TENSOR_CAST_FAILED = 201, + SNPE_ERRORCODE_DLSYSTEM_FIXED_POINT_PARAM_INVALID = 202, + SNPE_ERRORCODE_DLSYSTEM_SIZE_MISMATCH = 203, + SNPE_ERRORCODE_DLSYSTEM_NAME_NOT_FOUND = 204, + SNPE_ERRORCODE_DLSYSTEM_VALUE_MISMATCH = 205, + SNPE_ERRORCODE_DLSYSTEM_INSERT_FAILED = 206, + SNPE_ERRORCODE_DLSYSTEM_TENSOR_FILE_READ_FAILED = 207, + SNPE_ERRORCODE_DLSYSTEM_DIAGLOG_FAILURE = 208, + SNPE_ERRORCODE_DLSYSTEM_LAYER_NOT_SET = 209, + SNPE_ERRORCODE_DLSYSTEM_WRONG_NUMBER_INPUT_BUFFERS = 210, + SNPE_ERRORCODE_DLSYSTEM_RUNTIME_TENSOR_SHAPE_MISMATCH = 211, + SNPE_ERRORCODE_DLSYSTEM_TENSOR_MISSING = 212, + SNPE_ERRORCODE_DLSYSTEM_TENSOR_ITERATION_UNSUPPORTED = 213, + SNPE_ERRORCODE_DLSYSTEM_BUFFER_MANAGER_MISSING = 214, + SNPE_ERRORCODE_DLSYSTEM_RUNTIME_BUFFER_SOURCE_UNSUPPORTED = 215, + SNPE_ERRORCODE_DLSYSTEM_BUFFER_CAST_FAILED = 216, + SNPE_ERRORCODE_DLSYSTEM_WRONG_TRANSITION_TYPE = 217, + SNPE_ERRORCODE_DLSYSTEM_LAYER_ALREADY_REGISTERED = 218, + SNPE_ERRORCODE_DLSYSTEM_TENSOR_DIM_INVALID = 219, + + SNPE_ERRORCODE_DLSYSTEM_BUFFERENCODING_UNKNOWN = 240, + SNPE_ERRORCODE_DLSYSTEM_BUFFER_INVALID_PARAM = 241, + + // DlContainer errors + SNPE_ERRORCODE_DLCONTAINER_MODEL_PARSING_FAILED = 300, + SNPE_ERRORCODE_DLCONTAINER_UNKNOWN_LAYER_CODE = 301, + SNPE_ERRORCODE_DLCONTAINER_MISSING_LAYER_PARAM = 302, + SNPE_ERRORCODE_DLCONTAINER_LAYER_PARAM_NOT_SUPPORTED = 303, + SNPE_ERRORCODE_DLCONTAINER_LAYER_PARAM_INVALID = 304, + SNPE_ERRORCODE_DLCONTAINER_TENSOR_DATA_MISSING = 305, + SNPE_ERRORCODE_DLCONTAINER_MODEL_LOAD_FAILED = 306, + SNPE_ERRORCODE_DLCONTAINER_MISSING_RECORDS = 307, + SNPE_ERRORCODE_DLCONTAINER_INVALID_RECORD = 308, + SNPE_ERRORCODE_DLCONTAINER_WRITE_FAILURE = 309, + SNPE_ERRORCODE_DLCONTAINER_READ_FAILURE = 310, + SNPE_ERRORCODE_DLCONTAINER_BAD_CONTAINER = 311, + SNPE_ERRORCODE_DLCONTAINER_BAD_DNN_FORMAT_VERSION = 312, + SNPE_ERRORCODE_DLCONTAINER_UNKNOWN_AXIS_ANNOTATION = 313, + SNPE_ERRORCODE_DLCONTAINER_UNKNOWN_SHUFFLE_TYPE = 314, + SNPE_ERRORCODE_DLCONTAINER_TEMP_FILE_FAILURE = 315, + + // Network errors + SNPE_ERRORCODE_NETWORK_EMPTY_NETWORK = 400, + SNPE_ERRORCODE_NETWORK_CREATION_FAILED = 401, + SNPE_ERRORCODE_NETWORK_PARTITION_FAILED = 402, + SNPE_ERRORCODE_NETWORK_NO_OUTPUT_DEFINED = 403, + SNPE_ERRORCODE_NETWORK_MISMATCH_BETWEEN_NAMES_AND_DIMS = 404, + SNPE_ERRORCODE_NETWORK_MISSING_INPUT_NAMES = 405, + SNPE_ERRORCODE_NETWORK_MISSING_OUTPUT_NAMES = 406, + SNPE_ERRORCODE_NETWORK_EXECUTION_FAILED = 407, + + // Host runtime errors + SNPE_ERRORCODE_HOST_RUNTIME_TARGET_UNAVAILABLE = 500, + + // CPU runtime errors + SNPE_ERRORCODE_CPU_LAYER_NOT_SUPPORTED = 600, + SNPE_ERRORCODE_CPU_LAYER_PARAM_NOT_SUPPORTED = 601, + SNPE_ERRORCODE_CPU_LAYER_PARAM_INVALID = 602, + SNPE_ERRORCODE_CPU_LAYER_PARAM_COMBINATION_INVALID = 603, + SNPE_ERRORCODE_CPU_BUFFER_NOT_FOUND = 604, + SNPE_ERRORCODE_CPU_NETWORK_NOT_SUPPORTED = 605, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_ERRORCODE_CPU_UDO_OPERATION_FAILED = 606, +#endif //DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // CPU fixed-point runtime errors + SNPE_ERRORCODE_CPU_FXP_LAYER_NOT_SUPPORTED = 700, + SNPE_ERRORCODE_CPU_FXP_LAYER_PARAM_NOT_SUPPORTED = 701, + SNPE_ERRORCODE_CPU_FXP_LAYER_PARAM_INVALID = 702, + SNPE_ERRORCODE_CPU_FXP_OPTION_INVALID = 703, + + // GPU runtime errors + SNPE_ERRORCODE_GPU_LAYER_NOT_SUPPORTED = 800, + SNPE_ERRORCODE_GPU_LAYER_PARAM_NOT_SUPPORTED = 801, + SNPE_ERRORCODE_GPU_LAYER_PARAM_INVALID = 802, + SNPE_ERRORCODE_GPU_LAYER_PARAM_COMBINATION_INVALID = 803, + SNPE_ERRORCODE_GPU_KERNEL_COMPILATION_FAILED = 804, + SNPE_ERRORCODE_GPU_CONTEXT_NOT_SET = 805, + SNPE_ERRORCODE_GPU_KERNEL_NOT_SET = 806, + SNPE_ERRORCODE_GPU_KERNEL_PARAM_INVALID = 807, + SNPE_ERRORCODE_GPU_OPENCL_CHECK_FAILED = 808, + SNPE_ERRORCODE_GPU_OPENCL_FUNCTION_ERROR = 809, + SNPE_ERRORCODE_GPU_BUFFER_NOT_FOUND = 810, + SNPE_ERRORCODE_GPU_TENSOR_DIM_INVALID = 811, + SNPE_ERRORCODE_GPU_MEMORY_FLAGS_INVALID = 812, + SNPE_ERRORCODE_GPU_UNEXPECTED_NUMBER_OF_IO = 813, + SNPE_ERRORCODE_GPU_LAYER_PROXY_ERROR = 814, + SNPE_ERRORCODE_GPU_BUFFER_IN_USE = 815, + SNPE_ERRORCODE_GPU_BUFFER_MODIFICATION_ERROR = 816, + SNPE_ERRORCODE_GPU_DATA_ARRANGEMENT_INVALID = 817, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_ERRORCODE_GPU_UDO_OPERATION_FAILED = 818, +#endif //DNN_RUNTIME_HAVE_UDO_CAPABILITY + // DSP runtime errors + SNPE_ERRORCODE_DSP_LAYER_NOT_SUPPORTED = 900, + SNPE_ERRORCODE_DSP_LAYER_PARAM_NOT_SUPPORTED = 901, + SNPE_ERRORCODE_DSP_LAYER_PARAM_INVALID = 902, + SNPE_ERRORCODE_DSP_LAYER_PARAM_COMBINATION_INVALID = 903, + SNPE_ERRORCODE_DSP_STUB_NOT_PRESENT = 904, + SNPE_ERRORCODE_DSP_LAYER_NAME_TRUNCATED = 905, + SNPE_ERRORCODE_DSP_LAYER_INPUT_BUFFER_NAME_TRUNCATED = 906, + SNPE_ERRORCODE_DSP_LAYER_OUTPUT_BUFFER_NAME_TRUNCATED = 907, + SNPE_ERRORCODE_DSP_RUNTIME_COMMUNICATION_ERROR = 908, + SNPE_ERRORCODE_DSP_RUNTIME_INVALID_PARAM_ERROR = 909, + SNPE_ERRORCODE_DSP_RUNTIME_SYSTEM_ERROR = 910, + SNPE_ERRORCODE_DSP_RUNTIME_CRASHED_ERROR = 911, + SNPE_ERRORCODE_DSP_BUFFER_SIZE_ERROR = 912, + SNPE_ERRORCODE_DSP_UDO_EXECUTE_ERROR = 913, + SNPE_ERRORCODE_DSP_UDO_LIB_NOT_REGISTERED_ERROR = 914, + SNPE_ERRORCODE_DSP_UDO_INVALID_QUANTIZATION_TYPE_ERROR = 915, + + // Model validataion errors + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_NOT_SUPPORTED = 1000, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_PARAM_NOT_SUPPORTED = 1001, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_PARAM_INVALID = 1002, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_PARAM_MISSING = 1003, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_PARAM_COMBINATION_INVALID = 1004, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_ORDERING_INVALID = 1005, + SNPE_ERRORCODE_MODEL_VALIDATION_INVALID_CONSTRAINT = 1006, + SNPE_ERRORCODE_MODEL_VALIDATION_MISSING_BUFFER = 1007, + SNPE_ERRORCODE_MODEL_VALIDATION_BUFFER_REUSE_NOT_SUPPORTED = 1008, + SNPE_ERRORCODE_MODEL_VALIDATION_LAYER_COULD_NOT_BE_ASSIGNED = 1009, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_ERRORCODE_MODEL_VALIDATION_UDO_LAYER_FAILED = 1010, +#endif // DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // UDL errors + SNPE_ERRORCODE_UDL_LAYER_EMPTY_UDL_NETWORK = 1100, + SNPE_ERRORCODE_UDL_LAYER_PARAM_INVALID = 1101, + SNPE_ERRORCODE_UDL_LAYER_INSTANCE_MISSING = 1102, + SNPE_ERRORCODE_UDL_LAYER_SETUP_FAILED = 1103, + SNPE_ERRORCODE_UDL_EXECUTE_FAILED = 1104, + SNPE_ERRORCODE_UDL_BUNDLE_INVALID = 1105, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_ERRORCODE_UDO_REGISTRATION_FAILED = 1106, + SNPE_ERRORCODE_UDO_GET_PACKAGE_FAILED = 1107, + SNPE_ERRORCODE_UDO_GET_IMPLEMENTATION_FAILED = 1108, +#endif // DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // Dependent library errors + SNPE_ERRORCODE_STD_LIBRARY_ERROR = 1200, + + // Unknown exception (catch (...)), Has no component attached to this + SNPE_ERRORCODE_UNKNOWN_EXCEPTION = 1210, + + // Storage Errors + SNPE_ERRORCODE_STORAGE_INVALID_KERNEL_REPO = 1300, + +#ifdef DNN_RUNTIME_HAVE_AIP_RUNTIME + // AIP runtime errors + SNPE_ERRORCODE_AIP_LAYER_NOT_SUPPORTED = 1400, + SNPE_ERRORCODE_AIP_LAYER_PARAM_NOT_SUPPORTED = 1401, + SNPE_ERRORCODE_AIP_LAYER_PARAM_INVALID = 1402, + SNPE_ERRORCODE_AIP_LAYER_PARAM_COMBINATION_INVALID = 1403, + SNPE_ERRORCODE_AIP_STUB_NOT_PRESENT = 1404, + SNPE_ERRORCODE_AIP_LAYER_NAME_TRUNCATED = 1405, + SNPE_ERRORCODE_AIP_LAYER_INPUT_BUFFER_NAME_TRUNCATED = 1406, + SNPE_ERRORCODE_AIP_LAYER_OUTPUT_BUFFER_NAME_TRUNCATED = 1407, + SNPE_ERRORCODE_AIP_RUNTIME_COMMUNICATION_ERROR = 1408, + SNPE_ERRORCODE_AIP_RUNTIME_INVALID_PARAM_ERROR = 1409, + SNPE_ERRORCODE_AIP_RUNTIME_SYSTEM_ERROR = 1410, + SNPE_ERRORCODE_AIP_RUNTIME_TENSOR_MISSING = 1411, + SNPE_ERRORCODE_AIP_RUNTIME_TENSOR_SHAPE_MISMATCH = 1412, + SNPE_ERRORCODE_AIP_RUNTIME_BAD_AIX_RECORD = 1413, +#endif // DNN_RUNTIME_HAVE_AIP_RUNTIME + + // DlCaching errors + SNPE_ERRORCODE_DLCACHING_INVALID_METADATA = 1500, + SNPE_ERRORCODE_DLCACHING_INVALID_INITBLOB = 1501, + + // Infrastructure Errors + SNPE_ERRORCODE_INFRA_CLUSTERMGR_INSTANCE_INVALID = 1600, + SNPE_ERRORCODE_INFRA_CLUSTERMGR_EXECUTE_SYNC_FAILED = 1601, + + // Memory Errors + SNPE_ERRORCODE_MEMORY_CORRUPTION_ERROR = 1700 + +} Snpe_ErrorCode_t; + + + +/** + * Clear the last error code + */ +SNPE_API void Snpe_ErrorCode_clearLastErrorCode(); + +/** +* Returns the error code of the last error encountered. +* +* @return The error code. +* +* @note The returned error code is significant only when the return +* value of the call indicated an error. +*/ +SNPE_API Snpe_ErrorCode_t Snpe_ErrorCode_getLastErrorCode(); + +/** +* Returns the error string of the last error encountered. +* +* @return The error string. +* +* @note The returned error string is significant only when the return +* value of the call indicated an error. +*/ +SNPE_API const char* Snpe_ErrorCode_GetLastErrorString(); + +/** + * Returns the info string of the last error encountered. + */ +SNPE_API const char* Snpe_ErrorCode_getLastInfoString(); + +/** + * Returns the uint32_t representation of the error code enum. + * + * @param[in] code The error code to be converted. + * + * @return uint32_t representation of the error code. + */ +SNPE_API uint32_t Snpe_ErrorCode_enumToUInt32(Snpe_ErrorCode_t code); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // _DL_ERROR_H_ + diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.hpp new file mode 100644 index 00000000..55dc2140 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlError.hpp @@ -0,0 +1,261 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include + +#include "DlSystem/DlError.h" + + +namespace DlSystem { + +enum class ErrorCode : uint32_t { + NONE = 0, + + // C API Error Codes + // This is a temporary place for them. We still have to figure out how to manage + // passing error codes from the C API to C++ if we want to use things like SetLastError + SNPE_CAPI_CREATE_FAILURE = 10, + SNPE_CAPI_HANDLEGEN_FAILURE = 11, + SNPE_CAPI_DELETE_FAILURE = 12, + SNPE_CAPI_BAD_HANDLE = 13, + SNPE_CAPI_BAD_ARGUMENT = 14, + SNPE_CAPI_BAD_ALLOC = 15, + + + // System config errors + SNPE_CONFIG_MISSING_PARAM = 100, + SNPE_CONFIG_INVALID_PARAM = 101, + SNPE_CONFIG_MISSING_FILE = 102, + SNPE_CONFIG_NNCONFIG_NOT_SET = 103, + SNPE_CONFIG_NNCONFIG_INVALID = 104, + SNPE_CONFIG_WRONG_INPUT_NAME = 105, + SNPE_CONFIG_INCORRECT_INPUT_DIMENSIONS = 106, + SNPE_CONFIG_DIMENSIONS_MODIFICATION_NOT_SUPPORTED = 107, + SNPE_CONFIG_BOTH_OUTPUT_LAYER_TENSOR_NAMES_SET = 108, + + SNPE_CONFIG_NNCONFIG_ONLY_TENSOR_SUPPORTED = 120, + SNPE_CONFIG_NNCONFIG_ONLY_USER_BUFFER_SUPPORTED = 121, + + // DlSystem errors + SNPE_DLSYSTEM_MISSING_BUFFER = 200, + SNPE_DLSYSTEM_TENSOR_CAST_FAILED = 201, + SNPE_DLSYSTEM_FIXED_POINT_PARAM_INVALID = 202, + SNPE_DLSYSTEM_SIZE_MISMATCH = 203, + SNPE_DLSYSTEM_NAME_NOT_FOUND = 204, + SNPE_DLSYSTEM_VALUE_MISMATCH = 205, + SNPE_DLSYSTEM_INSERT_FAILED = 206, + SNPE_DLSYSTEM_TENSOR_FILE_READ_FAILED = 207, + SNPE_DLSYSTEM_DIAGLOG_FAILURE = 208, + SNPE_DLSYSTEM_LAYER_NOT_SET = 209, + SNPE_DLSYSTEM_WRONG_NUMBER_INPUT_BUFFERS = 210, + SNPE_DLSYSTEM_RUNTIME_TENSOR_SHAPE_MISMATCH = 211, + SNPE_DLSYSTEM_TENSOR_MISSING = 212, + SNPE_DLSYSTEM_TENSOR_ITERATION_UNSUPPORTED = 213, + SNPE_DLSYSTEM_BUFFER_MANAGER_MISSING = 214, + SNPE_DLSYSTEM_RUNTIME_BUFFER_SOURCE_UNSUPPORTED = 215, + SNPE_DLSYSTEM_BUFFER_CAST_FAILED = 216, + SNPE_DLSYSTEM_WRONG_TRANSITION_TYPE = 217, + SNPE_DLSYSTEM_LAYER_ALREADY_REGISTERED = 218, + SNPE_DLSYSTEM_TENSOR_DIM_INVALID = 219, + + SNPE_DLSYSTEM_BUFFERENCODING_UNKNOWN = 240, + SNPE_DLSYSTEM_BUFFER_INVALID_PARAM = 241, + + // DlContainer errors + SNPE_DLCONTAINER_MODEL_PARSING_FAILED = 300, + SNPE_DLCONTAINER_UNKNOWN_LAYER_CODE = 301, + SNPE_DLCONTAINER_MISSING_LAYER_PARAM = 302, + SNPE_DLCONTAINER_LAYER_PARAM_NOT_SUPPORTED = 303, + SNPE_DLCONTAINER_LAYER_PARAM_INVALID = 304, + SNPE_DLCONTAINER_TENSOR_DATA_MISSING = 305, + SNPE_DLCONTAINER_MODEL_LOAD_FAILED = 306, + SNPE_DLCONTAINER_MISSING_RECORDS = 307, + SNPE_DLCONTAINER_INVALID_RECORD = 308, + SNPE_DLCONTAINER_WRITE_FAILURE = 309, + SNPE_DLCONTAINER_READ_FAILURE = 310, + SNPE_DLCONTAINER_BAD_CONTAINER = 311, + SNPE_DLCONTAINER_BAD_DNN_FORMAT_VERSION = 312, + SNPE_DLCONTAINER_UNKNOWN_AXIS_ANNOTATION = 313, + SNPE_DLCONTAINER_UNKNOWN_SHUFFLE_TYPE = 314, + SNPE_DLCONTAINER_TEMP_FILE_FAILURE = 315, + + // Network errors + SNPE_NETWORK_EMPTY_NETWORK = 400, + SNPE_NETWORK_CREATION_FAILED = 401, + SNPE_NETWORK_PARTITION_FAILED = 402, + SNPE_NETWORK_NO_OUTPUT_DEFINED = 403, + SNPE_NETWORK_MISMATCH_BETWEEN_NAMES_AND_DIMS = 404, + SNPE_NETWORK_MISSING_INPUT_NAMES = 405, + SNPE_NETWORK_MISSING_OUTPUT_NAMES = 406, + SNPE_NETWORK_EXECUTION_FAILED = 407, + + // Host runtime errors + SNPE_HOST_RUNTIME_TARGET_UNAVAILABLE = 500, + + // CPU runtime errors + SNPE_CPU_LAYER_NOT_SUPPORTED = 600, + SNPE_CPU_LAYER_PARAM_NOT_SUPPORTED = 601, + SNPE_CPU_LAYER_PARAM_INVALID = 602, + SNPE_CPU_LAYER_PARAM_COMBINATION_INVALID = 603, + SNPE_CPU_BUFFER_NOT_FOUND = 604, + SNPE_CPU_NETWORK_NOT_SUPPORTED = 605, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_CPU_UDO_OPERATION_FAILED = 606, +#endif //DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // CPU fixed-point runtime errors + SNPE_CPU_FXP_LAYER_NOT_SUPPORTED = 700, + SNPE_CPU_FXP_LAYER_PARAM_NOT_SUPPORTED = 701, + SNPE_CPU_FXP_LAYER_PARAM_INVALID = 702, + SNPE_CPU_FXP_OPTION_INVALID = 703, + + // GPU runtime errors + SNPE_GPU_LAYER_NOT_SUPPORTED = 800, + SNPE_GPU_LAYER_PARAM_NOT_SUPPORTED = 801, + SNPE_GPU_LAYER_PARAM_INVALID = 802, + SNPE_GPU_LAYER_PARAM_COMBINATION_INVALID = 803, + SNPE_GPU_KERNEL_COMPILATION_FAILED = 804, + SNPE_GPU_CONTEXT_NOT_SET = 805, + SNPE_GPU_KERNEL_NOT_SET = 806, + SNPE_GPU_KERNEL_PARAM_INVALID = 807, + SNPE_GPU_OPENCL_CHECK_FAILED = 808, + SNPE_GPU_OPENCL_FUNCTION_ERROR = 809, + SNPE_GPU_BUFFER_NOT_FOUND = 810, + SNPE_GPU_TENSOR_DIM_INVALID = 811, + SNPE_GPU_MEMORY_FLAGS_INVALID = 812, + SNPE_GPU_UNEXPECTED_NUMBER_OF_IO = 813, + SNPE_GPU_LAYER_PROXY_ERROR = 814, + SNPE_GPU_BUFFER_IN_USE = 815, + SNPE_GPU_BUFFER_MODIFICATION_ERROR = 816, + SNPE_GPU_DATA_ARRANGEMENT_INVALID = 817, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_GPU_UDO_OPERATION_FAILED = 818, +#endif //DNN_RUNTIME_HAVE_UDO_CAPABILITY + // DSP runtime errors + SNPE_DSP_LAYER_NOT_SUPPORTED = 900, + SNPE_DSP_LAYER_PARAM_NOT_SUPPORTED = 901, + SNPE_DSP_LAYER_PARAM_INVALID = 902, + SNPE_DSP_LAYER_PARAM_COMBINATION_INVALID = 903, + SNPE_DSP_STUB_NOT_PRESENT = 904, + SNPE_DSP_LAYER_NAME_TRUNCATED = 905, + SNPE_DSP_LAYER_INPUT_BUFFER_NAME_TRUNCATED = 906, + SNPE_DSP_LAYER_OUTPUT_BUFFER_NAME_TRUNCATED = 907, + SNPE_DSP_RUNTIME_COMMUNICATION_ERROR = 908, + SNPE_DSP_RUNTIME_INVALID_PARAM_ERROR = 909, + SNPE_DSP_RUNTIME_SYSTEM_ERROR = 910, + SNPE_DSP_RUNTIME_CRASHED_ERROR = 911, + SNPE_DSP_BUFFER_SIZE_ERROR = 912, + SNPE_DSP_UDO_EXECUTE_ERROR = 913, + SNPE_DSP_UDO_LIB_NOT_REGISTERED_ERROR = 914, + SNPE_DSP_UDO_INVALID_QUANTIZATION_TYPE_ERROR = 915, + SNPE_DSP_RUNTIME_INVALID_RPC_DRIVER = 916, + SNPE_DSP_RUNTIME_RPC_PERMISSION_ERROR = 917, + SNPE_DSP_RUNTIME_DSP_FILE_OPEN_ERROR = 918, + + // Model validataion errors + SNPE_MODEL_VALIDATION_LAYER_NOT_SUPPORTED = 1000, + SNPE_MODEL_VALIDATION_LAYER_PARAM_NOT_SUPPORTED = 1001, + SNPE_MODEL_VALIDATION_LAYER_PARAM_INVALID = 1002, + SNPE_MODEL_VALIDATION_LAYER_PARAM_MISSING = 1003, + SNPE_MODEL_VALIDATION_LAYER_PARAM_COMBINATION_INVALID = 1004, + SNPE_MODEL_VALIDATION_LAYER_ORDERING_INVALID = 1005, + SNPE_MODEL_VALIDATION_INVALID_CONSTRAINT = 1006, + SNPE_MODEL_VALIDATION_MISSING_BUFFER = 1007, + SNPE_MODEL_VALIDATION_BUFFER_REUSE_NOT_SUPPORTED = 1008, + SNPE_MODEL_VALIDATION_LAYER_COULD_NOT_BE_ASSIGNED = 1009, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_MODEL_VALIDATION_UDO_LAYER_FAILED = 1010, +#endif // DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // UDL errors + SNPE_UDL_LAYER_EMPTY_UDL_NETWORK = 1100, + SNPE_UDL_LAYER_PARAM_INVALID = 1101, + SNPE_UDL_LAYER_INSTANCE_MISSING = 1102, + SNPE_UDL_LAYER_SETUP_FAILED = 1103, + SNPE_UDL_EXECUTE_FAILED = 1104, + SNPE_UDL_BUNDLE_INVALID = 1105, +#ifdef DNN_RUNTIME_HAVE_UDO_CAPABILITY + SNPE_UDO_REGISTRATION_FAILED = 1106, + SNPE_UDO_GET_PACKAGE_FAILED = 1107, + SNPE_UDO_GET_IMPLEMENTATION_FAILED = 1108, +#endif // DNN_RUNTIME_HAVE_UDO_CAPABILITY + + // Dependent library errors + SNPE_STD_LIBRARY_ERROR = 1200, + + // Unknown exception (catch (...)), Has no component attached to this + SNPE_UNKNOWN_EXCEPTION = 1210, + + // Storage Errors + SNPE_STORAGE_INVALID_KERNEL_REPO = 1300, + +#ifdef DNN_RUNTIME_HAVE_AIP_RUNTIME + // AIP runtime errors + SNPE_AIP_LAYER_NOT_SUPPORTED = 1400, + SNPE_AIP_LAYER_PARAM_NOT_SUPPORTED = 1401, + SNPE_AIP_LAYER_PARAM_INVALID = 1402, + SNPE_AIP_LAYER_PARAM_COMBINATION_INVALID = 1403, + SNPE_AIP_STUB_NOT_PRESENT = 1404, + SNPE_AIP_LAYER_NAME_TRUNCATED = 1405, + SNPE_AIP_LAYER_INPUT_BUFFER_NAME_TRUNCATED = 1406, + SNPE_AIP_LAYER_OUTPUT_BUFFER_NAME_TRUNCATED = 1407, + SNPE_AIP_RUNTIME_COMMUNICATION_ERROR = 1408, + SNPE_AIP_RUNTIME_INVALID_PARAM_ERROR = 1409, + SNPE_AIP_RUNTIME_SYSTEM_ERROR = 1410, + SNPE_AIP_RUNTIME_TENSOR_MISSING = 1411, + SNPE_AIP_RUNTIME_TENSOR_SHAPE_MISMATCH = 1412, + SNPE_AIP_RUNTIME_BAD_AIX_RECORD = 1413, + SNPE_AIP_AXIS_QUANT_UNSUPPORTED = 1414, + +#endif // DNN_RUNTIME_HAVE_AIP_RUNTIME + + // DlCaching errors + SNPE_DLCACHING_INVALID_METADATA = 1500, + SNPE_DLCACHING_INVALID_INITBLOB = 1501, + + // Infrastructure Errors + SNPE_INFRA_CLUSTERMGR_INSTANCE_INVALID = 1600, + SNPE_INFRA_CLUSTERMGR_EXECUTE_SYNC_FAILED = 1601, + + // Memory Errors + SNPE_MEMORY_CORRUPTION_ERROR = 1700 + +}; + + +inline ErrorCode getLastErrorCode(){ + return static_cast(Snpe_ErrorCode_getLastErrorCode()); +} + +inline const char* getLastErrorString(){ + return Snpe_ErrorCode_GetLastErrorString(); +} + +inline const char* getLastInfoString(){ + return Snpe_ErrorCode_getLastInfoString(); +} + + +inline uint32_t enumToUInt32(ErrorCode code){ + return Snpe_ErrorCode_enumToUInt32(static_cast(code)); +} + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ErrorCode); + + +namespace zdl{ namespace DlSystem { + inline ErrorCode getLastErrorCode() { return ::DlSystem::getLastErrorCode() ; } + inline const char* getLastErrorString() { return ::DlSystem::getLastErrorString() ; } + inline const char* getLastInfoString() { return ::DlSystem::getLastInfoString() ; } + inline uint32_t enumToUInt32(ErrorCode code){ return ::DlSystem::enumToUInt32(code); } +}} // ns zdl::DlSystem diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlOptional.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlOptional.hpp new file mode 100644 index 00000000..e7bbf666 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlOptional.hpp @@ -0,0 +1,244 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include +#include + + +//============================================================================== +// +// Copyright (c) 2016, 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +//#include +#include +//#include + + +namespace DlSystem { + + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * @brief . + * + * Class to manage a value that may or may not exist. The boolean value + * of the Optional class is true if the object contains a value and false + * if it does not contain a value. + * + * The class must be evaluated and confirmed as true (containing a value) + * before being dereferenced. + */ +template +class Optional { +public: + enum class LIFECYCLE { + NONE = 0, + REFERENCE_OWNED = 1, + POINTER_OWNED = 2, + POINTER_NOT_OWNED = 3 + }; + + struct ReferenceCount { + size_t count = 0; + + void increment() { count++; } + + size_t decrement() { + if (count > 0) { + count--; + } + return count; + } + }; + + using U = typename std::remove_pointer::type; + + /** + * The default constructor is set to not have any value, and is + * therefore evaluated as false. + */ + // Do not explicit it so we can return {} + Optional() { + m_Type = LIFECYCLE::NONE; + } + + /** + * Construct an Optional class using an object. + * @param[in] Reference to an object v + * @param[out] Optional instance of object v + */ + template + Optional (const T& v, typename std::enable_if::value>::type* = 0) + : m_Type(LIFECYCLE::REFERENCE_OWNED) { + try { + m_StoragePtr = new T(v); + } catch (...) { + m_StoragePtr = nullptr; + m_Type = LIFECYCLE::NONE; + } + } + + template + Optional(U* v, LIFECYCLE type, typename std::enable_if::value>::type* = 0) + : m_Type(type) { + switch (m_Type) { + case LIFECYCLE::POINTER_OWNED: + m_StoragePtr = v; + m_Count = new ReferenceCount(); + m_Count->increment(); + break; + case LIFECYCLE::POINTER_NOT_OWNED: + m_StoragePtr = v; + break; + case LIFECYCLE::REFERENCE_OWNED: + throw std::bad_exception(); + case LIFECYCLE::NONE: + break; + } + } + + Optional(const Optional &other) : m_Type(other.m_Type), m_Count(other.m_Count) { + if (isReference()) { + m_StoragePtr = new U(*other.m_StoragePtr); + } else if (isPointer()) { + m_StoragePtr = other.m_StoragePtr; + if (isOwned()) { + m_Count->increment(); + } + } + } + + Optional& operator=(const Optional& other) noexcept { + Optional tmp(other); + swap(std::move(tmp)); + return *this; + } + + Optional(Optional&& other) noexcept { + swap(std::move(other)); + } + + Optional& operator=(Optional&& other) noexcept { + swap(std::move(other)); + return *this; + } + + ~Optional() { + if (isOwned()) { + if (isReference() || (isPointer() && m_Count->decrement() == 0)) { + delete m_StoragePtr; + delete m_Count; + } + } + } + + /** + * Boolean value of Optional class is only true when there exists a value. + */ + operator bool() const noexcept { return isValid(); } + + bool operator!() const noexcept { return !isValid(); } + + /** + * Get reference of Optional object + * @warning User must validate Optional has value before. + */ + const T& operator*() { return this->GetReference(); } + + /** + * Get reference of Optional object + * @warning User must validate Optional has value before. + */ + const T& operator*() const { return this->GetReference(); } + + operator T&() { return this->GetReference(); } + + T operator->() { + T self = this->GetReference(); + return self; + } + + void release(){ + if(isOwned() && isPointer()){ + m_Type = LIFECYCLE::POINTER_NOT_OWNED; + if(m_Count && m_Count->decrement() == 0){ + delete m_Count; + m_Count = nullptr; + } + } + } +private: + void swap(Optional&& other) { + m_Type = other.m_Type; + m_StoragePtr = other.m_StoragePtr; + m_Count = other.m_Count; + + other.m_Type = LIFECYCLE::NONE; + other.m_StoragePtr = nullptr; + other.m_Count = nullptr; + } + + template + typename std::enable_if::value, const Q&>::type GetReference() const noexcept { + if (!isReference()) std::terminate(); + return *static_cast(m_StoragePtr); + } + + template + typename std::enable_if::value, const Q&>::type GetReference() const noexcept { + if (!isPointer()) std::terminate(); + return static_cast(m_StoragePtr); + } + + template + typename std::enable_if::value, Q&>::type GetReference() noexcept { + if (!isReference()) std::terminate(); + return *m_StoragePtr; + } + + template + typename std::enable_if::value, Q&>::type GetReference() noexcept { + if (!isPointer()) std::terminate(); + return m_StoragePtr; + } + + bool isPointer() const { + return m_Type == LIFECYCLE::POINTER_OWNED || m_Type == LIFECYCLE::POINTER_NOT_OWNED; + } + + bool isOwned() const { + return m_Type == LIFECYCLE::REFERENCE_OWNED || m_Type == LIFECYCLE::POINTER_OWNED; + } + + bool isReference() const { + return m_Type == LIFECYCLE::REFERENCE_OWNED; + } + + bool isValid() const { + return m_Type != LIFECYCLE::NONE; + } + + U* m_StoragePtr = nullptr; + LIFECYCLE m_Type; + ReferenceCount *m_Count = nullptr; +}; + +} // ns DlSystem + + + +namespace zdl { namespace DlSystem { template using Optional = ::DlSystem::Optional; }} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.h new file mode 100644 index 00000000..fac01d1c --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.h @@ -0,0 +1,122 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + + +/** + * @file + */ + +#ifndef _DL_VERSION_H_ +#define _DL_VERSION_H_ + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A class that contains the different portions of a version number. + * A typedef to indicate a SNPE DlVersion handle + */ +typedef void* Snpe_DlVersion_Handle_t; + +/** + * Construct a DlVersion + * + * @return a handle to the created DlVersion + */ +SNPE_API +Snpe_DlVersion_Handle_t Snpe_DlVersion_Create(); + + +/** + * Destroys/frees DlVersion + * + * @param[in] handle : Handle to access DlVersion + * + * @return SNPE_SUCCESS if Delete operation successful. +*/ +SNPE_API +Snpe_ErrorCode_t Snpe_DlVersion_Delete(Snpe_DlVersion_Handle_t handle); + +/** + * Get the major version number. + * @param[in] handle : Handle to access DlVersion + * @return Major version + */ +SNPE_API +int32_t Snpe_DlVersion_GetMajor(Snpe_DlVersion_Handle_t handle); + +/** + * Get the minor version number. + * @param[in] handle : Handle to access DlVersion + * @return Minor version + */ +SNPE_API +int32_t Snpe_DlVersion_GetMinor(Snpe_DlVersion_Handle_t handle); + +/** + * Get the teeny version number. + * @param[in] handle : Handle to access DlVersion + * @return Teeny version + */ +SNPE_API +int32_t Snpe_DlVersion_GetTeeny(Snpe_DlVersion_Handle_t handle); + +/** + * Get the string holding information about the build version. + * + * @param[in] handle : Handle to access DlVersion + * @return Build information + */ +SNPE_API +const char* Snpe_DlVersion_GetBuild(Snpe_DlVersion_Handle_t handle); + +/** + * @brief Returns a string in the form Major.Minor.Teeny.Build + * + * @param[in] handle : Handle to access DlVersion + * @return A formatted char* holding the version information. + * + * @note the returned string will be invalidated by subsequent calls to this function + */ +SNPE_API +const char* Snpe_DlVersion_ToString(Snpe_DlVersion_Handle_t handle); + +/** + * @brief Create a DlVersion from a string + * + * @param stringValue The formatted DlVersion string + * + * @return A handle to the created DlVersion + */ +SNPE_API +Snpe_DlVersion_Handle_t Snpe_DlVersion_FromString(const char* stringValue); + + + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DL_VERSION_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.hpp new file mode 100644 index 00000000..7badab1f --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/DlVersion.hpp @@ -0,0 +1,118 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include + +#include "Wrapper.hpp" +#include "String.hpp" + +#include "DlSystem/DlVersion.h" +#include "SNPE/SNPEUtil.h" + + +namespace DlSystem { + +class Version_t : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_DlVersion_Delete}; + + template + using MajorReference = WrapperDetail::GenericConstMemberReference; + + template + using MinorReference = WrapperDetail::GenericConstMemberReference; + + template + using TeenyReference = WrapperDetail::GenericConstMemberReference; + + + static std::string BuildGetter(Snpe_DlVersion_Handle_t handle){ + return Snpe_DlVersion_GetBuild(handle); + } + + template + using BuildReference = WrapperDetail::GenericConstMemberReference; + + + static const std::string& toString(int32_t Major, int32_t Minor, int32_t Teeny, const std::string& Build){ + thread_local std::string toret; + + toret = std::to_string(Major); + toret += '.'; + toret += std::to_string(Minor); + toret += '.'; + toret += std::to_string(Teeny); + if(!Build.empty()){ + toret += '.'; + toret += Build; + } + + return toret; + } + +public: + Version_t() + : BaseType(Snpe_DlVersion_Create()) + { } + + Version_t(int32_t Major, int32_t Minor, int32_t Teeny, const std::string& Build) + : BaseType(Snpe_DlVersion_FromString(toString(Major, Minor, Teeny, Build).c_str())) + { } + + + /// Holds the major version number. Changes in this value indicate + /// major changes that break backward compatibility. + MajorReference Major{*this}; + + /// Holds the minor version number. Changes in this value indicate + /// minor changes made to library that are backwards compatible + /// (such as additions to the interface). + MinorReference Minor{*this}; + + /// Holds the teeny version number. Changes in this value indicate + /// changes such as bug fixes and patches made to the library that + /// do not affect the interface. + TeenyReference Teeny{*this}; + + /// This string holds information about the build version. + BuildReference Build{*this}; + + + static Version_t fromString(const std::string& stringValue){ + return moveHandle(Snpe_DlVersion_FromString(stringValue.c_str())); + } + + /** + * @brief Returns a string in the form Major.Minor.Teeny.Build + * + * @return A formatted string holding the version information. + */ + std::string toString() const{ + return Snpe_DlVersion_ToString(handle()); + } + + /** + * @brief Returns a string in the form Major.Minor.Teeny.Build + * + * @return A formatted string holding the version information. + */ + String asString() const{ + return String(toString()); + } +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, Version_t) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.h new file mode 100644 index 00000000..96453ef9 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.h @@ -0,0 +1,117 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _IBUFFER_ATTRIBUTES_H +#define _IBUFFER_ATTRIBUTES_H + +#include "DlSystem/IUserBuffer.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE IBufferAttributes handle + */ +typedef void* Snpe_IBufferAttributes_Handle_t; + + +/** + * @brief Gets the buffer's element size, in bytes + * + * This can be used to compute the memory size required + * to back this buffer. + * + * @param[in] handle : Handle to access IBufferAttributes + * + * @return Element size, in bytes + */ +SNPE_API +size_t Snpe_IBufferAttributes_GetElementSize(Snpe_IBufferAttributes_Handle_t handle); + +/** + * @brief Gets the element's encoding type + * + * @param[in] handle : Handle to access IBufferAttributes + * + * @return encoding type + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_IBufferAttributes_GetEncodingType(Snpe_IBufferAttributes_Handle_t handle); + +/** + * @brief Gets the number of elements in each dimension + * + * @param[in] handle : Handle to access IBufferAttributes + * + * @return Dimension size, in terms of number of elements + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_IBufferAttributes_GetDims(Snpe_IBufferAttributes_Handle_t handle); + +/** + * @brief Gets the alignment requirement of each dimension + * + * Alignment per each dimension is expressed as an multiple, for + * example, if one particular dimension can accept multiples of 8, + * the alignment will be 8. + * + * @param[in] handle : Handle to access IBufferAttributes + * + * @return Alignment in each dimension, in terms of multiple of + * number of elements + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_IBufferAttributes_GetAlignments(Snpe_IBufferAttributes_Handle_t handle); + +/** + * @brief Gets the buffer encoding returned from the network responsible + * for generating this buffer. Depending on the encoding type, this will + * be an instance of an encoding type specific derived class. + * + * @param[in] handle : Handle to access IBufferAttributes + * + * @return Derived user buffer encoding object. + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_IBufferAttributes_GetEncoding_Ref(Snpe_IBufferAttributes_Handle_t handle); + +/** + * @brief Destroys the IBufferAttributes object + * + * @param[handle] handle : Handle to access IBufferAttributes + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IBufferAttributes_Delete(Snpe_IBufferAttributes_Handle_t handle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _IBUFFER_ATTRIBUTES_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.hpp new file mode 100644 index 00000000..2a86fcec --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IBufferAttributes.hpp @@ -0,0 +1,85 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include +#include "TensorShape.hpp" + +#include "DlSystem/IBufferAttributes.h" +#include "IUserBuffer.hpp" + +namespace DlSystem { + + +class IBufferAttributes : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_IBufferAttributes_Delete}; +public: + + size_t getElementSize() const noexcept{ + return Snpe_IBufferAttributes_GetElementSize(handle()); + } + + UserBufferEncoding::ElementType_t getEncodingType() const noexcept{ + return static_cast(Snpe_IBufferAttributes_GetEncodingType(handle())); + } + + TensorShape getDims() const{ + return moveHandle(Snpe_IBufferAttributes_GetDims(handle())); + } + + TensorShape getAlignments() const{ + return moveHandle(Snpe_IBufferAttributes_GetAlignments(handle())); + } + + UserBufferEncoding* getEncoding() const{ + auto h = Snpe_IBufferAttributes_GetEncoding_Ref(handle()); + switch(Snpe_UserBufferEncoding_GetElementType(h)){ + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNSIGNED8BIT: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT32: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT32: + return makeReference(h); + + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT16: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF8: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF16: + return makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_BOOL8: + return makeReference(h); + + default: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNKNOWN: + return makeReference(h); + } + } + +}; + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, IBufferAttributes) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.h new file mode 100644 index 00000000..a3c3c623 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.h @@ -0,0 +1,156 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_IOBUFFER_DATATYPE_MAP_H +#define DL_SYSTEM_IOBUFFER_DATATYPE_MAP_H + +#include + +#include "DlSystem/DlError.h" +#include "DlSystem/DlEnums.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE IOBufferDataTypeMap handle + */ +typedef void* Snpe_IOBufferDataTypeMap_Handle_t; + +/** + * @brief . + * + * Creates a new Buffer Data type map + * + */ +SNPE_API +Snpe_IOBufferDataTypeMap_Handle_t Snpe_IOBufferDataTypeMap_Create(); + +/** + * @brief Destroys the map + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IOBufferDataTypeMap_Delete(Snpe_IOBufferDataTypeMap_Handle_t handle); +/** + * @brief Adds a name and the corresponding buffer data type + * to the map + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @param[in] name : The name of the buffer + * + * @param[in] bufferDataType : data type of the buffer + * + * @note If a buffer with the same name already exists, no new + * buffer is added. + */ +SNPE_API +Snpe_ErrorCode_t +Snpe_IOBufferDataTypeMap_Add(Snpe_IOBufferDataTypeMap_Handle_t handle, const char* name, Snpe_IOBufferDataType_t bufferDataType); + +/** + * @brief Removes a buffer name from the map + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @param[in] name : The name of the buffer + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IOBufferDataTypeMap_Remove(Snpe_IOBufferDataTypeMap_Handle_t handle, const char* name); + +/** + * @brief Returns the type of the named buffer + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @param[in] name : The name of the buffer + * + * @return The type of the buffer, or UNSPECIFIED if the buffer does not exist + * + */ +SNPE_API +Snpe_IOBufferDataType_t Snpe_IOBufferDataTypeMap_GetBufferDataType(Snpe_IOBufferDataTypeMap_Handle_t handle, const char* name); + +/** + * @brief Returns the type of the first buffer + * + * @param handle : Handle to access the IOBufferDataType map + * + * @return The type of the first buffer, or SNPE_IO_BUFFER_DATATYPE_UNSPECIFIED if the map is empty. + */ +SNPE_API +Snpe_IOBufferDataType_t Snpe_IOBufferDataTypeMap_GetBufferDataTypeOfFirst(Snpe_IOBufferDataTypeMap_Handle_t handle); + +/** + * @brief Returns the size of the buffer type map. + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @return The size of the map + * + */ +SNPE_API +size_t Snpe_IOBufferDataTypeMap_Size(Snpe_IOBufferDataTypeMap_Handle_t handle); + +/** + * @brief Checks the existence of the named buffer in the map + * + * @param[in] handle : Handle to access the IOBufferDataType map + * + * @param[in] name : The name of the buffer + * + * @return 1 if the named buffer exists, 0 otherwise. + * + */ +SNPE_API +int Snpe_IOBufferDataTypeMap_Find(Snpe_IOBufferDataTypeMap_Handle_t handle, const char* name); + +/** + * @brief Resets the map + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IOBufferDataTypeMap_Clear(Snpe_IOBufferDataTypeMap_Handle_t handle); + +/** + * @brief Checks whether the map is empty + * + * @return 1 if the map is empty, 0 otherwise. + * + */ +SNPE_API +int Snpe_IOBufferDataTypeMap_Empty(Snpe_IOBufferDataTypeMap_Handle_t handle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_IOBUFFER_DATATYPE_MAP_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.hpp new file mode 100644 index 00000000..c39d3320 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IOBufferDataTypeMap.hpp @@ -0,0 +1,69 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include + +#include "DlEnums.hpp" + + +#include "DlSystem/IOBufferDataTypeMap.h" + +namespace DlSystem { + +class IOBufferDataTypeMap : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_IOBufferDataTypeMap_Delete}; + +public: + + IOBufferDataTypeMap() + : BaseType(Snpe_IOBufferDataTypeMap_Create()) + { } + + void add(const char* name, IOBufferDataType_t bufferDataType){ + Snpe_IOBufferDataTypeMap_Add(handle(), name, static_cast(bufferDataType)); + } + + void remove(const char* name){ + Snpe_IOBufferDataTypeMap_Remove(handle(), name); + } + + IOBufferDataType_t getBufferDataType(const char* name){ + return static_cast(Snpe_IOBufferDataTypeMap_GetBufferDataType(handle(), name)); + } + + IOBufferDataType_t getBufferDataType(){ + return static_cast(Snpe_IOBufferDataTypeMap_GetBufferDataTypeOfFirst(handle())); + } + + size_t size() const{ + return Snpe_IOBufferDataTypeMap_Size(handle()); + } + + bool find(const char* name) const{ + return Snpe_IOBufferDataTypeMap_Find(handle(), name); + } + + void clear(){ + Snpe_IOBufferDataTypeMap_Clear(handle()); + } + + bool empty() const{ + return Snpe_IOBufferDataTypeMap_Empty(handle()); + } +}; + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, IOBufferDataTypeMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.h new file mode 100644 index 00000000..913f3bdc --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.h @@ -0,0 +1,118 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef _DL_SYSTEM_ITENSOR_H_ +#define _DL_SYSTEM_ITENSOR_H_ + +#include + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/DlError.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Represents a tensor which holds n-dimensional data. It is important to + * understand how the tensor data is represented in memory + * relative to the tensor dimensions. Tensors store data in + * memory in row-major order (i.e. the last tensor dimension is + * the fastest varying one). For example, if you have a two + * dimensional tensor with 3 rows and 2 columns (i.e. the tensor + * dimensions are 3,2 as returned in tensor dimension vectors) + * with the following data in terms rows and columns: + * + * | 1 2 |
+ * | 3 4 |
+ * | 5 6 |
+ * + * This data would be stored in memory as 1,2,3,4,5,6. + */ +typedef void* Snpe_ITensor_Handle_t; + + +/** + * Destroys/frees an ITensor + * + * @param[in] userBufferHandle : Handle to access the IUserBuffer + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_ITensor_Delete(Snpe_ITensor_Handle_t iTensorHandle); + +/** + * Returns a tensor iterator pointing to the beginning + * of the data in the tensor. + * + * @param[in] tensorHandle : Handle to access ITensor + * + * @return The tensor data as a void pointer. + */ +SNPE_API +void* Snpe_ITensor_GetData(Snpe_ITensor_Handle_t tensorHandle); + +/** + * @brief Gets the shape of this tensor. + * + * The last element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying dimension, etc. + * + * @param[in] tensorHandle : Handle to access ITensor + * + * @return A TensorShape handle holding the tensor dimensions. + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_ITensor_GetShape(Snpe_ITensor_Handle_t tensorHandle); + +/** + * Returns the element size of the data in the tensor + * (discounting strides). This is how big a buffer would + * need to be to hold the tensor data contiguously in + * memory. + * + * @param[in] tensorHandle : Handle to access ITensor + * + * @return The size of the tensor (in elements). + */ +SNPE_API +size_t Snpe_ITensor_GetSize(Snpe_ITensor_Handle_t tensorHandle); + +SNPE_API +int Snpe_ITensor_IsQuantized(Snpe_ITensor_Handle_t tensorHandle); + +SNPE_API +float Snpe_ITensor_GetDelta(Snpe_ITensor_Handle_t tensorHandle); + +SNPE_API +float Snpe_ITensor_GetOffset(Snpe_ITensor_Handle_t tensorHandle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DL_SYSTEM_ITENSOR_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.hpp new file mode 100644 index 00000000..4785a39d --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensor.hpp @@ -0,0 +1,95 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "TensorShape.hpp" +#include "ITensorItr.hpp" + +#include "DlSystem/ITensor.h" + + +namespace DlSystem { + + +class ITensor : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_ITensor_Delete}; + + template + T* getData(){ + return static_cast(Snpe_ITensor_GetData(handle())); + } + + template + const T* getData() const{ + return static_cast(Snpe_ITensor_GetData(handle())); + } + +public: + using iterator = DlSystem::ITensorItr; + using const_iterator = DlSystem::ITensorItr; + + + iterator begin(){ + return iterator(getData()); + } + + const_iterator begin() const{ + return const_iterator(getData()); + } + + const_iterator cbegin() const{ + return begin(); + } + + iterator end(){ + return begin() + getSize(); + } + + const_iterator end() const{ + return cbegin() + getSize(); + } + + const_iterator cend() const{ + return end(); + } + + TensorShape getShape() const{ + return moveHandle(Snpe_ITensor_GetShape(handle())); + } + + size_t getSize() const{ + return Snpe_ITensor_GetSize(handle()); + } + + // Serialize to std::ostream is no longer supported + void serialize(std::ostream &output) const = delete; + + bool isQuantized() const{ + return Snpe_ITensor_IsQuantized(handle()); + } + + float GetDelta() const{ + return Snpe_ITensor_GetDelta(handle()); + } + + float GetOffset() const{ + return Snpe_ITensor_GetOffset(handle()); + } +}; + + +} //ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ITensor) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorFactory.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorFactory.hpp new file mode 100644 index 00000000..5ef1e9d3 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorFactory.hpp @@ -0,0 +1,52 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "ITensor.hpp" + +#include + + +#include "SNPE/SNPEUtil.h" + +namespace DlSystem{ +// NOTE: These factories use a different handle type because they are singletons +// Never copy this pattern unless you're also implementing a singleton +class ITensorFactory : public Wrapper{ + friend BaseType; + + using BaseType::BaseType; + static constexpr DeleteFunctionType DeleteFunction{NoOpDeleter}; + +public: + ITensorFactory() + : BaseType(nullptr) + { } + + + std::unique_ptr createTensor(const TensorShape &shape) noexcept{ + return makeUnique(Snpe_Util_CreateITensor(getHandle(shape))); + } + + // Create from std::istream is no longer supported + std::unique_ptr createTensor(std::istream &input) noexcept = delete; + + std::unique_ptr createTensor(const TensorShape &shape, + const unsigned char *data, + size_t dataSize) noexcept{ + auto handle = Snpe_Util_CreateITensorDataSize(getHandle(shape), data, dataSize); + return makeUnique(handle); + } + +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, ITensorFactory) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItr.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItr.hpp new file mode 100644 index 00000000..801aa217 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItr.hpp @@ -0,0 +1,199 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include +#include + +#include "Wrapper.hpp" +#include "ITensorItrImpl.hpp" + +namespace DlSystem{ + +template +class ITensorItr{ +public: + using iterator_category = std::bidirectional_iterator_tag; + using pointer = typename std::conditional::type; + using value_type = float; + using difference_type = std::ptrdiff_t; + using reference = typename std::conditional::type; + + + ITensorItr() = delete; + virtual ~ITensorItr() = default; + + explicit ITensorItr(pointer data) noexcept + : m_Impl{nullptr}, + m_IsTrivial{true}, + m_Data{data}, + m_DataStart{data} + { } + + ITensorItr(std::unique_ptr impl, + bool isTrivial = false, + float* data = nullptr) + : m_Impl(impl->clone()), + m_IsTrivial(isTrivial), + m_Data(data), + m_DataStart(data) + { } + + ITensorItr(const ITensorItr& itr) + : m_Impl(itr.m_Impl ? itr.m_Impl->clone() : nullptr), + m_IsTrivial(itr.m_IsTrivial), + m_Data(itr.m_Data), + m_DataStart(itr.m_DataStart) + { } + + ITensorItr(ITensorItr&& itr) noexcept + : m_Impl(std::move(itr.m_Impl)), + m_IsTrivial(itr.m_IsTrivial), + m_Data(itr.m_Data), + m_DataStart(itr.m_DataStart) + { } + + ITensorItr& operator=(const ITensorItr& other){ + if (this == &other) return *this; + + m_Impl = other.m_Impl ? other.m_Impl->clone() : nullptr; + m_IsTrivial = other.m_IsTrivial; + m_Data = other.m_Data; + m_DataStart = other.m_DataStart; + return *this; + } + ITensorItr& operator=(ITensorItr&& other) noexcept{ + if(this != &other){ + m_Impl = std::move(other.m_Impl); + m_IsTrivial = other.m_IsTrivial; + m_Data = other.m_Data; + m_DataStart = other.m_DataStart; + } + return *this; + } + + inline ITensorItr& operator++(){ + if (m_IsTrivial){ + m_Data++; + } else { + m_Impl->increment(); + } + return *this; + } + inline ITensorItr operator++(int){ + ITensorItr tmp(*this); + operator++(); + return tmp; + } + inline ITensorItr& operator--(){ + if (m_IsTrivial){ + m_Data--; + } else { + m_Impl->decrement(); + } + return *this; + } + inline ITensorItr operator--(int){ + ITensorItr tmp(*this); + operator--(); + return tmp; + } + inline ITensorItr& operator+=(int rhs){ + if (m_IsTrivial){ + m_Data += rhs; + } else { + m_Impl->increment(rhs); + } + return *this; + } + inline friend ITensorItr operator+(ITensorItr lhs, int rhs){ + lhs += rhs; + return lhs; + } + inline ITensorItr& operator-=(int rhs){ + if (m_IsTrivial){ + m_Data -= rhs; + } else { + m_Impl->decrement(rhs); + } + return *this; + } + inline friend ITensorItr operator-(ITensorItr lhs, int rhs){ + lhs -= rhs; + return lhs; + } + + inline size_t operator-(const ITensorItr& rhs){ + if (m_IsTrivial) return (m_Data - m_DataStart) - (rhs.m_Data - rhs.m_DataStart); + return m_Impl->getPosition() - rhs.m_Impl->getPosition(); + } + + inline friend bool operator<(const ITensorItr& lhs, const ITensorItr& rhs){ + if (lhs.m_IsTrivial) return lhs.m_Data < rhs.m_Data; + return lhs.m_Impl->dataPointer() < rhs.m_Impl->dataPointer(); + } + inline friend bool operator>(const ITensorItr& lhs, const ITensorItr& rhs){ + return rhs < lhs; + } + inline friend bool operator<=(const ITensorItr& lhs, const ITensorItr& rhs){ + return !(lhs > rhs); + } + inline friend bool operator>=(const ITensorItr& lhs, const ITensorItr& rhs){ + return !(lhs < rhs); + } + + inline bool operator==(const ITensorItr& rhs) const{ + if (m_IsTrivial) return m_Data == rhs.m_Data; + return m_Impl->dataPointer() == rhs.m_Impl->dataPointer(); + } + inline bool operator!=(const ITensorItr& rhs) const{ + return !operator==(rhs); + } + + inline reference operator[](size_t idx){ + if (m_IsTrivial) return *(m_DataStart + idx); + return m_Impl->getReferenceAt(idx); + } + inline reference operator*(){ + if (m_IsTrivial) return *m_Data; + return m_Impl->getReference(); + } + inline reference operator->(){ + return *(*this); + } + inline float* dataPointer() const{ + if (m_IsTrivial) return m_Data; + return m_Impl->dataPointer(); + } + + +protected: + std::unique_ptr<::DlSystem::ITensorItrImpl> m_Impl; + bool m_IsTrivial = false; + pointer m_Data = nullptr; + pointer m_DataStart = nullptr; +}; + + +inline void fill(ITensorItr first, ITensorItr end, float val){ + std::fill(first, end, val); +} +template +OutItr copy(InItr first, InItr last, OutItr result){ + return std::copy(first, last, result); +} + +} // ns DlSystem + + +// ALIAS_IN_ZDL_NAMESPACE +namespace zdl{ namespace DlSystem{ + template + using ITensorItr = ::DlSystem::ITensorItr; +}} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItrImpl.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItrImpl.hpp new file mode 100644 index 00000000..6b9a497b --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/ITensorItrImpl.hpp @@ -0,0 +1,32 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once +#include "Wrapper.hpp" + +namespace DlSystem { + +class ITensorItrImpl { +public: + ITensorItrImpl() = default; + virtual ~ITensorItrImpl() = default; + + virtual float getValue() const = 0; + virtual float& getReference() = 0; + virtual float& getReferenceAt(size_t idx) = 0; + virtual float* dataPointer() const = 0; + virtual void increment(int incVal = 1) = 0; + virtual void decrement(int decVal = 1) = 0; + virtual size_t getPosition() = 0; + virtual std::unique_ptr clone() = 0; + +private: + ITensorItrImpl& operator=(const ITensorItrImpl& other) = delete; + ITensorItrImpl(const ITensorItrImpl& other) = delete; +}; + +} // ns DlSystem diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.h new file mode 100644 index 00000000..fc4cc316 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.h @@ -0,0 +1,714 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _IUSER_BUFFER_H +#define _IUSER_BUFFER_H + +#include +#include + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/DlError.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE UserByfferEncoding handle + */ +typedef void* Snpe_UserBufferEncoding_Handle_t; + +/** + * @brief . + * + * An enum class of all supported element types in a IUserBuffer + */ +//enum class Snpe_UserBufferEncoding_ElementType_t +typedef enum +{ + /// Unknown element type. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNKNOWN = 0, + + /// Each element is presented by float. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT = 1, + + /// Each element is presented by an unsigned int. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNSIGNED8BIT = 2, + + /// Each element is presented by float16. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT16 = 3, + + /// Each element is presented by an 8-bit quantized value. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF8 = 10, + + /// Each element is presented by an 16-bit quantized value. + SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF16 = 11, + + /// Each element is presented by Int32 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT32 = 12, + + /// Each element is presented by UInt32 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT32 = 13, + + /// Each element is presented by Int8 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT8 = 14, + + /// Each element is presented by UInt8 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT8 = 15, + + /// Each element is presented by Int16 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT16 = 16, + + /// Each element is presented by UInt16 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT16 = 17, + + /// Each element is present by Bool8 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_BOOL8 = 18, + + /// Each element is present by Int64 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT64 = 19, + + /// Each element is present by UInt64 + SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT64 = 20 + +}Snpe_UserBufferEncoding_ElementType_t; + + +/** + * @brief Retrieves the element type + * + * @param[in] userBufferEncodingHandle : Handle to access userBufferEncoding + * + * @return Element type + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_UserBufferEncoding_GetElementType(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access userBufferEncoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncoding_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Destroys/frees a UserBufferEncoding + * + * @param[in] userBufferEncodingHandle : Handle to access UserBufferEncoding + * + * @return indication of success/failures + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncoding_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + + +/** + * @brief . + * + * A base class buffer source type + * + * @note User buffer from CPU support all kinds of runtimes; + * User buffer from GLBUFFER support only GPU runtime. + */ +typedef void* Snpe_UserBufferSource_Handle_t; + +typedef enum +{ + /// Unknown buffer source type. + SNPE_USERBUFFERSOURCE_SOURCETYPE_UNKNOWN = 0, + + /// The network inputs are from CPU buffer. + SNPE_USERBUFFERSOURCE_SOURCETYPE_CPU = 1, + + /// The network inputs are from OpenGL buffer. + SNPE_USERBUFFERSOURCE_SOURCETYPE_GLBUFFER = 2 +}Snpe_UserBufferSource_SourceType_t; + +/** + * @brief Retrieves the source type + * + * @param[in] userBufferSourceHandle : Handle to access userBufferSource + * + * @return Source type + */ +SNPE_API +Snpe_UserBufferSource_SourceType_t Snpe_UserBufferSource_GetSourceType(Snpe_UserBufferSource_Handle_t userBufferSourceHandle); + +/** + * @brief Destroys/frees a UserBufferSource + * + * @param[in] userBufferSourceHandle : Handle to access UserBufferSource + * + * @return indication of success/failures + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferSource_Delete(Snpe_UserBufferSource_Handle_t userBufferSourceHandle); + +/** + * @brief . + * + * An source type where input data is delivered from OpenGL buffer + */ +SNPE_API +Snpe_UserBufferSource_Handle_t Snpe_UserBufferSourceGLBuffer_Create(); + +/** + * @brief Destroys the userBuffer + * + * @param[in] userBufferSourceHandle : Handle to access the UserBuffer + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferSourceGLBuffer_Delete(Snpe_UserBufferSource_Handle_t userBufferSourceHandle); + +// Encoding 8 Bit +/** + * @brief . + * + * An encoding type where each element is represented by an unsigned int. + * + * Userbuffer size assumes uint8 encoding for each element. + * (i.e., a tensor with dimensions (2,3) will be represented by (2 * 3) * 1 = 6 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingUnsigned8Bit_Create(); + +/** + * @brief Copy Constructor for UserBufferEncodingUnsigned8Bit + * + * An encoding type where each element is represented by an unsigned int. + * + * Userbuffer size assumes uint8 encoding for each element. + * (i.e., a tensor with dimensions (2,3) will be represented by (2 * 3) * 1 = 6 bytes in memory). + * + * @param[in] otherHandle : a handle to another UserBufferEncodingUnsigned8Bit to copy + * + * @return a handle to the UserBufferEncodingUnsigned8Bit + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingUnsigned8Bit_CreateCopy(Snpe_UserBufferEncoding_Handle_t otherHandle); + +/** + * @brief Destroys the encodingUnsigned8Bit + * + * @param[in] userBufferEncodingHandle : Handle to access the encodingUnsigned8Bit + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingUnsigned8Bit_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingUnsigned8Bit_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + + +// Encoding Float +/** + * @brief . + * + * An encoding type where each element is represented by a float. + * + * Userbuffer size assumes float encoding for each element. + * (i.e., a tensor with dimensions (2,3) will be represented by (2 * 3) * 4 = 24 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingFloat_Create(); + +/** + * @brief Copy Constructor for UserBufferEncodingFloat + * + * An encoding type where each element is represented by a float. + * + * Userbuffer size assumes float encoding for each element. + * (i.e., a tensor with dimensions (2,3) will be represented by (2 * 3) * 4 = 24 bytes in memory). + * + * @param[in] otherHandle : a handle to another UserBufferEncodingFloat to copy + * + * @return a handle to the constructed UserBufferEncodingFloat + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingFloat_CreateCopy(Snpe_UserBufferEncoding_Handle_t otherHandle); + +/** + * @brief Destroys the encodingFloat + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingFloat_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingFloat_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +// Encoding FloatN +/** + * @brief . + * + * An encoding type where each element is represented by a float N + * + * Userbuffer size assumes float N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 16 will be represented by (2 * 3) * 2 = 12 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingFloatN_Create(uint8_t bWidth); + +/** + * @brief Copy Constructor for UserBufferEncodingFloatN + * + * An encoding type where each element is represented by a float N + * + * Userbuffer size assumes float N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 16 will be represented by (2 * 3) * 2 = 12 bytes in memory). + * + * @param[in] otherHandle : a handle to another UserBufferEncodingFloatN to copy + * + * @return a handle to the constructed UserBufferEncodingFloatN + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingFloatN_CreateCopy(Snpe_UserBufferEncoding_Handle_t otherHandle); + + +/** + * @brief Destroys the encodingFloatN + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingFloatN_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingFloatN_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + + +/** + * @brief Get the Float type corresponding to a given bitwidth + * + * @param width bitwidth of Float type + * + * @return ElementType corresponding to a Float of width bits + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_UserBufferEncodingFloatN_GetTypeFromWidth(uint8_t width); + +/** + * @brief . + * + * An encoding type where each element is represented by tfN, which is an + * N-bit quantized value, which has an exact representation of 0.0 + * + * Userbuffer size assumes tf N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 16 will be represented by (2 * 3) * 2 = 12 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingTfN_Create(uint64_t stepFor0, float stepSize, uint8_t bWidth); + +/** + * @brief Copy Constructor for UserBufferEncodingTfN + * + * An encoding type where each element is represented by tfN, which is an + * N-bit quantized value, which has an exact representation of 0.0 + * + * Userbuffer size assumes tf N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 16 will be represented by (2 * 3) * 2 = 12 bytes in memory). + * @param otherHandle the UserBufferEncodingTfN to copy + * @return a handle to a newly constructed UserBufferEncodingTfN + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingTfN_CreateCopy(Snpe_UserBufferEncoding_Handle_t otherHandle); + +/** + * @brief Destroys the encodingTfN + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingTfN_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingTfN_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Sets the step value that represents 0 + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @param[in] stepExactly0 : The step value that represents 0 + * + */ +SNPE_API +void Snpe_UserBufferEncodingTfN_SetStepExactly0(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle, uint64_t stepExactly0); + +/** + * @brief Sets the float value that each step represents + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @param[in] quantizedStepSize : The float value of each step size + * + */ +SNPE_API +void Snpe_UserBufferEncodingTfN_SetQuantizedStepSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle, float quantizedStepSize); + +/** + * @brief Retrieves the step that represents 0.0 + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Step value + */ +SNPE_API +uint64_t Snpe_UserBufferEncodingTfN_GetStepExactly0(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the step size + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Step size + */ +SNPE_API +float Snpe_UserBufferEncodingTfN_GetQuantizedStepSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * Calculates the minimum floating point value that + * can be represented with this encoding. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Minimum representable floating point value + */ +SNPE_API +float Snpe_UserBufferEncodingTfN_GetMin(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * Calculates the maximum floating point value that + * can be represented with this encoding. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Maximum representable floating point value + */ +SNPE_API +float Snpe_UserBufferEncodingTfN_GetMax(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Get the tfN type corresponding to a given bitwidth + * + * @param width bitwidth of tfN type + * + * @return ElementType corresponding to a tfN of width bits + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_UserBufferEncodingTfN_GetTypeFromWidth(uint8_t width); + +// Encoding Int N +/** + * @brief . + * + * An encoding type where each element is represented by a Int + * + * Userbuffer size assumes int N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 32 will be represented by (2 * 3) * 4 = 24 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingIntN_Create(uint8_t bWidth); + +/** + * @brief Copy Constructor for UserBufferEncodingIntN + * + * An encoding type where each element is represented by a Int + * + * Userbuffer size assumes int N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 32 will be represented by (2 * 3) * 4 = 24 bytes in memory). + * @param otherHandle the UserBufferEncodingIntN to copy + * @return a handle to a newly constructed UserBufferEncodingIntN + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingIntN_CreateCopy(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Destroys the encodingIntN + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingIntN_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingIntN_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Get the int type corresponding to a given bitwidth + * + * @param width bitwidth of int type + * + * @return ElementType corresponding to a int of width bits + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_UserBufferEncodingIntN_GetTypeFromWidth(uint8_t bWidth); + +// Encoding Uint N +/** + * @brief . + * + * An encoding type where each element is represented by a Uint + * + * Userbuffer size assumes uint N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 32 will be represented by (2 * 3) * 4 = 24 bytes in memory). + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingUintN_Create(uint8_t bWidth); + +/** + * @brief Copy Constructor for UserBufferEncodingUintN + * + * An encoding type where each element is represented by a Uint + * + * Userbuffer size assumes uint N encoding for each element. + * (i.e., a tensor with dimensions (2,3) with a provided bitwidth of 32 will be represented by (2 * 3) * 4 = 24 bytes in memory). + * @param otherHandle the UserBufferEncodingUintN to copy + * @return a handle to a newly constructed UserBufferEncodingUintN + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingUintN_CreateCopy(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Destroys the encodingUintN + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingUintN_Delete(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferEncodingHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingUintN_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Get the uint type corresponding to a given bitwidth + * + * @param width bitwidth of uint type + * + * @return ElementType corresponding to a uint of width bits + */ +SNPE_API +Snpe_UserBufferEncoding_ElementType_t Snpe_UserBufferEncodingUintN_GetTypeFromWidth(uint8_t bWidth); + + +// Encoding Bool +/** + * @brief . + * + * An encoding type where each element is represented by a Bool + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingBool_Create(uint8_t bWidth); + +/** + * @brief Copy Constructor for UserBufferEncodingBool + * + * An encoding type where each element is represented by a bool + * + * @param otherHandle the UserBufferEncodingBool to copy + * @return a handle to a newly constructed UserBufferEncodingBool + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_UserBufferEncodingBool_CreateCopy(Snpe_UserBufferEncoding_Handle_t userBufferEncodingHandle); + +/** + * @brief Destroys the encodingBool + * + * @param[in] userBufferHandle : Handle to access the encoding + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferEncodingBool_Delete(Snpe_UserBufferEncoding_Handle_t userBufferHandle); + +/** + * @brief Retrieves the size of the element, in bytes. + * + * @param[in] userBufferHandle : Handle to access the encoding + * + * @return Size of the element, in bytes. + */ +SNPE_API +size_t Snpe_UserBufferEncodingBool_GetElementSize(Snpe_UserBufferEncoding_Handle_t userBufferHandle); + + + +/** + * A typedef to indicate a SNPE IUserBuffer handle + * UserBuffer contains a pointer and info on how to walk it and interpret its content. + */ +typedef void* Snpe_IUserBuffer_Handle_t; + +/** + * Destroys/frees an IUserBuffer + * + * @param[in] userBufferHandle : Handle to access the IUserBuffer + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_IUserBuffer_Delete(Snpe_IUserBuffer_Handle_t userBufferHandle); + + +/** + * @brief Retrieves the total number of bytes between elements in each dimension if + * the buffer were to be interpreted as a multi-dimensional array. + * + * @param[in] userBufferHandle : Handle to access the user Buffer + * + * @warning Do not modify the TensorShape returned by reference. Treat it as a const reference. + * + * @return A const reference to the number of bytes between elements in each dimension. + * e.g. A tightly packed tensor of floats with dimensions [4, 3, 2] would + * return strides of [24, 8, 4]. + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_IUserBuffer_GetStrides_Ref(Snpe_IUserBuffer_Handle_t userBufferHandle); + +/** + * @brief Retrieves the size of the buffer, in bytes. + * + * @param[in] userBufferHandle : Handle to access the user Buffer + * + * @return Size of the underlying buffer, in bytes. + */ +SNPE_API +size_t Snpe_IUserBuffer_GetSize(Snpe_IUserBuffer_Handle_t userBufferHandle); + +/** + * @brief Retrieves the size of the inference data in the buffer, in bytes. + * + * The inference results from a dynamic-sized model may not be exactly the same size + * as the UserBuffer provided to SNPE. This function can be used to get the amount + * of output inference data, which may be less or greater than the size of the UserBuffer. + * + * If the inference results fit in the UserBuffer, getOutputSize() would be less than + * or equal to getSize(). But if the inference results were more than the capacity of + * the provided UserBuffer, the results would be truncated to fit the UserBuffer. But, + * getOutputSize() would be greater than getSize(), which indicates a bigger buffer + * needs to be provided to SNPE to hold all of the inference results. + * + * @param[in] userBufferHandle : Handle to access the user Buffer + * + * @return Size required for the buffer to hold all inference results, which can be less + * or more than the size of the buffer, in bytes. + */ +SNPE_API +size_t Snpe_IUserBuffer_GetOutputSize(Snpe_IUserBuffer_Handle_t userBufferHandle); + +/** + * @brief Changes the underlying memory that backs the UserBuffer. + * + * This can be used to avoid creating multiple UserBuffer objects + * when the only thing that differs is the memory location. + * + * @param[in] userBufferHandle : Handle to access the user Buffer + * + * @param[in] buffer : Pointer to the memory location + * + * @return Whether the set succeeds. + */ +SNPE_API +int Snpe_IUserBuffer_SetBufferAddress(Snpe_IUserBuffer_Handle_t userBufferHandle, void* buffer); + +/** + * @brief Gets a reference to the data encoding object of + * the underlying buffer + * + * This is necessary when the UserBuffer is re-used, and the encoding + * parameters can change. For example, each input can be quantized with + * different step sizes. + * + * @param[in] userBufferHandle : Handle to access the user Buffer + * + * @return Data encoding meta-data + */ +SNPE_API +Snpe_UserBufferEncoding_Handle_t Snpe_IUserBuffer_GetEncoding_Ref(Snpe_IUserBuffer_Handle_t userBufferHandle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _IUSER_BUFFER_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.hpp new file mode 100644 index 00000000..727c195b --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBuffer.hpp @@ -0,0 +1,390 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include +#include "TensorShape.hpp" + +#include "DlSystem/IUserBuffer.h" + + +namespace DlSystem { + + +class UserBufferEncoding: public Wrapper { + friend BaseType; + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserBufferEncoding_Delete}; +protected: + UserBufferEncoding(HandleType handle) + : BaseType(handle) + { } +public: + + virtual ~UserBufferEncoding() = default; + + UserBufferEncoding(UserBufferEncoding&& other) noexcept + : BaseType(std::move(other)) + { } + + enum class ElementType_t + { + /// Unknown element type. + UNKNOWN = 0, + + /// Each element is presented by 32-bit float. + FLOAT = 1, + + /// Each element is presented by an unsigned int. + UNSIGNED8BIT = 2, + + /// Each element is presented by 16-bit float. + FLOAT16 = 3, + + /// Each element is presented by an 8-bit quantized value. + TF8 = 10, + + /// Each element is presented by an 16-bit quantized value. + TF16 = 11, + + /// Each element is presented by Int32 + INT32 = 12, + + /// Each element is presented by UInt32 + UINT32 = 13, + + /// Each element is presented by Int8 + INT8 = 14, + + /// Each element is presented by UInt8 + UINT8 = 15, + + /// Each element is presented by Int16 + INT16 = 16, + + /// Each element is presented by UInt16 + UINT16 = 17, + + // Each element is presented by Bool8 + BOOL8 = 18, + + // Each element is presented by Int64 + INT64 = 19, + + // Each element is presented by UInt64 + UINT64 = 20 + }; + + ElementType_t getElementType() const noexcept{ + return static_cast(Snpe_UserBufferEncoding_GetElementType(handle())); + } + + size_t getElementSize() const noexcept{ + return Snpe_UserBufferEncoding_GetElementSize(handle()); + } +}; + + +class UserBufferSource: public Wrapper { + friend BaseType; + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserBufferSource_Delete}; + +public: + enum class SourceType_t + { + /// Unknown buffer source type. + UNKNOWN = 0, + + /// The network inputs are from CPU buffer. + CPU = 1, + + /// The network inputs are from OpenGL buffer. + GLBUFFER = 2 + }; +protected: + UserBufferSource(HandleType handle) + : BaseType(handle) + { } +public: + SourceType_t getSourceType() const noexcept{ + return static_cast(Snpe_UserBufferSource_GetSourceType(handle())); + } + +}; + +class UserBufferSourceGLBuffer : public UserBufferSource{ +public: + UserBufferSourceGLBuffer() + : UserBufferSource(Snpe_UserBufferSourceGLBuffer_Create()) + { } +}; + +class UserBufferEncodingUnsigned8Bit : public UserBufferEncoding{ +public: + using UserBufferEncoding::UserBufferEncoding; + UserBufferEncodingUnsigned8Bit() + : UserBufferEncoding(Snpe_UserBufferEncodingUnsigned8Bit_Create()) + { } +}; + +class UserBufferEncodingFloatN : public UserBufferEncoding{ +public: + using UserBufferEncoding::UserBufferEncoding; + + UserBufferEncodingFloatN(uint8_t bWidth=32) + : UserBufferEncoding(Snpe_UserBufferEncodingFloatN_Create(bWidth)) + { } + + UserBufferEncodingFloatN(const UserBufferEncodingFloatN& other) + : UserBufferEncoding(Snpe_UserBufferEncodingFloatN_CreateCopy(other.handle())) + { } + + static ElementType_t getTypeFromWidth(uint8_t width){ + return static_cast(Snpe_UserBufferEncodingFloatN_GetTypeFromWidth(width)); + } +}; + +class UserBufferEncodingFloat : public UserBufferEncoding{ +public: + using UserBufferEncoding::UserBufferEncoding; + UserBufferEncodingFloat() + : UserBufferEncoding(Snpe_UserBufferEncodingFloat_Create()) + { } + UserBufferEncodingFloat(const UserBufferEncodingFloat& other) + : UserBufferEncoding(Snpe_UserBufferEncodingFloat_CreateCopy(other.handle())) + { } + + UserBufferEncodingFloat(UserBufferEncodingFloat&& other) noexcept + : UserBufferEncoding(std::move(other)) + { } +}; + + +class UserBufferEncodingTfN : public UserBufferEncoding{ +public: + + using UserBufferEncoding::UserBufferEncoding; + template::value && std::is_floating_point::value, int>::type = 0> + UserBufferEncodingTfN(T stepFor0, U stepSize, uint8_t bWidth=8) + : UserBufferEncoding(Snpe_UserBufferEncodingTfN_Create(stepFor0, stepSize, bWidth)) + { } + + UserBufferEncodingTfN(const UserBufferEncoding& ubEncoding) + : UserBufferEncoding(Snpe_UserBufferEncodingTfN_CreateCopy(getHandle(ubEncoding))) + { } + UserBufferEncodingTfN(const UserBufferEncodingTfN& ubEncoding) + : UserBufferEncoding(Snpe_UserBufferEncodingTfN_CreateCopy(getHandle(ubEncoding))) + { } + + void setStepExactly0(uint64_t stepExactly0){ + Snpe_UserBufferEncodingTfN_SetStepExactly0(handle(), stepExactly0); + } + + void setQuantizedStepSize(const float quantizedStepSize){ + Snpe_UserBufferEncodingTfN_SetQuantizedStepSize(handle(), quantizedStepSize); + } + + uint64_t getStepExactly0() const{ + return Snpe_UserBufferEncodingTfN_GetStepExactly0(handle()); + } + + float getMin() const{ + return Snpe_UserBufferEncodingTfN_GetMin(handle()); + } + float getMax() const{ + return Snpe_UserBufferEncodingTfN_GetMax(handle()); + } + + float getQuantizedStepSize() const{ + return Snpe_UserBufferEncodingTfN_GetQuantizedStepSize(handle()); + } + + static ElementType_t getTypeFromWidth(uint8_t width){ + return static_cast(Snpe_UserBufferEncodingTfN_GetTypeFromWidth(width)); + } +}; + +class UserBufferEncodingIntN : public UserBufferEncoding{ +public: + + UserBufferEncodingIntN(uint8_t bWidth=32) + : UserBufferEncoding(Snpe_UserBufferEncodingIntN_Create(bWidth)) + { } + + UserBufferEncodingIntN(const UserBufferEncoding& ubEncoding) + : UserBufferEncoding(Snpe_UserBufferEncodingIntN_CreateCopy(getHandle(ubEncoding))) + { } + + static ElementType_t getTypeFromWidth(uint8_t width){ + return static_cast(Snpe_UserBufferEncodingIntN_GetTypeFromWidth(width)); + } +}; + + + +class UserBufferEncodingUintN : public UserBufferEncoding{ +public: + + UserBufferEncodingUintN(uint8_t bWidth=32) + : UserBufferEncoding(Snpe_UserBufferEncodingUintN_Create(bWidth)) + { } + + UserBufferEncodingUintN(const UserBufferEncoding& ubEncoding) + : UserBufferEncoding(Snpe_UserBufferEncodingUintN_CreateCopy(getHandle(ubEncoding))) + { } + + static ElementType_t getTypeFromWidth(uint8_t width){ + return static_cast(Snpe_UserBufferEncodingUintN_GetTypeFromWidth(width)); + } +}; + + +class UserBufferEncodingTf8 : public UserBufferEncodingTfN{ +public: + using UserBufferEncodingTfN::UserBufferEncodingTfN; + UserBufferEncodingTf8() = delete; + + template::value && std::is_floating_point::value, int>::type = 0> + UserBufferEncodingTf8(T stepFor0, U stepSize) + : UserBufferEncodingTfN(stepFor0, stepSize, 8) + { } + + UserBufferEncodingTf8(const UserBufferEncoding& ubEncoding) + : UserBufferEncodingTfN(ubEncoding) + { } + +}; + +class UserBufferEncodingBool : public UserBufferEncoding{ +public: + UserBufferEncodingBool(uint8_t bWidth=8) + : UserBufferEncoding(Snpe_UserBufferEncodingBool_Create(bWidth)) + { } + + UserBufferEncodingBool(const UserBufferEncoding& ubEncoding) + : UserBufferEncoding(Snpe_UserBufferEncodingBool_CreateCopy(getHandle(ubEncoding))) + { } +}; + +class IUserBuffer: public Wrapper { + friend BaseType; + using BaseType::BaseType; + static constexpr DeleteFunctionType DeleteFunction{Snpe_IUserBuffer_Delete}; + +public: + const TensorShape& getStrides() const{ + return *makeReference(Snpe_IUserBuffer_GetStrides_Ref(handle())); + } + + size_t getSize() const{ + return Snpe_IUserBuffer_GetSize(handle()); + } + + size_t getOutputSize() const{ + return Snpe_IUserBuffer_GetOutputSize(handle()); + } + + bool setBufferAddress(void* buffer) noexcept{ + return Snpe_IUserBuffer_SetBufferAddress(handle(), buffer); + } + + const UserBufferEncoding& getEncoding() const noexcept{ + auto h = Snpe_IUserBuffer_GetEncoding_Ref(handle()); + switch(Snpe_UserBufferEncoding_GetElementType(h)){ + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNSIGNED8BIT: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT16: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT32: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT16: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT32: + return *makeReference(h); + + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT16: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF8: + return *makeReference(h); + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF16: + return *makeReference(h); + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_BOOL8: + return *makeReference(h); + + default: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNKNOWN: + return *makeReference(h); + } + } + UserBufferEncoding& getEncoding() noexcept{ + auto h = Snpe_IUserBuffer_GetEncoding_Ref(handle()); + switch(Snpe_UserBufferEncoding_GetElementType(h)){ + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNSIGNED8BIT: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT16: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UINT32: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT8: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT16: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_INT32: + return *makeReference(h); + + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_FLOAT16: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF8: + return *makeReference(h); + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_TF16: + return *makeReference(h); + + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_BOOL8: + return *makeReference(h); + + default: + case SNPE_USERBUFFERENCODING_ELEMENTTYPE_UNKNOWN: + return *makeReference(h); + } + } + +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncoding) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferSource) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferSourceGLBuffer) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingUnsigned8Bit) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingFloatN) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingFloat) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingTfN) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingIntN) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingUintN) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferEncodingTf8) + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, IUserBuffer) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBufferFactory.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBufferFactory.hpp new file mode 100644 index 00000000..b3bbb087 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/IUserBufferFactory.hpp @@ -0,0 +1,68 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include + +#include "Wrapper.hpp" +#include "IUserBuffer.hpp" +#include "TensorShape.hpp" + + +#include "SNPE/SNPEUtil.h" + +namespace DlSystem{ + + +// NOTE: These factories use a different handle type because they are singletons +// Never copy this pattern unless you're also implementing a singleton +class IUserBufferFactory : public Wrapper{ + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{NoOpDeleter}; + +public: + IUserBufferFactory() + : BaseType(nullptr) + { } + + std::unique_ptr createUserBuffer(void *buffer, + size_t bufSize, + const TensorShape &strides, + UserBufferEncoding* userBufferEncoding) noexcept{ + if(!userBufferEncoding) return {}; + auto handle = Snpe_Util_CreateUserBuffer(buffer, + bufSize, + getHandle(strides), + getHandle(userBufferEncoding)); + return makeUnique(handle); + } + + std::unique_ptr createUserBuffer(void *buffer, + size_t bufSize, + const TensorShape &strides, + UserBufferEncoding* userBufferEncoding, + UserBufferSource* userBufferSource) noexcept{ + if(!userBufferEncoding || !userBufferSource) return {}; + auto handle = Snpe_Util_CreateUserBufferFromSource(buffer, + bufSize, + getHandle(strides), + getHandle(*userBufferEncoding), + getHandle(*userBufferSource)); + return makeUnique(handle); + } + +}; + + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, IUserBufferFactory) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.h new file mode 100644 index 00000000..15b2a089 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.h @@ -0,0 +1,329 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_PLATFORMCONFIG_H +#define DL_SYSTEM_PLATFORMCONFIG_H + +#include "DlSystem/DlError.h" +#include "DlSystem/DlEnums.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief . + * + * A structure OpenGL configuration + * + * @note When certain OpenGL context and display are provided to UserGLConfig for using + * GPU buffer as input directly, the user MUST ensure the particular OpenGL + * context and display remain vaild throughout the execution of neural network models. + */ +typedef void* Snpe_UserGLConfig_Handle_t; + +/** + * @brief . + * + * Creates a new userGLConfig + * + */ +SNPE_API +Snpe_UserGLConfig_Handle_t Snpe_UserGLConfig_Create(); + +/** + * @brief Destroys the userGLConfig + * + * @param[in] handle : Handle to access the userGLConfig + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserGLConfig_Delete(Snpe_UserGLConfig_Handle_t handle); + +/** + * @brief Sets the EGL context + * + * @param[in] handle : Handle to access userGLConfig + * + * @param[in] userGLContext : void pointer + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserGLConfig_SetUserGLContext(Snpe_UserGLConfig_Handle_t handle, void* userGLContext); + +/** + * @brief Sets the EGL Display + * + * @param[in] handle : Handle to access userGLConfig + * + * @param[in] userGLDisplay : void pointer + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserGLConfig_SetUserGLDisplay(Snpe_UserGLConfig_Handle_t handle, void* userGLDisplay); + + +/** + * @brief Get EGL context + * + * @param[in] handle : Handle to access userGLConfig + * + * @return userGLContext of type void pointer + * + */ +SNPE_API +void* Snpe_UserGLConfig_GetUserGLContext(Snpe_UserGLConfig_Handle_t handle); + +/** + * @brief Get EGL Display + * + * @param[in] handle : Handle to access userGLConfig + * + * @return userGLDisplay of type void pointer + * + */ +SNPE_API +void* Snpe_UserGLConfig_GetUserGLDisplay(Snpe_UserGLConfig_Handle_t handle); + + +/** + * @brief . + * + * A structure Gpu configuration + */ +typedef void* Snpe_UserGpuConfig_Handle_t; + +/** + * @brief . + * + * Creates a new userGpuConfig + * + */ +SNPE_API +Snpe_UserGpuConfig_Handle_t Snpe_UserGpuConfig_Create(); + +/** + * @brief Destroys the userGpuConfig + * + * @param[in] handle : Handle to access userGLConfig + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserGpuConfig_Delete(Snpe_UserGpuConfig_Handle_t handle); + +/** + * @brief Set the userGpuConfig + * + * @param[in] handle : Handle to access userGpuConfig + * + * @param[in] glHandle : Handle needed to access userGlConfig + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +void Snpe_UserGpuConfig_Set(Snpe_UserGpuConfig_Handle_t handle, Snpe_UserGLConfig_Handle_t glHandle); + +/** + * @brief Get the userGpuConfig + * + * @param[in] handle : Handle to access userGpuConfig + * + * @return Handle needed to access userGlConfig + */ +SNPE_API +Snpe_UserGLConfig_Handle_t Snpe_UserGpuConfig_Get_Ref(Snpe_UserGpuConfig_Handle_t handle); + + + +/** + * A typedef to indicate a SNPE PlatformConfig handle + */ +typedef void* Snpe_PlatformConfig_Handle_t; + + +/** + * @brief . + * + * Creates a new PlatformConfig + * + */ +SNPE_API +Snpe_PlatformConfig_Handle_t Snpe_PlatformConfig_Create(); + + +/** + * @brief Copy-Construct a PlatformConfig from another PlatformConfig + * + * @param[in] otherHandle Handle to the other PlatformConfig + * + * @return Handle to the Copy-Constructed PlatformConfig + */ +SNPE_API +Snpe_PlatformConfig_Handle_t Snpe_PlatformConfig_CreateCopy(Snpe_PlatformConfig_Handle_t otherHandle); + +/** + * @brief Destroys the PlatformConfig + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PlatformConfig_Delete(Snpe_PlatformConfig_Handle_t handle); + + +typedef enum +{ + /// Unknown platform type. + SNPE_PLATFORMCONFIG_PLATFORMTYPE_UNKNOWN = 0, + + /// Snapdragon CPU. + SNPE_PLATFORMCONFIG_PLATFORMTYPE_CPU = 1, + + /// Adreno GPU. + SNPE_PLATFORMCONFIG_PLATFORMTYPE_GPU = 2, + + /// Hexagon DSP. + SNPE_PLATFORMCONFIG_PLATFORMTYPE_DSP = 3 +} Snpe_PlatformConfig_PlatformType_t; + + +/** + * @brief Retrieves the platform type + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return Platform type + */ +SNPE_API +Snpe_PlatformConfig_PlatformType_t Snpe_PlatformConfig_GetPlatformType(Snpe_PlatformConfig_Handle_t handle); + +/** + * @brief Indicates whther the plaform configuration is valid. + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return 1 if the platform configuration is valid; 0 otherwise. + */ +SNPE_API +int Snpe_PlatformConfig_IsValid(Snpe_PlatformConfig_Handle_t handle); + +/** + * @brief Retrieves the Gpu configuration + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return userGpuConfig populated with the Gpu configuration. + * + */ +SNPE_API +Snpe_UserGpuConfig_Handle_t Snpe_PlatformConfig_GetUserGpuConfig(Snpe_PlatformConfig_Handle_t handle); + +/** + * @brief Sets the Gpu configuration + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @param[in] gpuHandle : Gpu Configuration handle + * + * @return 1 if Gpu configuration was successfully set; 0 otherwise. + */ +SNPE_API +int Snpe_PlatformConfig_SetUserGpuConfig(Snpe_PlatformConfig_Handle_t handle, Snpe_UserGpuConfig_Handle_t gpuHandle); + +/** + * @brief Sets the platform options + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @param[in] options : Options as a const char* in the form of "keyword:options" + * + * @return 1 if options are pass validation; otherwise 0. If false, the options are not updated. + */ +SNPE_API +int Snpe_PlatformConfig_SetPlatformOptions(Snpe_PlatformConfig_Handle_t handle, const char* options); + +/** + * @brief Indicates whther the plaform configuration is valid. + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return 1 if the platform configuration is valid; 0 otherwise. + */ +SNPE_API +int Snpe_PlatformConfig_IsOptionsValid(Snpe_PlatformConfig_Handle_t handle); + +/** + * @brief Gets the platform options + * + * @param[in] handle : Handle needed to access the platformConfig + * + * @return Options as a const char* + */ +SNPE_API +const char* Snpe_PlatformConfig_GetPlatformOptions(Snpe_PlatformConfig_Handle_t handle); + +/** + * @brief Sets the platform options + * + * @note the returned string will be invalidated by subsequent calls to this function + * + * @param[in] handle : Handle needed to access the platformConfig + * @param[in] optionName : Name of platform options" + * @param[in] value : Value of specified optionName + * + * @return If 1, add "optionName:value" to platform options if optionName don't exist, otherwise update the + * value of specified optionName. + * If 0, the platform options will not be changed. + */ +SNPE_API +int Snpe_PlatformConfig_SetPlatformOptionValue(Snpe_PlatformConfig_Handle_t handle, const char* optionName, const char* value); + +/** + * @brief Removes the platform options + * + * @param[in] handle : Handle needed to access the platformConfig + * @param[in] optionName : Name of platform options" + * @param[in] value : Value of specified optionName + * + * @return If 1, removed "optionName:value" to platform options if optionName don't exist, do nothing. + * If 0, the platform options will not be changed. + */ +SNPE_API +int Snpe_PlatformConfig_RemovePlatformOptionValue(Snpe_PlatformConfig_Handle_t handle, const char* optionName, const char* value); + +SNPE_API +void Snpe_PlatformConfig_SetIsUserGLBuffer(int isUserGLBuffer); + +SNPE_API +int Snpe_PlatformConfig_GetIsUserGLBuffer(); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_PLATFORMCONFIG_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.hpp new file mode 100644 index 00000000..5995c51b --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/PlatformConfig.hpp @@ -0,0 +1,265 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include "DlSystem/PlatformConfig.h" + +namespace DlSystem { + +struct UserGLConfig +{ + /// Holds user EGL context. + /// + void* userGLContext = nullptr; + + /// Holds user EGL display. + void* userGLDisplay = nullptr; +}; + +struct UserGpuConfig{ + /// Holds user OpenGL configuration. + /// + UserGLConfig userGLConfig; +}; + +class PlatformConfig : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_PlatformConfig_Delete}; + + class UserGLConfigInternal : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserGLConfig_Delete}; + + public: + UserGLConfigInternal() + : BaseType(Snpe_UserGLConfig_Create()) + { } + UserGLConfigInternal(const UserGLConfig& uglc) + : UserGLConfigInternal() + { + setUserGLContext(uglc.userGLContext); + setUserGLDisplay(uglc.userGLDisplay); + } + void setUserGLContext(void* userGLContext){ + Snpe_UserGLConfig_SetUserGLContext(handle(), userGLContext); + } + void setUserGLDisplay(void* userGLDisplay){ + Snpe_UserGLConfig_SetUserGLDisplay(handle(), userGLDisplay); + } + + void* getUserGLContext(){ + return Snpe_UserGLConfig_GetUserGLContext(handle()); + } + void* getUserGLDisplay(){ + return Snpe_UserGLConfig_GetUserGLDisplay(handle()); + } + }; + + + + class UserGpuConfigInternal : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserGpuConfig_Delete}; + + public: + UserGpuConfigInternal() + : BaseType(Snpe_UserGpuConfig_Create()) + { } + + void set(const UserGLConfig& userGLConfig){ + UserGLConfigInternal uglc(userGLConfig); + Snpe_UserGpuConfig_Set(handle(), getHandle(uglc)); + } + + void get(UserGLConfig& uglc){ + UserGLConfigInternal uglci(moveHandle(Snpe_UserGpuConfig_Get_Ref(handle()), true)); + + uglc.userGLContext = uglci.getUserGLContext(); + uglc.userGLDisplay = uglci.getUserGLDisplay(); + } + + }; +public: + + /** + * @brief . + * + * An enum class of all supported platform types + */ + enum class PlatformType_t + { + /// Unknown platform type. + UNKNOWN = 0, + + /// Snapdragon CPU. + CPU = 1, + + /// Adreno GPU. + GPU = 2, + + /// Hexagon DSP. + DSP = 3 + }; + + /** + * @brief . + * + * A union class user platform configuration information + */ + struct PlatformConfigInfo + { + /// Holds user GPU Configuration. + /// + UserGpuConfig userGpuConfig; + + }; + + ~PlatformConfig() = default; + + PlatformConfig() + : BaseType(Snpe_PlatformConfig_Create()) + { } + + PlatformConfig(const PlatformConfig& other) + : BaseType(Snpe_PlatformConfig_CreateCopy(other.handle())) + { } + + /** + * @brief Retrieves the platform type + * + * @return Platform type + */ + PlatformType_t getPlatformType() const{ + return static_cast(Snpe_PlatformConfig_GetPlatformType(handle())); + }; + + /** + * @brief Indicates whther the plaform configuration is valid. + * + * @return True if the platform configuration is valid; false otherwise. + */ + bool isValid() const{ + return Snpe_PlatformConfig_IsValid(handle()); + }; + + /** + * @brief Retrieves the Gpu configuration + * + * @param[out] userGpuConfig The passed in userGpuConfig populated with the Gpu configuration on return. + * + * @return True if Gpu configuration was retrieved; false otherwise. + */ + bool getUserGpuConfig(UserGpuConfig& userGpuConfig) const{ + auto platformType = static_cast(Snpe_PlatformConfig_GetPlatformType(handle())); + if(platformType != PlatformType_t::GPU) return false; + + UserGpuConfigInternal gpuConf(moveHandle(Snpe_PlatformConfig_GetUserGpuConfig(handle()))); + + gpuConf.get(userGpuConfig.userGLConfig); + return true; + } + + /** + * @brief Sets the Gpu configuration + * + * @param[in] userGpuConfig Gpu Configuration + * + * @return True if Gpu configuration was successfully set; false otherwise. + */ + bool setUserGpuConfig(UserGpuConfig& userGpuConfig){ + UserGpuConfigInternal gpuConf; + gpuConf.set(userGpuConfig.userGLConfig); + return Snpe_PlatformConfig_SetUserGpuConfig(handle(), getHandle(gpuConf)); + } + + /** + * @brief Sets the platform options + * + * @param[in] options Options as a string in the form of "keyword:options" + * + * @return True if options are pass validation; otherwise false. If false, the options are not updated. + */ + bool setPlatformOptions(const std::string& options){ + return Snpe_PlatformConfig_SetPlatformOptions(handle(), options.c_str()); + } + + /** + * @brief Indicates whther the plaform configuration is valid. + * + * @return True if the platform configuration is valid; false otherwise. + */ + bool isOptionsValid() const{ + return Snpe_PlatformConfig_IsOptionsValid(handle()); + } + + /** + * @brief Gets the platform options + * + * @return Options as a string + */ + std::string getPlatformOptions() const { + return Snpe_PlatformConfig_GetPlatformOptions(handle()); + } + + /** + * @brief Sets the platform options + * + * @param[in] optionName Name of platform options" + * @param[in] value Value of specified optionName + * + * @return If true, add "optionName:value" to platform options if optionName don't exist, otherwise update the + * value of specified optionName. + * If false, the platform options will not be changed. + */ + bool setPlatformOptionValue(const std::string& optionName, const std::string& value){ + return Snpe_PlatformConfig_SetPlatformOptionValue(handle(), optionName.c_str(), value.c_str()); + } + + /** + * @brief Removes the platform options + * + * @param[in] optionName Name of platform options" + * @param[in] value Value of specified optionName + * + * @return If true, removed "optionName:value" to platform options if optionName don't exist, do nothing. + * If false, the platform options will not be changed. + */ + bool removePlatformOptionValue(const std::string& optionName, const std::string& value){ + return Snpe_PlatformConfig_RemovePlatformOptionValue(handle(), optionName.c_str(), value.c_str()); + } + + static void SetIsUserGLBuffer(bool isUserGLBuffer){ + Snpe_PlatformConfig_SetIsUserGLBuffer(isUserGLBuffer); + } + static bool GetIsUserGLBuffer(){ + return Snpe_PlatformConfig_GetIsUserGLBuffer(); + } + +}; + + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserGLConfig) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserGpuConfig) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, PlatformConfig) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.h new file mode 100644 index 00000000..2b699a7a --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.h @@ -0,0 +1,203 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_RUNTIME_LIST_H +#define DL_SYSTEM_RUNTIME_LIST_H + +#include + +#include "DlSystem/DlEnums.h" +#include "DlSystem/DlError.h" + +#include "StringList.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE RuntimeList handle + */ +typedef void* Snpe_RuntimeList_Handle_t; + +/** + * @brief . + * + * Creates a new runtime list + * + */ +SNPE_API +Snpe_RuntimeList_Handle_t Snpe_RuntimeList_Create(); + + +/** + * Copy-Constructs a RuntimeList and returns a handle to it + * + * @param runtimeListHandle the other RuntimeList to copy + * + * @return the handle to the created RuntimeList + */ +SNPE_API +Snpe_RuntimeList_Handle_t Snpe_RuntimeList_CreateCopy(Snpe_RuntimeList_Handle_t runtimeListHandle); + +/** + * @brief Destroys the RuntimeList + * + * @param[in] runtimeListHandle : Handle needed to access the runtimeList + * + * @return Error code. Returns SNPE_SUCCESS if destruction successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_Delete(Snpe_RuntimeList_Handle_t runtimeListHandle); + +/** + * Copy-assigns the contents of srcHandle into dstHandle + * + * @param src Source RuntimeList handle + * + * @param dst Destination RuntimeList handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_Assign(Snpe_RuntimeList_Handle_t src, Snpe_RuntimeList_Handle_t dst); + +/** + * @brief Returns the Runtime from list at position index + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @param[in] index : position in runtimeList + * + * @return The Runtime from list at position index + */ +SNPE_API +Snpe_Runtime_t Snpe_RuntimeList_GetRuntime(Snpe_RuntimeList_Handle_t runtimeListHandle, int index); + +/** + * @brief Set the Runtime of the list at position index + * + * @param[in] runtimeListHandle : Handle needed to access the runtimeList + * + * @param[in] index : position in runtimeList + * + * @param[in] runtime : The Runtime to assign to position index + * + * @return SNPE_SUCCESS on success + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_SetRuntime(Snpe_RuntimeList_Handle_t runtimeListHandle, size_t index, Snpe_Runtime_t runtime); + +/** + * @brief Adds runtime to the end of the runtime list + * order of precedence is former followed by latter entry + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @param[in] runtime to add + * + * @return Error code. Ruturns SNPE_SUCCESS If the runtime added successfully + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_Add(Snpe_RuntimeList_Handle_t runtimeListHandle, Snpe_Runtime_t runtime); + +/** + * @brief Removes the runtime from the list + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @param[in] runtime to be removed + * + * @return Error code. Ruturns SNPE_SUCCESS If the runtime removed successfully + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_Remove(Snpe_RuntimeList_Handle_t runtimeListHandle, Snpe_Runtime_t runtime) ; + +/** + * @brief Returns the number of runtimes in the list + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @return number of entries in the runtimeList. + */ +SNPE_API +size_t Snpe_RuntimeList_Size(Snpe_RuntimeList_Handle_t runtimeListHandle) ; + +/** + * @brief Returns 1 if the list is empty + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @return 1 if list empty, 0 otherwise. + */ +SNPE_API +int Snpe_RuntimeList_Empty(Snpe_RuntimeList_Handle_t runtimeListHandle) ; + +/** + * @brief . + * + * Removes all runtime from the list + * + * @param[in] runtimeListHandle: Handle needed to access the runtimeList + * + * @return Error code. Returns SNPE_SUCCESS if runtime list is cleared successfully. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeList_Clear(Snpe_RuntimeList_Handle_t runtimeListHandle); + +/** + * @brief Get a StringList of names from the runtime list in order of precedence + * + * @param runtimeListHandle Handle to a RuntimeList + * + * @return Handle to a StringList + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_RuntimeList_GetRuntimeListNames(Snpe_RuntimeList_Handle_t runtimeListHandle); + +/** + * @brief . + * + * @param[in] runtime const char* + * Returns a Runtime enum corresponding to the in param string + * + */ +SNPE_API +Snpe_Runtime_t Snpe_RuntimeList_StringToRuntime(const char* str); + +/** + * @brief . + * + * @param[in] runtime + * Returns a const char* corresponding to the in param runtime enum + * + */ +SNPE_API +const char* Snpe_RuntimeList_RuntimeToString(Snpe_Runtime_t runtime); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_RUNTIME_LIST_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.hpp new file mode 100644 index 00000000..a2abf2b7 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/RuntimeList.hpp @@ -0,0 +1,115 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "StringList.hpp" +#include "DlEnums.hpp" +#include "DlSystem/RuntimeList.h" + + + + + + +namespace DlSystem { + +class RuntimeList : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_RuntimeList_Delete}; + + static Runtime_t GetRuntime(HandleType handle, size_t idx){ + return static_cast(Snpe_RuntimeList_GetRuntime(handle, int(idx))); + } + static Snpe_ErrorCode_t SetRuntime(HandleType handle, size_t idx, Runtime_t runtime){ + return Snpe_RuntimeList_SetRuntime(handle, idx, static_cast(runtime)); + } + +private: + using RuntimeReference = WrapperDetail::MemberIndexedReference; + friend RuntimeReference; + +public: + + RuntimeList() + : BaseType(Snpe_RuntimeList_Create()) + { } + RuntimeList(const RuntimeList& other) + : BaseType(Snpe_RuntimeList_CreateCopy(other.handle())) + { } + RuntimeList(RuntimeList&& other) noexcept + : BaseType(std::move(other)) + { } + + RuntimeList(const Runtime_t& runtime) + : BaseType(Snpe_RuntimeList_Create()) + { + Snpe_RuntimeList_Add(handle(), static_cast(runtime)); + } + + RuntimeList& operator=(const RuntimeList& other){ + if(this != &other){ + Snpe_RuntimeList_Assign(other.handle(), handle()); + } + return *this; + } + + RuntimeList& operator=(RuntimeList&& other) noexcept{ + return moveAssign(std::move(other)); + } + + Runtime_t operator[](size_t idx) const{ + return GetRuntime(handle(), idx); + } + + RuntimeReference operator[](size_t idx) noexcept{ + return {*this, idx}; + } + + bool add(const Runtime_t& runtime){ + return SNPE_SUCCESS == Snpe_RuntimeList_Add(handle(), static_cast(runtime)); + } + + void remove(Runtime_t runtime) noexcept{ + Snpe_RuntimeList_Remove(handle(), static_cast(runtime)); + } + + size_t size() const noexcept{ + return Snpe_RuntimeList_Size(handle()); + } + + bool empty() const noexcept{ + return Snpe_RuntimeList_Empty(handle()); + } + + void clear() noexcept{ + Snpe_RuntimeList_Clear(handle()); + } + + StringList getRuntimeListNames() const{ + return moveHandle(Snpe_RuntimeList_GetRuntimeListNames(handle())); + } + + static Runtime_t stringToRuntime(const char* runtimeStr){ + return static_cast(Snpe_RuntimeList_StringToRuntime(runtimeStr)); + } + static const char* runtimeToString(Runtime_t runtime){ + return Snpe_RuntimeList_RuntimeToString(static_cast(runtime)); + } + +}; + + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, RuntimeList) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/SnpeApiExportDefine.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/SnpeApiExportDefine.h new file mode 100644 index 00000000..62c6718f --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/SnpeApiExportDefine.h @@ -0,0 +1,34 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +// Macro controlling visibility of SNPE API + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SNPE_API +#define SNPE_API +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/String.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/String.hpp new file mode 100644 index 00000000..85b2ef22 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/String.hpp @@ -0,0 +1,70 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + + +#include + + +#include "Wrapper.hpp" + +namespace DlSystem{ + + +// Just a backwards compatible wrapper for std::string +class String{ +public: + String() = delete; + explicit String(const std::string& str) + : m_String(str) + { } + explicit String(std::string&& str) noexcept + : m_String(std::move(str)) + { } + + explicit String(const char* str) + : m_String(str) + { } + + String(String&& other) noexcept = default; + String(const String& other) = delete; + + + String& operator=(String&& other) noexcept = default; + String& operator=(const String& other) = delete; + + bool operator<(const String& rhs) const noexcept{ return m_String < rhs.m_String; } + bool operator>(const String& rhs) const noexcept{ return m_String > rhs.m_String; } + bool operator<=(const String& rhs) const noexcept{ return m_String <= rhs.m_String; } + bool operator>=(const String& rhs) const noexcept{ return m_String >= rhs.m_String; } + bool operator==(const String& rhs) const noexcept{ return m_String == rhs.m_String; } + bool operator!=(const String& rhs) const noexcept{ return m_String != rhs.m_String; } + + + bool operator<(const std::string& rhs) const noexcept{ return m_String < rhs; } + bool operator>(const std::string& rhs) const noexcept{ return m_String > rhs; } + bool operator<=(const std::string& rhs) const noexcept{ return m_String <= rhs; } + bool operator>=(const std::string& rhs) const noexcept{ return m_String >= rhs; } + bool operator==(const std::string& rhs) const noexcept{ return m_String == rhs; } + bool operator!=(const std::string& rhs) const noexcept{ return m_String != rhs; } + + + const char* c_str() const noexcept{ return m_String.c_str(); } + + explicit operator std::string&() noexcept{ return m_String; } + explicit operator const std::string&() const noexcept{ return m_String; } + +private: + std::string m_String; +}; + + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, String) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.h new file mode 100644 index 00000000..faa793b3 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.h @@ -0,0 +1,154 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_STRING_LIST_H +#define DL_SYSTEM_STRING_LIST_H + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A typedef to indicate a SNPE StringList handle + */ +typedef void* Snpe_StringList_Handle_t; + +/** + * Constructs a StringList and returns a handle to it + * + * @return the handle to the created StringList + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_StringList_Create(); + +/** + * Constructs a StringList and returns a handle to it + * + * @param[in] size : size of list + * + * @return the handle to the created StringList + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_StringList_CreateSize(size_t size); + +/** + * Constructs a StringList and returns a handle to it + * + * @param[in] other : StringList handle to be copied from + * + * @return the handle to the created StringList + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_StringList_CreateCopy(Snpe_StringList_Handle_t other); + +/** + * Destroys/frees a StringList + * + * @param[in] stringListHandle : Handle to access the stringList + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_StringList_Delete(Snpe_StringList_Handle_t stringListHandle); + + +/** + * Append a string to the list. + * + * @param[in] stringListHandle : Handle to access the stringList + * @param[in] str Null-terminated ASCII string to append to the list. + * + * @return SNPE_SUCCESS if Append operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_StringList_Append(Snpe_StringList_Handle_t stringListHandle, const char* string); + +/** + * Returns the string at the indicated position, + * or an empty string if the positions is greater than the size + * of the list. + * + * @param[in] stringListHandle : Handle to access the stringList + * @param[in] idx Position in the list of the desired string + * + * @return the string at the indicated position + */ +SNPE_API +const char* Snpe_StringList_At(Snpe_StringList_Handle_t stringListHandle, size_t idx); + +/** + * Pointer to the first string in the list. + * Can be used to iterate through the list. + * + * @param[in] stringListHandle : Handle to access the stringList + * + * @return Pointer to the first string in the list. + */ +SNPE_API +const char** Snpe_StringList_Begin(Snpe_StringList_Handle_t stringListHandle); + +/** + * Pointer to one after the last string in the list. + * Can be used to iterate through the list. + * + * @param[in] stringListHandle : Handle to access the stringList + * + * @return Pointer to one after the last string in the list + */ +SNPE_API +const char** Snpe_StringList_End(Snpe_StringList_Handle_t stringListHandle); + +/** + * Return the number of valid string pointers held by this list. + * + * @param[in] stringListHandle : Handle to access the stringList + * + * @return The size of the StringList + */ +SNPE_API +size_t Snpe_StringList_Size(Snpe_StringList_Handle_t stringListHandle); + +/** + * Copy-assigns the contents of src into dst + * + * @param src Source StringList handle + * @param dst Destination StringList handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_StringList_Assign(Snpe_StringList_Handle_t src, Snpe_StringList_Handle_t dst); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_STRING_LIST_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.hpp new file mode 100644 index 00000000..2fd84bf1 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/StringList.hpp @@ -0,0 +1,73 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "DlSystem/DlError.hpp" + +#include "DlSystem/StringList.h" + + +namespace DlSystem { + +class StringList : public Wrapper{ + friend BaseType; + using BaseType::BaseType; + static constexpr DeleteFunctionType DeleteFunction = Snpe_StringList_Delete; + +public: + StringList() + : BaseType(Snpe_StringList_Create()) + { } + explicit StringList(size_t length) + : BaseType(Snpe_StringList_CreateSize(length)) + { } + StringList(const StringList& other) + : BaseType(Snpe_StringList_CreateCopy(other.handle())) + { } + StringList(StringList&& other) noexcept + : BaseType(std::move(other)) + { } + + + StringList& operator=(const StringList& other){ + if(this != &other){ + Snpe_StringList_Assign(other.handle(), handle()); + } + return *this; + } + StringList& operator=(StringList&& other) noexcept{ + return moveAssign(std::move(other)); + } + + + DlSystem::ErrorCode append(const char* str){ + return static_cast(Snpe_StringList_Append(handle(), str)); + } + + const char* at(size_t idx) const noexcept{ + return Snpe_StringList_At(handle(), idx); + } + + const char** begin() const noexcept{ + return Snpe_StringList_Begin(handle()); + } + const char** end() const noexcept{ + return Snpe_StringList_End(handle()); + } + + size_t size() const noexcept{ + return Snpe_StringList_Size(handle()); + } + +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, StringList) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.h new file mode 100644 index 00000000..aa367eda --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.h @@ -0,0 +1,154 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_TENSORMAP_H +#define DL_SYSTEM_TENSORMAP_H + +#include "DlSystem/ITensor.h" +#include "DlSystem/StringList.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A typedef to indicate a SNPE Tensor Map handle + */ +typedef void* Snpe_TensorMap_Handle_t; + + +/** + * Constructs a TensorMap and returns a handle to it + * + * @return the handle to the created TensorMap + */ +SNPE_API +Snpe_TensorMap_Handle_t Snpe_TensorMap_Create(); + + +/** + * Copy-Constructs a TensorMap and returns a handle to it + * + * @param tensorMapHandle the other TensorMap to copy + * + * @return the handle to the created TensorMap + */ +SNPE_API +Snpe_TensorMap_Handle_t Snpe_TensorMap_CreateCopy(Snpe_TensorMap_Handle_t tensorMapHandle); + +/** + * Copy-assigns the contents of srcHandle into dstHandle + * + * @param src Source TensorMap handle + * + * @param dst Destination TensorMap handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorMap_Assign(Snpe_TensorMap_Handle_t srcHandle, Snpe_TensorMap_Handle_t dstHandle); + + +/** + * Destroys/frees Tensor Map + * + * @param[in] handle : handle to tensorMap + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorMap_Delete(Snpe_TensorMap_Handle_t handle); + +/** + * @brief Adds a name and the corresponding tensor pointer + * to the map + * + * @param[in] handle : Handle to tensorMap + * @param[in] name : The name of the tensor + * @param[in] tensorHandle : Handle to access ITensor + * + * @note If a tensor with the same name already exists, the + * tensor is replaced with the existing tensor. + */ +SNPE_API +void Snpe_TensorMap_Add(Snpe_TensorMap_Handle_t handle, const char *name, Snpe_ITensor_Handle_t tensorHandle); + +/** + * @brief Removes a mapping of tensor and its name by its name + * + * @param[in] handle : Handle to tensorMap + * @param[in] name : The name of tensor to be removed + * + * @note If no tensor with the specified name is found, nothing + * is done. + */ +SNPE_API +void Snpe_TensorMap_Remove(Snpe_TensorMap_Handle_t handle, const char *name); + +/** + * @brief Returns the number of tensors in the map + * + * @param[in] handle : Handle to tensorMap + * + * @return Number of tensors in the map + */ +SNPE_API +size_t Snpe_TensorMap_Size(Snpe_TensorMap_Handle_t handle); + +/** + * @brief . + * + * @param[in] handle : Handle to tensorMap + * Removes all tensors from the map + */ +SNPE_API +void Snpe_TensorMap_Clear(Snpe_TensorMap_Handle_t handle); + +/** + * @brief Returns the tensor given its name. + * + * @param[in] handle : Handle to tensorMap + * @param[in] name : The name of the tensor to get. + * + * @return nullptr if no tensor with the specified name is + * found; otherwise, a valid pointer to the tensor. + */ +SNPE_API +Snpe_ITensor_Handle_t Snpe_TensorMap_GetTensor_Ref(Snpe_TensorMap_Handle_t handle, const char *name); + +/** + * @brief . + * + * @param[in] handle : Handle to tensorMap + * + * @return A StringList of the names of all tensors + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_TensorMap_GetTensorNames(Snpe_TensorMap_Handle_t handle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_TENSOR_MAP_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.hpp new file mode 100644 index 00000000..20a6c21f --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorMap.hpp @@ -0,0 +1,81 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "DlSystem/ITensor.hpp" +#include "DlSystem/StringList.hpp" +#include "DlSystem/DlError.hpp" + +#include "DlSystem/TensorMap.h" + +namespace DlSystem { + +class TensorMap : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_TensorMap_Delete}; +public: + + TensorMap() + : BaseType(Snpe_TensorMap_Create()) + { } + + TensorMap(const TensorMap& other) + : BaseType(Snpe_TensorMap_CreateCopy(other.handle())) + { } + + TensorMap(TensorMap&& other) noexcept + : BaseType(std::move(other)) + { } + + TensorMap& operator=(const TensorMap& other){ + if(this != &other){ + Snpe_TensorMap_Assign(other.handle(), handle()); + } + return *this; + } + TensorMap& operator=(TensorMap&& other) noexcept{ + return moveAssign(std::move(other)); + } + + DlSystem::ErrorCode add(const char* name, ITensor* tensor){ + if(!tensor) return DlSystem::ErrorCode::SNPE_CAPI_BAD_ARGUMENT; + Snpe_TensorMap_Add(handle(), name, getHandle(*tensor)); + return DlSystem::ErrorCode::NONE; + } + + void remove(const char* name) noexcept{ + Snpe_TensorMap_Remove(handle(), name); + } + + size_t size() const noexcept{ + return Snpe_TensorMap_Size(handle()); + } + + void clear() noexcept{ + Snpe_TensorMap_Clear(handle()); + } + + + ITensor* getTensor(const char* name) const noexcept{ + return makeReference(Snpe_TensorMap_GetTensor_Ref(handle(), name)); + } + + StringList getTensorNames() const{ + return moveHandle(Snpe_TensorMap_GetTensorNames(handle())); + } + +}; + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, TensorMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.h new file mode 100644 index 00000000..1fde628c --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.h @@ -0,0 +1,174 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_TENSOR_SHAPE_H +#define DL_SYSTEM_TENSOR_SHAPE_H + +#include + +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE TensorShape handle + */ +typedef void* Snpe_TensorShape_Handle_t; + + +/** + * @brief . + * + * Creates a new shape with a list of dims specified in array + * + * @param[in] dims The dimensions are specified in which the last + * element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying, etc. + * + * @param[in] size Size of the array. + * + * @return the handle to the created TensorShape + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_TensorShape_CreateDimsSize(const size_t *dims, size_t size); + +/** + * Constructs a TensorShape and returns a handle to it + * + * @return the handle to the created TensorShape + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_TensorShape_Create(); + +/** + * @brief . + * + * copy constructor. + * @param[in] other object to copy. + * + * @return the handle to the created TensorShape. + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_TensorShape_CreateCopy(Snpe_TensorShape_Handle_t other); + +/** + * Destroys/frees Tensor Shape + * + * @param[in] handle : handle to tensorShape + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShape_Delete(Snpe_TensorShape_Handle_t tensorShapeHandle); + +/** + * Copy-assigns the contents of srcHandle into dstHandle + * + * @param srcHandle Source TensorShape handle + * @param dstHandle Destination TensorShape handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShape_Assign(Snpe_TensorShape_Handle_t srcHandle, Snpe_TensorShape_Handle_t dstHandle); + +/** + * @brief . + * + * Concatenates additional dimensions specified in + * the array to the existing dimensions. + * + * @param[in] handle : handle to tensorShape + * @param[in] dims The dimensions are specified in which the last + * element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying, etc. + * + * @param[in] size Size of the array. + * + */ +SNPE_API +void Snpe_TensorShape_Concatenate(Snpe_TensorShape_Handle_t tensorShape, const size_t *dims, size_t size); + +/** + * @brief . + * + * @param[in] handle : handle to tensorShape + * + * Retrieves the rank i.e. number of dimensions. + * + * @return The rank + */ +SNPE_API +size_t Snpe_TensorShape_Rank(Snpe_TensorShape_Handle_t tensorShape); + +/** + * @brief . + * + * @param[in] handle : handle to tensorShape + * + * @param[in] index : Position in the dimension array. + * + * @return The dimension value in tensor shape + */ +SNPE_API +size_t Snpe_TensorShape_At(Snpe_TensorShape_Handle_t tensorShapeHandle, size_t index); + +/** + * @brief Set a value in a TensorShape at the provided index + * + * @param[in] handle : handle to tensorShape + * + * @param[in] index : Position in the dimension array. + * + * @param[in] value : Dimension value to set + * + * @return SNPE_SUCCESS on success + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShape_Set(Snpe_TensorShape_Handle_t tensorShapeHandle, size_t index, size_t value); + +/** + * @brief . + * + * Retrieves a pointer to the first dimension of shape + * + * @param[in] handle : handle to tensorShape + * + * @return nullptr if no dimension exists; otherwise, points to + * the first dimension. + * + */ +SNPE_API +const size_t* Snpe_TensorShape_GetDimensions(Snpe_TensorShape_Handle_t tensorShape); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_TENSOR_SHAPE_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.hpp new file mode 100644 index 00000000..776637c7 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShape.hpp @@ -0,0 +1,104 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include +#include + +#include "Wrapper.hpp" + +#include "DlSystem/TensorShape.h" + +namespace DlSystem { + + +using Dimension = size_t; + + + +class TensorShape : public Wrapper { + friend BaseType; + using BaseType::BaseType; + +protected: + static constexpr DeleteFunctionType DeleteFunction{Snpe_TensorShape_Delete}; + +private: + using DimensionReference = WrapperDetail::MemberIndexedReference; + friend DimensionReference; + +public: + + TensorShape() + : BaseType(Snpe_TensorShape_Create()) + { } + + TensorShape(const TensorShape& other) + : BaseType(Snpe_TensorShape_CreateCopy(other.handle())) + { } + + TensorShape(TensorShape&& other) noexcept + : BaseType(std::move(other)) + { } + + TensorShape(std::initializer_list dims) + : BaseType(Snpe_TensorShape_CreateDimsSize(dims.begin(), dims.size())) + { } + + TensorShape& operator=(const TensorShape& other) noexcept{ + if(this != &other){ + Snpe_TensorShape_Assign(other.handle(), handle()); + } + return *this; + } + + TensorShape& operator=(TensorShape&& other) noexcept{ + return moveAssign(std::move(other)); + } + + TensorShape(const size_t *dims, size_t size) + : BaseType(Snpe_TensorShape_CreateDimsSize(dims, size)) + { } + + TensorShape(const std::vector& dims) + : TensorShape(dims.data(), dims.size()) + { } + + + void concatenate(const size_t *dims, size_t size){ + Snpe_TensorShape_Concatenate(handle(), dims, size); + } + + void concatenate(const size_t &dim){ + return concatenate(&dim, 1); + } + + size_t operator[](size_t idx) const{ + return Snpe_TensorShape_At(handle(), idx); + } + + DimensionReference operator[](size_t idx){ + return {*this, idx}; + } + + size_t rank() const{ + return Snpe_TensorShape_Rank(handle()); + } + + const size_t* getDimensions() const{ + return Snpe_TensorShape_GetDimensions(handle()); + } + + +}; + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, Dimension) +ALIAS_IN_ZDL_NAMESPACE(DlSystem, TensorShape) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.h new file mode 100644 index 00000000..520fa5ab --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.h @@ -0,0 +1,163 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + + +/** + * @file + */ + +#ifndef _SNPE_TENSOR_SHAPE_MAP_H_ +#define _SNPE_TENSOR_SHAPE_MAP_H_ + + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" + +#include "DlSystem/TensorShape.h" +#include "DlSystem/StringList.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE TensorShapeMap handle + */ +typedef void* Snpe_TensorShapeMap_Handle_t; + +/** + * Constructs a TensorShapeMap and returns a handle to it + * + * @return the handle to the created TensorShapeMap + */ +SNPE_API +Snpe_TensorShapeMap_Handle_t Snpe_TensorShapeMap_Create(); + +/** + * @brief . + * + * copy constructor. + * + * @param[in] tsmHandle : Handle to the other object to copy. + * @return the handle to the created TensorShapeMap + */ +SNPE_API +Snpe_TensorShapeMap_Handle_t Snpe_TensorShapeMap_CreateCopy(Snpe_TensorShapeMap_Handle_t tsmHandle); + +/** + * Destroys/frees Tensor Shape Map + * + * @param[in] tsmhandle : handle to access Tensor Shape Map + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShapeMap_Delete(Snpe_TensorShapeMap_Handle_t tsmHandle); + +/** + * @brief . + * + * assignment operator. Copy-assigns from srcHandle to dstHandle + * @param[in] srcHandle : handle to source Tensor Shape Map object + * @param[out] dstHandle : handle to destination Tensor Shape Map object + * + * @return Returns SNPE_SUCCESS if Assignment successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShapeMap_Assign(Snpe_TensorShapeMap_Handle_t srcHandle, Snpe_TensorShapeMap_Handle_t dstHandle); + +/** + * @brief Adds a name and the corresponding tensor pointer + * to the map + * + * @param[in] tsmhandle : handle to access Tensor Shape Map + * @param[in] name The name of the tensor + * @param[in] tsHandle : Handle to access Tensor Shape + * + * @return Returns SNPE_SUCCESS if Add operation successful + * @note If a tensor with the same name already exists, no new + * tensor is added. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShapeMap_Add(Snpe_TensorShapeMap_Handle_t tsmHandle, const char* name, Snpe_TensorShape_Handle_t tsHandle); + +/** + * @brief Removes a mapping of tensor and its name by its name + * + * @param[in] tsmhandle : handle to access Tensor Shape Map + * @param[in] name The name of tensor to be removed + * @return Returns SNPE_SUCCESS if Remove operation successful + * + * @note If no tensor with the specified name is found, nothing + * is done. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShapeMap_Remove(Snpe_TensorShapeMap_Handle_t tsmHandle, const char* name); + +/** + * @brief Returns the number of tensors in the map + * @param[in] tsmhandle : handle to access Tensor Shape Map + * @return Returns number entries in TensorShapeMap + */ +SNPE_API +size_t Snpe_TensorShapeMap_Size(Snpe_TensorShapeMap_Handle_t tsmHandle); + +/** + * @brief . + * + * Removes all tensors from the map + * @param[in] tsmhandle : handle to access Tensor Shape Map + * @return Returns SNPE_SUCCESS if Clear operation successful + */ +SNPE_API +Snpe_ErrorCode_t Snpe_TensorShapeMap_Clear(Snpe_TensorShapeMap_Handle_t tsmHandle); + +/** + * @brief Returns the tensor given its name. + * + * @param[in] tsmhandle : handle to access Tensor Shape Map + * @param[in] name The name of the tensor to get. + * + * @return nullptr if no tensor with the specified name is + * found; otherwise, a valid Tensor Shape Handle. + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_TensorShapeMap_GetTensorShape(Snpe_TensorShapeMap_Handle_t tsmHandle, const char* name); + +/** + * @brief . + * + * @param[in] tsmHandle : handle to access Tensor Shape Map + * @return A stringList Handle to access names of all tensor shapes + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_TensorShapeMap_GetTensorShapeNames(Snpe_TensorShapeMap_Handle_t tsmHandle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_TENSOR_SHAPE_MAP_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.hpp new file mode 100644 index 00000000..8b79a6e2 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/TensorShapeMap.hpp @@ -0,0 +1,77 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include "DlSystem/StringList.hpp" +#include "DlSystem/TensorShape.hpp" +#include "DlSystem/DlError.hpp" + +#include "DlSystem/TensorShapeMap.h" + +namespace DlSystem { + +class TensorShapeMap : public Wrapper { + friend BaseType; + using BaseType::BaseType; + static constexpr DeleteFunctionType DeleteFunction{Snpe_TensorShapeMap_Delete}; + +public: + TensorShapeMap() + : BaseType(Snpe_TensorShapeMap_Create()) + { } + TensorShapeMap(const TensorShapeMap& other) + : BaseType(Snpe_TensorShapeMap_CreateCopy(other.handle())) + { } + TensorShapeMap(TensorShapeMap&& other) noexcept + : BaseType(std::move(other)) + { } + + TensorShapeMap& operator=(const TensorShapeMap& other){ + if(this != &other){ + Snpe_TensorShapeMap_Assign(other.handle(), handle()); + } + return *this; + } + TensorShapeMap& operator=(TensorShapeMap&& other) noexcept{ + return moveAssign(std::move(other)); + } + + DlSystem::ErrorCode add(const char *name, const TensorShape& tensorShape){ + return static_cast( + Snpe_TensorShapeMap_Add(handle(), name, getHandle(tensorShape)) + ); + } + + DlSystem::ErrorCode remove(const char* name) noexcept{ + return static_cast(Snpe_TensorShapeMap_Remove(handle(), name)); + } + + size_t size() const noexcept{ + return Snpe_TensorShapeMap_Size(handle()); + } + + DlSystem::ErrorCode clear() noexcept{ + return static_cast(Snpe_TensorShapeMap_Clear(handle())); + } + + TensorShape getTensorShape(const char* name) const noexcept{ + return moveHandle(Snpe_TensorShapeMap_GetTensorShape(handle(), name)); + } + + StringList getTensorShapeNames() const{ + return moveHandle(Snpe_TensorShapeMap_GetTensorShapeNames(handle())); + } + +}; + +} // ns DlSystem + + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, TensorShapeMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.h new file mode 100644 index 00000000..2da1c792 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.h @@ -0,0 +1,151 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_USER_BUFFER_MAP_H +#define DL_SYSTEM_USER_BUFFER_MAP_H + +#include "DlSystem/StringList.h" +#include "DlSystem/IUserBuffer.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE UserBufferMap handle + */ +typedef void* Snpe_UserBufferMap_Handle_t; + +/** + * @brief . + * + * Creates a new empty UserBuffer map + */ +SNPE_API +Snpe_UserBufferMap_Handle_t Snpe_UserBufferMap_Create(); + +/** + * copy constructor. + * @param[in] other : Handle to the other userBufferMap to be copied from. + */ +SNPE_API +Snpe_UserBufferMap_Handle_t Snpe_UserBufferMap_CreateCopy(Snpe_UserBufferMap_Handle_t other); + + +/** + * @brief Adds a name and the corresponding UserBuffer pointer + * to the map + * + * @param[in] handle : Handle to access UserBufferMap + * @param[in] name : The name of the UserBuffer + * @param[in] bufferHandle : Handle to access UserBuffer + * + * @note If a UserBuffer with the same name already exists, the new + * UserBuffer pointer would be updated. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferMap_Add(Snpe_UserBufferMap_Handle_t handle, const char *name, Snpe_IUserBuffer_Handle_t bufferHandle); + +/** + * @brief Removes a mapping of one UserBuffer and its name by its name + * + * @param[in] handle : Handle to access UserBufferMap + * + * @param[in] name : The name of UserBuffer to be removed + * + * @note If no UserBuffer with the specified name is found, nothing + * is done. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferMap_Remove(Snpe_UserBufferMap_Handle_t handle, const char *name); + +/** + * @brief Returns the number of UserBuffers in the map + * @param[in] handle : Handle to access UserBufferMap + */ +SNPE_API +size_t Snpe_UserBufferMap_Size(Snpe_UserBufferMap_Handle_t handle); + +/** + * @brief . + * + * @param[in] handle : Handle to access UserBufferMap + * Removes all UserBuffers from the map + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferMap_Clear(Snpe_UserBufferMap_Handle_t handle); + +/** + * @brief Returns the UserBuffer given its name. + * + * @param[in] handle : Handle to access UserBufferMap + * + * @param[in] name : The name of the UserBuffer to get. + * + * @return nullptr if no UserBuffer with the specified name is + * found; otherwise, a valid pointer to the UserBuffer. + */ +SNPE_API +Snpe_IUserBuffer_Handle_t Snpe_UserBufferMap_GetUserBuffer_Ref(Snpe_UserBufferMap_Handle_t handle , const char *name); + +/** + * @brief . + * + * Returns the names of all UserBuffers + * + * @param[in] handle : Handle to access UserBufferMap + * + * @return A list of UserBuffer names. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_UserBufferMap_GetUserBufferNames(Snpe_UserBufferMap_Handle_t handle); + +/** + * Copy-assigns the contents of srcHandle into dstHandle + * + * @param src Source UserBufferMap handle + * @param dst Destination UserBufferMap handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferMap_Assign(Snpe_UserBufferMap_Handle_t srcHandle, Snpe_UserBufferMap_Handle_t dstHandle); + +/** + * Destroys/frees UserBuffer Map + * + * @param[in] handle : Handle to access UserBuffer Map + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferMap_Delete(Snpe_UserBufferMap_Handle_t handle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_USER_BUFFER_MAP_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.hpp new file mode 100644 index 00000000..acf3207c --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserBufferMap.hpp @@ -0,0 +1,80 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include + +#include "Wrapper.hpp" +#include "DlSystem/DlError.hpp" +#include "DlSystem/StringList.hpp" +#include "DlSystem/IUserBuffer.hpp" + +#include "DlSystem/UserBufferMap.h" + +namespace DlSystem { + +class UserBufferMap : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserBufferMap_Delete}; + +public: + UserBufferMap() + : BaseType(Snpe_UserBufferMap_Create()) + { } + + UserBufferMap(const UserBufferMap& other) + : BaseType(Snpe_UserBufferMap_CreateCopy(other.handle())) + { } + UserBufferMap(UserBufferMap&& other) noexcept + : BaseType(std::move(other)) + { } + + UserBufferMap& operator=(const UserBufferMap& other){ + if(this != &other){ + Snpe_UserBufferMap_Assign(other.handle(), handle()); + } + return *this; + } + UserBufferMap& operator=(UserBufferMap&& other) noexcept{ + return moveAssign(std::move(other)); + } + + DlSystem::ErrorCode add(const char* name, IUserBuffer* buffer){ + if(!buffer) return ErrorCode::SNPE_CAPI_BAD_ARGUMENT; + return static_cast(Snpe_UserBufferMap_Add(handle(), name, getHandle(*buffer))); + } + + DlSystem::ErrorCode remove(const char* name) noexcept{ + return static_cast(Snpe_UserBufferMap_Remove(handle(), name)); + } + + size_t size() const noexcept{ + return Snpe_UserBufferMap_Size(handle()); + } + + DlSystem::ErrorCode clear() noexcept{ + return static_cast(Snpe_UserBufferMap_Clear(handle())); + } + + IUserBuffer* getUserBuffer(const char* name) const noexcept{ + return makeReference(Snpe_UserBufferMap_GetUserBuffer_Ref(handle(), name)); + } + + StringList getUserBufferNames() const{ + return moveHandle(Snpe_UserBufferMap_GetUserBufferNames(handle())); + } + +}; + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserBufferMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.h new file mode 100644 index 00000000..c927d33e --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.h @@ -0,0 +1,156 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef DL_SYSTEM_USER_MEMORY_MAP_H +#define DL_SYSTEM_USER_MEMORY_MAP_H + +#include "DlSystem/StringList.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE User Memory handle + */ +typedef void* Snpe_UserMemoryMap_Handle_t; + +/** + * @brief . + * + * Creates a new empty UserMemory map + */ +SNPE_API +Snpe_UserMemoryMap_Handle_t Snpe_UserMemoryMap_Create(); + +/** + * copy constructor. + * @param[in] other : Handle to the other object to copy. + */ +SNPE_API +Snpe_UserMemoryMap_Handle_t Snpe_UserMemoryMap_Copy(Snpe_UserMemoryMap_Handle_t other); + +/** + * Copy-assigns the contents of srcHandle into dstHandle + * + * @param[in] srcHandle Source UserMemoryMap handle + * + * @param[out] dstHandle Destination UserMemoryMap handle + * + * @return SNPE_SUCCESS on successful copy-assignment + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserMemoryMap_Assign(Snpe_UserMemoryMap_Handle_t srcHandle, Snpe_UserMemoryMap_Handle_t dstHandle); + +/** + * Destroys/frees UserMemory Map + * + * @param[in] handle : Handle to access UserMemory Map + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserMemoryMap_Delete(Snpe_UserMemoryMap_Handle_t handle); + +/** + * @brief Adds a name and the corresponding buffer address + * to the map + * + * @param[in] handle : Handle to access UserMemory Map + * @param[in] name : The name of the UserMemory + * @param[in] address : The pointer to the Buffer Memory + * + * @note If a UserBuffer with the same name already exists, the new + * address would be updated. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserMemoryMap_Add(Snpe_UserMemoryMap_Handle_t handle, const char *name, void *address); + +/** + * @brief Removes a mapping of one Buffer address and its name by its name + * + * @param[in] handle : Handle to access UserMemory Map + * @param[in] name : The name of Memory address to be removed + * + * @note If no UserBuffer with the specified name is found, nothing + * is done. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserMemoryMap_Remove(Snpe_UserMemoryMap_Handle_t handle, const char *name); + +/** + * @brief Returns the number of User Memory addresses in the map + * @param[in] handle : Handle to access UserMemory Map + */ +SNPE_API +size_t Snpe_UserMemoryMap_Size(Snpe_UserMemoryMap_Handle_t handle); + +/** + * @brief . + * + * Removes all User Memory from the map + * @param[in] handle : Handle to access UserMemory Map + */ +SNPE_API +Snpe_ErrorCode_t Snpe_UserMemoryMap_Clear(Snpe_UserMemoryMap_Handle_t handle); + +/** + * @brief . + * Returns the names of all User Memory + * + * @param[in] handle : Handle to access UserMemory Map + * + * @return Returns a handle to the stringList. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_UserMemoryMap_GetUserBufferNames(Snpe_UserMemoryMap_Handle_t handle); + +/** + * @brief Returns the no of UserMemory addresses mapped to the buffer + * + * @param[in] handle : Handle to access UserMemory Map + * @param[in] name : The name of the UserMemory + * + */ +SNPE_API +size_t Snpe_UserMemoryMap_GetUserMemoryAddressCount(Snpe_UserMemoryMap_Handle_t handle, const char *name); + +/** + * @brief Returns address at a specified index corresponding to a UserMemory buffer name + * + * @param[in] handle : Handle to access UserMemory Map + * @param[in] name : The name of the buffer + * @param[in] index : The index in the list of addresses + * + */ +SNPE_API +void* Snpe_UserMemoryMap_GetUserMemoryAddressAtIndex(Snpe_UserMemoryMap_Handle_t handle, const char *name, uint32_t index); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DL_SYSTEM_USER_MEMORY_MAP_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.hpp new file mode 100644 index 00000000..36e9cd37 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/DlSystem/UserMemoryMap.hpp @@ -0,0 +1,76 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "DlSystem/DlError.hpp" +#include "DlSystem/StringList.hpp" + +#include "DlSystem/UserMemoryMap.h" + +namespace DlSystem { + +class UserMemoryMap : public Wrapper { + friend BaseType; +// Use this to get free move Ctor and move assignment operator, provided this class does not specify +// as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserMemoryMap_Delete}; +public: + UserMemoryMap() + : BaseType(Snpe_UserMemoryMap_Create()) + { } + UserMemoryMap(const UserMemoryMap& other) + : BaseType(Snpe_UserMemoryMap_Copy(other.handle())) + { } + UserMemoryMap(UserMemoryMap&& other) noexcept + : BaseType(std::move(other)) + { } + + UserMemoryMap& operator=(const UserMemoryMap& other){ + if(this != &other){ + Snpe_UserMemoryMap_Assign(handle(), other.handle()); + } + return *this; + } + + DlSystem::ErrorCode add(const char* name, void* address) noexcept{ + return static_cast(Snpe_UserMemoryMap_Add(handle(), name, address)); + } + + DlSystem::ErrorCode remove(const char* name){ + return static_cast(Snpe_UserMemoryMap_Remove(handle(), name)); + } + + size_t size() const noexcept{ + return Snpe_UserMemoryMap_Size(handle()); + } + + DlSystem::ErrorCode clear() noexcept{ + return static_cast(Snpe_UserMemoryMap_Clear(handle())); + } + + StringList getUserBufferNames() const{ + return moveHandle(Snpe_UserMemoryMap_GetUserBufferNames(handle())); + } + + size_t getUserMemoryAddressCount(const char* name) const noexcept{ + return Snpe_UserMemoryMap_GetUserMemoryAddressCount(handle(), name); + } + + void* getUserMemoryAddressAtIndex(const char* name, uint32_t index) const noexcept{ + return Snpe_UserMemoryMap_GetUserMemoryAddressAtIndex(handle(), name, index); + } + +}; + + +} // ns DlSystem + +ALIAS_IN_ZDL_NAMESPACE(DlSystem, UserMemoryMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.h new file mode 100644 index 00000000..282ee547 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.h @@ -0,0 +1,107 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _PLATFORM_VALIDATOR_H_ +#define _PLATFORM_VALIDATOR_H_ + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" +#include "DlSystem/DlEnums.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A typedef to indicate a SNPE PlatformValidator handle + */ +typedef void* Snpe_PlatformValidator_Handle_t; + +/** + * @brief . + * + * Creates a new Platform Validator + * + */ +SNPE_API +Snpe_PlatformValidator_Handle_t Snpe_PlatformValidator_Create(); + + +/** + * Destroys/frees Platform Validator + * + * @param[in] handle : Handle to access Platform Validator + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PlatformValidator_Delete(Snpe_PlatformValidator_Handle_t handle); + +/** + * @brief Sets the runtime processor for compatibility check + * + * @return Void + */ +SNPE_API +void Snpe_PlatformValidator_SetRuntime(Snpe_PlatformValidator_Handle_t handle, + Snpe_Runtime_t runtime, + bool unsignedPD=true); + +/** + * @brief Checks if the Runtime prerequisites for SNPE are available. + * + * @return 1 if the Runtime prerequisites are available, else 0. + */ +SNPE_API +int Snpe_PlatformValidator_IsRuntimeAvailable(Snpe_PlatformValidator_Handle_t handle, + bool unsignedPD=true); + +/** + * @brief Returns the core version for the Runtime selected. + * + * @return char* which contains the actual core version value + */ +SNPE_API +const char* Snpe_PlatformValidator_GetCoreVersion(Snpe_PlatformValidator_Handle_t handle); + +/** + * @brief Returns the library version for the Runtime selected. + * + * @return char* which contains the actual lib version value + */ +SNPE_API +const char* Snpe_PlatformValidator_GetLibVersion(Snpe_PlatformValidator_Handle_t handle); + +/** + * @brief Runs a small program on the runtime and Checks if SNPE is supported for Runtime. + * + * @return If 1, the device is ready for SNPE execution, else return 0. + */ +SNPE_API +int Snpe_PlatformValidator_RuntimeCheck(Snpe_PlatformValidator_Handle_t handle, + bool unsignedPD=true); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PLATFORM_VALIDATOR_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.hpp new file mode 100644 index 00000000..de52635c --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/PlatformValidator/PlatformValidator.hpp @@ -0,0 +1,57 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include + +#include "Wrapper.hpp" + +#include "DlSystem/DlEnums.hpp" + + +#include "PlatformValidator/PlatformValidator.h" + + +namespace SNPE { + +class PlatformValidator : public Wrapper { + friend BaseType; + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_PlatformValidator_Delete}; + +public: + PlatformValidator() + : BaseType(Snpe_PlatformValidator_Create()) + { } + + void setRuntime(DlSystem::Runtime_t runtime, bool unsignedPD=true){ + Snpe_PlatformValidator_SetRuntime(handle(), static_cast(runtime), unsignedPD); + } + + bool isRuntimeAvailable(bool unsignedPD=true){ + return Snpe_PlatformValidator_IsRuntimeAvailable(handle(), unsignedPD); + } + + std::string getCoreVersion(){ + return Snpe_PlatformValidator_GetCoreVersion(handle()); + } + + std::string getLibVersion(){ + return Snpe_PlatformValidator_GetLibVersion(handle()); + } + + bool runtimeCheck(bool unsignedPD=true){ + return Snpe_PlatformValidator_RuntimeCheck(handle(), unsignedPD); + } + +}; + +} // ns SNPE + +ALIAS_IN_ZDL_NAMESPACE(SNPE, PlatformValidator) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.h new file mode 100644 index 00000000..8a2bb7d2 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.h @@ -0,0 +1,85 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef _SNPE_APPLICATION_BUFFER_MAP_H_ +#define _SNPE_APPLICATION_BUFFER_MAP_H_ + + +#ifdef __cplusplus +#include +#else +#include +#endif + + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" +#include "DlSystem/StringList.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef void* Snpe_ApplicationBufferMap_Handle_t; + +SNPE_API +Snpe_ApplicationBufferMap_Handle_t Snpe_ApplicationBufferMap_Create(); + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_Delete(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle); + + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_Add(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle, + const char* name, + const uint8_t* buff, + size_t size); + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_AddFloat(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle, + const char* name, + const float* buff, + size_t size); + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_Remove(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle, + const char* name); + +SNPE_API +size_t Snpe_ApplicationBufferMap_Size(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_Clear(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle); + + +SNPE_API +Snpe_StringList_Handle_t Snpe_ApplicationBufferMap_GetUserBufferNames(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle); + + +SNPE_API +Snpe_ErrorCode_t Snpe_ApplicationBufferMap_GetUserBuffer(Snpe_ApplicationBufferMap_Handle_t applicationBufferMapHandle, + const char* name, + size_t* size, + const uint8_t** data); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_APPLICATION_BUFFER_MAP_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.hpp new file mode 100644 index 00000000..6ad745bb --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/ApplicationBufferMap.hpp @@ -0,0 +1,90 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include +#include +#include + +#include "Wrapper.hpp" +#include "DlSystem/StringList.hpp" + +#include "SNPE/ApplicationBufferMap.h" + +namespace PSNPE { + +class ApplicationBufferMap : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_ApplicationBufferMap_Delete}; +public: + ApplicationBufferMap() + : BaseType(Snpe_ApplicationBufferMap_Create()){} + + explicit ApplicationBufferMap(const std::unordered_map> &buffer) + : ApplicationBufferMap(){ + for(const auto &kv: buffer){ + add(kv.first.c_str(), kv.second); + } + } + + void add(const char *name, const std::vector &buff){ + Snpe_ApplicationBufferMap_Add(handle(), name, buff.data(), buff.size()); + } + + void add(const char *name, const std::vector &buff){ + Snpe_ApplicationBufferMap_Add(handle(), name, reinterpret_cast(buff.data()), buff.size()*sizeof(float)); + } + + void remove(const char *name) noexcept{ + Snpe_ApplicationBufferMap_Remove(handle(), name); + } + + size_t size() const noexcept{ + return Snpe_ApplicationBufferMap_Size(handle()); + } + + void clear() noexcept{ + Snpe_ApplicationBufferMap_Clear(handle()); + } + + std::vector getUserBuffer(const char *name) const{ + size_t size{}; + const uint8_t *data{}; + Snpe_ApplicationBufferMap_GetUserBuffer(handle(), name, &size, &data); + + return std::vector(data, data + size); + } + + std::vector operator[](const char *name) const{ + return getUserBuffer(name); + } + + DlSystem::StringList getUserBufferNames() const{ + return moveHandle(Snpe_ApplicationBufferMap_GetUserBufferNames(handle())); + } + + std::unordered_map> getUserBuffer() const{ + std::unordered_map> toret; + for(auto name: getUserBufferNames()){ + toret.emplace(name, getUserBuffer(name)); + } + + return toret; + } + +}; + +} // ns PSNPE + + +ALIAS_IN_ZDL_NAMESPACE(PSNPE, ApplicationBufferMap) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.h new file mode 100644 index 00000000..2358d535 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.h @@ -0,0 +1,898 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022,2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _SNPE_PSNPE_H_ +#define _SNPE_PSNPE_H_ + + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "DlContainer/DlContainer.h" +#include "SNPE/ApplicationBufferMap.h" +#include "SNPE/RuntimeConfigList.h" +#include "SNPE/UserBufferList.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/IBufferAttributes.h" + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" + +#include "DlSystem/UserMemoryMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A typedef to indicate the callback PSNPE handle of Async Output mode + */ +typedef void* Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t; + +//SNPE_API +//Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t Snpe_PSNPE_OutputAsyncCallbackParam_Create(size_t index, +// int status, +// const char* errorMsg); +// +//SNPE_API +//Snpe_ErrorCode_t Snpe_PSNPE_OutputAsyncCallbackParam_Delete(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t oacpHandle); + +// NOTE: we don't need _{Create,Delete} functions because the user does not create or delete these handles +// They're passed in to the callback functions they created + +/** + * @brief Get the data index of an output async PSNPE object + * + * @param[in] oacpHandle Handle to access the PSNPE object of output async mode + * + * @return The data idx for output async mode + */ +SNPE_API +size_t Snpe_PSNPE_OutputAsyncCallbackParam_GetDataIdx(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t oacpHandle); + +/** + * @brief Execute an output async PSNPE object + * + * @param[in] oacpHandle Handle to access the PSNPE object of output async mode + * + * @return True if executed successfully with outputAsync mode + */ +SNPE_API +int Snpe_PSNPE_OutputAsyncCallbackParam_GetExecuteStatus(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t oacpHandle); + +/** + * @brief Get the error message during the execution of PSNPE output async mode + * + * @param[in] oacpHandle Handle to access the PSNPE object of output async mode + * + * @return Error message + */ +SNPE_API +const char* Snpe_PSNPE_OutputAsyncCallbackParam_GetErrorMsg(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t oacpHandle); + +/** + * @brief Get the ID of an output async PSNPE object + * + * @param[in] oacpHandle Handle to access the PSNPE object of output async mode + * + * @return The id of an PSNPE object for output async mode + */ +SNPE_API +size_t Snpe_PSNPE_OutputAsyncCallbackParam_GetID(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t oacpHandle); + + + +/** + * A typedef to indicate the output callback of PSNPE handle of input-output async mode + */ +typedef void* Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t; + +/** + * @brief Get the data index of an input-output async PSNPE object + * + * @param[in] oacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return The data index for input-output async mode + */ +SNPE_API +size_t Snpe_PSNPE_InputOutputAsyncCallbackParam_GetDataIdx(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * @brief Execute an input-output async PSNPE object + * + * @param[in] oacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return True if executed successfully with input-output async mode + */ +SNPE_API +int Snpe_PSNPE_InputOutputAsyncCallbackParam_GetExecuteStatus(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * @brief Get the error message during the execution of PSNPE input-output async mode + * + * @param[in] oacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return error message + */ +SNPE_API +const char* Snpe_PSNPE_InputOutputAsyncCallbackParam_GetErrorMsg(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * @brief Get the names of output buffers to the network + * + * @param[in] ioacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return Handle of output buffer name list + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_PSNPE_InputOutputAsyncCallbackParam_GetUserBufferNames(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * @brief Get the output buffer map of PSNPE object for input-output async mode + * + * @param[in] ioacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return The reference handle of output ApplicationBufferMap + */ +SNPE_API +Snpe_ApplicationBufferMap_Handle_t Snpe_PSNPE_InputOutputAsyncCallbackParam_GetOutputMap_Ref(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * @brief Get the id of the output callback for input-output async mode + * + * @param[in] oacpHandle Handle to access the PSNPE object of input-output async mode + * + * @return The id for output callback for input-output async mode + */ +SNPE_API +size_t Snpe_PSNPE_InputOutputAsyncCallbackParam_GetID(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle); + +/** + * A typedef to indicate the input callback of PSNPE handle of input-output async mode + */ +typedef void* Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t; + +/** + * @brief Get the input list for input callback of input-output async mode + * + * @param[in] ioacpHandle Handle to access the object of input callback of input-output async mode + * + * @return List the inputs + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_PSNPE_InputOutputInputAsyncCallbackParam_GetInputs(Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t ioiacpHandle); + +/** + * @brief Get the input names for input callback of input-output async mode + * + * @param[in] ioacpHandle Handle to access the object of input callback of input-output async mode + * + * @return List the names of input + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_PSNPE_InputOutputInputAsyncCallbackParam_GetInputNames(Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t ioiacpHandle); + +/** + * @brief Get the id of the input callback for input-output async mode + * + * @param[in] oacpHandle Handle to access the object of input-output async mode + * + * @return The id of input callback for input-output async mode + */ +SNPE_API +size_t Snpe_PSNPE_InputOutputInputAsyncCallbackParam_GetID(Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t ioiacpHandle); + +/** + * @brief A struct to indicate userbuffer data type in output callback of input-output async mode + */ +typedef struct{ + /// data for the one output + const uint8_t* data; + /// the data size of this output + size_t size; +} Snpe_UserBufferData_t; + +/** + * @brief Get the output data of the output callback for input-output async mode + * + * @param[in] oacpHandle Handle to access the object of output callback of input-output async mode + * + * @param[in] name The output name of output callback of input-output async mode + * + * @return The output data of output callback for input-output async mode + */ +SNPE_API +Snpe_UserBufferData_t Snpe_PSNPE_InputOutputAsyncCallbackParam_GetUserBuffer(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t ioacpHandle, + const char* name); +/** + * A typedef to indicate build configuration + */ +typedef void* Snpe_BuildConfig_Handle_t; + +/** + * A typedef to indicate a PSNPE object + */ +typedef void* Snpe_PSNPE_Handle_t; + +/** + * A typedef to indicate if PSNPE object is built in serial or parallel, default = 0 + */ +typedef enum SNPE_API { + SNPE_PSNPE_BUILDMODE_SERIAL = 0, + SNPE_PSNPE_BUILDMODE_PARALLEL = 1 +} Snpe_PSNPE_BuildMode_t; + +/** + * A typedef to indicate if PSNPE objects are executed in sync mode or output async mode or input-output async mode, default = 0 + */ +typedef enum SNPE_API { + SNPE_PSNPE_INPUTOUTPUTTRANSMISSIONMODE_SYNC = 0, + SNPE_PSNPE_INPUTOUTPUTTRANSMISSIONMODE_OUTPUTASYNC = 1, + SNPE_PSNPE_INPUTOUTPUTTRANSMISSIONMODE_INPUTOUTPUTASYNC = 2 +} Snpe_PSNPE_InputOutputTransmissionMode_t; + +// BuildConfig +/** + * @brief Create the object of snpe build config + * + * @return the SNPE build handle + */ +SNPE_API +Snpe_BuildConfig_Handle_t Snpe_BuildConfig_Create(); + +/** + * @brief Release the object of snpe build config + * + * @param[in] buildConfigHandle Handle to access the object of snpe buid config + * + * @return The error of build config result + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_Delete(Snpe_BuildConfig_Handle_t buildConfigHandle); + +/** + * @brief Get the mode of build snpe object, serial or parallel + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The value of Snpe_PSNPE_BuildMode_t + */ +SNPE_API +Snpe_PSNPE_BuildMode_t Snpe_BuildConfig_GetBuildMode(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set the mode of build snpe object, serial or parallel + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] buildMode A typedef of Snpe_PSNPE_BuildMode_t + * + * @return The result of setting mode + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetBuildMode(Snpe_BuildConfig_Handle_t bcHandle, Snpe_PSNPE_BuildMode_t buildMode); + +/** + * @brief Set the dlc model + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] dlcHandle A handle of snpe DLC container + * + * @return The result of setting dlc model + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetContainer(Snpe_BuildConfig_Handle_t bcHandle, Snpe_DlContainer_Handle_t dlcHandle); + +/** + * @brief Get dlc container in snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The reference handle of DLC container + */ +SNPE_API +Snpe_DlContainer_Handle_t Snpe_BuildConfig_GetContainer_Ref(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set output buffer names in snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] slHandle A handle of the output layer name list + * + * @return The result of setting output names + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetOutputBufferNames(Snpe_BuildConfig_Handle_t bcHandle, Snpe_StringList_Handle_t slHandle); + +/** + * @brief Get output buffer names in snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The reference handle of output buffer name list. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_BuildConfig_GetOutputBufferNames_Ref(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set output buffer names in snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] slHandle List of tensor names to output. An empty list will result in producing output for the final output tensor of the model. The list will be copied + * + * @return The result of setting output tensors + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetOutputTensors(Snpe_BuildConfig_Handle_t bcHandle, Snpe_StringList_Handle_t slHandle); + +/** + * @brief Get output tensors in snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The reference handle of output tensor list + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_BuildConfig_GetOutputTensors_Ref(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set runtime config list for snpe buildConfig + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] rclHandle Handle to access the object of runtime config list + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetRuntimeConfigList(Snpe_BuildConfig_Handle_t bcHandle, Snpe_RuntimeConfigList_Handle_t rclHandle); + +/** + * @brief Get runtime config list for snpe buildConfig + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The reference handle of runtime config list + */ +SNPE_API +Snpe_RuntimeConfigList_Handle_t Snpe_BuildConfig_GetRuntimeConfigList_Ref(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Get input thread number of input data for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The number of input thread + */ +SNPE_API +size_t Snpe_BuildConfig_GetInputThreadNumbers(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set input thread number of input data for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] threadNumbers The number of input thread for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputThreadNumbers(Snpe_BuildConfig_Handle_t bcHandle, size_t threadNumbers); + +/** + * @brief Get output thread number of output data for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The number of output thread + */ +SNPE_API +size_t Snpe_BuildConfig_GetOutputThreadNumbers(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set output thread number of output data for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] threadNumbers The number of output thread for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetOutputThreadNumbers(Snpe_BuildConfig_Handle_t bcHandle, size_t threadNumbers); + +/** + * @brief Set output callback for output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] callbackFunc The ouutput callback function for output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetOutputCallback(Snpe_BuildConfig_Handle_t bcHandle, + void (*callbackFunc)(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t)); +/** + * @brief Set the id of output callback function for output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] id The id of output callback function + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetOutputCallbackID(Snpe_BuildConfig_Handle_t bcHandle, size_t id); + +/** + * @brief Set the inside output callback handle to NULL for output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_ClearOutputCallback(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set output callback for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] callbackFunc The output callback function for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputOutputCallback(Snpe_BuildConfig_Handle_t bcHandle, + void (*callbackFunc)(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t)); + +/** + * @brief Set the id of output callback function for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] id The id of output callback function for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputOutputCallbackID(Snpe_BuildConfig_Handle_t bcHandle, size_t id); + +/** + * @brief Set the inside output callback handle to NULL for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_ClearInputOutputCallback(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set input callback for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] callbackFunc The input callback function for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputOutputInputCallback(Snpe_BuildConfig_Handle_t bcHandle, + Snpe_ApplicationBufferMap_Handle_t (*callbackFunc)( + Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t + ) + ); + +/** + * @brief Set the id of input callback function for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] id The id of input callback function for input-output async mode + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputOutputInputCallbackID(Snpe_BuildConfig_Handle_t bcHandle, size_t id); + +/** + * @brief Set the inside input callback handle to NULL for input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_ClearInputOutputInputCallback(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set the input and output transmission mode including sync mode, output async mode and input-output async mode, defult is sync mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] iotMode The typedef of Snpe_PSNPE_InputOutputTransmissionMode_t + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetInputOutputTransmissionMode(Snpe_BuildConfig_Handle_t bcHandle, + Snpe_PSNPE_InputOutputTransmissionMode_t iotMode); + +/** + * @brief Get the input and output transmission mode including sync mode, output async mode and input-output async mode + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The typedef of Snpe_PSNPE_InputOutputTransmissionMode_t + */ +SNPE_API +Snpe_PSNPE_InputOutputTransmissionMode_t Snpe_BuildConfig_GetInputOutputTransmissionMode(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set the profiling level for PSNPE build config, default is SNPE_PROFILING_LEVEL_OFF + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] profilingLevel The typedef of Snpe_ProfilingLevel_t + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetProfilingLevel(Snpe_BuildConfig_Handle_t bcHandle, Snpe_ProfilingLevel_t profilingLevel); + +/** + * @brief Get the profiling level for PSNPE build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The typedef of Snpe_ProfilingLevel_t + */ +SNPE_API +Snpe_ProfilingLevel_t Snpe_BuildConfig_GetProfilingLevel(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief To be deprecated, set the encode value when you want to divide one image into 2 or 4 parts to run, default is 0 which means the input don't need dividing. + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] encode0 The uint64 value of encode0 + * + * @param[in] encode1 The uint64 value of encode1 + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetEncode(Snpe_BuildConfig_Handle_t bcHandle, uint64_t encode0, uint64_t encode1); + +/** + * @brief To be deprecated, set the encode0 value for snpe build config which is a special feature used in SM8250 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] encode0 The uint64 value of encode0 + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetEncode0(Snpe_BuildConfig_Handle_t bcHandle, uint64_t encode0); + +/** + * @brief To be deprecated, set the encode1 value for snpe build config which is a special feature used in SM8250 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] encode1 The uint64 value of encode1 + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetEncode1(Snpe_BuildConfig_Handle_t bcHandle, uint64_t encode1); + +/** + * @brief To be deprecated, get the encode0 and encode1 value for snpe build config which is a special feature used in SM8250 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The uint64 value of encode + */ +SNPE_API +uint64_t* Snpe_BuildConfig_GetEncode(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief To be deprecated, get the encode0 value for snpe build config which is a special feature used in SM8250 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The uint64 value of encode0 + */ +SNPE_API +uint64_t Snpe_BuildConfig_GetEncode0(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief To be deprecated, get the encode1 value for snpe build config which is a special feature used in SM8250 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The uint64 value of encode1 + */ +SNPE_API +uint64_t Snpe_BuildConfig_GetEncode1(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set true or false for enabling init cache for snpe build config, enabling init cache = 1 + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] enableInitCache True for enabing init cache + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetEnableInitCache(Snpe_BuildConfig_Handle_t bcHandle, int enableInitCache); + +/** + * @brief Get the satus of enabling init cache for snpe build config, enabling init cache = 1. + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] enableInitCache True for enabing init cache + * + * @return 1 or 0 for enabling init cache + */ +SNPE_API +int Snpe_BuildConfig_GetEnableInitCache(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Handle needed to access the platformConfig. + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] platformOptions Options as a const char* + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetPlatformOptions(Snpe_BuildConfig_Handle_t bcHandle, const char* platformOptions); + +/** + * @brief Get the optional platform features for snpe build config + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return Options as a const char* + */ +SNPE_API +const char* Snpe_BuildConfig_GetPlatformOptions(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Set the path directory of output diag log you want to save + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @param[in] diaglogOutputDir The string directory + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_BuildConfig_SetDiaglogOutputDir(Snpe_BuildConfig_Handle_t bcHandle, const char* diaglogOutputDir); + +/** + * @brief Get the path of output diag log + * + * @param[in] bcHandle Handle to access the object of snpe buid config + * + * @return The string directory + */ +SNPE_API +const char* Snpe_BuildConfig_GetDiaglogOutputDir(Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Create the handle of PSNPE object + * + * @return The handle of PSNPE object + */ +SNPE_API +Snpe_PSNPE_Handle_t Snpe_PSNPE_Create(); + +/** + * @brief Release the handle of PSNPE object + * + * @param[in] psnpeHandle Handle to access the PSNPE object + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_Delete(Snpe_PSNPE_Handle_t psnpeHandle); + +/** + * @brief Build the instance of PSNPE object accorading of snpe build config + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_Build(Snpe_PSNPE_Handle_t psnpeHandle, Snpe_BuildConfig_Handle_t bcHandle); + +/** + * @brief Execute PSNPE object for sync mode. + * + * @param[in] psnpeHandle Handle to access the PSNPE object + * + * @param[in] inputBufferListHandle Handle to access the input user buffer list + * + * @param[in] outputBufferListHandle Handle to access the output user buffer list + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_Execute(Snpe_PSNPE_Handle_t psnpeHandle, + Snpe_UserBufferList_Handle_t inputBufferListHandle, + Snpe_UserBufferList_Handle_t outputBufferListHandle); + +/** + * @brief Execute PSNPE object for input-output async mode + * + * @param[in] psnpeHandle Handle to access the PSNPE object + * + * @param[in] inputMapHandle Handle to access the input buffer map + * + * @param[in] dataIndex The index of input data + * + * @param[in] isTF8buff If the input buffer is TF8 + * + * @param[in] isTF8Outputbuff If the output buffer is TF8 + * + * @return The result error message + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_ExecuteInputOutputAsync(Snpe_PSNPE_Handle_t psnpeHandle, + Snpe_StringList_Handle_t inputMapHandle, + size_t dataIndex, + int isTF8buff, + int isTF8Outputbuff); + +/** + * @brief Get the input tensor names for PSNPE object. + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @return The string list of input tensor names + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_PSNPE_GetInputTensorNames(Snpe_PSNPE_Handle_t psnpeHandle); + +/** + * @brief Get the output tensor names for PSNPE object + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @return The string list of output tensor names + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_PSNPE_GetOutputTensorNames(Snpe_PSNPE_Handle_t psnpeHandle); + +/** + * @brief Get the input dimension shape for PSNPE object + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @return The tensor shape of input dimension + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_PSNPE_GetInputDimensions(Snpe_PSNPE_Handle_t psnpeHandle); + +/** + * @brief Get the input dimension shape for the specific input name for PSNPE object + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @param[in] name The name of input data + * + * @return The tensor shape of a specific input name + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_PSNPE_GetInputDimensions_Name(Snpe_PSNPE_Handle_t psnpeHandle, const char* name); + +/** + * @brief Get the number of elements in each dimension for input and output buffer + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @param[in] name The name of input and output buffer + * + * @return Dimension size + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_PSNPE_GetBufferAttributesDims(Snpe_PSNPE_Handle_t psnpeHandle, const char* name); + +/* To be deprecated, please use new api Snpe_PSNPE_RegisterUserMemoryMappedBuffers */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_RegisterIonBuffers(Snpe_PSNPE_Handle_t psnpeHandle, Snpe_UserMemoryMap_Handle_t ionBufferMapHandle); + +/* To be deprecated, please use new api Snpe_PSNPE_DeregisterUserMemoryMappedBuffers */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_DeregisterIonBuffers(Snpe_PSNPE_Handle_t psnpeHandle, Snpe_StringList_Handle_t ionBufferNames); + +/** + * @brief Register Client Memory-Mapped Buffers (Example ION buffers in Android) + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] bufferMapHandle A UserMemoryMap of virtual addresses + * + * @note UserBuffer type passed for registration must match the data type of the tensor in the dlc + * For regular UserBuffers SNPE performs an online data conversion (quantization or + * dequantization etc). This is not possible for memory mapped buffers hence can lead to + * issues during execution or accuracy degradation + * + * @return SNPE_SUCCESS upon successful memory mapped buffer registration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_RegisterUserMemoryMappedBuffers(Snpe_PSNPE_Handle_t psnpeHandle, Snpe_UserMemoryMap_Handle_t bufferMapHandle); + +/** + * @brief Deregister Client Memory-Mapped Buffers (Example ION buffers in Android) + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] bufferNamesHandle A StringList of memory mapped buffer names + * + * @return SNPE_SUCCESS upon successful memory mapped buffer deregistration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_PSNPE_DeregisterUserMemoryMappedBuffers(Snpe_PSNPE_Handle_t psnpeHandle, Snpe_StringList_Handle_t bufferNamesHandle); + +/** + * @brief Get the error message during the failed execution + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @return The error message + */ +SNPE_API +const char* Snpe_PSNPE_GetLastErrorString(Snpe_PSNPE_Handle_t psnpeHandle); + +/** + * @brief Get the handle of IBufferAttributes + * + * @param[in] bcHandle Handle to access the PSNPE object + * + * @param[in] name The name of attribute buffer + * + * @return Handle to access IBufferAttributes + */ +SNPE_API +Snpe_IBufferAttributes_Handle_t Snpe_PSNPE_GetInputOutputBufferAttributes(Snpe_PSNPE_Handle_t psnpeHandle, const char *name); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_PSNPE_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.hpp new file mode 100644 index 00000000..bd3af1ac --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/PSNPE.hpp @@ -0,0 +1,537 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include +#include +#include +#include +#include + + +#include "Wrapper.hpp" + + +#include "DlSystem/DlEnums.hpp" +#include "DlSystem/DlVersion.hpp" +#include "DlSystem/StringList.hpp" +#include "DlSystem/DlOptional.hpp" +#include "DlSystem/IBufferAttributes.hpp" +#include "DlSystem/UserMemoryMap.hpp" + +#include "SNPE/UserBufferList.hpp" +#include "SNPE/ApplicationBufferMap.hpp" +#include "SNPE/RuntimeConfigList.hpp" +#include "DlContainer/IDlContainer.hpp" + +#include "SNPE/RuntimeConfigList.hpp" + + +#include "SNPE/PSNPE.h" + +namespace PSNPE{ + +enum BuildMode { + SERIAL = 0, + PARALLEL = 1 +}; +/** + * @brief Input and output transmission mode + */ +enum InputOutputTransmissionMode { + sync = 0, + outputAsync = 1, + inputOutputAsync = 2 +}; + + +struct OutputAsyncCallbackParam : public Wrapper { +private: + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{NoOpDeleter}; + + + template + using DataIndexReference = WrapperDetail::GenericConstMemberReference + ; + + + template + using ExecuteStatusReference = WrapperDetail::GenericConstMemberReference + >; + + + static std::string ErrMsgGetter(Snpe_DlVersion_Handle_t handle){ + return Snpe_PSNPE_OutputAsyncCallbackParam_GetErrorMsg(handle); + } + template + using ErrorMsgReference = WrapperDetail::GenericConstMemberReference + ; + + template + using CallbackIDReference = WrapperDetail::GenericConstMemberReference + ; + + + + +public: + OutputAsyncCallbackParam() = delete; + OutputAsyncCallbackParam(OutputAsyncCallbackParam&& other) noexcept + : BaseType(std::move(other)) + { } + + DataIndexReference dataIndex{*this}; + ExecuteStatusReference executeStatus{*this}; + ErrorMsgReference errorMsg{*this}; + + CallbackIDReference callbackID{*this}; +}; + + + +struct InputOutputInputAsyncCallbackParam : public Wrapper { +private: + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{NoOpDeleter}; + + + static std::vector GetInputs(HandleType handle){ + DlSystem::StringList inputs(moveHandle(Snpe_PSNPE_InputOutputInputAsyncCallbackParam_GetInputs(handle))); + + return std::vector(inputs.begin(), inputs.end()); + } + + template + using InputsReference = WrapperDetail::GenericConstMemberReference + ; + + + static DlSystem::StringList GetInputNames(HandleType handle){ + return moveHandle(Snpe_PSNPE_InputOutputInputAsyncCallbackParam_GetInputNames(handle)); + } + template + using InputNamesReference = WrapperDetail::GenericConstMemberReference + ; + + template + using CallbackIDReference = WrapperDetail::GenericConstMemberReference + ; + + +public: + InputOutputInputAsyncCallbackParam() = delete; + InputOutputInputAsyncCallbackParam(InputOutputInputAsyncCallbackParam&& other) noexcept + : BaseType(std::move(other)) + { } + + InputsReference> inputs{*this}; + InputNamesReference inputNames{*this}; + CallbackIDReference callbackID{*this}; + +}; + + + + + +struct InputOutputAsyncCallbackParam : public Wrapper { +private: + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{NoOpDeleter}; + + template + using DataIndexReference = WrapperDetail::GenericConstMemberReference + ; + + static bool GetExecuteStatus(HandleType handle){ + return Snpe_PSNPE_InputOutputAsyncCallbackParam_GetExecuteStatus(handle); + } + template + using ExecuteStatusReference = WrapperDetail::GenericConstMemberReference + ; + + static std::string ErrMsgGetter(Snpe_DlVersion_Handle_t handle){ + return Snpe_PSNPE_OutputAsyncCallbackParam_GetErrorMsg(handle); + } + template + using ErrorMsgReference = WrapperDetail::GenericConstMemberReference + ; + + + + // This should work + static ApplicationBufferMap GetOutputMap(HandleType handle){ + return moveHandle(Snpe_PSNPE_InputOutputAsyncCallbackParam_GetOutputMap_Ref(handle), true); + } + + template + using OutputMapReference = WrapperDetail::GenericConstMemberReference + ; + + template + using CallbackIDReference = WrapperDetail::GenericConstMemberReference + ; + +public: + + InputOutputAsyncCallbackParam(InputOutputAsyncCallbackParam&& other) noexcept + : BaseType(std::move(other)) + { } + + DataIndexReference dataIndex{*this}; + OutputMapReference outputMap{*this}; /// OOOH, this will be super tricky to not have a copy every time + ExecuteStatusReference executeStatus{*this}; + ErrorMsgReference errorMsg{*this}; + CallbackIDReference callbackID{*this}; +}; + +/** + * @brief This callback is called when the output data is ready, only use for Output Async mode + */ +using OutputAsyncCallbackFunc = std::function; +/** + * @brief This callback is called when the output data is ready, only use for Output-Input Async mode + */ +using InputOutputAsyncCallbackFunc = std::function; +/** + * @brief This callback is called when the input data is ready,only use for Output-Input Async mode + */ +using InputOutputAsyncInputCallback = std::function(InputOutputInputAsyncCallbackParam)>; + + +struct BuildConfig final { + BuildMode buildMode = BuildMode::SERIAL; ///< Specify build in serial mode or parallel mode + zdl::DlContainer::IDlContainer* container;///< The opened container ptr + zdl::DlSystem::StringList outputBufferNames;///< Specify the output layer name + zdl::DlSystem::StringList outputTensors;///< Specify the output layer name + RuntimeConfigList runtimeConfigList;///< The runtime config list for PSNPE, @see RuntimeConfig + size_t inputThreadNumbers = 1;///< Specify the number of threads used in the execution phase to process input data, only used in inputOutputAsync mode + size_t outputThreadNumbers = 1;///< Specify the number of threads used in the execution phase to process output data, only used in inputOutputAsync and outputAsync mode + OutputAsyncCallbackFunc outputCallback;///< The callback to deal with output data ,only used in outputAsync mode + InputOutputAsyncCallbackFunc inputOutputCallback;///< The callback to deal with output data ,only used in inputOutputAsync mode + InputOutputAsyncInputCallback inputOutputInputCallback;///< The callback to deal with input data ,only used in inputOutputAsync mode + InputOutputTransmissionMode inputOutputTransmissionMode = InputOutputTransmissionMode::sync;///< Specify execution mode + zdl::DlSystem::ProfilingLevel_t profilingLevel = zdl::DlSystem::ProfilingLevel_t::OFF;///< Specify profiling level for Diaglog + uint64_t encode[2] = {0, 0}; + bool enableInitCache = false; + std::string platformOptions; + std::string diaglogOutputDir = "./diaglogs/"; ///< Specify a diaglog output directory to save the generated Diaglog files. + + size_t callbackID{}; +}; + + + + + +class PSNPE : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_PSNPE_Delete}; +// struct BuildConfigInternal : public Wrapper{ +// +// }; +public: + PSNPE() + : BaseType(Snpe_PSNPE_Create()) + { } + +private: + + template + static std::unordered_map& getCallbackMap(){ + static std::unordered_map toret; + return toret; + } + template + static std::mutex& getCallbackMapMutex(){ + static std::mutex mtx; + return mtx; + } + + static void outputCallbackTrampoline(Snpe_PSNPE_OutputAsyncCallbackParam_Handle_t paramHandle){ + OutputAsyncCallbackParam param(moveHandle(paramHandle)); + std::function callback; + { + std::lock_guard lk(getCallbackMapMutex()); + callback = getCallbackMap()[param.callbackID]; + } + callback(std::move(param)); + } + static void inputOutputCallbackTrampoline(Snpe_PSNPE_InputOutputAsyncCallbackParam_Handle_t paramHandle){ + InputOutputAsyncCallbackParam param(moveHandle(paramHandle)); + std::function callback; + { + std::lock_guard lk(getCallbackMapMutex()); + callback = getCallbackMap()[param.callbackID]; + } + callback(std::move(param)); + } + + static Snpe_ApplicationBufferMap_Handle_t inputOutputInputCallbackTrampoline( + Snpe_PSNPE_InputOutputInputAsyncCallbackParam_Handle_t paramHandle + ){ + InputOutputInputAsyncCallbackParam param(moveHandle(paramHandle)); + + std::function(InputOutputInputAsyncCallbackParam)> callback; + { + std::lock_guard lk(getCallbackMapMutex()); + callback = getCallbackMap()[param.callbackID]; + } + auto abm = callback(std::move(param)); + return WrapperDetail::HandleReleaser::release(*abm); + } + + template + class CallbackIdManager{ + public: + ~CallbackIdManager(){ + clear(); + } + std::pair registerCallback(WrapperCallbackType func){ + size_t id = get(); + + std::lock_guard lk(getCallbackMapMutex()); + getCallbackMap()[id] = std::move(func); + return {id, CapiCallback}; + } + private: + size_t m_CallbackId{}; + + void clear(){ + if(m_CallbackId){ + std::lock_guard lk(getCallbackMapMutex()); + getCallbackMap().erase(m_CallbackId); + } + } + + size_t get(){ + static std::atomic id{0}; + clear(); + m_CallbackId = ++id; + return m_CallbackId; + } + + }; + CallbackIdManager outputCallbackIdManager; + + CallbackIdManager inputOutputCallbackIdManager; + + CallbackIdManager inputOutputInputCallbackIdManager; + + +public: + + + + bool build(BuildConfig& buildConfig) noexcept{ + // Copy the BuildConfig across the CAPI boundary + + Snpe_BuildConfig_Handle_t bcHandle = Snpe_BuildConfig_Create(); + + Snpe_BuildConfig_SetBuildMode(bcHandle, static_cast(buildConfig.buildMode)); + Snpe_BuildConfig_SetContainer(bcHandle, getHandle(buildConfig.container)); + Snpe_BuildConfig_SetOutputBufferNames(bcHandle, getHandle(buildConfig.outputBufferNames)); + Snpe_BuildConfig_SetOutputTensors(bcHandle, getHandle(buildConfig.outputTensors)); + Snpe_BuildConfig_SetRuntimeConfigList(bcHandle, getHandle(buildConfig.runtimeConfigList)); + + Snpe_BuildConfig_SetInputThreadNumbers(bcHandle, buildConfig.inputThreadNumbers); + Snpe_BuildConfig_SetOutputThreadNumbers(bcHandle, buildConfig.outputThreadNumbers); + + + if(buildConfig.outputCallback){ + auto id_callback = outputCallbackIdManager.registerCallback(buildConfig.outputCallback); + Snpe_BuildConfig_SetOutputCallbackID(bcHandle, id_callback.first); + Snpe_BuildConfig_SetOutputCallback(bcHandle, id_callback.second); + } + + if(buildConfig.inputOutputCallback){ + auto id_callback = inputOutputCallbackIdManager.registerCallback(buildConfig.inputOutputCallback); + Snpe_BuildConfig_SetInputOutputCallbackID(bcHandle, id_callback.first); + Snpe_BuildConfig_SetInputOutputCallback(bcHandle, id_callback.second); + } + + if(buildConfig.inputOutputInputCallback){ + auto id_callback = inputOutputInputCallbackIdManager.registerCallback(buildConfig.inputOutputInputCallback); + Snpe_BuildConfig_SetInputOutputInputCallbackID(bcHandle, id_callback.first); + Snpe_BuildConfig_SetInputOutputInputCallback(bcHandle, id_callback.second); + } + + + Snpe_BuildConfig_SetInputOutputTransmissionMode(bcHandle, + static_cast(buildConfig.inputOutputTransmissionMode)); + + Snpe_BuildConfig_SetProfilingLevel(bcHandle, static_cast(buildConfig.profilingLevel)); + Snpe_BuildConfig_SetEncode(bcHandle, buildConfig.encode[0], buildConfig.encode[1]); + Snpe_BuildConfig_SetEnableInitCache(bcHandle, buildConfig.enableInitCache); + Snpe_BuildConfig_SetPlatformOptions(bcHandle, buildConfig.platformOptions.c_str()); + Snpe_BuildConfig_SetDiaglogOutputDir(bcHandle, buildConfig.diaglogOutputDir.c_str()); + + + auto status = Snpe_PSNPE_Build(handle(), bcHandle); + Snpe_BuildConfig_Delete(bcHandle); + + + return status == SNPE_SUCCESS; + } + + /** + * @brief Execute snpe instances in Async Output mode and Sync mode + * + * @param[in] inputBufferList A list of user buffers that contains the input data + * + * @param[in,out] outputBufferList A list of user buffers that will hold the output data + * + */ + bool execute(UserBufferList& inputBufferList, UserBufferList& outputBufferList) noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_Execute(handle(), getHandle(inputBufferList), getHandle(outputBufferList)); + } + + /** + * @brief Execute snpe instances in Async Input/Output mode + * + * @param[in]inputMap A map of input buffers that contains input data. The names of buffers + * need to be matched with names retrived through getInputTensorNames() + * + * @param dataIndex Index of the input data + * + * @param isTF8buff Whether prefer to using 8 bit quantized element for inference + * + * @return True if executed successfully; flase, otherwise. + */ + bool executeInputOutputAsync(const DlSystem::StringList& inputMap, size_t dataIndex, bool isTF8buff, bool isTF8Outputbuff) noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_ExecuteInputOutputAsync(handle(), getHandle(inputMap), dataIndex, isTF8buff, isTF8Outputbuff); + } + bool executeInputOutputAsync(const std::vector& inputMap, size_t dataIndex, bool isTF8buff, bool isTF8Outputbuff) noexcept{ + DlSystem::StringList sl(inputMap.size()); + for(auto&& e : inputMap) sl.append(e.c_str()); + return executeInputOutputAsync(sl, dataIndex, isTF8buff, isTF8Outputbuff); + } + + bool executeInputOutputAsync(const DlSystem::StringList& inputMap, size_t dataIndex, bool isTF8buff) noexcept{ + return executeInputOutputAsync(inputMap, dataIndex, isTF8buff, isTF8buff); + } + bool executeInputOutputAsync(const std::vector& inputMap, size_t dataIndex, bool isTF8buff) noexcept{ + return executeInputOutputAsync(inputMap, dataIndex, isTF8buff, isTF8buff); + } + + + + /** + * @brief Returns the input layer names of the network. + * + * @return StringList which contains the input layer names + */ + const DlSystem::StringList getInputTensorNames() const noexcept{ + return moveHandle(Snpe_PSNPE_GetInputTensorNames(handle())); + } + + /** + * @brief Returns the output layer names of the network. + * + * @return StringList which contains the output layer names + */ + const DlSystem::StringList getOutputTensorNames() const noexcept{ + return moveHandle(Snpe_PSNPE_GetOutputTensorNames(handle())); + } + + /** + * @brief Returns the input tensor dimensions of the network. + * + * @return TensorShape which contains the dimensions. + */ + const DlSystem::TensorShape getInputDimensions() const noexcept{ + return moveHandle(Snpe_PSNPE_GetInputDimensions(handle())); + } + + const zdl::DlSystem::TensorShape getInputDimensions(const char *name) const noexcept{ + return moveHandle(Snpe_PSNPE_GetInputDimensions_Name(handle(), name)); + } + + /** + * @brief Returns attributes of buffers. + * + * @see zdl::SNPE + * + * @return BufferAttributes of input/output tensor named. + */ + zdl::DlSystem::TensorShape getBufferAttributesDims(const char *name) const noexcept{ + return moveHandle(Snpe_PSNPE_GetBufferAttributesDims(handle(), name)); + } + + DlSystem::Optional getInputOutputBufferAttributes(const char *name) const noexcept{ + return { + new DlSystem::IBufferAttributes(moveHandle(Snpe_PSNPE_GetInputOutputBufferAttributes(handle(), name))), + DlSystem::Optional::LIFECYCLE::POINTER_OWNED + }; + } + /* To be deprecated, please use new api registerMemoryMappedBuffers */ + bool registerIonBuffers(const DlSystem::UserMemoryMap& ionBufferMap) const noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_RegisterIonBuffers(handle(), getHandle(ionBufferMap)); + } + /* To be deprecated, please use new api deregisterMemoryMappedBuffers */ + bool deregisterIonBuffers(const DlSystem::StringList& ionBufferNames) const noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_DeregisterIonBuffers(handle(), getHandle(ionBufferNames)); + } + + bool registerMemoryMappedBuffers(const DlSystem::UserMemoryMap& memoryMappedBufferMap) noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_RegisterUserMemoryMappedBuffers(handle(), getHandle(memoryMappedBufferMap)); + } + + bool deregisterMemoryMappedBuffers(const DlSystem::StringList& bufferNames) noexcept{ + return SNPE_SUCCESS == Snpe_PSNPE_DeregisterUserMemoryMappedBuffers(handle(), getHandle(bufferNames)); + } + + const char* getLastErrorString(){ + return Snpe_PSNPE_GetLastErrorString(handle()); + } + +private: + PSNPE(const PSNPE&) = delete; + PSNPE& operator=(const PSNPE&) = delete; + +}; + +} // ns PSNPE + + + +ALIAS_IN_ZDL_NAMESPACE(PSNPE, BuildMode) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, InputOutputTransmissionMode) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, OutputAsyncCallbackParam) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, InputOutputAsyncCallbackParam) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, InputOutputInputAsyncCallbackParam) + +ALIAS_IN_ZDL_NAMESPACE(PSNPE, OutputAsyncCallbackFunc) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, InputOutputAsyncCallbackFunc) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, InputOutputAsyncInputCallback) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, BuildConfig) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, PSNPE) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.h new file mode 100644 index 00000000..59295d59 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.h @@ -0,0 +1,118 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef _SNPE_RUNTIME_CONFIG_LIST_H_ +#define _SNPE_RUNTIME_CONFIG_LIST_H_ + + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" + +#include "DlSystem/DlEnums.h" +#include "DlSystem/RuntimeList.h" +#include "DlSystem/TensorShapeMap.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* Snpe_RuntimeConfig_Handle_t; + +SNPE_API +Snpe_RuntimeConfig_Handle_t Snpe_RuntimeConfig_Create(); + +SNPE_API +Snpe_RuntimeConfig_Handle_t Snpe_RuntimeConfig_CreateCopy(Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_Delete(Snpe_RuntimeConfig_Handle_t rcHandle); + + +SNPE_API +Snpe_Runtime_t Snpe_RuntimeConfig_GetRuntime(Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_SetRuntime(Snpe_RuntimeConfig_Handle_t rcHandle, Snpe_Runtime_t runtime); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_SetRuntimeList(Snpe_RuntimeConfig_Handle_t rcHandle, Snpe_RuntimeList_Handle_t rlHandle); + +SNPE_API +Snpe_RuntimeList_Handle_t Snpe_RuntimeConfig_GetRuntimeList_Ref(Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_PerformanceProfile_t Snpe_RuntimeConfig_GetPerformanceProfile(Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_SetPerformanceProfile(Snpe_RuntimeConfig_Handle_t rcHandle, Snpe_PerformanceProfile_t perfProfile); + +SNPE_API +int Snpe_RuntimeConfig_GetEnableCPUFallback(Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_SetEnableCPUFallback(Snpe_RuntimeConfig_Handle_t rcHandle, int enableCpuFallback); + + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfig_SetInputDimensionsMap(Snpe_RuntimeConfig_Handle_t rcHandle, Snpe_TensorShapeMap_Handle_t tsmHandle); + +SNPE_API +Snpe_TensorShapeMap_Handle_t Snpe_RuntimeConfig_GetInputDimensionsMap_Ref(Snpe_RuntimeConfig_Handle_t rcHandle); + + + +typedef void* Snpe_RuntimeConfigList_Handle_t; + +SNPE_API +Snpe_RuntimeConfigList_Handle_t Snpe_RuntimeConfigList_Create(); + +SNPE_API +Snpe_RuntimeConfigList_Handle_t Snpe_RuntimeConfigList_CreateSize(size_t size); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfigList_Delete(Snpe_RuntimeConfigList_Handle_t rclHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfigList_PushBack(Snpe_RuntimeConfigList_Handle_t rclHandle, Snpe_RuntimeConfig_Handle_t rcHandle); + +SNPE_API +Snpe_RuntimeConfig_Handle_t Snpe_RuntimeConfigList_At_Ref(Snpe_RuntimeConfigList_Handle_t rclHandle, size_t idx); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfigList_Assign(Snpe_RuntimeConfigList_Handle_t rclSrcHandle, Snpe_RuntimeConfigList_Handle_t rclDstHandle); + +SNPE_API +size_t Snpe_RuntimeConfigList_Size(Snpe_RuntimeConfigList_Handle_t rclHandle); + +SNPE_API +size_t Snpe_RuntimeConfigList_Capacity(Snpe_RuntimeConfigList_Handle_t rclHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_RuntimeConfigList_Clear(Snpe_RuntimeConfigList_Handle_t rclHandle); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_RUNTIME_CONFIG_LIST_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.hpp new file mode 100644 index 00000000..faf052c5 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/RuntimeConfigList.hpp @@ -0,0 +1,153 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + + +#include "DlSystem/DlEnums.hpp" +#include "DlSystem/RuntimeList.hpp" +#include "DlSystem/TensorShapeMap.hpp" + + +#include "SNPE/RuntimeConfigList.h" + +namespace PSNPE { + + + +struct RuntimeConfig : public Wrapper { +private: + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_RuntimeConfig_Delete}; + + template + using RuntimeReference = WrapperDetail::GenericMemberReference + , + CastingSetter >; + + + template + using RuntimeListReference = WrapperMemberReference< + RuntimeListType, + Snpe_RuntimeList_Handle_t, + Snpe_RuntimeConfig_GetRuntimeList_Ref, + Snpe_RuntimeConfig_SetRuntimeList + >; + + template + using InputDimensionsMapReference = WrapperMemberReference< + InputDimensionsMapType, + Snpe_TensorShapeMap_Handle_t, + Snpe_RuntimeConfig_GetInputDimensionsMap_Ref, + Snpe_RuntimeConfig_SetInputDimensionsMap + >; + + template + using PerfProfileReference = WrapperDetail::GenericMemberReference + , + CastingSetter >; + + template + using EnableCPUFallbackReference = WrapperDetail::GenericMemberReference + , + CastingSetter >; + +public: + RuntimeConfig() + : BaseType(Snpe_RuntimeConfig_Create()) + { } + RuntimeConfig(const RuntimeConfig& other) + : BaseType(Snpe_RuntimeConfig_CreateCopy(other.handle())) + { } + + RuntimeConfig(RuntimeConfig&& other) noexcept + : BaseType(std::move(other)) + { } + + RuntimeConfig& operator=(RuntimeConfig&& other) noexcept{ + return moveAssign(std::move(other)); + } + + + RuntimeReference runtime{*this, DlSystem::Runtime_t::CPU_FLOAT32}; + RuntimeListReference runtimeList{*this}; + PerfProfileReference perfProfile{*this, DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE}; + InputDimensionsMapReference inputDimensionsMap{*this}; + EnableCPUFallbackReference enableCPUFallback{*this, false}; + +}; + + +class RuntimeConfigList : public Wrapper { +private: + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_RuntimeConfigList_Delete}; + +public: + RuntimeConfigList() + : BaseType(Snpe_RuntimeConfigList_Create()) + { } + RuntimeConfigList(size_t size) + : BaseType(Snpe_RuntimeConfigList_CreateSize(size)) + { } + + RuntimeConfigList(RuntimeConfigList&& other) noexcept + : BaseType(std::move(other)) + { } + + RuntimeConfigList& operator=(RuntimeConfigList&& other) noexcept{ + return moveAssign(std::move(other)); + } + RuntimeConfigList& operator=(const RuntimeConfigList& other){ + Snpe_RuntimeConfigList_Assign(other.handle(), handle()); + return *this; + } + + + + void push_back(const RuntimeConfig& runtimeConfig){ + Snpe_RuntimeConfigList_PushBack(handle(), getHandle(runtimeConfig)); + } + + RuntimeConfig& operator[](size_t index){ + return *makeReference(Snpe_RuntimeConfigList_At_Ref(handle(), index)); + } + const RuntimeConfig& operator[](size_t index) const{ + return *makeReference(Snpe_RuntimeConfigList_At_Ref(handle(), index)); + } + + size_t size() const noexcept{ + return Snpe_RuntimeConfigList_Size(handle()); + } + size_t capacity() const noexcept{ + return Snpe_RuntimeConfigList_Capacity(handle()); + } + + void clear() noexcept{ + Snpe_RuntimeConfigList_Clear(handle()); + } + +}; + +} // ns PSNPE + + +ALIAS_IN_ZDL_NAMESPACE(PSNPE, RuntimeConfig) +ALIAS_IN_ZDL_NAMESPACE(PSNPE, RuntimeConfigList) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.h new file mode 100644 index 00000000..eb05473a --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.h @@ -0,0 +1,336 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + */ + +#ifndef _SNPE_SNPE_H_ +#define _SNPE_SNPE_H_ + + +#include "DlSystem/IBufferAttributes.h" +#include "DlSystem/ITensor.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/TensorMap.h" +#include "DlSystem/StringList.h" +#include "DlSystem/IUserBuffer.h" +#include "DlSystem/UserBufferMap.h" +#include "DlSystem/UserMemoryMap.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" + +#include "DiagLog/IDiagLog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A typedef to indicate a SNPE handle + */ +typedef void* Snpe_SNPE_Handle_t; + +/** + * Destroys/frees a SNPE object + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_Delete(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Gets the names of input tensors to the network + * + * To support multiple input scenarios, where multiple tensors are + * passed through execute() in a TensorMap, each tensor needs to + * be uniquely named. The names of tensors can be retrieved + * through this function. + * + * In the case of a single input, one name will be returned. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @return A StringList of input tensor names. + * + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_SNPE_GetInputTensorNames(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Gets the names of output tensors to the network + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @return List of output tensor names. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_SNPE_GetOutputTensorNames(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Gets the names of output tensor from the input layer name + * + * @param[in] snpeHandle Handle to access the SNPE object + * @param[in] name Layer name + * + * @return Output tensor names. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_SNPE_GetOutputTensorNamesByLayerName(Snpe_SNPE_Handle_t snpeHandle, const char* name); + + +/** + * @brief Processes the input data and returns the output + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] inputHandle A map of tensors that contains the input data for + * each input. The names of tensors needs to be + * matched with names retrieved through + * getInputTensorNames() + * + * @param[in,out] outputHandle An empty map of tensors that will contain the output + * data of potentially multiple layers (the key + * in the map is the layer name) upon return + * + * @note output TensorMap has to be empty. To forward propagate + * and get results in user-supplied tensors, use + * Snpe_SNPE_ExecuteUserBuffers(). + * + * @return SNPE_SUCCESS upon successful execution + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_ExecuteITensors(Snpe_SNPE_Handle_t snpeHandle, Snpe_TensorMap_Handle_t inputHandle, Snpe_TensorMap_Handle_t outputHandle); + +/** + * @brief Processes the input data and returns the output + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] inputHandle A single tensor contains the input data. + * + * @param[in,out] outputHandle An empty map of tensors that will contain the output + * data of potentially multiple layers (the key + * in the map is the layer name) upon return + * + * @note output TensorMap has to be empty. To forward propagate + * and get results in user-supplied tensors, use + * Snpe_SNPE_ExecuteUserBuffers. + * + * @return SNPE_SUCCESS upon successful execution + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_ExecuteITensor(Snpe_SNPE_Handle_t snpeHandle, Snpe_ITensor_Handle_t inputHandle, Snpe_TensorMap_Handle_t outputHandle); + +/** + * @brief Processes the input data and returns the output, using + * user-supplied buffers + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] inputHandle A map of UserBuffers that contains the input data for + * each input. The names of UserBuffers needs to be + * matched with names retrieved through + * getInputTensorNames() + * + * @param[in,out] outputHandle A map of UserBuffers that will hold the output + * data of potentially multiple layers (the key + * in the map is the UserBuffer name) + * + * @note input and output UserBuffer maps must be fully pre-populated. with + * dimensions matching what the network expects. + * For example, if there are 5 output UserBuffers they all have to be + * present in map. + * + * Caller must guarantee that for the duration of execute(), the buffer + * stored in UserBuffer would remain valid. For more detail on buffer + * ownership and lifetime requirements, please refer to zdl::DlSystem::UserBuffer + * documentation. + * + * @return SNPE_SUCCESS upon successful execution + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_ExecuteUserBuffers(Snpe_SNPE_Handle_t snpeHandle, Snpe_UserBufferMap_Handle_t inputHandle, Snpe_UserBufferMap_Handle_t outputHandle); + + +/** + * @brief Register Client ION Buffers + * + * @note To be deprecated, please use new api Snpe_SNPE_RegisterUserMemoryMappedBuffers + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] ionBufferMapHandle A UserMemoryMap of virtual addresses + * + * @return SNPE_SUCCESS upon successful ION Buffer registration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_RegisterIonBuffers(Snpe_SNPE_Handle_t snpeHandle, Snpe_UserMemoryMap_Handle_t ionBufferMapHandle); + +/** + * @brief Deregister Client ION Buffers + * + * @note To be deprecated, please use new api Snpe_SNPE_DeregisterUserMemoryMappedBuffers + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] ionBufferNamesHandle A StringList of ION Buffer names + * + * @return SNPE_SUCCESS upon successful ION Buffer deregistration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_DeregisterIonBuffers(Snpe_SNPE_Handle_t snpeHandle, Snpe_StringList_Handle_t ionBufferNamesHandle); + +/** + * @brief Register Client Memory-Mapped Buffers (Example ION buffers in Android) + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] bufferMapHandle A UserMemoryMap of virtual addresses + * + * @note UserBuffer type passed for registration must match the data type of the tensor in the dlc + * For regular UserBuffers SNPE performs an online data conversion (quantization or + * dequantization etc). This is not possible for memory mapped buffers hence can lead to + * issues during execution or accuracy degradation + * + * @return SNPE_SUCCESS upon successful memory mapped buffer registration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_RegisterUserMemoryMappedBuffers(Snpe_SNPE_Handle_t snpeHandle, Snpe_UserMemoryMap_Handle_t bufferMapHandle); + +/** + * @brief Deregister Client Memory-Mapped Buffers (Example ION buffers in Android) + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] bufferNamesHandle A StringList of memory mapped buffer names + * + * @return SNPE_SUCCESS upon successful memory mapped buffer deregistration + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPE_DeregisterUserMemoryMappedBuffers(Snpe_SNPE_Handle_t snpeHandle, Snpe_StringList_Handle_t bufferNamesHandle); + +/** + * @brief Returns the version string embedded at model conversion + * time. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @return Model version string, which is a free-form string + * supplied at the time of the conversion + * + */ +SNPE_API +const char* Snpe_SNPE_GetModelVersion(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Returns the dimensions of the input data to the model in the + * form of TensorShape. The dimensions in TensorShape corresponds to + * what the tensor dimensions would need to be for an input tensor to + * the model. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] name input name. + * + * @note Note that this function only makes sense for networks + * that have a fixed input size. For networks in which the + * input size varies with each call of Execute(), this + * function should not be used. + * + * @return a TensorShape that maintains dimensions, + * matching the tensor dimensions for input to the model, + * where the last entry is the fastest varying dimension, etc. + * + * @see Snpe_ITensor_Handle_t + * @see Snpe_TensorShape_Handle_t + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_SNPE_GetInputDimensions(Snpe_SNPE_Handle_t snpeHandle, const char* name); + +/** + * @brief Returns the dimensions of the first input's data to the model in the + * form of TensorShape. The dimensions in TensorShape corresponds to + * what the tensor dimensions would need to be for an input tensor to + * the model. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @note Note that this function only makes sense for networks + * that have a fixed input size. For networks in which the + * input size varies with each call of Execute(), this + * function should not be used. + * + * @return a TensorShape that maintains dimensions, + * matching the tensor dimensions for first input to the model, + * where the last entry is the fastest varying dimension, etc. + * + * @see Snpe_ITensor_Handle_t + * @see Snpe_TensorShape_Handle_t + */ +SNPE_API +Snpe_TensorShape_Handle_t Snpe_SNPE_GetInputDimensionsOfFirstTensor(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Gets the output layer(s) for the network. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @note The output layers returned by this function may be + * different than those specified when the network was created + * via the @ref CAPI_SNPEBuilder "SNPEBuilder". For example, if the + * network was created in debug mode with no explicit output + * layers specified, this will contain all layers. + * + * + * @return A StringList of output layer names. + */ +SNPE_API +Snpe_StringList_Handle_t Snpe_SNPE_GetOutputLayerNames(Snpe_SNPE_Handle_t snpeHandle); + +/** + * @brief Returns attributes of buffers used to feed input tensors and receive result from output tensors. + * + * @param[in] snpeHandle Handle to access the SNPE object + * + * @param[in] name Tensor name. + * + * @return BufferAttributes of input/output tensor named + */ +SNPE_API +Snpe_IBufferAttributes_Handle_t Snpe_SNPE_GetInputOutputBufferAttributes(Snpe_SNPE_Handle_t snpeHandle, const char *name); + +/** + * @brief . + * + * Get the diagnostic logging interface + * + * @param[in] snpeHandle Handle to access the SNPE object + * + */ +SNPE_API +Snpe_IDiagLog_Handle_t Snpe_SNPE_GetDiagLogInterface_Ref(Snpe_SNPE_Handle_t snpeHandle); + + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.hpp new file mode 100644 index 00000000..d4ad18df --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPE.hpp @@ -0,0 +1,125 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "DlSystem/StringList.hpp" +#include "DlSystem/TensorMap.hpp" +#include "DlSystem/UserBufferMap.hpp" +#include "DlSystem/UserMemoryMap.hpp" +#include "DlSystem/IBufferAttributes.hpp" +#include "DiagLog/IDiagLog.hpp" + +#include "DlSystem/DlOptional.hpp" + + +#include "SNPE/SNPE.h" + +namespace SNPE{ + +class SNPE : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_SNPE_Delete}; + + template + static DlSystem::Optional makeOptional(H handle){ + return DlSystem::Optional(T(moveHandle(handle))); + } +public: + + DlSystem::Optional getInputTensorNames() const noexcept{ + return makeOptional(Snpe_SNPE_GetInputTensorNames(handle())); + } + + DlSystem::Optional getOutputTensorNames() const noexcept{ + return makeOptional(Snpe_SNPE_GetOutputTensorNames(handle())); + } + + DlSystem::StringList getOutputTensorNamesByLayerName(const char *name) const noexcept{ + return moveHandle(Snpe_SNPE_GetOutputTensorNamesByLayerName(handle(), name)); + } + + bool execute(const DlSystem::TensorMap& input, DlSystem::TensorMap& output) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_ExecuteITensors(handle(), getHandle(input), getHandle(output)); + } + + + bool execute(const DlSystem::ITensor* input, DlSystem::TensorMap& output) noexcept{ + if(!input) return false; + return SNPE_SUCCESS == Snpe_SNPE_ExecuteITensor(handle(), getHandle(*input), getHandle(output)); + } + + bool execute(const DlSystem::UserBufferMap& input, const DlSystem::UserBufferMap& output) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_ExecuteUserBuffers(handle(), getHandle(input), getHandle(output)); + } + + + /* To be deprecated, please use new api registerMemoryMappedBuffers */ + bool registerIonBuffers(const DlSystem::UserMemoryMap& ionBufferMap) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_RegisterUserMemoryMappedBuffers(handle(), getHandle(ionBufferMap)); + } + + /* To be deprecated, please use new api deregisterMemoryMappedBuffers */ + bool deregisterIonBuffers(const DlSystem::StringList& ionBufferNames) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_DeregisterUserMemoryMappedBuffers(handle(), getHandle(ionBufferNames)); + } + + bool registerMemoryMappedBuffers(const DlSystem::UserMemoryMap& memoryMappedBufferMap) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_RegisterUserMemoryMappedBuffers(handle(), getHandle(memoryMappedBufferMap)); + } + + bool deregisterMemoryMappedBuffers(const DlSystem::StringList& bufferNames) noexcept{ + return SNPE_SUCCESS == Snpe_SNPE_DeregisterUserMemoryMappedBuffers(handle(), getHandle(bufferNames)); + } + + std::string getModelVersion() const{ + auto str = Snpe_SNPE_GetModelVersion(handle()); + return str ? str : ""; + } + + DlSystem::Optional getInputDimensions() const noexcept{ + return makeOptional(Snpe_SNPE_GetInputDimensionsOfFirstTensor(handle())); + } + + DlSystem::Optional getInputDimensions(const char* name) const noexcept{ + return makeOptional(Snpe_SNPE_GetInputDimensions(handle(), name)); + } + + DlSystem::Optional getOutputLayerNames() const noexcept{ + return makeOptional(Snpe_SNPE_GetOutputLayerNames(handle())); + } + + + DlSystem::Optional getInputOutputBufferAttributes(const char* name) const noexcept{ + return DlSystem::Optional( + new DlSystem::IBufferAttributes(moveHandle(Snpe_SNPE_GetInputOutputBufferAttributes(handle(), name))), + DlSystem::Optional::LIFECYCLE::POINTER_OWNED + ); + } + + DlSystem::Optional getDiagLogInterface() noexcept{ + auto diagLogHandle = Snpe_SNPE_GetDiagLogInterface_Ref(handle()); + if(!diagLogHandle) return {}; + // Bind lifespan of this reference to this object + auto toret = makeReference(diagLogHandle); + return {toret, DlSystem::Optional::LIFECYCLE::POINTER_NOT_OWNED}; + } + +private: + SNPE(const SNPE&) = delete; + SNPE& operator=(const SNPE&) = delete; + +}; + +} // ns SNPE + +ALIAS_IN_ZDL_NAMESPACE(SNPE, SNPE) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.h new file mode 100644 index 00000000..6adcebad --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.h @@ -0,0 +1,334 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _SNPE_BUILDER_H_ +#define _SNPE_BUILDER_H_ + +#include "SNPE/SNPE.h" +#include "DlSystem/DlEnums.h" +#include "DlSystem/DlError.h" +#include "DlSystem/IOBufferDataTypeMap.h" +#include "DlSystem/TensorShapeMap.h" +#include "DlSystem/RuntimeList.h" +#include "DlSystem/PlatformConfig.h" +#include "DlContainer/DlContainer.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * A typedef to indicate a SNPEBuilder handle + */ +typedef void* Snpe_SNPEBuilder_Handle_t; + +/** + * The builder class for creating SNPE objects. + * Not meant to be extended. + */ + + +/** + * @brief Constructor of NeuralNetwork Builder ith a supplied model. + * + * @param[in] containerHandle A DlContainer holding the model. + * + * @return A new instance of a SNPEBuilder object + * that can be used to configure and build + * an instance of SNPE. + * + */ +SNPE_API +Snpe_SNPEBuilder_Handle_t Snpe_SNPEBuilder_Create(Snpe_DlContainer_Handle_t containerHandle); + +/** + * Destroys/frees a SNPEBuilder object + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @return SNPE_SUCCESS if Delete operation successful. + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_Delete(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle); + +/** + * @brief Requests a performance profile. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] performanceProfile The target performance profile. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetPerformanceProfile(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_PerformanceProfile_t performanceProfile); + +/** + * @brief Sets the profiling level. Default profiling level for + * SNPEBuilder is off. Off and basic only applies to DSP runtime. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] profilingLevel The target profiling level. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetProfilingLevel(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_ProfilingLevel_t profilingLevel); + +/** + * @brief Sets a preference for execution priority. + * + * This allows the caller to give coarse hint to SNPE runtime + * about the priority of the network. SNPE runtime is free to use + * this information to co-ordinate between different workloads + * that may or may not extend beyond SNPE. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] priority The target performance profile. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetExecutionPriorityHint(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_ExecutionPriorityHint_t priority); + +/** + * @brief Sets the layers that will generate output. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] outputLayerNames List of layer names to + * output. An empty list will + * result in only the final + * layer of the model being + * the output layer. The list + * will be copied. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetOutputLayers(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_StringList_Handle_t outputLayerNames); + +/** + * @brief Sets the output tensor names. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] outputTensorNames List of tensor names to + * output. An empty list will + * result in producing output for the final + * output tensor of the model. + * The list will be copied. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetOutputTensors(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_StringList_Handle_t outputTensorNames); + +/** + * @brief Sets whether this neural network will perform inference with + * input from user-supplied buffers, and write output to user-supplied + * buffers. Default behaviour is to use tensors created by + * ITensorFactory. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] bufferMode Boolean whether to use user-supplied buffer or not. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetUseUserSuppliedBuffers(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, int bufferMode); + +/** + * @brief Sets the debug mode of the runtime. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] debugMode This enables debug mode for the runtime. It + * does two things. For an empty + * outputLayerNames list, all layers will be + * output. It might also disable some internal + * runtime optimizations (e.g., some networks + * might be optimized by combining layers, + * etc.). + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetDebugMode(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, int debugMode); + + + +/** + * @brief Sets network's input dimensions to enable resizing of + * the spatial dimensions of each layer for fully convolutional networks, + * and the batch dimension for all networks. + * + * @param[in] tensorShapeMapHandle : Handle to the map of input names and their new dimensions. + * The new dimensions overwrite the input dimensions + * embedded in the model and then resize each layer + * of the model. If the model contains + * layers whose dimensions cannot be resized e.g FullyConnected, + * exception will be thrown when SNPE instance is actually built. + * In general the batch dimension is always resizable. + * After resizing of layers' dimensions in model based + * on new input dimensions, the new model is revalidated + * against all runtime constraints, whose failures may + * result in cpu fallback situation. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetInputDimensions(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_TensorShapeMap_Handle_t inputDimensionsMapHandle); + +/** + * @brief Sets the mode of init caching functionality. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] mode Boolean. This flag enables/disables the functionality of init caching. + * When init caching functionality is enabled, a set of init caches + * will be created during network building/initialization process + * and will be added to DLC container. If such DLC container is saved + * by the user, in subsequent network building/initialization processes + * these init caches will be loaded from the DLC so as to reduce initialization time. + * In disable mode, no init caches will be added to DLC container. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetInitCacheMode(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, int cacheMode); + +/** + * @brief Returns an instance of SNPE based on the current parameters. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @return A new instance of a @ref CAPI_SNPE "SNPE" object that can be used + * to execute models or null if any errors occur. + */ +SNPE_API +Snpe_SNPE_Handle_t Snpe_SNPEBuilder_Build(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle); + +/** + * @brief Sets the platform configuration. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] platformConfig The platform configuration. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetPlatformConfig(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_PlatformConfig_Handle_t platformConfigHandle); + +/** + * @brief Sets network's runtime order of precedence. Example: + * CPU_FLOAT32, GPU_FLOAT16, AIP_FIXED8_TF + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] runtimeListHandle The list of runtime in order of precedence + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetRuntimeProcessorOrder(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_RuntimeList_Handle_t runtimeListHandle); + +/** + * @brief Sets the unconsumed tensors as output + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] setOutput Boolean. This enables unconsumed tensors (i.e) + * outputs which are not inputs to any + * layer (basically dead ends) to be marked + * for output + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetUnconsumedTensorsAsOutputs(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, int setOutput); + +/** + * @brief Execution terminated when exceeding time limit. + * Only valid for dsp runtime currently. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] timeout Time limit value in microseconds + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetTimeOut(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, uint64_t timeoutMicroSec); + + +/** + * @brief Sets the datatype of the buffer. + * Only valid for dsp runtime currently. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] dataTypeMapHandle Map of the buffer names and the datatype that needs to be set. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetBufferDataType(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, Snpe_IOBufferDataTypeMap_Handle_t dataTypeMapHandle); + +/** + * @brief Sets up the entire initialization callflow to + * happen on the user's thread + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] singleThreadedInit Flag indicating user's intent to perform initialization callflow + * on caller's thread. + * When set to 1, initialization will happen on the user's thread + * When set to 0, initialization will happen on a new thread. This is the default + * behavior (analogous to not calling this API) +*/ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetSingleThreadedInit(Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, int singleThreadedInit); + +/** + * @brief Sets the fixed point execution mode for CPU runtime. + * If a floating point DLC is executed with this option set, the program will be terminated with an exception. + * If a quantized DLC is executed without this option set, the execution will be in floating point mode in CPU. + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] cpuFxpMode Boolean If set to true, enables the fixed point mode. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetCpuFixedPointMode( + Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, bool cpuFxpMode); + +/** + * @brief Sets model name for logging + * + * @param[in] snpeBuilderHandle Handle to access the SNPEBuilder object + * + * @param[in] modelName String Model name for logging. + * + */ +SNPE_API +Snpe_ErrorCode_t Snpe_SNPEBuilder_SetModelName( + Snpe_SNPEBuilder_Handle_t snpeBuilderHandle, const char *modelName); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_BUILDER_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.hpp new file mode 100644 index 00000000..37995f4e --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEBuilder.hpp @@ -0,0 +1,136 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include + + +#include "Wrapper.hpp" +#include "SNPE.hpp" +#include "DlSystem/RuntimeList.hpp" +#include "DlContainer/IDlContainer.hpp" +#include "DlSystem/PlatformConfig.hpp" +#include "DlSystem/TensorShapeMap.hpp" + +#include "DlSystem/DlEnums.hpp" + +#include "DlSystem/IOBufferDataTypeMap.hpp" + +#include "SNPE/SNPEBuilder.h" + + +namespace SNPE { + +class SNPEBuilder : public Wrapper { + friend BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_SNPEBuilder_Delete}; +public: + + explicit SNPEBuilder(DlContainer::IDlContainer *container) + : BaseType(Snpe_SNPEBuilder_Create(getHandle(container))) + { } + + + SNPEBuilder& setPerformanceProfile(DlSystem::PerformanceProfile_t performanceProfile){ + Snpe_SNPEBuilder_SetPerformanceProfile(handle(), static_cast(performanceProfile)); + return *this; + } + + SNPEBuilder& setProfilingLevel(DlSystem::ProfilingLevel_t profilingLevel){ + Snpe_SNPEBuilder_SetProfilingLevel(handle(), static_cast(profilingLevel)); + return *this; + } + + SNPEBuilder& setExecutionPriorityHint(DlSystem::ExecutionPriorityHint_t priority){ + Snpe_SNPEBuilder_SetExecutionPriorityHint(handle(), static_cast(priority)); + return *this; + } + + SNPEBuilder& setOutputLayers(const DlSystem::StringList& outputLayerNames){ + Snpe_SNPEBuilder_SetOutputLayers(handle(), getHandle(outputLayerNames)); + return *this; + } + + SNPEBuilder& setOutputTensors(const DlSystem::StringList& outputTensorNames){ + Snpe_SNPEBuilder_SetOutputTensors(handle(), getHandle(outputTensorNames)); + return *this; + } + + SNPEBuilder& setUseUserSuppliedBuffers(int bufferMode){ + Snpe_SNPEBuilder_SetUseUserSuppliedBuffers(handle(), bufferMode); + return *this; + } + + SNPEBuilder& setDebugMode(int debugMode){ + Snpe_SNPEBuilder_SetDebugMode(handle(), debugMode); + return *this; + } + + SNPEBuilder& setInputDimensions(const DlSystem::TensorShapeMap& inputDimensionsMap){ + Snpe_SNPEBuilder_SetInputDimensions(handle(), getHandle(inputDimensionsMap)); + return *this; + } + + SNPEBuilder& setInitCacheMode(int cacheMode){ + Snpe_SNPEBuilder_SetInitCacheMode(handle(), cacheMode); + return *this; + } + + SNPEBuilder& setPlatformConfig(const DlSystem::PlatformConfig& platformConfigHandle){ + Snpe_SNPEBuilder_SetPlatformConfig(handle(), getHandle(platformConfigHandle)); + return *this; + } + + SNPEBuilder& setRuntimeProcessorOrder(const DlSystem::RuntimeList& runtimeList){ + Snpe_SNPEBuilder_SetRuntimeProcessorOrder(handle(), getHandle(runtimeList)); + return *this; + } + + SNPEBuilder& setUnconsumedTensorsAsOutputs(int setOutput){ + Snpe_SNPEBuilder_SetUnconsumedTensorsAsOutputs(handle(), setOutput); + return *this; + } + + SNPEBuilder& setTimeOut(uint64_t timeoutMicroSec){ + Snpe_SNPEBuilder_SetTimeOut(handle(), timeoutMicroSec); + return *this; + } + + + SNPEBuilder& setBufferDataType(const DlSystem::IOBufferDataTypeMap& dataTypeMap){ + Snpe_SNPEBuilder_SetBufferDataType(handle(), getHandle(dataTypeMap)); + return *this; + } + + SNPEBuilder& setSingleThreadedInit(int singleThreadedInit){ + Snpe_SNPEBuilder_SetSingleThreadedInit(handle(), singleThreadedInit); + return *this; + } + + SNPEBuilder& setCpuFixedPointMode(bool cpuFxpMode){ + Snpe_SNPEBuilder_SetCpuFixedPointMode(handle(), cpuFxpMode); + return *this; + } + + SNPEBuilder& setModelName(DlSystem::String modelName){ + Snpe_SNPEBuilder_SetModelName(handle(), modelName.c_str()); + return *this; + } + + std::unique_ptr build() noexcept{ + auto h = Snpe_SNPEBuilder_Build(handle()); + return h ? makeUnique(h) : nullptr; + } + +}; + +} // ns SNPE + + +ALIAS_IN_ZDL_NAMESPACE(SNPE, SNPEBuilder) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEFactory.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEFactory.hpp new file mode 100644 index 00000000..6c2486ee --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEFactory.hpp @@ -0,0 +1,88 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" + +#include "DlSystem/DlEnums.hpp" +#include "DlSystem/DlVersion.hpp" +#include "DlSystem/ITensorFactory.hpp" +#include "DlSystem/IUserBufferFactory.hpp" + + +#include "SNPE/SNPEUtil.h" +#include "DlSystem/DlEnums.h" + +namespace SNPE { + + +class SNPEFactory { +public: + + + static bool isRuntimeAvailable(DlSystem::Runtime_t runtime){ + return Snpe_Util_IsRuntimeAvailable(static_cast(runtime)); + } + + static bool isRuntimeAvailable(DlSystem::Runtime_t runtime, DlSystem::RuntimeCheckOption_t option){ + return Snpe_Util_IsRuntimeAvailableCheckOption(static_cast(runtime), + static_cast(option)); + } + + static DlSystem::ITensorFactory& getTensorFactory(){ + static DlSystem::ITensorFactory iTensorFactory; + return iTensorFactory; + } + + static DlSystem::IUserBufferFactory& getUserBufferFactory(){ + static DlSystem::IUserBufferFactory iUserBufferFactory; + return iUserBufferFactory; + } + + static DlSystem::Version_t getLibraryVersion(){ + return WrapperDetail::moveHandle(Snpe_Util_GetLibraryVersion()); + } + + static bool setSNPEStorageLocation(const char* storagePath){ + return SNPE_SUCCESS == Snpe_Util_SetSNPEStorageLocation(storagePath); + } + + static bool addOpPackage(const std::string& regLibraryPath){ + return SNPE_SUCCESS == Snpe_Util_AddOpPackage(regLibraryPath.c_str()); + } + + static bool isGLCLInteropSupported(){ + return Snpe_Util_IsGLCLInteropSupported(); + } + + static const char* getLastError(){ + return Snpe_Util_GetLastError(); + } + + static bool initializeLogging(const DlSystem::LogLevel_t& level){ + return Snpe_Util_InitializeLogging(static_cast(level)); + } + + static bool initializeLogging(const DlSystem::LogLevel_t& level, const std::string& logPath){ + return Snpe_Util_InitializeLoggingPath(static_cast(level), logPath.c_str()); + } + + static bool setLogLevel(const DlSystem::LogLevel_t& level){ + return Snpe_Util_SetLogLevel(static_cast(level)); + } + + static bool terminateLogging(){ + return Snpe_Util_TerminateLogging(); + } +}; + + +} // ns SNPE + + +ALIAS_IN_ZDL_NAMESPACE(SNPE, SNPEFactory) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEUtil.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEUtil.h new file mode 100644 index 00000000..a3e1d1e1 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/SNPEUtil.h @@ -0,0 +1,354 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + */ + +#ifndef _SNPE_UTIL_H_ +#define _SNPE_UTIL_H_ + +#include "SNPE/SNPE.h" +#include "DlSystem/DlEnums.h" +#include "DlSystem/DlError.h" +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/IUserBuffer.h" +#include "DlSystem/ITensor.h" +#include "DlSystem/TensorShape.h" +#include "DlSystem/DlVersion.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Creates a UserBuffer + * + * @param[in] buffer Pointer to the buffer that the caller supplies + * + * @param[in] bufSize Buffer size, in bytes + * + * @param[in] stridesHandle Total number of bytes between elements in each dimension. + * E.g. A tightly packed tensor of floats with dimensions [4, 3, 2] would have strides of [24, 8, 4]. + * + * @param[in] userBufferEncodingHandle Handle to a UserBufferEncoding object + * + * @note Caller has to ensure that memory pointed to by buffer stays accessible + * for the lifetime of the object created + * + * @return Handle to the created UserBuffer + */ +SNPE_API +Snpe_IUserBuffer_Handle_t Snpe_Util_CreateUserBuffer(void *buffer, + size_t bufSize, + Snpe_TensorShape_Handle_t stridesHandle, + Snpe_IUserBuffer_Handle_t userBufferEncodingHandle); + +/** + * @brief Creates a UserBuffer with a provided UserBufferSource + * + * @param[in] buffer Pointer to the buffer that the caller supplies + * + * @param[in] bufSize Buffer size, in bytes + * + * @param[in] stridesHandle Total number of bytes between elements in each dimension. + * E.g. A tightly packed tensor of floats with dimensions [4, 3, 2] would have strides of [24, 8, 4]. + * + * @param[in] userBufferEncodingHandle Handle to a UserBufferEncoding object + * + * @param[in] userBufferSourceHandle Handle to a UserBufferSource object + * + * @return Handle to the created UserBuffer + */ +SNPE_API +Snpe_IUserBuffer_Handle_t Snpe_Util_CreateUserBufferFromSource(void *buffer, + size_t bufSize, + Snpe_TensorShape_Handle_t stridesHandle, + Snpe_IUserBuffer_Handle_t userBufferEncodingHandle, + Snpe_UserBufferSource_Handle_t userBufferSourceHandle); + +/** + * @brief Creates a UserBuffer + * + * @param[in] buffer Pointer to the buffer that the caller supplies + * + * @param[in] bufSize Buffer size, in bytes + * + * @param[in] stridesHandle Total number of bytes between elements in each dimension. + * E.g. A tightly packed tensor of floats with dimensions [4, 3, 2] would have strides of [24, 8, 4]. + * + * @param[in] userBufferEncodingHandle Reference to an UserBufferEncoding object + * + * @param[in] userBufferSourceHandle Reference to an UserBufferSource object + * + * @note Caller has to ensure that memory pointed to by buffer stays accessible + * for the lifetime of the object created + * + * @return the created UserBuffer + * + */ +SNPE_API +Snpe_IUserBuffer_Handle_t Snpe_Util_CreateUserGlBuffer(void *buffer, + size_t bufSize, + Snpe_TensorShape_Handle_t stridesHandle, + Snpe_IUserBuffer_Handle_t userBufferEncodingHandle, + Snpe_IUserBuffer_Handle_t userBufferSourceHandle); + +/** + * Creates a new ITensor with uninitialized data. + * + * ITensor buffer size assumes float32 encoding for each element. + * (i.e., a tensor with dimensions (2,3) will be represented by (2 * 3) * 4 = 24 bytes in memory) + * + * The strides for the tensor will match the tensor dimensions + * (i.e., the tensor data is contiguous in memory). + * + * @param[in] shapeHandle The dimensions for the tensor in which the last + * element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying, etc. + * + * @return The created tensor + */ +SNPE_API +Snpe_ITensor_Handle_t Snpe_Util_CreateITensor(Snpe_TensorShape_Handle_t shapeHandle); + +/** + * Create a new ITensor with specific data. + * (i.e. the tensor data is contiguous in memory). This tensor is + * primarily used to create a tensor where tensor size can't be + * computed directly from dimension. One such example is + * NV21-formatted image, or any YUV formatted image + * + * @param[in] shapeHandle The dimensions for the tensor in which the last + * element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying, etc. + * + * @param[in] data The actual data with which the Tensor object is filled. + * + * @param[in] dataSize The size of data + * + * @return A handle to the created tensor + */ +SNPE_API +Snpe_ITensor_Handle_t Snpe_Util_CreateITensorDataSize(Snpe_TensorShape_Handle_t shapeHandle, const uint8_t* data, size_t dataSize); + +/** + * Create a new ITensor with specific data. + * (i.e. the tensor data is contiguous in memory). This tensor is + * primarily used to create a tensor where tensor size can't be + * computed directly from dimension. One such example is + * NV21-formatted image, or any YUV formatted image + * + * @param[in] shapeHandle The dimensions for the tensor in which the last + * element of the vector represents the fastest varying + * dimension and the zeroth element represents the slowest + * varying, etc. + * + * @param[in] data The actual data with which the Tensor object is filled. + * + * @param[in] dataSize The size of data + * + * @return the created tensor + */ +SNPE_API +Snpe_ITensor_Handle_t Snpe_Util_CreateITensor_NV21(Snpe_TensorShape_Handle_t shapeHandle, unsigned char *data, size_t dataSize); + +/** + * Indicates whether the supplied runtime is available on the + * current platform. + * + * @param[in] runtime The target runtime to check. + * + * @return Boolean: Non-zero if the supplied runtime is available; 0 otherwise + * + */ +SNPE_API +int Snpe_Util_IsRuntimeAvailable(Snpe_Runtime_t runtime); + +/** + * Indicates whether the supplied runtime is available on the + * current platform. + * + * @param[in] runtime The target runtime to check. + * + * @param[in] runtimeCheckOption Extent to perform runtime available check. + * + * @return Boolean: Non-zero if the supplied runtime is available; 0 otherwise + * + */ +SNPE_API +int Snpe_Util_IsRuntimeAvailableCheckOption(Snpe_Runtime_t runtime, Snpe_RuntimeCheckOption_t runtimeCheckOption); + + +/** + * Gets the version of the SNPE library. + * + * @return Version of the SNPE library. + * + */ +SNPE_API +Snpe_DlVersion_Handle_t Snpe_Util_GetLibraryVersion(); + +/** + * Set the SNPE storage location for all SNPE instances in this + * process. Note that this may only be called once, and if so + * must be called before creating any SNPE instances. + * + * @param[in] storagePath Absolute path to a directory which SNPE may + * use for caching and other storage purposes. + * + * @return Boolean: Non-zero if the supplied path was succesfully set as + * the SNPE storage location, 0 otherwise. + * + */ +SNPE_API +int Snpe_Util_SetSNPEStorageLocation(const char* storagePath); + +/** + * @brief Register a user-defined op package with SNPE. + * + * @param[in] regLibraryPath Path to the registration library + * that allows clients to register a set of operations that are + * part of the package, and share op info with SNPE + * + * @return Boolean: Non-zero if successful, 0 otherwise. + */ +SNPE_API +int Snpe_Util_AddOpPackage(const char* regLibraryPath ); + +/** + * Indicates whether the OpenGL and OpenCL interoperability is supported + * on GPU platform. + * + * @return Boolean: Non-zero if the OpenGL and OpenCl interop is supported; 0 otherwise + * + */ +SNPE_API +int Snpe_Util_IsGLCLInteropSupported(); + +/** + * @return A string description of the last error + */ +SNPE_API +const char* Snpe_Util_GetLastError(); + +/** + * Initializes logging with the specified log level. + * initializeLogging with level, is used on Android platforms + * and after successful initialization, SNPE + * logs are printed in android logcat logs. + * + * It is recommended to initializeLogging before creating any + * SNPE instances, in order to capture information related to + * core initialization. If this is called again after first + * time initialization, subsequent calls are ignored. + * Also, Logging can be re-initialized after a call to + * terminateLogging API by calling initializeLogging again. + * + * A typical usage of Logging life cycle can be + * initializeLogging() + * any other SNPE API like isRuntimeAvailable() + * * setLogLevel() - optional - can be called anytime + * between initializeLogging & terminateLogging + * SNPE instance creation, inference, destroy + * terminateLogging(). + * + * Please note, enabling logging can have performance impact. + * + * @param[in] level Log level (LOG_INFO, LOG_WARN, etc.). + * + * @return Boolean: non-zero if successful, 0 otherwise. + */ +SNPE_API +int Snpe_Util_InitializeLogging(Snpe_LogLevel_t level); + +/** + * Initializes logging with the specified log level and log path. + * initializeLogging with level & log path, is used on non Android + * platforms and after successful initialization, SNPE + * logs are printed in std output & into log files created in the + * log path. + * + * It is recommended to initializeLogging before creating any + * SNPE instances, in order to capture information related to + * core initialization. If this is called again after first + * time initialization, subsequent calls are ignored. + * Also, Logging can be re-initialized after a call to + * terminateLogging API by calling initializeLogging again. + * + * A typical usage of Logging life cycle can be + * initializeLogging() + * any other SNPE API like isRuntimeAvailable() + * * setLogLevel() - optional - can be called anytime + * between initializeLogging & terminateLogging + * SNPE instance creation, inference, destroy + * terminateLogging() + * + * Please note, enabling logging can have performance impact + * + * @param[in] level Log level (LOG_INFO, LOG_WARN, etc.). + * + * @param[in] logPath of directory to store logs. + * If path is empty, the default path is "./Log". + * For android, the log path is ignored. + * + * @return Boolean: non-zero if successful, 0 otherwise. + */ +SNPE_API +int Snpe_Util_InitializeLoggingPath(Snpe_LogLevel_t level, const char* logPath); + +/** + * Updates the current logging level with the specified level. + * setLogLevel is optional, called anytime after initializeLogging + * and before terminateLogging, to update the log level set. + * Log levels can be updated multiple times by calling setLogLevel + * A call to setLogLevel() is ignored if it is made before + * initializeLogging() or after terminateLogging() + * + * @param[in] level Log level (LOG_INFO, LOG_WARN, etc.). + * + * @return Boolean: non-zero if successful, 0 otherwise. + */ +SNPE_API +int Snpe_Util_SetLogLevel(Snpe_LogLevel_t level); + +/** + * Terminates logging. + * + * It is recommended to terminateLogging after initializeLogging + * in order to disable logging information. + * If this is called before initialization or after first time termination, + * calls are ignored. + * + * @warning Snpe_Util_TerminateLogging() must not be called while another thread is executing. + * In a multi-threaded use case, the individual threads must have a cooperative life cycle + * management strategy for the logger. + * + * @return Boolean: non-zero if successful, 0 otherwise. + */ +SNPE_API +int Snpe_Util_TerminateLogging(); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_UTIL_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.h new file mode 100644 index 00000000..e6a42ddb --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.h @@ -0,0 +1,77 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2022,2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef _SNPE_USER_BUFFER_LIST_H_ +#define _SNPE_USER_BUFFER_LIST_H_ + + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "DlSystem/SnpeApiExportDefine.h" +#include "DlSystem/DlError.h" + +#include "DlSystem/UserBufferMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* Snpe_UserBufferList_Handle_t; + +SNPE_API +Snpe_UserBufferList_Handle_t Snpe_UserBufferList_Create(); + +SNPE_API +Snpe_UserBufferList_Handle_t Snpe_UserBufferList_CreateCopy(Snpe_UserBufferList_Handle_t userBufferListHandle); + +SNPE_API +Snpe_UserBufferList_Handle_t Snpe_UserBufferList_CreateSize(size_t size); + +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferList_Delete(Snpe_UserBufferList_Handle_t userBufferListHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferList_PushBack(Snpe_UserBufferList_Handle_t userBufferListHandle, + Snpe_UserBufferMap_Handle_t userBufferMapHandle); + +SNPE_API +Snpe_UserBufferMap_Handle_t Snpe_UserBufferList_At_Ref(Snpe_UserBufferList_Handle_t userBufferListHandle, + size_t idx); + +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferList_Assign(Snpe_UserBufferList_Handle_t srcUserBufferListHandle, + Snpe_UserBufferList_Handle_t dstUserBufferListHandle); + +SNPE_API +size_t Snpe_UserBufferList_Size(Snpe_UserBufferList_Handle_t userBufferListHandle); + +SNPE_API +size_t Snpe_UserBufferList_Capacity(Snpe_UserBufferList_Handle_t userBufferListHandle); + +SNPE_API +Snpe_ErrorCode_t Snpe_UserBufferList_Clear(Snpe_UserBufferList_Handle_t userBufferListHandle); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _SNPE_USER_BUFFER_LIST_H_ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.hpp new file mode 100644 index 00000000..fec82dbc --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SNPE/UserBufferList.hpp @@ -0,0 +1,76 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#include "Wrapper.hpp" +#include "DlSystem/UserBufferMap.hpp" + +#include "SNPE/UserBufferList.h" + + +namespace PSNPE { + +class UserBufferList : public Wrapper { + friend BaseType; + // Use this to get free move Ctor and move assignment operator, provided this class does not specify + // as copy assignment operator or copy Ctor + using BaseType::BaseType; + + static constexpr DeleteFunctionType DeleteFunction{Snpe_UserBufferList_Delete}; + +public: + UserBufferList() + : BaseType(Snpe_UserBufferList_Create()) + { } + explicit UserBufferList(size_t size) + : BaseType(Snpe_UserBufferList_CreateSize(size)) + { } + + UserBufferList(const UserBufferList& other) + : BaseType(Snpe_UserBufferList_CreateCopy(other.handle())) + { } + UserBufferList(UserBufferList&& other) noexcept + : BaseType(std::move(other)) + { } + + UserBufferList& operator=(const UserBufferList& other){ + if(this != &other){ + Snpe_UserBufferList_Assign(other.handle(), handle()); + } + return *this; + } + UserBufferList& operator=(UserBufferList&& other){ + return moveAssign(std::move(other)); + } + + + void push_back(const DlSystem::UserBufferMap& userBufferMap){ + Snpe_UserBufferList_PushBack(handle(), getHandle(userBufferMap)); + } + + DlSystem::UserBufferMap& operator[](size_t idx){ + return *makeReference(Snpe_UserBufferList_At_Ref(handle(), idx)); + } + + size_t size() const noexcept{ + return Snpe_UserBufferList_Size(handle()); + } + + size_t capacity() const noexcept{ + return Snpe_UserBufferList_Capacity(handle()); + } + + void clear() noexcept{ + Snpe_UserBufferList_Clear(handle()); + } +}; + + +} // ns PSNPE + +ALIAS_IN_ZDL_NAMESPACE(PSNPE, UserBufferList) diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoBase.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoBase.h new file mode 100644 index 00000000..f7af604a --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoBase.h @@ -0,0 +1,546 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2019-2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_BASE_H +#define SNPE_UDO_BASE_H + +#include + +// Provide values to use for API version. +#define API_VERSION_MAJOR 1 +#define API_VERSION_MINOR 6 +#define API_VERSION_TEENY 0 + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +// Defines a bitmask of enum values. +typedef uint32_t SnpeUdo_Bitmask_t; +typedef SnpeUdo_Bitmask_t Udo_Bitmask_t; + +// A string of characters, rather than an array of bytes. +// Assumed to be UTF-8. +typedef char* SnpeUdo_String_t; +typedef SnpeUdo_String_t Udo_String_t; + +// The maximum allowable length of a SnpeUdo_String_t in bytes, +// including null terminator. SNPE will truncate strings longer +// than this. +#define SNPE_UDO_MAX_STRING_SIZE 1024 + +/** + * An enum which holds the various error types. + * The error types are divided to classes : + * 0 - 99 : generic errors + * 100 - 200 : errors related to configuration + * + */ +typedef enum +{ + /// No Error + SNPE_UDO_NO_ERROR = 0, UDO_NO_ERROR = 0, + /// Unsupported value for core type + SNPE_UDO_WRONG_CORE = 1, UDO_WRONG_CORE = 1, + /// Invalid attribute/argument passed into UDO API + SNPE_UDO_INVALID_ARGUMENT = 2, UDO_INVALID_ARGUMENT = 2, + /// Unsupported feature error + SNPE_UDO_UNSUPPORTED_FEATURE = 3, UDO_UNSUPPORTED_FEATURE = 3, + /// Error relating to memory allocation + SNPE_UDO_MEM_ALLOC_ERROR = 4, UDO_MEM_ALLOC_ERROR = 4, + /* Configuration Specific errors */ + /// No op with given attributes available in library + SNPE_UDO_WRONG_OPERATION = 100, UDO_WRONG_OPERATION = 100, + /// Unsupported value for core type in UDO configuration + SNPE_UDO_WRONG_CORE_TYPE = 101, UDO_WRONG_CORE_TYPE = 101, + /// Wrong number of params in UDO definition + SNPE_UDO_WRONG_NUM_OF_PARAMS = 102, UDO_WRONG_NUM_OF_PARAMS = 102, + /// Wrong number of dimensions for tensor(s) in UDO definition + SNPE_UDO_WRONG_NUM_OF_DIMENSIONS = 103, UDO_WRONG_NUM_OF_DIMENSIONS = 103, + /// Wrong number of input tensors in UDO definition + SNPE_UDO_WRONG_NUM_OF_INPUTS = 104, UDO_WRONG_NUM_OF_INPUTS = 104, + /// Wrong number of output tensors in UDO definition + SNPE_UDO_WRONG_NUM_OF_OUTPUTS = 105, UDO_WRONG_NUM_OF_OUTPUTS = 105, + SNPE_UDO_PROGRAM_CACHE_NOT_FOUND = 106, UDO_PROGRAM_CACHE_NOT_FOUND = 106, + SNPE_UDO_UNKNOWN_ERROR = 0xFFFFFFFF, UDO_UNKNOWN_ERROR = 0xFFFFFFFF +} SnpeUdo_ErrorType_t; + +typedef SnpeUdo_ErrorType_t Udo_ErrorType_t; + +/** + * An enum which holds the various data types. + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + * \n FIXED_XX types are targeted for data in tensors. + * \n UINT / INT types are targeted for scalar params + */ +typedef enum +{ + /// data type: 16-bit floating point + SNPE_UDO_DATATYPE_FLOAT_16 = 0x01, UDO_DATATYPE_FLOAT_16 = 0x01, + /// data type: 32-bit floating point + SNPE_UDO_DATATYPE_FLOAT_32 = 0x02, UDO_DATATYPE_FLOAT_32 = 0x02, + /// data type: 4-bit fixed point + SNPE_UDO_DATATYPE_FIXED_4 = 0x04, UDO_DATATYPE_FIXED_4 = 0x04, + /// data type: 8-bit fixed point + SNPE_UDO_DATATYPE_FIXED_8 = 0x08, UDO_DATATYPE_FIXED_8 = 0x08, + /// data type: 16-bit fixed point + SNPE_UDO_DATATYPE_FIXED_16 = 0x10, UDO_DATATYPE_FIXED_16 = 0x10, + /// data type: 32-bit fixed point + SNPE_UDO_DATATYPE_FIXED_32 = 0x20, UDO_DATATYPE_FIXED_32 = 0x20, + /// data type: 8-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_8 = 0x100, UDO_DATATYPE_UINT_8 = 0x100, + /// data type: 16-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_16 = 0x200, UDO_DATATYPE_UINT_16 = 0x200, + /// data type: 32-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_32 = 0x400, UDO_DATATYPE_UINT_32 = 0x400, + /// data type: 8-bit signed integer + SNPE_UDO_DATATYPE_INT_8 = 0x1000, UDO_DATATYPE_INT_8 = 0x1000, + /// data type: 16-bit signed integer + SNPE_UDO_DATATYPE_INT_16 = 0x2000, UDO_DATATYPE_INT_16 = 0x2000, + /// data type: 32-bit signed integer + SNPE_UDO_DATATYPE_INT_32 = 0x4000, UDO_DATATYPE_INT_32 = 0x4000, + SNPE_UDO_DATATYPE_LAST = 0xFFFFFFFF, UDO_DATATYPE_LAST = 0xFFFFFFFF +} SnpeUdo_DataType_t; + +typedef SnpeUdo_DataType_t Udo_DataType_t; + +/** + * An enum which holds the various layouts. + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + */ +typedef enum +{ + /// data layout (4D): NHWC (batch-height-width-channel) + SNPE_UDO_LAYOUT_NHWC = 0x01, UDO_LAYOUT_NHWC = 0x01, + /// data layout (4D): NCHW (batch-channel-height-width) + SNPE_UDO_LAYOUT_NCHW = 0x02, UDO_LAYOUT_NCHW = 0x02, + /// data layout (5D): NDHWC (batch-depth-height-width-channel) + SNPE_UDO_LAYOUT_NDHWC = 0x04, UDO_LAYOUT_NDHWC = 0x04, + SNPE_UDO_LAYOUT_GPU_OPTIMAL1 = 0x08, UDO_LAYOUT_GPU_OPTIMAL1 = 0x08, + SNPE_UDO_LAYOUT_GPU_OPTIMAL2 = 0x10, UDO_LAYOUT_GPU_OPTIMAL2 = 0x10, + SNPE_UDO_LAYOUT_DSP_OPTIMAL1 = 0x11, UDO_LAYOUT_DSP_OPTIMAL1 = 0x11, + SNPE_UDO_LAYOUT_DSP_OPTIMAL2 = 0x12, UDO_LAYOUT_DSP_OPTIMAL2 = 0x12, + // Indicates no data will be allocated for this tensor. + // Used to specify optional inputs/outputs positionally. + SNPE_UDO_LAYOUT_NULL = 0x13, UDO_LAYOUT_NULL = 0x13, + SNPE_UDO_LAYOUT_LAST = 0xFFFFFFFF, UDO_LAYOUT_LAST = 0xFFFFFFFF +} SnpeUdo_TensorLayout_t; + +typedef SnpeUdo_TensorLayout_t Udo_TensorLayout_t; + +/** + * An enum which holds the UDO library Core type . + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + */ +typedef enum +{ + /// Library target IP Core is undefined + SNPE_UDO_CORETYPE_UNDEFINED = 0x00, UDO_CORETYPE_UNDEFINED = 0x00, + /// Library target IP Core is CPU + SNPE_UDO_CORETYPE_CPU = 0x01, UDO_CORETYPE_CPU = 0x01, + /// Library target IP Core is GPU + SNPE_UDO_CORETYPE_GPU = 0x02, UDO_CORETYPE_GPU = 0x02, + /// Library target IP Core is DSP + SNPE_UDO_CORETYPE_DSP = 0x04, UDO_CORETYPE_DSP = 0x04, + SNPE_UDO_CORETYPE_LAST = 0xFFFFFFFF, UDO_CORETYPE_LAST = 0xFFFFFFFF +} SnpeUdo_CoreType_t; + +typedef SnpeUdo_CoreType_t Udo_CoreType_t; + +/** + * An enum to specify the parameter type : Scalar or Tensor + */ +typedef enum +{ + /// UDO static param type: scalar + SNPE_UDO_PARAMTYPE_SCALAR = 0x00, UDO_PARAMTYPE_SCALAR = 0x00, + /// UDO static param type: string + SNPE_UDO_PARAMTYPE_STRING = 0x01, UDO_PARAMTYPE_STRING = 0x01, + /// UDO static param type: tensor + SNPE_UDO_PARAMTYPE_TENSOR = 0x02, UDO_PARAMTYPE_TENSOR = 0x02, + SNPE_UDO_PARAMTYPE_LAST = 0xFFFFFFFF, UDO_PARAMTYPE_LAST = 0xFFFFFFFF +} SnpeUdo_ParamType_t; + +typedef SnpeUdo_ParamType_t Udo_ParamType_t; + +/** + * An enum to specify quantization type + */ +typedef enum +{ + /// Tensor Quantization type: NONE. Signifies unquantized tensor data + SNPE_UDO_QUANTIZATION_NONE = 0x00, UDO_QUANTIZATION_NONE = 0x00, + /// Tensor Quantization type: Tensorflow-style + SNPE_UDO_QUANTIZATION_TF = 0x01, UDO_QUANTIZATION_TF = 0x01, + SNPE_UDO_QUANTIZATION_QMN = 0x02, UDO_QUANTIZATION_QMN = 0x02, + SNPE_UDO_QUANTIZATION_LAST = 0xFFFFFFFF, UDO_QUANTIZATION_LAST = 0xFFFFFFFF +} SnpeUdo_QuantizationType_t; + +typedef SnpeUdo_QuantizationType_t Udo_QuantizationType_t; + +/** + * @brief A struct which is used to provide a version number using 3 values : major, minor, teeny + * + */ +typedef struct +{ + /// version field: major - for backward-incompatible changes + uint32_t major; + /// version field: minor - for backward-compatible feature updates + uint32_t minor; + /// version field: teeny - for minor bug-fixes and clean-up + uint32_t teeny; +} SnpeUdo_Version_t; + +typedef SnpeUdo_Version_t Udo_Version_t; + +/** + * @brief A struct returned from version query, contains the Library version and API version + * + */ +typedef struct +{ + /// Version of UDO library. Controlled by users + SnpeUdo_Version_t libVersion; + /// Version of SNPE UDO API used in compiling library. Determined by SNPE + SnpeUdo_Version_t apiVersion; +} SnpeUdo_LibVersion_t; + +/** + * @brief A struct returned from version query, contains the package version + * + */ +typedef struct +{ + /// Version of UDO API used in package. + Udo_Version_t apiVersion; +} Udo_PkgVersion_t; + +/** + * @brief A union to hold the value of a generic type. Allows defining a parameter struct + * in a generic way, with a "value" location that holds the data regardless of the type. + * + */ +typedef union +{ + /// value type: float + float floatValue; + /// value type: unsigned 32-bit integer + uint32_t uint32Value; + /// value type: signed 32-bit integer + int32_t int32Value; + /// value type: unsigned 16-bit integer + uint16_t uint16Value; + /// value type: signed 16-bit integer + int16_t int16Value; + /// value type: unsigned 8-bit integer + uint8_t uint8Value; + /// value type: signed 8-bit integer + int8_t int8Value; +} SnpeUdo_Value_t; + +typedef SnpeUdo_Value_t Udo_Value_t; + +/** + * @brief A struct which defines a scalar parameter : name, data type, and union of values + * + */ +typedef struct +{ + /// The parameter data type : float, int, etc. + SnpeUdo_DataType_t dataType; + /// a union of specified type which holds the data + SnpeUdo_Value_t dataValue; +} SnpeUdo_ScalarParam_t; + +typedef SnpeUdo_ScalarParam_t Udo_ScalarParam_t; + +/** + * @brief A struct which defines the quantization parameters in case of Tensorflow style quantization + * + */ +typedef struct +{ + /// minimum value of the quantization range of data + float minValue; + /// maximum value of the quantization range of data + float maxValue; +} SnpeUdo_TFQuantize_t; + +typedef SnpeUdo_TFQuantize_t Udo_TFQuantize_t; + +/** + * @brief A struct which defines the quantization type, and union of supported quantization structs + * + */ +typedef struct +{ + /// quantization type (only TF-style currently supported) + SnpeUdo_QuantizationType_t quantizeType; + union + { + /// TF-style min-max quantization ranges + SnpeUdo_TFQuantize_t TFParams; + }; +} SnpeUdo_QuantizeParams_t; + +typedef SnpeUdo_QuantizeParams_t Udo_QuantizeParams_t; + +/** + * @brief A struct which defines the datatype associated with a specified core-type + * This should be used to denote the datatypes for a single tensor info, depending + * on the intended execution core. + * + */ +typedef struct +{ + /// The IP Core + SnpeUdo_CoreType_t coreType; + /// The associated datatype for this coreType + SnpeUdo_DataType_t dataType; +} SnpeUdo_PerCoreDatatype_t; + +typedef SnpeUdo_PerCoreDatatype_t Udo_PerCoreDatatype_t; + +/** + * @brief A struct which defines a tensor parameter : name, data type, layout, quantization, more. + * Also holds a pointer to the tensor data. + * + */ +typedef struct +{ + /// The maximum allowable dimensions of the tensor. The memory held in + /// _tensorData_ is guaranteed to be large enough for this. + uint32_t* maxDimensions; + /// The current dimensions of the tensor. An operation may modify the current + /// dimensions of its output, to indicate cases where the output has been + /// "resized". + /// Note that for static parameters, the current and max dimensions must + /// match. + uint32_t* currDimensions; + /// Quantization params applicable to the tensor. Currently only supports + /// Tensorflow quantization style. + SnpeUdo_QuantizeParams_t quantizeParams; + /// Number of dimensions to the tensor: 3D, 4D, etc. + uint32_t tensorRank; + /// The parameter data type: float, int, etc. + SnpeUdo_DataType_t dataType; + /// The tensor layout type: NCHW, NHWC, etc. + SnpeUdo_TensorLayout_t layout; + /// Opaque pointer to tensor data. User may be required to re-interpret the pointer + /// based on core-specific definitions. + void* tensorData; +} SnpeUdo_TensorParam_t; + +typedef SnpeUdo_TensorParam_t Udo_TensorParam_t; + +/** + * @brief A struct which defines tensor information for activation tensors only + * + * It describes an activation tensor object using its name, the intended layout and the datatype + * it will take depending on the intended runtime core. The repeated field indicates that + * that the tensor info describes several input/output activation tensors, which all share the + * aforementioned properties. + */ +typedef struct +{ + /// The tensor name + SnpeUdo_String_t tensorName; + /// The tensor layout type: NCHW, NHWC, etc. + SnpeUdo_TensorLayout_t layout; + /// The per core datatype: {SNPE_UDO_DATATYPE, SNPE_UDO_CORE_TYPE} + SnpeUdo_PerCoreDatatype_t* perCoreDatatype; + /// A boolean field indicating that this tensorinfo will be repeated e.x for ops such as Concat or Split + bool repeated; + /// A boolean field indicating whether input is static or not. + bool isStatic; +} SnpeUdo_TensorInfo_t; + +typedef SnpeUdo_TensorInfo_t Udo_TensorInfo_t; + +/** + * @brief struct which defines a UDO parameter - a union of scalar, tensor and string parameters + * + */ +typedef struct +{ + /// Type is scalar or tensor + SnpeUdo_ParamType_t paramType; + /// The param name, for example : "offset", "activation_type" + SnpeUdo_String_t paramName; + union + { + /// scalar param value + SnpeUdo_ScalarParam_t scalarParam; + /// tensor param value + SnpeUdo_TensorParam_t tensorParam; + /// string param value + SnpeUdo_String_t stringParam; + }; +} SnpeUdo_Param_t; + +typedef SnpeUdo_Param_t Udo_Param_t; + +/** + * @brief A struct which defines Operation information which is specific for IP core (CPU, GPU, DSP ...) + * + */ +typedef struct +{ + /// The IP Core + SnpeUdo_CoreType_t udoCoreType; + /// Bitmask, defines supported internal calculation types (like FLOAT_32, etc) + /// Based on SnpeUdo_DataType + SnpeUdo_Bitmask_t operationCalculationTypes; +} SnpeUdo_OpCoreInfo_t; + +typedef SnpeUdo_OpCoreInfo_t Udo_OpCoreInfo_t; + +/** + * @brief A struct which defines the common and core-specific Operation information + * + */ +typedef struct +{ + /// Operation type + SnpeUdo_String_t operationType; + /// A bitmask describing which IP Cores (CPU, GPU, DSP ...) support this operation + /// Translated based on SnpeUdo_CoreType + SnpeUdo_Bitmask_t supportedByCores; + /// Number of static parameters defined by the op + uint32_t numOfStaticParams; + /// Array of static parameters. Can be scalar or tensor params + SnpeUdo_Param_t* staticParams; + /// Number of input tensors this op receives + uint32_t numOfInputs; + /// Array of input tensor names to this operation + SnpeUdo_String_t* inputNames; + /// Number of output tensors this op receives + uint32_t numOfOutputs; + /// Array of output tensor names to this operation + SnpeUdo_String_t* outputNames; + /// Number of cores that the op can execute on + uint32_t numOfCoreInfo; + /// Array of per-core information entries + SnpeUdo_OpCoreInfo_t* opPerCoreInfo; + /// Array of input tensor infos for this operation + SnpeUdo_TensorInfo_t* inputInfos; + /// Array of output tensor infos for this operation + SnpeUdo_TensorInfo_t* outputInfos; +} SnpeUdo_OperationInfo_t; + +typedef SnpeUdo_OperationInfo_t Udo_OperationInfo_t; + +/** + * @brief A struct which provides the implementation library info : type, name + * + */ +typedef struct +{ + /// Defines the IP Core that this implementation library is targeting + SnpeUdo_CoreType_t udoCoreType; + /// library name. will be looked at in the standard library path + SnpeUdo_String_t libraryName; +} SnpeUdo_LibraryInfo_t; + +typedef SnpeUdo_LibraryInfo_t Udo_LibraryInfo_t; + +/** + * @brief A struct returned by the registration library and contains information on the UDO package : + * name, operations, libraries, etc. + * + */ +typedef struct +{ + /// A string containing the package name + SnpeUdo_String_t packageName; + /// A bitmask describing supported IP cores (CPU, GPU, DSP ...) + /// Translated based on SnpeUdo_CoreType + SnpeUdo_Bitmask_t supportedCoreTypes; + /// The number of implementation libraries in the package + uint32_t numOfImplementationLib; + /// Array of implementation libraries names/types + SnpeUdo_LibraryInfo_t* implementationLib; + /// A string containing all operation types separated by space + SnpeUdo_String_t operationsString; + /// Number of supported operations + uint32_t numOfOperations; + /// Array of Operation info structs. Each entry describes one + /// Operation (name, params, inputs, outputs) + SnpeUdo_OperationInfo_t* operationsInfo; +} SnpeUdo_RegInfo_t; + +typedef SnpeUdo_RegInfo_t Udo_RegInfo_t; + +/** +* @brief A struct returned by the implementation library and contains information on the +* specific library: name, IP Core, operations, etc. +* +*/ +typedef struct +{ + /// Defines the IP Core that this implementation library is targeting + SnpeUdo_CoreType_t udoCoreType; + /// A string containing the package name + SnpeUdo_String_t packageName; + /// A string containing all operation types separated by space + SnpeUdo_String_t operationsString; + /// Number of supported operations + uint32_t numOfOperations; +} SnpeUdo_ImpInfo_t; + +typedef SnpeUdo_ImpInfo_t Udo_ImpInfo_t; + +/** + * @brief This struct defines an operation. It is used for validation + * or creation of an operation. + * In case of using it for creation, the static params which are tensors + * contain pointers to the real data (weights, for example), and input/output + * tensors also include pointers to the buffers used. + */ +typedef struct +{ + /// The IP Core that the operation is defined for - CPU, GPU, DSP... + SnpeUdo_CoreType_t udoCoreType; + /// Operation type + SnpeUdo_String_t operationType; + /// The number of static parameters provided in the staticParams array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfStaticParams; + /// Array of static parameters + SnpeUdo_Param_t* staticParams; + /// The number of input parameters provided in inputs array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfInputs; + /// Array of input tensors, providing layout, data type, sizes, etc + /// When used to create an operation, also contains the initial location of the data + SnpeUdo_TensorParam_t* inputs; + /// The number of output parameters provided in inputs array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfOutputs; + /// Array of output tensors, providing layout, data type, sizes, etc + /// When used to create an operation, also contains the initial location of the data + SnpeUdo_TensorParam_t* outputs; +} SnpeUdo_OpDefinition_t; + +typedef SnpeUdo_OpDefinition_t Udo_OpDefinition_t; + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#endif //SNPE_UDO_BASE_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoReg.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoReg.h new file mode 100644 index 00000000..2166be59 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoReg.h @@ -0,0 +1,117 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2019-2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_REG_H +#define SNPE_UDO_REG_H + +#include "SnpeUdo/UdoShared.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * @brief Initialize the shared library's data structures. Calling any other + * library function before this one will result in an error being returned. + * + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_initRegLibrary(void); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_InitRegLibraryFunction_t)(void); + +/** + * @brief A function to query the API version of the UDO registration library. + * The function populates a SnpeUdo_LibVersion_t struct, which contains a SnpeUdo_Version_t + * struct for API version and library version. + * + * @param[in, out] version A pointer to struct which contains major, minor, teeny information for + * library and api versions. + * + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_getRegLibraryVersion(SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_getRegLibraryVersion_t)(SnpeUdo_LibVersion_t** version); + +/** + * @brief Release the shared library's data structures, and invalidate any + * handles returned by the library. The behavior of any outstanding + * asynchronous calls made to this library when this function is called + * are undefined. All library functions (except SnpeUdo_InitRegLibrary) will + * return an error after this function has been successfully called. + * + * It should be possible to call SnpeUdo_InitRegLibrary after calling this + * function, and re-initialize the library. + * + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_terminateRegLibrary(void); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_TerminateRegLibraryFunction_t)(void); + + +/** + * @brief A function to query the info on the UDO set. + * The function populates a structure which contains information about + * the package and operations contained in it. + * + * @param[in, out] registrationInfo A struct which contains information on the set of UDOs + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_getRegInfo(SnpeUdo_RegInfo_t** registrationInfo); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_GetRegInfoFunction_t)(SnpeUdo_RegInfo_t** registrationInfo); + +/** + * @brief A function to validate that a set of params is supported by an operation + * The function receives an operation definition struct, and returns if this configuration is + * supported (e.g. if an operation can be created using this configuration) + * + * @param[in] opDefinition A struct of SnpeUdo_OpDefinition type, containing the information needed to + * validate that an operation can be created with this configuration. + * + * @return Error code, indicating is the operation can be created on this set or not. + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_validateOperation(SnpeUdo_OpDefinition_t* opDefinition); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ValidateOperationFunction_t)(SnpeUdo_OpDefinition_t* opDefinition); + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //SNPE_UDO_REG_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoShared.h b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoShared.h new file mode 100644 index 00000000..816a8a74 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/SnpeUdo/UdoShared.h @@ -0,0 +1,57 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +//============================================================================== +// +// Copyright (c) 2019-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_SHARED_H +#define SNPE_UDO_SHARED_H + +#include "SnpeUdo/UdoBase.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * @brief A function to return the various versions as they relate to the UDO + * The function returns a struct containing the the following: + * libVersion: the version of the implementation library compiled for the UDO. Set by user + * apiVersion: the version of the UDO API used in compiling the implementation library. + * Set by SNPE + * + * @param[in, out] version A pointer to Version struct of type SnpeUdo_LibVersion_t + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_getVersion (SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_GetVersionFunction_t) (SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_GetVersionFunction_t Udo_GetVersionFunction_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#endif // SNPE_UDO_SHARED_H diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/Wrapper.hpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/Wrapper.hpp new file mode 100644 index 00000000..5f908f15 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inc/zdl/Wrapper.hpp @@ -0,0 +1,449 @@ +//============================================================================= +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= +#pragma once + +#define SNPE_WRAPPER_TYPES + +#include +#include +#include +#include + +#include + +#include + + +#include "DlSystem/DlError.h" + +// Put type aliases in zdl::namespace +#define ALIAS_IN_ZDL_NAMESPACE(ns, type) namespace zdl{ namespace ns { using type = ::ns::type; }} + + +// Uncomment to print info from the Wrapper base class +//#define WRAPPER_DEBUG_PRINTS + + +#ifdef WRAPPER_DEBUG_PRINTS + +#ifdef _MSC_VER +#define WRAPPER_FUNCTION_NAME __FUNCTION__ +#define WRAPPER_TRACE() std::cout << __LINE__ << ":\t" << WRAPPER_FUNCTION_NAME << std::endl +#define WRAPPER_ETRACE() std::cout << __LINE__ << ":\t" << WRAPPER_FUNCTION_NAME << std::endl +#else +#define WRAPPER_FUNCTION_NAME __PRETTY_FUNCTION__ +#define WRAPPER_TRACE() std::cout << "\e[33m" << __LINE__ << ":\t" << WRAPPER_FUNCTION_NAME << "\e[0m" << std::endl +#define WRAPPER_ETRACE() std::cout << "\e[31m" << __LINE__ << ":\t" << WRAPPER_FUNCTION_NAME << "\e[0m" << std::endl +#endif + +#include +#else +#define WRAPPER_TRACE() do{}while(0) +#define WRAPPER_ETRACE() do{}while(0) +#endif + + +namespace WrapperDetail { + + +template +using GetterFuncType = MemberType(*)(HandleType); + +template +using SetterFuncType = Snpe_ErrorCode_t(*)(HandleType, MemberType); + + + +// Allow Wrappers to have members that require CAPI calls for access +template GetterFunc, + SetterFuncType SetterFunc +> +class GenericMemberReference{ + OwnerType& owner; +public: + + + ~GenericMemberReference() = default; + GenericMemberReference() = delete; + + GenericMemberReference(const GenericMemberReference&) = delete; + GenericMemberReference(GenericMemberReference&&) noexcept = default; + + GenericMemberReference(OwnerType& owner) + : owner{owner} + { } + explicit GenericMemberReference(OwnerType& owner, MemberType member) + : owner{owner} + { + operator=(member); + } + GenericMemberReference& operator=(MemberType member){ + SetterFunc(owner.handle(), member); + return *this; + } + + operator MemberType() const{ + return GetterFunc(owner.handle()); + } + + GenericMemberReference& + operator=(const GenericMemberReference& other){ + return operator=(other.operator MemberType()); + } + + MemberType operator()() const{ + return operator MemberType(); + } + +}; + +// Allow Wrappers to have members that require CAPI calls for access +template GetterFunc +> +class GenericConstMemberReference{ + + OwnerType& owner; + +public: + ~GenericConstMemberReference() = default; + GenericConstMemberReference() = delete; + + GenericConstMemberReference(const GenericConstMemberReference&) = delete; + GenericConstMemberReference(GenericConstMemberReference&&) noexcept = default; + + GenericConstMemberReference(OwnerType& owner) + : owner{owner} + { } + + operator MemberType() const{ + return GetterFunc(owner.handle()); + } + + + template::value,int>::Type=0> + operator const char*() const{ + thread_local std::string tlss; + tlss = operator MemberType(); + return tlss.c_str(); + } + + MemberType operator()() const{ + return operator MemberType(); + } + +}; + + + +// Allows returning references to literals through the CAPI's _Get and _Set functions +template +using GetterIndexedFuncType = MemberType(*)(HandleType, IndexType); + +template +using SetterIndexedFuncType = Snpe_ErrorCode_t(*)(HandleType, IndexType, MemberType); + +template GetterFunc, + SetterIndexedFuncType SetterFunc +> +class MemberIndexedReference{ + OwnerType& owner; + IndexType idx; + +public: + MemberIndexedReference(OwnerType& owner, IndexType idx) + : owner{owner}, + idx{idx} + { } + MemberIndexedReference(const MemberIndexedReference&) noexcept = default; + MemberIndexedReference(MemberIndexedReference&&) noexcept = default; + + MemberIndexedReference& operator=(const MemberIndexedReference&) noexcept = default; + MemberIndexedReference& operator=(MemberIndexedReference&&) noexcept = default; + + MemberIndexedReference operator=(MemberType member){ + SetterFunc(owner.handle(), idx, member); + return *this; + } + + operator MemberType() const{ + return GetterFunc(owner.handle(), idx); + } + +}; + + + +// Allow moving ownership of handles +template +struct HandleMover { + Handle handle; + bool isReference; +}; + +template +HandleMover moveHandle(Handle handle, bool isReference = false){ + return {handle, isReference}; +} + +// Virtual base class to allow for WrapperStorage to hold pointers to any Wrapper type +class WrapperBase{ +public: + virtual ~WrapperBase() = default; +}; + +// Storage type for Wrappers. Will have a set if the CAPI type is capable of creating reference handles +template +struct WrapperStorage{ + Handle handle; + bool isReference; + constexpr WrapperStorage(Handle handle = {}, bool isReference = false) noexcept + : handle{handle}, + isReference{isReference} + { } +}; + +template +struct WrapperStorage{ + Handle handle; + bool isReference; + mutable std::set> referencedObjects; + WrapperStorage(Handle handle = {}, bool isReference = false) noexcept + : handle{handle}, + isReference{isReference} + { } +}; + +// Allow a handle to be unbound from a Wrapper +struct HandleReleaser{ + template + static typename WrapperType::HandleType release(WrapperType& wrapper){ + auto toret = wrapper.m_Storage.handle; + wrapper.m_Storage.handle = {}; + return toret; + } +}; + +} // ns WrapperDetail + + + +// The base class for all Wrappers around the CAPI +// NOTE: This Wrapper class leverages the Curiously Recurring Template Pattern (CRTP) +template +class Wrapper : public WrapperDetail::WrapperBase{ + friend struct WrapperDetail::HandleReleaser; + // Allow certain types to access getHandle() and handle() + template + friend class Wrapper; + + template, + WrapperDetail::SetterIndexedFuncType> + friend class WrapperDetail::MemberIndexedReference; + + template> + friend class WrapperDetail::GenericConstMemberReference; + + template, WrapperDetail::SetterFuncType> + friend class WrapperDetail::GenericMemberReference; + + + +protected: + using HandleType = Handle; + using BaseType = Wrapper; + using DeleteFunctionType = Snpe_ErrorCode_t(*)(Handle); + + using StorageType = WrapperDetail::WrapperStorage; + + + template Getter> + static WrapperValueType CastingGetter(HandleType handle){ + return static_cast(Getter(handle)); + } + template Setter> + static Snpe_ErrorCode_t CastingSetter(HandleType handle, WrapperValueType value){ + return Setter(handle,static_cast(value)); + } + + + template + struct WrapperMemberReference{ + Derived& owner; + + WrapperMemberReference(Derived& owner) + : owner{owner} + { } + WrapperMemberReference(Derived& owner, const RlType& other) + : owner{owner} + { + operator=(other); + } + + WrapperMemberReference& operator=(const RlType& rl){ + Setter(getHandle(owner), getHandle(rl)); + return *this; + } + + operator RlType&() { + return *owner.template makeReference( Getter(getHandle(owner)) ); + } + operator RlType&() const { + return *owner.template makeReference( Getter(getHandle(owner)) ); + } + + RlType& operator()(){ + return operator RlType&(); + } + const RlType& operator()() const{ + return operator RlType&(); + } + }; + + // For Factory/Singleton types, we need a way for the deleter to do nothing + static Snpe_ErrorCode_t NoOpDeleter(Handle){ + return SNPE_SUCCESS; + } + + // Simplify calls to WrapperDetail::moveHandle. Can be removed, but will require updating all calls to moveHandle + template + static WrapperDetail::HandleMover moveHandle(H handle, bool isReference = false){ + return WrapperDetail::moveHandle(handle, isReference); + } + + + HandleType& handle() noexcept{ return m_Storage.handle; } + const HandleType& handle() const noexcept{ return m_Storage.handle; } + + bool isReference() const noexcept{ return m_Storage.isReference; } + + void Dtor(){ + if(!isReference() && !handle()){ + if(Derived::DeleteFunction != NoOpDeleter){ + WRAPPER_ETRACE(); + } + } + if(!isReference() && handle()){ + WRAPPER_TRACE(); +#ifdef WRAPPER_DEBUG_PRINTS + auto status = Derived::DeleteFunction(handle()); + if(status != SNPE_SUCCESS){ + WRAPPER_ETRACE(); + } +#else + Derived::DeleteFunction(handle()); +#endif + + handle() = nullptr; + } else { + WRAPPER_TRACE(); + } + } + +protected: + + // Only compile these if the class creates references. This will save memory and time + template::type=0> + void addReference(WrapperBase* wrapperBase) const{ // accesses mutable member + if(!wrapperBase){ + WRAPPER_ETRACE(); + } + m_Storage.referencedObjects.insert(std::unique_ptr(wrapperBase)); + } + + template::type=0> + T* makeReference(H referenceHandle) const{ + if(!referenceHandle){ + WRAPPER_ETRACE(); + return nullptr; + } + auto refObj = new T(moveHandle(referenceHandle, true)); + addReference(refObj); + return refObj; + } + + // This will be used to access another Wrapped type's handles once handle() is made protected + template + static OtherHandle getHandle(const Wrapper& otherObject){ + return otherObject.handle(); + } + + template + static OtherHandle getHandle(const Wrapper* otherObject){ + if(!otherObject) return {}; + return getHandle(*otherObject); + } + + template + static std::unique_ptr makeUnique(H handle){ + if(!handle) return {}; + return std::unique_ptr(new T(moveHandle(handle))); + } + + +public: + ~Wrapper(){ + Dtor(); + } +protected: + // Only derived types should have access to this + Wrapper(HandleType handle, bool isReference = false) + : m_Storage{handle, isReference} + { WRAPPER_TRACE(); } + +public: + // We should never have an empty wrapper + Wrapper() = delete; + + // Move semantics are essentially free for all wrapper types + Wrapper(Wrapper&& other) noexcept + : m_Storage{std::move(other.m_Storage)} + { + WRAPPER_TRACE(); + other.handle() = nullptr; + } + Wrapper(const Wrapper&) = delete; + + + Wrapper& operator=(Wrapper&& other) noexcept{ + WRAPPER_TRACE(); + if(this != &other){ + std::swap(m_Storage, other.m_Storage); + other.Dtor(); + } + return *this; + } + Wrapper& operator=(const Wrapper&) = delete; + + + // Allow a CAPI handle to be taken over by a Wrapper + Wrapper(WrapperDetail::HandleMover handleMover) noexcept + : Wrapper(handleMover.handle, handleMover.isReference) + { WRAPPER_TRACE(); } + +protected: + // Simplify Derived's move assignment operators + Derived& moveAssign(Derived&& other) noexcept{ WRAPPER_TRACE(); + return static_cast(operator=(std::move(other))); + } + + +private: + StorageType m_Storage; + +}; diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference.cpp new file mode 100644 index 00000000..d0cd64da --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference.cpp @@ -0,0 +1,194 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "android/log.h" + +#include "hpp/CheckRuntime.hpp" +#include "hpp/SetBuilderOptions.hpp" +#include "hpp/Util.hpp" +#include "LoadContainer.hpp" +#include "CreateUserBuffer.hpp" +#include "LoadInputTensor.hpp" + +#include +#include +#include + +std::unique_ptr snpe_HRNET; +std::unique_ptr snpe_BB; + +std::mutex mtx; +static zdl::DlSystem::Runtime_t runtime = zdl::DlSystem::Runtime_t::CPU; +static zdl::DlSystem::RuntimeList runtimeList; +bool useUserSuppliedBuffers = true; +bool useIntBuffer = false; + +zdl::DlSystem::UserBufferMap inputMap, outputMap; +std::vector > snpeUserBackedInputBuffers, snpeUserBackedOutputBuffers; +std::unordered_map > applicationOutputBuffers; +std::unordered_map > applicationInputBuffers; +int bitWidth = 32; + + +#include +#include + +std::string build_network_BB(const uint8_t * dlc_buffer_BB, const size_t dlc_size_BB, const char runtime_arg, ModelName modelName) +{ + std::string outputLogger; + bool usingInitCaching = false; //shubham: TODO check with true + + std::unique_ptr container_BB = nullptr ; + + container_BB = loadContainerFromBuffer(dlc_buffer_BB, dlc_size_BB); + + if (container_BB == nullptr) { + LOGE("Error while opening the container file."); + return "Error while opening the container file.\n"; + } + + runtimeList.clear(); + LOGI("runtime arg %c",runtime_arg); + zdl::DlSystem::Runtime_t runtime = zdl::DlSystem::Runtime_t::CPU; + if (runtime_arg == 'D'){ + runtime = zdl::DlSystem::Runtime_t::DSP; + LOGI("Added DSP"); + } + else if (runtime_arg == 'G') + { + runtime = zdl::DlSystem::Runtime_t::GPU_FLOAT32_16_HYBRID; //can be written as GPU + LOGI("Added GPU"); + } + + if(runtime != zdl::DlSystem::Runtime_t::UNSET) + { + bool ret = runtimeList.add(checkRuntime(runtime)); + if(ret == false){ + LOGE("Cannot set runtime"); + return outputLogger + "\nCannot set runtime"; + } + } else { + return outputLogger + "\nCannot set runtime"; + } + + + mtx.lock(); + snpe_BB = setBuilderOptions(container_BB, runtime, runtimeList, useUserSuppliedBuffers, usingInitCaching, modelName); + mtx.unlock(); + + if (snpe_BB == nullptr) { + LOGE("SNPE Prepare failed: Builder option failed for BB"); + outputLogger += "Model Prepare failed for BB"; + return outputLogger + "SNPE Prepare failed for BB"; + } + + outputLogger += "\nBB Model Network Prepare success !!!\n"; + + //Creating Buffer + createInputBufferMap(inputMap, applicationInputBuffers, snpeUserBackedInputBuffers, snpe_BB, useIntBuffer, bitWidth); + createOutputBufferMap(outputMap, applicationOutputBuffers, snpeUserBackedOutputBuffers, snpe_BB, useIntBuffer, bitWidth); + return outputLogger; +} + + + +bool executeDLC(cv::Mat &img, int orig_width, int orig_height, int &numberofobj, std::vector> &BB_coords, std::vector &BB_names, Model *modelobj) { + + LOGI("execute_net_BB"); + ATrace_beginSection("preprocessing"); + + struct timeval start_time, end_time; + float milli_time, seconds, useconds; + + mtx.lock(); + assert(snpe_BB!=nullptr); + + if(!loadInputUserBuffer(applicationInputBuffers, snpe_BB, img, inputMap, bitWidth, modelobj)) + { + LOGE("Failed to load Input UserBuffer"); + mtx.unlock(); + return false; + } + + //std::string name_out_boxes = "885"; + //std::string name_out_classes = "877"; + + // get output tensor names of the network that need to be populated + const auto &outputNamesOpt = snpe_BB->getOutputTensorNames(); + if (!outputNamesOpt) throw std::runtime_error("Error obtaining output tensor names"); + const zdl::DlSystem::StringList &outputNames = *outputNamesOpt; + assert(outputNames.size() > 0); + + if (outputNames.size()) LOGI("Preprocessing and loading in application Output Buffer for BB"); + + std::string name_out_boxes; + + //YoloX is using only single output tensor + if (modelobj->model_name != YoloX) { + name_out_boxes = outputNames.at(1); + LOGI("Filling %s buffer name_out_boxes", name_out_boxes.c_str()); + } + + + std::string name_out_classes = outputNames.at(0); + LOGI("Filling %s buffer name_out_classes", name_out_classes.c_str()); + + ATrace_endSection(); + gettimeofday(&start_time, NULL); + ATrace_beginSection("inference time"); + + bool execStatus = snpe_BB->execute(inputMap, outputMap); + ATrace_endSection(); + ATrace_beginSection("postprocessing time"); + gettimeofday(&end_time, NULL); + seconds = end_time.tv_sec - start_time.tv_sec; //seconds + useconds = end_time.tv_usec - start_time.tv_usec; //milliseconds + milli_time = ((seconds) * 1000 + useconds/1000.0); + //LOGI("Inference time %f ms", milli_time); + + if(execStatus== true){ + LOGI("Exec BB status is true"); + } + else{ + LOGE("Exec BB status is false"); + mtx.unlock(); + return false; + } + + std::vector BBout_boxcoords; + + //YoloX is using only single output tensor + if (modelobj->model_name != YoloX) { + LOGI("reading output name_out_boxes"); + BBout_boxcoords = applicationOutputBuffers.at(name_out_boxes); + } + + LOGI("reading output name_out_classes"); + std::vector BBout_class = applicationOutputBuffers.at(name_out_classes); + //LOGI("reading output done. Calling postprocess"); + + modelobj->postprocess(orig_width, orig_height, numberofobj, BB_coords, BB_names, BBout_boxcoords, BBout_class, milli_time); + + ATrace_endSection(); + mtx.unlock(); + return true; +} + diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference_helper.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference_helper.cpp new file mode 100644 index 00000000..bef75104 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/inference_helper.cpp @@ -0,0 +1,288 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +#include +#include +#include +#include +#include +#include +#include "android/log.h" + +#include "zdl/SNPE/SNPE.hpp" +#include "zdl/SNPE/SNPEFactory.hpp" +#include "zdl/DlSystem/DlVersion.hpp" +#include "zdl/DlSystem/DlEnums.hpp" +#include "zdl/DlSystem/String.hpp" +#include "zdl/DlContainer/IDlContainer.hpp" +#include "zdl/SNPE/SNPEBuilder.hpp" +#include "zdl/DlSystem/ITensor.hpp" +#include "zdl/DlSystem/StringList.hpp" +#include "zdl/DlSystem/TensorMap.hpp" +#include "zdl/DlSystem/TensorShape.hpp" +#include "DlSystem/ITensorFactory.hpp" + +#include "hpp/LoadInputTensor.hpp" +#include "hpp/Util.hpp" +#include "inference.h" + +bool SetAdspLibraryPath(std::string nativeLibPath) { + nativeLibPath += ";/data/local/tmp/mv_dlc;/vendor/lib/rfsa/adsp;/vendor/dsp/cdsp;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp"; + + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "ADSP Lib Path = %s \n", nativeLibPath.c_str()); + std::cout << "ADSP Lib Path = " << nativeLibPath << std::endl; + + return setenv("ADSP_LIBRARY_PATH", nativeLibPath.c_str(), 1 /*override*/) == 0; +} + + +std::unique_ptr loadContainerFromBuffer(const uint8_t * buffer, const size_t size) +{ + std::unique_ptr container; + container = zdl::DlContainer::IDlContainer::open(buffer, size); + return container; +} + + +zdl::DlSystem::Runtime_t checkRuntime(zdl::DlSystem::Runtime_t runtime) +{ + static zdl::DlSystem::Version_t Version = zdl::SNPE::SNPEFactory::getLibraryVersion(); + + LOGI("SNPE Version = %s", Version.asString().c_str()); //Print Version number + + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(runtime)) { + LOGE("Selected runtime not present. Falling back to GPU."); + runtime = zdl::DlSystem::Runtime_t::GPU; + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(runtime)){ + LOGE("Selected runtime not present. Falling back to CPU."); + runtime = zdl::DlSystem::Runtime_t::CPU; + } + } + + return runtime; +} + +std::unique_ptr setBuilderOptions(std::unique_ptr & container, + zdl::DlSystem::Runtime_t runtime, + zdl::DlSystem::RuntimeList runtimeList, + bool useUserSuppliedBuffers, + bool useCaching, + ModelName modelName) +{ + std::unique_ptr snpe; + zdl::SNPE::SNPEBuilder snpeBuilder(container.get()); + + if(runtimeList.empty()) + { + runtimeList.add(runtime); + } + + std::string platformOptionStr = "useAdaptivePD:ON"; +// if (isSignedStatus == UNSIGNED_PD) { + // use unsignedPD feature for untrusted app. + // platformOptionStr += "unsignedPD:ON"; +// } + zdl::DlSystem::PlatformConfig platformConfig; + bool setSuccess = platformConfig.setPlatformOptions(platformOptionStr); + if (!setSuccess) + LOGE("=========> failed to set platformconfig: %s", platformOptionStr.c_str()); + else + LOGI("=========> platformconfig set: %s", platformOptionStr.c_str()); + + bool isValid = platformConfig.isOptionsValid(); + if (!isValid) + LOGE("=========> platformconfig option is invalid"); + else + LOGI("=========> platformconfig option: valid"); + + + zdl::DlSystem::StringList stringruntime = runtimeList.getRuntimeListNames(); + for (const char *name : stringruntime) + LOGI("runtime sh %s", name); + + snpe = snpeBuilder.setOutputLayers({}) + .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::BURST) + .setExecutionPriorityHint( + zdl::DlSystem::ExecutionPriorityHint_t::HIGH) + .setRuntimeProcessorOrder(runtimeList) + .setUseUserSuppliedBuffers(useUserSuppliedBuffers) + .setPlatformConfig(platformConfig) + .setInitCacheMode(useCaching) + .setUnconsumedTensorsAsOutputs(true) + .build(); + + return snpe; + +} + +// ==============================User Buffer func=================================== // +// ================================================================================= // + + +//CreateUserbuffer INPUT/OUTPUT for BB +void createUserBuffer(zdl::DlSystem::UserBufferMap& userBufferMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + const char * name, + const bool isTfNBuffer, + int bitWidth) +{ + + auto bufferAttributesOpt = snpe->getInputOutputBufferAttributes(name); + if (!bufferAttributesOpt) throw std::runtime_error(std::string("Error obtaining attributes for input tensor ") + name); + + // calculate the size of buffer required by the input tensor + const zdl::DlSystem::TensorShape& bufferShape = (*bufferAttributesOpt)->getDims(); + + size_t bufferElementSize = 0; + if (isTfNBuffer) { + bufferElementSize = bitWidth / 8; + } + else { + bufferElementSize = sizeof(float); + } + + // Calculate the stride based on buffer strides. + // Note: Strides = Number of bytes to advance to the next element in each dimension. + // For example, if a float tensor of dimension 2x4x3 is tightly packed in a buffer of 96 bytes, then the strides would be (48,12,4) + // Note: Buffer stride is usually known and does not need to be calculated. + + int num_dims = bufferShape.rank(); //bufferShape rank is generally 1 more than expected, as it add 1 for batchSize, so 320x320x3 will look like 1x320x320x3 + std::vector strides(num_dims); + strides[strides.size() - 1] = bufferElementSize; + size_t stride = strides[strides.size() - 1]; + for (size_t i = num_dims - 1; i > 0; i--) { + stride *= bufferShape[i]; + strides[i - 1] = stride; + //LOGI("\nstrides[%d]: %d",i,stride); + //LOGI("\nbuffershape[%d]: %d",i,bufferShape[i]); + } + + size_t bufSize=bufferElementSize; + for(int i=0;i userBufferEncoding; + if (isTfNBuffer) + userBufferEncoding = std::unique_ptr( + new zdl::DlSystem::UserBufferEncodingTfN(0, 1.0, bitWidth)); + else + userBufferEncoding = std::unique_ptr( + new zdl::DlSystem::UserBufferEncodingFloat()); + + // create user-backed storage to load input data onto it + applicationBuffers.emplace(name, std::vector(bufSize)); + + // create SNPE user buffer from the user-backed buffer + zdl::DlSystem::IUserBufferFactory &ubFactory = zdl::SNPE::SNPEFactory::getUserBufferFactory(); + snpeUserBackedBuffers.push_back( + ubFactory.createUserBuffer(applicationBuffers.at(name).data(), + bufSize, + strides, + userBufferEncoding.get())); + if (snpeUserBackedBuffers.back() == nullptr) + throw std::runtime_error(std::string("Error while creating user buffer.")); + + // add the user-backed buffer to the inputMap, which is later on fed to the network for execution + userBufferMap.add(name, snpeUserBackedBuffers.back().get()); + +} + +/* + Cretae OutPut Buffer Map for BB + */ +void createOutputBufferMap(zdl::DlSystem::UserBufferMap& outputMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + bool isTfNBuffer, + int bitWidth) +{ + //LOGI("Creating Output Buffer for BB"); + const auto& outputNamesOpt = snpe->getOutputTensorNames(); + if (!outputNamesOpt) throw std::runtime_error("Error obtaining output tensor names"); + const zdl::DlSystem::StringList& outputNames = *outputNamesOpt; + + // create SNPE user buffers for each application storage buffer + for (const char *name : outputNames) { + LOGI("Creating output buffer %s", name); + createUserBuffer(outputMap, applicationBuffers, snpeUserBackedBuffers, snpe, name, isTfNBuffer, bitWidth); + } + +} +/* + * Create Input Buffer Map for BB + */ +void createInputBufferMap(zdl::DlSystem::UserBufferMap& inputMap, + std::unordered_map>& applicationBuffers, + std::vector>& snpeUserBackedBuffers, + std::unique_ptr& snpe, + bool isTfNBuffer, + int bitWidth) { + //LOGI("Creating Input Buffer for BB"); + const auto &inputNamesOpt = snpe->getInputTensorNames(); + if (!inputNamesOpt) throw std::runtime_error("Error obtaining input tensor names"); + const zdl::DlSystem::StringList &inputNames = *inputNamesOpt; + assert(inputNames.size() > 0); + + // create SNPE user buffers for each application storage buffer + for (const char *name: inputNames) { + LOGI("Creating Input Buffer = %s", name); + createUserBuffer(inputMap, applicationBuffers, snpeUserBackedBuffers, snpe, name, + isTfNBuffer, bitWidth); + } +} + +//Preprocessing and loading in application Input Buffer for BB +bool loadInputUserBuffer(std::unordered_map>& applicationBuffers, + std::unique_ptr& snpe, + cv::Mat &img, + zdl::DlSystem::UserBufferMap& inputMap, + int bitWidth, Model *modelobj) { + + // get input tensor names of the network that need to be populated + const auto &inputNamesOpt = snpe->getInputTensorNames(); + if (!inputNamesOpt) throw std::runtime_error("Error obtaining input tensor names"); + const zdl::DlSystem::StringList &inputNames = *inputNamesOpt; + assert(inputNames.size() > 0); + + if (inputNames.size()) LOGI("Preprocessing and loading in application Input Buffer for BB"); + + + for (size_t j = 0; j < inputNames.size(); j++) { + const char *name = inputNames.at(j); + LOGI("Filling %s buffer ", name); + + if(bitWidth == 8 || bitWidth == 16) { + LOGE("bitwidth 8 and 16 are NOT DEFINED"); + return false; + } else { + + std::vector dims; + auto bufferAttributesOpt = snpe->getInputOutputBufferAttributes(name); + if (!bufferAttributesOpt) throw std::runtime_error(std::string("Error obtaining attributes for input tensor ") + name); + + const zdl::DlSystem::TensorShape& bufferShape = (*bufferAttributesOpt)->getDims(); + int num_dims = bufferShape.rank(); + for(int i=0;ipreprocess(applicationBuffers.at(name),img, dims); //functions loads data in applicationBuffer + + } + } + return true; +} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/objectdetectionYoloNas.cpp b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/objectdetectionYoloNas.cpp new file mode 100644 index 00000000..c53cfa54 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/cpp/objectdetectionYoloNas.cpp @@ -0,0 +1,195 @@ +// -*- mode: cpp -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +#include +using namespace cv; +#include +#include +#include +#include +#include + +#include "hpp/inference.h" +#include "hpp/Util.hpp" + +#include "zdl/SNPE/SNPE.hpp" +#include "zdl/SNPE/SNPEFactory.hpp" + +#include "YOLONAS_Model.h" +#include "SSDMobileNetV2_Model.h" +#include "YOLO_X_Model.h" + +Model *modelobj; + +extern "C" JNIEXPORT jstring JNICALL +Java_com_qcom_aistack_1objdetect_SNPEHelper_queryRuntimes( + JNIEnv* env, + jobject /* this */, + jstring native_dir_path) { + const char *cstr = env->GetStringUTFChars(native_dir_path, nullptr); + env->ReleaseStringUTFChars(native_dir_path, cstr); + + std::string runT_Status; + std::string nativeLibPath = std::string(cstr); + +// runT_Status += "\nLibs Path : " + nativeLibPath + "\n"; + + if (!SetAdspLibraryPath(nativeLibPath)) { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "Failed to set ADSP Library Path\n"); + + runT_Status += "\nFailed to set ADSP Library Path\nTerminating"; + return env->NewStringUTF(runT_Status.c_str()); + } + + // ====================================================================================== // + runT_Status = "Querying Runtimes : \n\n"; + // DSP unsignedPD check + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(zdl::DlSystem::Runtime_t::DSP,zdl::DlSystem::RuntimeCheckOption_t::UNSIGNEDPD_CHECK)) { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "UnsignedPD DSP runtime : Absent\n"); + runT_Status += "UnsignedPD DSP runtime : Absent\n"; + } + else { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "UnsignedPD DSP runtime : Present\n"); + runT_Status += "UnsignedPD DSP runtime : Present\n"; + } + // DSP signedPD check + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(zdl::DlSystem::Runtime_t::DSP)) { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "DSP runtime : Absent\n"); + runT_Status += "DSP runtime : Absent\n"; + } + else { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "DSP runtime : Present\n"); + runT_Status += "DSP runtime : Present\n"; + } + // GPU check + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(zdl::DlSystem::Runtime_t::GPU)) { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "GPU runtime : Absent\n"); + runT_Status += "GPU runtime : Absent\n"; + } + else { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "GPU runtime : Present\n"); + runT_Status += "GPU runtime : Present\n"; + } + // CPU check + if (!zdl::SNPE::SNPEFactory::isRuntimeAvailable(zdl::DlSystem::Runtime_t::CPU)) { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "CPU runtime : Absent\n"); + runT_Status += "CPU runtime : Absent\n"; + } + else { + __android_log_print(ANDROID_LOG_INFO, "SNPE ", "CPU runtime : Present\n"); + runT_Status += "CPU runtime : Present\n"; + } + + return env->NewStringUTF(runT_Status.c_str()); +} + + + +//initializing network +extern "C" +JNIEXPORT jstring JNICALL +Java_com_qcom_aistack_1objdetect_SNPEHelper_initSNPE(JNIEnv *env, jobject thiz, jobject asset_manager, jchar runtime, jstring jdlc_name) { + LOGI("Reading SNPE DLC ..."); + std::string result; + + //AAssetManager* mgr = AAssetManager_fromJava(env, asset_manager); + //AAsset* asset_BB = AAssetManager_open(mgr, "Quant_yoloNas_s_320.dlc", AASSET_MODE_UNKNOWN); + + const char *cstr = env->GetStringUTFChars(jdlc_name, 0); + AAssetManager* mgr = AAssetManager_fromJava(env, asset_manager); + AAsset* asset_BB = AAssetManager_open(mgr, cstr, AASSET_MODE_UNKNOWN); + + if(strcmp(cstr,"Quant_yoloNas_s_320.dlc")==0) { + LOGI("Quant_yoloNas_s_320 dlc"); + } + + modelobj= new YOLONAS_Model(); + + //Changing PrePost for different models + if (strcmp(cstr,"ssd_mobilenetV2_without_ABP-NMS_Q.dlc")==0){ + LOGI("ssd_mobilenetV2_without_ABP-NMS_Q dlc"); + modelobj = new SSDMobileNetV2_Model(); + modelobj->msg(); + } + else if(strcmp(cstr,"yolox_x_212_Q.dlc")==0){ + LOGI("YOLO_X dlc"); + modelobj = new YOLO_X_Model(); + modelobj->msg(); + } + + env->ReleaseStringUTFChars(jdlc_name, cstr); + + + if (NULL == asset_BB) { + LOGE("Failed to load ASSET, needed to load DLC\n"); + result = "Failed to load ASSET, needed to load DLC\n"; + return env->NewStringUTF(result.c_str()); + } + + long dlc_size_BB = AAsset_getLength(asset_BB); + LOGI("DLC BB Size = %ld MB\n", dlc_size_BB / (1024*1024)); + result += "DLC BB Size = " + std::to_string(dlc_size_BB); + char* dlc_buffer_BB = (char*) malloc(sizeof(char) * dlc_size_BB); + AAsset_read(asset_BB, dlc_buffer_BB, dlc_size_BB); + + result += "\n\nBuilding Models DLC Network:\n"; + result += build_network_BB(reinterpret_cast(dlc_buffer_BB), dlc_size_BB,runtime, modelobj->model_name); + + return env->NewStringUTF(result.c_str()); +} + + +//inference +extern "C" +JNIEXPORT jint JNICALL +Java_com_qcom_aistack_1objdetect_SNPEHelper_inferSNPE(JNIEnv *env, jobject thiz, jlong inputMat, jint actual_width, jint actual_height, + jobjectArray jboxcoords, jobjectArray objnames) { + + LOGI("infer SNPE S"); + + cv::Mat &img = *(cv::Mat*) inputMat; + std::string bs; + int numberofobj = 0; + std::vector> BB_coords; + std::vector BB_names; + + bool status = executeDLC(img,actual_width, actual_height, numberofobj, BB_coords, BB_names, modelobj); + + if(numberofobj ==0) + { + LOGI("No object detected"); + } + else if (numberofobj == -1){ + LOGE("ERROR in loading model properly"); + return -1; + } + else if(status == false) + { + LOGE("fatal ERROR"); + return 0; + } + else { + //LOGI("number of detected objects: %d",numberofobj); + + for (int z = 0; z < numberofobj; z++){ + jfloatArray boxcoords = (jfloatArray) env->GetObjectArrayElement(jboxcoords, z); + env->SetObjectArrayElement(objnames, z,env->NewStringUTF(BB_names[z].data())); + + + float tempbox[5]; //4 coords and 1 processing time + for(int k=0;k<5;k++) + tempbox[k]=BB_coords[z][k]; + env->SetFloatArrayRegion(boxcoords,0,5,tempbox); + } + //LOGI("executeDLC_returned successfully"); + } + //LOGD("infer SNPE E"); + return numberofobj; + +} \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/ic_launcher-playstore.png b/ai-solutions/android/03-ObjectDetection/app/src/main/ic_launcher-playstore.png new file mode 100644 index 00000000..58cdfd91 Binary files /dev/null and b/ai-solutions/android/03-ObjectDetection/app/src/main/ic_launcher-playstore.png differ diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/CameraFragment.java b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/CameraFragment.java new file mode 100644 index 00000000..4534ddf7 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/CameraFragment.java @@ -0,0 +1,1131 @@ +// -*- mode: java -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= + +package com.qcom.aistack_objdetect; + +import android.Manifest; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.graphics.SurfaceTexture; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CaptureFailure; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; +import android.view.LayoutInflater; +import android.view.Surface; +import android.view.TextureView; +import android.view.View; +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.Arrays; + + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.graphics.ImageFormat; +import android.graphics.Point; +import android.graphics.RectF; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraMetadata; +import android.hardware.camera2.params.StreamConfigurationMap; +import android.media.Image; +import android.media.ImageReader; +import android.support.v4.app.DialogFragment; +import android.util.Size; +import android.util.SparseIntArray; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + + + +public class CameraFragment extends Fragment +{ + + /** + * Conversion from screen rotation to JPEG orientation. + */ + private SNPEHelper mSnpeHelper; + public long tic = 0,tic2=0; + private boolean mNetworkLoaded; + + private ProgressDialog dialog_model_error; + + private FragmentRender mFragmentRender; + + public int fps=0,frame_count =-1; + public static char runtime_var; + + public static String dlc_name_var; + + private String mCameraId; + private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); + private static final int REQUEST_CAMERA_PERMISSION = 1; + private static final String FRAGMENT_DIALOG = "dialog"; + + static { + ORIENTATIONS.append(Surface.ROTATION_0, 90); + ORIENTATIONS.append(Surface.ROTATION_90, 0); + ORIENTATIONS.append(Surface.ROTATION_180, 270); + ORIENTATIONS.append(Surface.ROTATION_270, 180); + } + + + /** + * Camera state: Showing camera preview. + */ + private static final int STATE_PREVIEW = 0; + + /** + * Camera state: Waiting for the focus to be locked. + */ + private static final int STATE_WAITING_LOCK = 1; + + /** + * Camera state: Waiting for the exposure to be precapture state. + */ + private static final int STATE_WAITING_PRECAPTURE = 2; + + /** + * Camera state: Waiting for the exposure state to be something other than precapture. + */ + private static final int STATE_WAITING_NON_PRECAPTURE = 3; + + /** + * Camera state: Picture was taken. + */ + private static final int STATE_PICTURE_TAKEN = 4; + + /** + * Max preview width that is guaranteed by Camera2 API + */ + private static final int MAX_PREVIEW_WIDTH = 1920; + + /** + * Max preview height that is guaranteed by Camera2 API + */ + private static final int MAX_PREVIEW_HEIGHT = 1080; + + private TextureView mTextureView; + /** + * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a + * {@link TextureView}. + + */ + private final TextureView.SurfaceTextureListener mSurfaceTextureListener + = new TextureView.SurfaceTextureListener() { + + @Override + public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) { +// System.out.println("Textureiew widthxheight: "+mTextureView.getWidth()+ mTextureView.getHeight()); + openCamera(width, height); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) { + configureTransform(width, height); + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture texture) { + } + + }; + + /** + * A {@link CameraCaptureSession } for camera preview. + */ + private CameraCaptureSession mCaptureSession; + + /** + * A reference to the opened {@link CameraDevice}. + */ + private CameraDevice mCameraDevice; + + /** + * The {@link android.util.Size} of camera preview. + */ + private Size mPreviewSize; + + /** + * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state. + */ + private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { + + @Override + public void onOpened(@NonNull CameraDevice cameraDevice) { + // This method is called when the camera is opened. We start camera preview here. + mCameraOpenCloseLock.release(); + mCameraDevice = cameraDevice; + createCameraPreviewSession(); + } + + @Override + public void onDisconnected(@NonNull CameraDevice cameraDevice) { + mCameraOpenCloseLock.release(); + cameraDevice.close(); + mCameraDevice = null; + } + + @Override + public void onError(@NonNull CameraDevice cameraDevice, int error) { + mCameraOpenCloseLock.release(); + cameraDevice.close(); + mCameraDevice = null; + Activity activity = getActivity(); + if (null != activity) { + activity.finish(); + } + } + + }; + + public static CameraFragment create(Bundle SavedInstanceState) { + System.out.println("==>CameraFragment"); + final CameraFragment fragment = new CameraFragment(); + runtime_var = SavedInstanceState.getChar("key"); + dlc_name_var = SavedInstanceState.getString("selected_dlc_name"); + System.out.println("CameraFragment class got data runtime_var="+runtime_var); + System.out.println("CameraFragment class got data selected_dlc_name="+dlc_name_var); + return fragment; + } + /** + * An additional thread for running tasks that shouldn't block the UI. + */ + private HandlerThread mBackgroundThread; + + /** + * A {@link Handler} for running tasks in the background. + */ + private Handler mBackgroundHandler; + + /** + * An {@link ImageReader} that handles still image capture. + */ + private ImageReader mImageReader; + + /** + * This is the output file for our picture. + */ + private File mFile; + + /** + * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a + * still image is ready to be saved. + */ + private final ImageReader.OnImageAvailableListener mOnImageAvailableListener + = new ImageReader.OnImageAvailableListener() { + + @Override + public void onImageAvailable(ImageReader reader) { + mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile)); + } + + }; + + /** + * {@link CaptureRequest.Builder} for the camera preview + */ + private CaptureRequest.Builder mPreviewRequestBuilder; + + /** + * {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder} + */ + private CaptureRequest mPreviewRequest; + + /** + * The current state of camera state for taking pictures. + * + * @see #mCaptureCallback + */ + private int mState = STATE_PREVIEW; + + /** + * A {@link Semaphore} to prevent the app from exiting before closing the camera. + */ + private Semaphore mCameraOpenCloseLock = new Semaphore(1); + + /** + * Whether the current camera device supports Flash or not. + */ + private boolean mFlashSupported; + + /** + * Orientation of the camera sensor + */ + private int mSensorOrientation; + /** + * A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture. + */ + private CameraCaptureSession.CaptureCallback mCaptureCallback + = new CameraCaptureSession.CaptureCallback() { + + private void process(CaptureResult result) { + switch (mState) { + case STATE_PREVIEW: { + // We have nothing to do when the camera preview is working normally. + break; + } + case STATE_WAITING_LOCK: { + Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); + if (afState == null) { + captureStillPicture(); + } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || + CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) { + // CONTROL_AE_STATE can be null on some devices + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + if (aeState == null || + aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { + mState = STATE_PICTURE_TAKEN; + captureStillPicture(); + } else { + runPrecaptureSequence(); + } + } + break; + } + case STATE_WAITING_PRECAPTURE: { + // CONTROL_AE_STATE can be null on some devices + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + if (aeState == null || + aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE || + aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { + mState = STATE_WAITING_NON_PRECAPTURE; + } + break; + } + case STATE_WAITING_NON_PRECAPTURE: { + // CONTROL_AE_STATE can be null on some devices + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { + mState = STATE_PICTURE_TAKEN; + captureStillPicture(); + } + break; + } + } + } + + @Override + public void onCaptureProgressed(@NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull CaptureResult partialResult) { + process(partialResult); + } + + @Override + public void onCaptureCompleted(@NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull TotalCaptureResult result) { + process(result); + } + + }; + + + /** + * Shows a {@link Toast} on the UI thread. + * + * @param text The message to show + */ + private void showToast(final String text) { + final Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(activity, text, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + /** + * Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that + * is at least as large as the respective texture view size, and that is at most as large as the + * respective max size, and whose aspect ratio matches with the specified value. If such size + * doesn't exist, choose the largest one that is at most as large as the respective max size, + * and whose aspect ratio matches with the specified value. + * + * @param choices The list of sizes that the camera supports for the intended output + * class + * @param textureViewWidth The width of the texture view relative to sensor coordinate + * @param textureViewHeight The height of the texture view relative to sensor coordinate + * @param maxWidth The maximum width that can be chosen + * @param maxHeight The maximum height that can be chosen + * @param aspectRatio The aspect ratio + * @return The optimal {@code Size}, or an arbitrary one if none were big enough + */ + private static Size chooseOptimalSize(Size[] choices, int textureViewWidth, + int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) { + + // Collect the supported resolutions that are at least as big as the preview Surface + List bigEnough = new ArrayList<>(); + // Collect the supported resolutions that are smaller than the preview Surface + List notBigEnough = new ArrayList<>(); + int w = aspectRatio.getWidth(); + int h = aspectRatio.getHeight(); + for (Size option : choices) { + if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight && + option.getHeight() == option.getWidth() * h / w) { + if (option.getWidth() >= textureViewWidth && + option.getHeight() >= textureViewHeight) { + bigEnough.add(option); + } else { + notBigEnough.add(option); + } + } + } + + // Pick the smallest of those big enough. If there is no one big enough, pick the + // largest of those not big enough. + if (bigEnough.size() > 0) { + return Collections.min(bigEnough, new CompareSizesByArea()); + } else if (notBigEnough.size() > 0) { + return Collections.max(notBigEnough, new CompareSizesByArea()); + } else { + return choices[0]; + } + } + + public static CameraFragment newInstance() { + return new CameraFragment(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_camera, container, false); + } + + @Override + public void onViewCreated(final View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mTextureView = view.findViewById(R.id.surface); + mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); + mFragmentRender = view.findViewById(R.id.fragmentRender); + + } + + @Override + public void onResume() { + super.onResume(); + + startBackgroundThread(); + + // When the screen is turned off and turned back on, the SurfaceTexture is already + // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open + // a camera and start preview from here (otherwise, we wait until the surface is ready in + // the SurfaceTextureListener). + if (mTextureView.isAvailable()) { + openCamera(mTextureView.getWidth(), mTextureView.getHeight()); + } else { + mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); + } + + ensureNetCreated(); + + } + + @Override + public void onPause() { + closeCamera(); + stopBackgroundThread(); + super.onPause(); + } + + @Override + public void onDestroy() { + stopBackgroundThread(); + closeCamera(); + super.onDestroy(); + } + + private void requestCameraPermission() { + if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { + new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG); + } else { + requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + if (requestCode == REQUEST_CAMERA_PERMISSION) { + if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) { + ErrorDialog.newInstance(getString(R.string.request_permission)) + .show(getChildFragmentManager(), FRAGMENT_DIALOG); + } + } else { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + + /** + * Sets up member variables related to camera. + * + * @param width The width of available size for camera preview + * @param height The height of available size for camera preview + */ + @SuppressWarnings("SuspiciousNameCombination") + private void setUpCameraOutputs(int width, int height) { + Activity activity = getActivity(); + CameraManager mCameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); + try { + for (String cameraId : mCameraManager.getCameraIdList()) { + CameraCharacteristics characteristics + = mCameraManager.getCameraCharacteristics(cameraId); + + // We don't use a front facing camera in this sample. + Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); + if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) { + continue; + } + + StreamConfigurationMap map = characteristics.get( + CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); + if (map == null) { + continue; + } + + // For still image captures, we use the largest available size. + Size largest = Collections.max( + Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), + new CompareSizesByArea()); + mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), + ImageFormat.JPEG, /*maxImages*/2); + mImageReader.setOnImageAvailableListener( + mOnImageAvailableListener, mBackgroundHandler); + + // Find out if we need to swap dimension to get the preview size relative to sensor + // coordinate. + int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + //noinspection ConstantConditions + mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); + boolean swappedDimensions = false; + switch (displayRotation) { + case Surface.ROTATION_0: + case Surface.ROTATION_180: + if (mSensorOrientation == 90 || mSensorOrientation == 270) { + swappedDimensions = true; + } + break; + case Surface.ROTATION_90: + case Surface.ROTATION_270: + if (mSensorOrientation == 0 || mSensorOrientation == 180) { + swappedDimensions = true; + } + break; + default: + System.out.println("Display rotation is invalid: " + displayRotation); + } + + Point displaySize = new Point(); + activity.getWindowManager().getDefaultDisplay().getSize(displaySize); + int rotatedPreviewWidth = width; + int rotatedPreviewHeight = height; + int maxPreviewWidth = displaySize.x; + int maxPreviewHeight = displaySize.y; + + if (swappedDimensions) { + rotatedPreviewWidth = height; + rotatedPreviewHeight = width; + maxPreviewWidth = displaySize.y; + maxPreviewHeight = displaySize.x; + } + + if (maxPreviewWidth > MAX_PREVIEW_WIDTH) { + maxPreviewWidth = MAX_PREVIEW_WIDTH; + } + + if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) { + maxPreviewHeight = MAX_PREVIEW_HEIGHT; + } + + // Danger, W.R.! Attempting to use too large a preview size could exceed the camera + // bus' bandwidth limitation, resulting in gorgeous previews but the storage of + // garbage capture data. + mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), + rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth, + maxPreviewHeight, largest); + + // Check if the flash is supported. + Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); + mFlashSupported = available == null ? false : available; + + mCameraId = cameraId; + return; + } + } catch (CameraAccessException e) { + e.printStackTrace(); + } catch (NullPointerException e) { + // Currently an NPE is thrown when the Camera2API is used but not supported on the + // device this code runs. + ErrorDialog.newInstance(getString(R.string.camera_error)) + .show(getChildFragmentManager(), FRAGMENT_DIALOG); + } + } + + /** + * Opens the camera specified by {@link CameraFragment#mCameraId}. + */ + private void openCamera(int width, int height) { + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) + != PackageManager.PERMISSION_GRANTED) { + requestCameraPermission(); + return; + } + setUpCameraOutputs(width, height); + configureTransform(width, height); + Activity activity = getActivity(); + CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); + try { + if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { + throw new RuntimeException("Time out waiting to lock camera opening."); + } + manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while trying to lock camera opening.", e); + } + } + + /** + * Closes the current {@link CameraDevice}. + */ + private void closeCamera() { + try { + mCameraOpenCloseLock.acquire(); + if (null != mCaptureSession) { + mCaptureSession.close(); + mCaptureSession = null; + } + if (null != mCameraDevice) { + mCameraDevice.close(); + mCameraDevice = null; + } + if (null != mImageReader) { + mImageReader.close(); + mImageReader = null; + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while trying to lock camera closing.", e); + } finally { + mCameraOpenCloseLock.release(); + } + } + + /** + * Starts a background thread and its {@link Handler}. + */ + private void startBackgroundThread() { + mBackgroundThread = new HandlerThread("CameraBackground"); + mBackgroundThread.start(); + mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); + } + + /** + * Stops the background thread and its {@link Handler}. + */ + private void stopBackgroundThread() { + + if (mBackgroundThread!=null) { + + mBackgroundThread.quitSafely(); + + mBackgroundThread = null; + mBackgroundHandler = null; + + } + } + + /** + * Creates a new {@link CameraCaptureSession} for camera preview. + */ + private void createCameraPreviewSession() { + try { + SurfaceTexture texture = mTextureView.getSurfaceTexture(); + assert texture != null; + + // We configure the size of default buffer to be the size of camera preview we want. + texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); + + // This is the output Surface we need to start preview. + Surface surface = new Surface(texture); + + // We set up a CaptureRequest.Builder with the output Surface. + mPreviewRequestBuilder + = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + mPreviewRequestBuilder.addTarget(surface); + + //Shubham + try { + mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCapture(), + null); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + /** + * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`. + * This method should be called after the camera preview size is determined in + * setUpCameraOutputs and also the size of `mTextureView` is fixed. + * + * @param viewWidth The width of `mTextureView` + * @param viewHeight The height of `mTextureView` + */ + private void configureTransform(int viewWidth, int viewHeight) { + Activity activity = getActivity(); + if (null == mTextureView || null == mPreviewSize || null == activity) { + return; + } + int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + Matrix matrix = new Matrix(); + RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); + RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); + float centerX = viewRect.centerX(); + float centerY = viewRect.centerY(); + if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { + bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); + matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); + float scale = Math.max( + (float) viewHeight / mPreviewSize.getHeight(), + (float) viewWidth / mPreviewSize.getWidth()); + matrix.postScale(scale, scale, centerX, centerY); + matrix.postRotate(90 * (rotation - 2), centerX, centerY); + } else if (Surface.ROTATION_180 == rotation) { + matrix.postRotate(180, centerX, centerY); + } + mTextureView.setTransform(matrix); + } + + /** + * Lock the focus as the first step for a still image capture. + */ + private void lockFocus() { + try { + // This is how to tell the camera to lock focus. + mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, + CameraMetadata.CONTROL_AF_TRIGGER_START); + // Tell #mCaptureCallback to wait for the lock. + mState = STATE_WAITING_LOCK; + mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, + mBackgroundHandler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + /** + * Run the precapture sequence for capturing a still image. This method should be called when + * we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}. + */ + private void runPrecaptureSequence() { + try { + // This is how to tell the camera to trigger. + mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); + // Tell #mCaptureCallback to wait for the precapture sequence to be set. + mState = STATE_WAITING_PRECAPTURE; + mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, + mBackgroundHandler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + /** + * Capture a still picture. This method should be called when we get a response in + * {@link #mCaptureCallback} from both {@link #lockFocus()}. + */ + private void captureStillPicture() { + try { + final Activity activity = getActivity(); + if (null == activity || null == mCameraDevice) { + return; + } + // This is the CaptureRequest.Builder that we use to take a picture. + final CaptureRequest.Builder captureBuilder = + mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); + captureBuilder.addTarget(mImageReader.getSurface()); + + // Use the same AE and AF modes as the preview. + captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, + CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); + setAutoFlash(captureBuilder); + + // Orientation + int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation)); + + CameraCaptureSession.CaptureCallback CaptureCallback + = new CameraCaptureSession.CaptureCallback() { + + @Override + public void onCaptureCompleted(@NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull TotalCaptureResult result) { + showToast("Saved: " + mFile); + unlockFocus(); + } + }; + + mCaptureSession.stopRepeating(); + mCaptureSession.abortCaptures(); + mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + /** + * Retrieves the JPEG orientation from the specified screen rotation. + * + * @param rotation The screen rotation. + * @return The JPEG orientation (one of 0, 90, 270, and 360) + */ + private int getOrientation(int rotation) { + // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X) + // We have to take that into account and rotate JPEG properly. + // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS. + // For devices with orientation of 270, we need to rotate the JPEG 180 degrees. + return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360; + } + + /** + * Unlock the focus. This method should be called when still image capture sequence is + * finished. + */ + private void unlockFocus() { + try { + // Reset the auto-focus trigger + mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, + CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); + setAutoFlash(mPreviewRequestBuilder); + mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, + mBackgroundHandler); + // After this, the camera will go back to the normal state of preview. + mState = STATE_PREVIEW; + mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, + mBackgroundHandler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void setAutoFlash(CaptureRequest.Builder requestBuilder) { + if (mFlashSupported) { + requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, + CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); + } + } + + /** + * Saves a JPEG {@link Image} into the specified {@link File}. + */ + private static class ImageSaver implements Runnable { + + /** + * The JPEG image + */ + private final Image mImage; + /** + * The file we save the image into. + */ + private final File mFile; + + ImageSaver(Image image, File file) { + mImage = image; + mFile = file; + } + + @Override + public void run() { + ByteBuffer buffer = mImage.getPlanes()[0].getBuffer(); + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + FileOutputStream output = null; + try { + output = new FileOutputStream(mFile); + output.write(bytes); + } catch (IOException e) { + e.printStackTrace(); + } finally { + mImage.close(); + if (null != output) { + try { + output.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + } + + /** + * Compares two {@code Size}s based on their areas. + */ + static class CompareSizesByArea implements Comparator { + + @Override + public int compare(Size lhs, Size rhs) { + // We cast here to ensure the multiplications won't overflow + return Long.signum((long) lhs.getWidth() * lhs.getHeight() - + (long) rhs.getWidth() * rhs.getHeight()); + } + + } + + /** + * Shows an error message dialog. + */ + public static class ErrorDialog extends DialogFragment { + + private static final String ARG_MESSAGE = "message"; + + public static ErrorDialog newInstance(String message) { + ErrorDialog dialog = new ErrorDialog(); + Bundle args = new Bundle(); + args.putString(ARG_MESSAGE, message); + dialog.setArguments(args); + return dialog; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity activity = getActivity(); + return new AlertDialog.Builder(activity) + .setMessage(getArguments().getString(ARG_MESSAGE)) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + activity.finish(); + } + }) + .create(); + } + + } + + /** + * Shows OK/Cancel confirmation dialog about camera permission. + */ + public static class ConfirmationDialog extends DialogFragment { + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Fragment parent = getParentFragment(); + return new AlertDialog.Builder(getActivity()) + .setMessage(R.string.request_permission) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + parent.requestPermissions(new String[]{Manifest.permission.CAMERA}, + REQUEST_CAMERA_PERMISSION); + } + }) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Activity activity = parent.getActivity(); + if (activity != null) { + activity.finish(); + } + } + }) + .create(); + } + } + + public class CameraCapture extends android.hardware.camera2.CameraCaptureSession.StateCallback { + @Override + public void onConfigured(@NonNull android.hardware.camera2.CameraCaptureSession + cameraCaptureSession) { + mCaptureSession = cameraCaptureSession; + + try { + // Auto focus should be continuous for camera preview. + mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, + CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); + // Flash is automatically enabled when necessary. + setAutoFlash(mPreviewRequestBuilder); + // Finally, we start displaying the camera preview. + mPreviewRequest = mPreviewRequestBuilder.build(); + cameraCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), new CameraSession(), + mBackgroundHandler); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void onConfigureFailed(@NonNull android.hardware.camera2.CameraCaptureSession + cameraCaptureSession) { + } + + } + + private class CameraSession extends android.hardware.camera2.CameraCaptureSession.CaptureCallback { + + @Override + public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull + CaptureRequest request, @NonNull TotalCaptureResult result) { + + super.onCaptureCompleted(session, request, result); +// int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation(); + frame_count+=1; + + try { + if (frame_count == 0) { + tic = System.currentTimeMillis(); + } else { + tic2 = System.currentTimeMillis(); + fps = (int) (1000 / (tic2 - tic)); + tic = System.currentTimeMillis(); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("mNetworkLoaded: "+mNetworkLoaded +" runtime_var: "+runtime_var+" dlc_name_var: "+dlc_name_var); + + if (mNetworkLoaded == true ) { + + Bitmap mBitmap = mTextureView.getBitmap(mTextureView.getWidth(),mTextureView.getHeight()); + + ArrayList BBlist = new ArrayList<>(); + System.out.println("calling inference"); + + int infer_result = mSnpeHelper.snpeInference(mBitmap, fps, BBlist); + + //sanjeev - added temp dialogue info box to graceful exit if model not loaded properly + if (infer_result == -1) + { + if (dialog_model_error==null) { + + dialog_model_error = new ProgressDialog(getActivity()); + + getActivity().runOnUiThread(new Runnable() { + + @Override + public void run() { + + if (dialog_model_error!=null) { + try { + dialog_model_error.setMessage(getString(R.string.model_loading_error)); + dialog_model_error.show(); + }catch (Exception e){ + e.printStackTrace(); + Toast.makeText(getContext(),getString(R.string.model_loading_error), Toast.LENGTH_SHORT).show(); + } + } + } + }); + + } + + } + + mFragmentRender.setCoordsList(BBlist); + } + } + + @Override + public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull + CaptureRequest request, @NonNull CaptureFailure failure) { + super.onCaptureFailed(session, request, failure); + } + + @Override + public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull + CaptureRequest request, @NonNull CaptureResult partialResult) { + super.onCaptureProgressed(session, request, partialResult); + } + + @Override + public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull + CaptureRequest request, long timestamp, long frameNumber) { + super.onCaptureStarted(session, request, timestamp, frameNumber); + + } + + } + + /** + * Method to ensure if neural network is loaded + * + * @return + */ + private boolean ensureNetCreated() { + if (mSnpeHelper == null) { + // load the neural network for object detection with SNPE + mSnpeHelper = new SNPEHelper(getActivity().getApplication()); + + // Show UI dialog till the model is not loaded yet. + ProgressDialog dialog=new ProgressDialog(getActivity()); + dialog.setMessage("Loading Model.."); + dialog.show(); + + //TODO for time being disabling + new Thread() { + public void run() { + mNetworkLoaded = mSnpeHelper.loadingMODELS(runtime_var, dlc_name_var); + //dismiss dialog when the model is loaded + dialog.dismiss(); + } + }.start() ; + + } + return mNetworkLoaded; + } + +} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/FragmentRender.java b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/FragmentRender.java new file mode 100644 index 00000000..a353b005 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/FragmentRender.java @@ -0,0 +1,104 @@ +// -*- mode: java -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +package com.qcom.aistack_objdetect; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; + + +import java.util.ArrayList; +import java.util.concurrent.locks.ReentrantLock; + +/** + * FragmentRender class is utility for making boxes on camera frames. + * FragmentRender has utility in fragment_camera.xml and CameraFragment Class + */ +public class FragmentRender extends View { + + private ReentrantLock mLock = new ReentrantLock(); + private ArrayList boxlist = new ArrayList<>(); + + private Paint mTextColor= new Paint(); + private Paint mBorderColor= new Paint(); + + public FragmentRender(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(); + } + + + public void setCoordsList(ArrayList t_boxlist) { + mLock.lock(); + postInvalidate(); + + if (boxlist==null) + { + mLock.unlock(); + return; + } + boxlist.clear(); + for(int j=0;j parent) { + System.out.println("Nothing"); + } + }); + + } + + public void startManinCameraActivity(View v) + { + Intent i =new Intent(this, MainActivity.class); + + Bundle args = new Bundle(); + args.putChar("key", runtime_var); + args.putCharSequence("selected_dlc_name", dlc_name); + i.putExtras(args); + + startActivity(i); + } + +} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/MainActivity.java b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/MainActivity.java new file mode 100644 index 00000000..ee572868 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/MainActivity.java @@ -0,0 +1,138 @@ +// -*- mode: java -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +package com.qcom.aistack_objdetect; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.WindowManager; +import android.widget.TextView; +import org.opencv.android.OpenCVLoader; +import java.util.HashMap; +import java.util.Map; + +/** + * MainActivity class displays the info of Selected Model,Runtime, classes supported by the model on UI through main_activity.xml + * It also passes the selected model and runtime info to the CameraFragment for making inference using selected Model and Runtime. + */ +public class MainActivity extends AppCompatActivity { + + static final Map model_name=new HashMap(); + static Map runtime_name=new HashMap(); + static Map class_count=new HashMap(); + + static final String[] modeloptions = {"YOLONAS", "SSDMobilenetV2", "YoloX"}; + static final String[] modeldlcname = {"Quant_yoloNas_s_320.dlc", "ssd_mobilenetV2_without_ABP-NMS_Q.dlc", "yolox_x_212_Q.dlc"}; + + static final char[] runtimeoptions = {'C', 'G', 'D'}; + static final String[] runtimename = {"CPU", "GPU", "DSP"}; + + static final String[] classcount = {"80", "21", "80"}; + + static { + //System.loadLibrary("objectdetectionYoloNas"); + + for (int i=0;i= Build.VERSION_CODES.M) { + passToFragment = MainActivity.this.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; + } + else{ + passToFragment = true; + } + if (passToFragment) { + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + Bundle args = new Bundle(); + args.putChar("key", runtime_value); + args.putCharSequence("selected_dlc_name", selected_dlc_name); + transaction.add(R.id.main_content, CameraFragment.create(args)); + transaction.commit(); + } else { + cameraPermission(); + } + } + + @Override + protected void onResume() { + super.onResume(); + overToCamera(runtime_var, dlc_name); + } + + @Override + protected void onStop() { + super.onStop(); + } +} \ No newline at end of file diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/RectangleBox.java b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/RectangleBox.java new file mode 100644 index 00000000..c0dcb7d0 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/RectangleBox.java @@ -0,0 +1,36 @@ +// -*- mode: java -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +package com.qcom.aistack_objdetect; + +import java.util.ArrayList; +/** + * RectangleBox class defines the property associated with each box like coordinates + * labels, confidence etc. + * Can also create copy of boxes. + */ +public class RectangleBox { + + public float top; + public float bottom; + public float left; + public float right; + + public int fps; + public String processing_time; + public String label; + public static ArrayList createBoxes(int num) { + final ArrayList boxes; + boxes = new ArrayList<>(); + for (int i = 0; i < num; ++i) { + boxes.add(new RectangleBox()); + } + return boxes; + } +} diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/SNPEHelper.java b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/SNPEHelper.java new file mode 100644 index 00000000..fa16fa86 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/java/com/qcom/aistack_objdetect/SNPEHelper.java @@ -0,0 +1,104 @@ +// -*- mode: java -*- +// ============================================================================= +// @@-COPYRIGHT-START-@@ +// +// Copyright (c) 2023 of Qualcomm Innovation Center, Inc. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// @@-COPYRIGHT-END-@@ +// ============================================================================= +package com.qcom.aistack_objdetect; + +import android.app.Application; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.util.Log; +import org.opencv.android.Utils; +import org.opencv.core.Mat; +import java.util.ArrayList; + +public class SNPEHelper { + private final Application mApplication; + private AssetManager assetManager; + + // Constructor + public SNPEHelper(Application application) { + mApplication = application; + } + + //Native functions + public native String queryRuntimes(String a); + public native String initSNPE(AssetManager assetManager, char a, String dlc_name); + public native int inferSNPE(long inputmataddress, int width,int height, float[][]boxcoords, String[] classname); + + + /** + * This method loads ML models on selected runtime + */ + public boolean loadingMODELS(char runtime_var, String dlc_name) { + + assetManager = mApplication.getAssets(); + String nativeDirPath = mApplication.getApplicationInfo().nativeLibraryDir; + String res_query = queryRuntimes(nativeDirPath); + System.out.println(res_query); + String tt = initSNPE(assetManager, runtime_var, dlc_name); + System.out.println("RESULT:"+tt); + + int success_count = tt.split("success", -1).length -1; + + if(success_count==1) + { + System.out.println("Model built successfully"); + return true; + } + + return false; + } + + /* + This method makes inference on bitmap. + */ + public int snpeInference(Bitmap modelInputBitmap, int fps, ArrayList BBlist) { + + int result=0; + + try{ + + Mat inputMat = new Mat(); + Utils.bitmapToMat(modelInputBitmap, inputMat); + + float[][] boxCoords = new float[100][5]; //Stores box coords for all person, MAXLIMIT is 100, last coords i.e. boxCoords[k][4] stores confidence value <-- IMP + String[] boxnames = new String[100]; + + //System.out.println("call inferSNPE input_Width="+modelInputBitmap.getWidth()+" input_Height="+modelInputBitmap.getHeight()); + + int numhuman = inferSNPE(inputMat.getNativeObjAddr(), modelInputBitmap.getWidth(), modelInputBitmap.getHeight(), boxCoords,boxnames); + + if (numhuman == -1) + { + Log.e("SNPEHelper", "Error loading model properly. Return error.."); + return -1; + } + + for(int k=0;k + + + + + + + + + + diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/res/drawable/ic_launcher_background.xml b/ai-solutions/android/03-ObjectDetection/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..50ae786e --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ai-solutions/android/03-ObjectDetection/app/src/main/res/layout/activity_home_screen.xml b/ai-solutions/android/03-ObjectDetection/app/src/main/res/layout/activity_home_screen.xml new file mode 100644 index 00000000..14e99e71 --- /dev/null +++ b/ai-solutions/android/03-ObjectDetection/app/src/main/res/layout/activity_home_screen.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + +