From 359d3ac803dbe48a527e7bfdb7303d6c0479b0be Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 22 Sep 2022 14:34:17 -0700 Subject: [PATCH] Remove deprecated API usage --- c_cxx/MNIST/MNIST.cpp | 3 +- c_cxx/README.md | 13 +++--- c_cxx/imagenet/CMakeLists.txt | 8 +++- c_cxx/imagenet/image_loader.h | 2 +- c_cxx/imagenet/local_filesystem.h | 1 + c_cxx/imagenet/main.cc | 33 ++++++-------- c_cxx/imagenet/sync_api.h | 2 - c_cxx/imagenet/sync_api_win.cc | 1 + c_cxx/squeezenet/main.cpp | 72 +++++++++++++++++-------------- 9 files changed, 72 insertions(+), 63 deletions(-) diff --git a/c_cxx/MNIST/MNIST.cpp b/c_cxx/MNIST/MNIST.cpp index d68fe0db1..a578534f6 100644 --- a/c_cxx/MNIST/MNIST.cpp +++ b/c_cxx/MNIST/MNIST.cpp @@ -40,7 +40,8 @@ struct MNIST { const char* input_names[] = {"Input3"}; const char* output_names[] = {"Plus214_Output_0"}; - session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1); + Ort::RunOptions run_options; + session_.Run(run_options, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1); softmax(results_); result_ = std::distance(results_.begin(), std::max_element(results_.begin(), results_.end())); return result_; diff --git a/c_cxx/README.md b/c_cxx/README.md index 34549159d..a84f7617f 100644 --- a/c_cxx/README.md +++ b/c_cxx/README.md @@ -12,9 +12,7 @@ This directory contains a few C/C++ sample applications for demoing onnxruntime ## Prerequisites 1. Visual Studio 2015/2017/2019 2. cmake(version >=3.13) -3. (optional) [libpng 1.6](http://www.libpng.org/pub/png/libpng.html) - -You may get a precompiled libpng library from [https://onnxruntimetestdata.blob.core.windows.net/models/libpng.zip](https://onnxruntimetestdata.blob.core.windows.net/models/libpng.zip) +3. (optional) [libpng 1.6](https://libpng.sourceforge.io/) ## Install ONNX Runtime ### Option 1: download a prebuilt package @@ -31,16 +29,16 @@ build.bat --config RelWithDebInfo --build_shared_lib --parallel By default this will build a project with "C:\Program Files (x86)\onnxruntime" install destination. This is a protected folder on Windows. If you do not want to run installation with elevated priviliges you will need to override the default installation location by passing extra CMake arguments. For example: ``` -build.bat --config RelWithDebInfo --build_shared_lib --parallel --cmake_extra_defines CMAKE_INSTALL_PREFIX=c:\dev\ort_install +build.bat --config RelWithDebInfo --build_dir .\build --build_shared_lib --parallel --cmake_extra_defines CMAKE_INSTALL_PREFIX=c:\dev\ort_install ``` -By default products of the build on Windows go to .\build\Windows\ folder. In the case above it would be .\build\Windows\RelWithDebInfo. +By default products of the build on Windows go to .\build\Windows\ folder. In the case above it would be .\build\RelWithDebInfo since the build folder is mentioned explicitly. If you did not specify alternative installation location above you would need to open an elevated command prompt to install onnxruntime. Run the following commands. ``` -cd .\Windows\RelWithDebInfo -msbuild INSTALL.vcxproj /p:Configuration=RelWithDebInfo +cmake --install .\build\RelWithDebInfo --config RelWithDebInfo + ``` ## Build the samples @@ -63,6 +61,7 @@ Or build it using msbuild ```bat msbuild onnxruntime_samples.sln /p:Configuration=Debug|Release +cmake --install .\build\Debug|Release --config Debug ``` To run the samples make sure that your Install Folder Bin is in the path so your sample executable can find onnxruntime dll and libpng if you used it. diff --git a/c_cxx/imagenet/CMakeLists.txt b/c_cxx/imagenet/CMakeLists.txt index 7b2e37114..7c6f442a4 100644 --- a/c_cxx/imagenet/CMakeLists.txt +++ b/c_cxx/imagenet/CMakeLists.txt @@ -2,6 +2,7 @@ # Licensed under the MIT License. set(FS_SOURCES local_filesystem.h sync_api.h controller.h controller.cc) + if(WIN32) LIST(APPEND FS_SOURCES local_filesystem_win.cc sync_api_win.cc) else() @@ -17,17 +18,22 @@ if(JPEG_FOUND) elseif(WIN32) SET(IMAGE_SRC image_loader_wic.cc) endif() + add_executable(image_classifier main.cc runnable_task.h data_processing.h ${IMAGE_SRC} - async_ring_buffer.h image_loader.cc image_loader.h cached_interpolation.h single_consumer.h) + async_ring_buffer.h image_loader.cc image_loader.h cached_interpolation.h single_consumer.h) + if(JPEG_FOUND) target_compile_definitions(image_classifier PRIVATE HAVE_JPEG) SET(IMAGE_HEADERS ${JPEG_INCLUDE_DIR}) SET(IMAGE_LIBS ${JPEG_LIBRARIES}) endif() + target_include_directories(image_classifier PRIVATE ${PROJECT_SOURCE_DIR}/include ${IMAGE_HEADERS}) + if(WIN32) target_compile_definitions(image_classifier PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX) endif() + target_link_libraries(image_classifier PRIVATE onnxruntime slim_fs_lib ${IMAGE_LIBS}) diff --git a/c_cxx/imagenet/image_loader.h b/c_cxx/imagenet/image_loader.h index 34bd76b3c..c0f24f659 100644 --- a/c_cxx/imagenet/image_loader.h +++ b/c_cxx/imagenet/image_loader.h @@ -8,7 +8,7 @@ #include "cached_interpolation.h" #include "sync_api.h" #include "data_processing.h" -#include +#include template void ResizeImageInMemory(const T* input_data, float* output_data, int in_height, int in_width, int out_height, diff --git a/c_cxx/imagenet/local_filesystem.h b/c_cxx/imagenet/local_filesystem.h index c6351ebd8..9330f5fdb 100644 --- a/c_cxx/imagenet/local_filesystem.h +++ b/c_cxx/imagenet/local_filesystem.h @@ -19,6 +19,7 @@ #include #include #endif + #include void ReadFileAsString(const ORTCHAR_T* fname, void*& p, size_t& len); diff --git a/c_cxx/imagenet/main.cc b/c_cxx/imagenet/main.cc index 21d83d6fd..62fa11a89 100644 --- a/c_cxx/imagenet/main.cc +++ b/c_cxx/imagenet/main.cc @@ -12,10 +12,11 @@ #include #include #include +#include -#include "providers.h" -#include "local_filesystem.h" -#include "sync_api.h" + #include "providers.h" + #include "local_filesystem.h" + #include "sync_api.h" #include @@ -26,8 +27,10 @@ #ifdef _WIN32 #include #endif + using namespace std::chrono; + class Validator : public OutputCollector { private: static std::vector ReadFileToVec(const TCharString& file_path, size_t expected_line_count) { @@ -81,8 +84,8 @@ class Validator : public OutputCollector { int image_size_; std::mutex m_; - char* input_name_ = nullptr; - char* output_name_ = nullptr; + std::optional input_name_; + std::optional output_name_; Ort::Env& env_; const TCharString model_path_; system_clock::time_point start_time_; @@ -90,11 +93,6 @@ class Validator : public OutputCollector { public: int GetImageSize() const { return image_size_; } - ~Validator() { - free(input_name_); - free(output_name_); - } - void PrintResult() { if (finished_count_ == 0) return; printf("Top-1 Accuracy %f\n", ((float)top_1_correct_count_.load() / finished_count_)); @@ -124,20 +122,15 @@ class Validator : public OutputCollector { VerifyInputOutputCount(session_); Ort::AllocatorWithDefaultOptions ort_alloc; { - char* t = session_.GetInputName(0, ort_alloc); - input_name_ = my_strdup(t); - ort_alloc.Free(t); - t = session_.GetOutputName(0, ort_alloc); - output_name_ = my_strdup(t); - ort_alloc.Free(t); + input_name_.emplace(session_.GetInputNameAllocated(0, ort_alloc)); + output_name_.emplace(session_.GetOutputNameAllocated(0, ort_alloc)); } Ort::TypeInfo info = session_.GetInputTypeInfo(0); auto tensor_info = info.GetTensorTypeAndShapeInfo(); size_t dim_count = tensor_info.GetDimensionsCount(); assert(dim_count == 4); - std::vector dims(dim_count); - tensor_info.GetDimensions(dims.data(), dims.size()); + std::vector dims = tensor_info.GetShape(); if (dims[1] != dims[2] || dims[3] != 3) { throw std::runtime_error("This model is not supported by this program. input tensor need be in NHWC format"); } @@ -150,8 +143,10 @@ class Validator : public OutputCollector { { std::lock_guard l(m_); const size_t remain = task_id_list.size(); + const char* input_names[] = {input_name_->get()}; + char* output_names[] = {output_name_->get()}; Ort::Value output_tensor{nullptr}; - session_.Run(Ort::RunOptions{nullptr}, &input_name_, &input_tensor, 1, &output_name_, &output_tensor, 1); + session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, &output_tensor, 1); float* probs = output_tensor.GetTensorMutableData(); for (const auto& s : task_id_list) { float* end = probs + output_class_count_; diff --git a/c_cxx/imagenet/sync_api.h b/c_cxx/imagenet/sync_api.h index 2a4f6bb4f..ad57a4ea6 100644 --- a/c_cxx/imagenet/sync_api.h +++ b/c_cxx/imagenet/sync_api.h @@ -8,8 +8,6 @@ #else #include #endif -#include -#include #ifdef _WIN32 #define my_strtol wcstol diff --git a/c_cxx/imagenet/sync_api_win.cc b/c_cxx/imagenet/sync_api_win.cc index afada9c03..0d4b3d456 100644 --- a/c_cxx/imagenet/sync_api_win.cc +++ b/c_cxx/imagenet/sync_api_win.cc @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "sync_api.h" +#include void CreateAndSubmitThreadpoolWork(_In_ ONNXRUNTIME_CALLBACK_FUNCTION callback, _In_ void* data, _In_opt_ PThreadPoolCallbackEnv pool) { diff --git a/c_cxx/squeezenet/main.cpp b/c_cxx/squeezenet/main.cpp index 5aa8b1d68..335ac89bd 100644 --- a/c_cxx/squeezenet/main.cpp +++ b/c_cxx/squeezenet/main.cpp @@ -3,9 +3,11 @@ // #include -#include #include +#include +#include + #ifdef HAVE_TENSORRT_PROVIDER_FACTORY_H #include #include @@ -60,13 +62,15 @@ void run_ort_trt() { //************************************************************************************************************************** // It's suggested to use CreateTensorRTProviderOptions() to get provider options - // since ORT takes care of valid options for you + // since ORT takes care of valid options for you //************************************************************************************************************************** api.CreateTensorRTProviderOptions(&tensorrt_options); - std::unique_ptr rel_trt_options(tensorrt_options, api.ReleaseTensorRTProviderOptions); - api.SessionOptionsAppendExecutionProvider_TensorRT_V2(static_cast(session_options), rel_trt_options.get()); + std::unique_ptr rel_trt_options( + tensorrt_options, api.ReleaseTensorRTProviderOptions); + api.SessionOptionsAppendExecutionProvider_TensorRT_V2(static_cast(session_options), + rel_trt_options.get()); - printf("Runing ORT TRT EP with default provider options\n"); + std::cout << "Running ORT TRT EP with default provider options" << std::endl; Ort::Session session(env, model_path, session_options); @@ -75,51 +79,58 @@ void run_ort_trt() { Ort::AllocatorWithDefaultOptions allocator; // print number of model input nodes - size_t num_input_nodes = session.GetInputCount(); - std::vector input_node_names(num_input_nodes); + const size_t num_input_nodes = session.GetInputCount(); + std::vector input_names_ptr; + std::vector input_node_names; + input_names_ptr.reserve(num_input_nodes); + input_node_names.reserve(num_input_nodes); std::vector input_node_dims; // simplify... this model has only 1 input node {1, 3, 224, 224}. // Otherwise need vector> - printf("Number of inputs = %zu\n", num_input_nodes); + std::cout << "Number of inputs = " << num_input_nodes << std::endl; // iterate over all input nodes - for (int i = 0; i < num_input_nodes; i++) { + for (size_t i = 0; i < num_input_nodes; i++) { // print input node names - char* input_name = session.GetInputName(i, allocator); - printf("Input %d : name=%s\n", i, input_name); - input_node_names[i] = input_name; + auto input_name = session.GetInputNameAllocated(i, allocator); + std::cout << "Input " << i << " : name =" << input_name.get() << std::endl; + input_node_names.push_back(input_name.get()); + input_names_ptr.push_back(std::move(input_name)); // print input node types - Ort::TypeInfo type_info = session.GetInputTypeInfo(i); + auto type_info = session.GetInputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); ONNXTensorElementDataType type = tensor_info.GetElementType(); - printf("Input %d : type=%d\n", i, type); + std::cout << "Input " << i << " : type = " << type << std::endl; // print input shapes/dims input_node_dims = tensor_info.GetShape(); - printf("Input %d : num_dims=%zu\n", i, input_node_dims.size()); - for (size_t j = 0; j < input_node_dims.size(); j++) - printf("Input %d : dim %zu=%jd\n", i, j, input_node_dims[j]); + std::cout << "Input " << i << " : num_dims = " << input_node_dims.size() << '\n'; + for (size_t j = 0; j < input_node_dims.size(); j++) { + std::cout << "Input " << i << " : dim[" << j << "] =" << input_node_dims[j] << '\n'; + } + std::cout << std::flush; } - size_t input_tensor_size = 224 * 224 * 3; // simplify ... using known dim values to calculate size - // use OrtGetTensorShapeElementCount() to get official size! + constexpr size_t input_tensor_size = 224 * 224 * 3; // simplify ... using known dim values to calculate size + // use OrtGetTensorShapeElementCount() to get official size! std::vector input_tensor_values(input_tensor_size); std::vector output_node_names = {"softmaxout_1"}; // initialize input data with values in [0.0, 1.0] - for (unsigned int i = 0; i < input_tensor_size; i++) - input_tensor_values[i] = (float)i / (input_tensor_size + 1); + for (unsigned int i = 0; i < input_tensor_size; i++) input_tensor_values[i] = (float)i / (input_tensor_size + 1); // create input tensor object from data values auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); - Ort::Value input_tensor = Ort::Value::CreateTensor(memory_info, input_tensor_values.data(), input_tensor_size, input_node_dims.data(), 4); + auto input_tensor = Ort::Value::CreateTensor(memory_info, input_tensor_values.data(), input_tensor_size, + input_node_dims.data(), 4); assert(input_tensor.IsTensor()); // score model & input tensor, get back output tensor - auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_node_names.data(), &input_tensor, 1, output_node_names.data(), 1); + auto output_tensors = + session.Run(Ort::RunOptions{nullptr}, input_node_names.data(), &input_tensor, 1, output_node_names.data(), 1); assert(output_tensors.size() == 1 && output_tensors.front().IsTensor()); // Get pointer to output tensor float values @@ -127,8 +138,10 @@ void run_ort_trt() { assert(abs(floatarr[0] - 0.000045) < 1e-6); // score the model, and print scores for first 5 classes - for (int i = 0; i < 5; i++) - printf("Score for class [%d] = %f\n", i, floatarr[i]); + for (int i = 0; i < 5; i++) { + std::cout << "Score for class [" << i << "] = " << floatarr[i] << '\n'; + } + std::cout << std::flush; // Results should be as below... // Score for class[0] = 0.000045 @@ -137,15 +150,10 @@ void run_ort_trt() { // Score for class[3] = 0.001180 // Score for class[4] = 0.001317 - - // release buffers allocated by ORT alloctor - for(const char* node_name : input_node_names) - allocator.Free(const_cast(reinterpret_cast(node_name))); - - printf("Done!\n"); + std::cout << "Done!" << std::endl; } -int main(int argc, char* argv[]) { +int main(int /*argc*/, char*[]) { run_ort_trt(); return 0; }