.. Copyright 2022 Advanced Micro Devices, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Running ResNet50 - C++ ====================== This page walks you through the C++ versions of the ResNet50 examples. These examples are intended to run in the development container because you need to build and compile these executables. You can see the full source files used here in the :amdinferTree:`repository ` for more details. The inference server binds its C++ API to Python so the Python usage and functions look similar to their C++ counterparts but there are some differences due to the available features in both languages. You can read the :ref:`Python version of this example ``, where ``T`` depends on the data type that a backend works with. Since there may be many images, ``preprocess`` returns an ``std::vector>``. .. literalinclude:: ../examples/resnet50/vitis.cpp :start-after: +prepare images: :end-before: -prepare images: :language: cpp :dedent: 2 Construct requests ------------------ Using the images after preprocessing, you can construct requests to the inference server. For each image, you create an ``InferenceRequest`` and add input tensors to it. The ResNet50 model only accepts a single input tensor so you just add one by specifying the image data, its shape, and data type. In this example, you create a vector of such requests. .. literalinclude:: ../examples/resnet50/vitis.cpp :start-after: +construct request: :end-before: -construct request: :language: cpp :dedent: 2 Make an inference ----------------- There are multiple ways of making a request to the inference server, some of which are used in the different implementations of these examples. Before processing the response, you should verify it's not an error. Then, you can examine the outputs and, depending on the model, postprocess the results. For ResNet50, the raw results from the inference server lists the probabilities for each output class. The postprocessing identifies the highest probability classes and the top few of these are printed using the labels file to map the indices to a human-readable name. Here are some examples of making an inference used in these examples: This is the simplest way to make an inference: a blocking single inference where you loop through all the requests and make requests to the server one at a time. .. literalinclude:: ../examples/resnet50/vitis.cpp :start-after: +validate: :end-before: -validate: :language: cpp :dedent: 2 You can also make a single asynchronous request to the server where you get back a ``std::future`` that you can use later to get the results of the inference. .. literalinclude:: ../examples/resnet50/ptzendnn.cpp :start-after: +validate :end-before: -validate :language: cpp :dedent: 6 There are also some helper methods that wrap the basic inference APIs provided by the client. The ``inferAsyncOrdered`` method accepts a vector of requests, makes all the requests asynchronously using the ``modelInferAsync`` API, waits until each request completes, and then returns a vector of responses. If there are multiple requests sent in this way, they may be batched together by the server. .. literalinclude:: ../examples/resnet50/migraphx.cpp :start-after: +validate: :end-before: -validate: :language: cpp :dedent: 2