Skip to content

Instantly share code, notes, and snippets.

@pranavsharma
Created May 8, 2024 22:39
Show Gist options
  • Save pranavsharma/9b816b36a35ae66a1478560d0eacc826 to your computer and use it in GitHub Desktop.
Save pranavsharma/9b816b36a35ae66a1478560d0eacc826 to your computer and use it in GitHub Desktop.
// Copyright(c) Microsoft Corporation.All rights reserved.
// Licensed under the MIT License.
//
#include <assert.h>
#include <onnxruntime_c_api.h>
#include <cmath>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;
const OrtApi *g_ort = OrtGetApiBase()->GetApi(ORT_API_VERSION);
const int NUM_FRAMES = 583;
//*****************************************************************************
// helper function to check for status
void CheckStatus(OrtStatus *status)
{
if (status != NULL)
{
const char *msg = g_ort->GetErrorMessage(status);
fprintf(stderr, "%s\n", msg);
g_ort->ReleaseStatus(status);
exit(1);
}
}
int main(int argc, char *argv[])
{
//*************************************************************************
// initialize enviroment...one enviroment per process
// enviroment maintains thread pools and other state info
OrtEnv *env;
CheckStatus(g_ort->CreateEnv(ORT_LOGGING_LEVEL_INFO, "test", &env));
cout << "Done with creating env\n";
// initialize session options if needed
OrtSessionOptions *session_options;
CheckStatus(g_ort->CreateSessionOptions(&session_options));
// CheckStatus(g_ort->SetIntraOpNumThreads(session_options, 1));
// Sets graph optimization level
// CheckStatus(g_ort->SetSessionGraphOptimizationLevel(session_options, ORT_ENABLE_));
// Optionally add more execution providers via session_options
// E.g. for CUDA include cuda_provider_factory.h and uncomment the following line:
// OrtSessionOptionsAppendExecutionProvider_CUDA(sessionOptions, 0);
// CheckStatus(g_ort->DisableMemPattern(session_options));
//*************************************************************************
// create session and load model into memory
// using squeezenet version 1.3
// URL = https://github.com/onnx/models/tree/master/squeezenet
OrtSession *session;
#ifdef _WIN32
const wchar_t *model_path = L"squeezenet1.1-7.onnx";
#else
const char *model_path = "/home/pranav/speech_model/mvocoder_gru.onnx";
#endif
printf("Using Onnxruntime C API\n");
CheckStatus(g_ort->CreateSession(env, model_path, session_options, &session));
/*
//*************************************************************************
// print model input layer (node names, types, shape etc.)
size_t num_input_nodes;
OrtStatus *status;
OrtAllocator *allocator;
CheckStatus(g_ort->GetAllocatorWithDefaultOptions(&allocator));
// print number of model input nodes
status = g_ort->SessionGetInputCount(session, &num_input_nodes);
std::vector<const char *> input_node_names(num_input_nodes);
std::vector<int64_t> input_node_dims; // simplify... this model has only 1 input node {1, 3, 224, 224}.
// Otherwise need vector<vector<>>
printf("Number of inputs = %zu\n", num_input_nodes);
// iterate over all input nodes
for (size_t i = 0; i < num_input_nodes; i++)
{
// print input node names
char *input_name;
status = g_ort->SessionGetInputName(session, i, allocator, &input_name);
printf("Input %zu : name=%s\n", i, input_name);
input_node_names[i] = input_name;
// print input node types
OrtTypeInfo *typeinfo;
status = g_ort->SessionGetInputTypeInfo(session, i, &typeinfo);
const OrtTensorTypeAndShapeInfo *tensor_info;
CheckStatus(g_ort->CastTypeInfoToTensorInfo(typeinfo, &tensor_info));
ONNXTensorElementDataType type;
CheckStatus(g_ort->GetTensorElementType(tensor_info, &type));
printf("Input %zu : type=%d\n", i, type);
// print input shapes/dims
size_t num_dims;
CheckStatus(g_ort->GetDimensionsCount(tensor_info, &num_dims));
printf("Input %zu : num_dims=%zu\n", i, num_dims);
input_node_dims.resize(num_dims);
CheckStatus(g_ort->GetDimensions(tensor_info, (int64_t *)input_node_dims.data(), num_dims));
input_node_dims[num_dims - 1] = NUM_FRAMES;
for (size_t j = 0; j < num_dims; j++)
printf("Input %zu : dim %zu=%jd\n", i, j, input_node_dims[j]);
g_ort->ReleaseTypeInfo(typeinfo);
}
// Results should be...
// Number of inputs = 1
// Input 0 : name = data_0
// Input 0 : type = 1
// Input 0 : num_dims = 4
// Input 0 : dim 0 = 1
// Input 0 : dim 1 = 3
// Input 0 : dim 2 = 224
// Input 0 : dim 3 = 224
//*************************************************************************
// Similar operations to get output node information.
// Use OrtSessionGetOutputCount(), OrtSessionGetOutputName()
// OrtSessionGetOutputTypeInfo() as shown above.
//*************************************************************************
// Score the model using sample data, and inspect values
size_t input_tensor_size = 1 * 80 * NUM_FRAMES; // simplify ... using known dim values to calculate size
// use OrtGetTensorShapeElementCount() to get official size!
std::vector<float> input_tensor_values(input_tensor_size);
std::vector<const char *> output_node_names = {"wave"};
// initialize input data with values in [0.0, 1.0]
for (size_t i = 0; i < input_tensor_size; i++)
input_tensor_values[i] = (float)i / (input_tensor_size + 1);
// create input tensor object from data values
OrtMemoryInfo *memory_info;
CheckStatus(g_ort->CreateCpuMemoryInfo(OrtArenaAllocator, OrtMemTypeDefault, &memory_info));
OrtValue *input_tensor = NULL;
CheckStatus(g_ort->CreateTensorWithDataAsOrtValue(memory_info, input_tensor_values.data(), input_tensor_size * sizeof(float), input_node_dims.data(), input_node_dims.size(), ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, &input_tensor));
int is_tensor;
CheckStatus(g_ort->IsTensor(input_tensor, &is_tensor));
assert(is_tensor);
g_ort->ReleaseMemoryInfo(memory_info);
// score model & input tensor, get back output tensor
std::cout << "Before Run()" << std::endl;
CheckStatus(g_ort->LogArenaStats(session));
{
OrtValue *output_tensor = NULL;
CheckStatus(g_ort->Run(session, NULL, input_node_names.data(), (const OrtValue *const *)&input_tensor, 1, output_node_names.data(), 1, &output_tensor));
CheckStatus(g_ort->IsTensor(output_tensor, &is_tensor));
assert(is_tensor);
g_ort->ReleaseValue(output_tensor);
}
std::cout << "After Run()" << std::endl;
CheckStatus(g_ort->LogArenaStats(session));
// // Get pointer to output tensor float values
// float *floatarr;
// CheckStatus(g_ort->GetTensorMutableData(output_tensor, (void **)&floatarr));
// //assert(std::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]);
// // Results should be as below...
// // Score for class[0] = 0.000045
// // Score for class[1] = 0.003846
// // Score for class[2] = 0.000125
// // Score for class[3] = 0.001180
// // Score for class[4] = 0.001317
g_ort->ReleaseValue(input_tensor);
*/
g_ort->ReleaseSession(session);
g_ort->ReleaseSessionOptions(session_options);
g_ort->ReleaseEnv(env);
printf("Done!\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment