Browse Source

windows version

master
Yuya Hanai 3 years ago
parent
commit
3ebd08c73d
  1. 18
      README.md
  2. 339
      example-onnx_mnist/src/ofApp.cpp

18
README.md

@ -7,9 +7,23 @@
## Installation ## Installation
- macOS - macOS
- copy `libonnxruntime.1.10.0.dylib` to `/usr/local/lib` - copy `libonnxruntime.1.10.0.dylib` to `/usr/local/lib`
- Generate a project using ProjectGenerator.
- Windows
- There are two ways to install ONNX Runtime on your project.
1. Install using NuGet
- I recommend this way in general.
- Generate a project using ProjectGenerator.
- Open `sln` file.
- Right click your project on `Solution Explorer` pane, and then select `Manage NuGet Packages...`.
- From `Browse` tab, search `Microsoft.ML.OnnxRuntime` (CPU) or `Microsoft.ML.OnnxRuntime.Gpu` (GPU) and install it.
2. DLL direct download
- You can download prebuilt DLLs from (here)[https://github.com/microsoft/onnxruntime/releases].
- Unzip downloaded `onnxruntime-win-x64-(gpu-)1.10.0.zip` and locate files on `libs\onnxruntime\lib\vs\x64\` .
- Generate a project using ProjectGenerator, then all libs are linked correctly and all dlls are copied to `bin`.
## Tested environment ## Tested environment
- MacBookPro 2018 Intel + macOS Catalina - oF 0.11.2 + MacBookPro 2018 Intel + macOS Catalina
- oF 0.11.2 + VS2017 + Windows 10 + RTX2080Ti + CUDA 11.4
## ToDo ## ToDo
- check M1 Mac (should work), Windows CPU&GPU, Linux CPU&GPU - check M1 Mac (should work), Linux CPU&GPU

339
example-onnx_mnist/src/ofApp.cpp

@ -3,168 +3,199 @@
#include "ofxOnnxRuntime.h" #include "ofxOnnxRuntime.h"
// code from // code from
//https://github.com/microsoft/onnxruntime-inference-examples/blob/main/c_cxx/MNIST/MNIST.cpp // https://github.com/microsoft/onnxruntime-inference-examples/blob/main/c_cxx/MNIST/MNIST.cpp
template <typename T> template <typename T> static void softmax(T &input) {
static void softmax(T& input) { float rowmax = *std::max_element(input.begin(), input.end());
float rowmax = *std::max_element(input.begin(), input.end()); std::vector<float> y(input.size());
std::vector<float> y(input.size()); float sum = 0.0f;
float sum = 0.0f; for (size_t i = 0; i != input.size(); ++i) {
for (size_t i = 0; i != input.size(); ++i) { sum += y[i] = std::exp(input[i] - rowmax);
sum += y[i] = std::exp(input[i] - rowmax); }
} for (size_t i = 0; i != input.size(); ++i) {
for (size_t i = 0; i != input.size(); ++i) { input[i] = y[i] / sum;
input[i] = y[i] / sum; }
}
} }
// This is the structure to interface with the MNIST model // This is the structure to interface with the MNIST model
// After instantiation, set the input_image_ data to be the 28x28 pixel image of the number to recognize // After instantiation, set the input_image_ data to be the 28x28 pixel image of
// Then call Run() to fill in the results_ data with the probabilities of each // the number to recognize Then call Run() to fill in the results_ data with the
// result_ holds the index with highest probability (aka the number the model thinks is in the image) // probabilities of each result_ holds the index with highest probability (aka
// the number the model thinks is in the image)
struct MNIST { struct MNIST {
MNIST() { MNIST() {
auto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
input_tensor_ = Ort::Value::CreateTensor<float>(memory_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size()); #ifdef _MSC_VER
output_tensor_ = Ort::Value::CreateTensor<float>(memory_info, results_.data(), results_.size(), output_shape_.data(), output_shape_.size()); Ort::SessionOptions sf;
}
#define USE_CUDA
std::ptrdiff_t Run() { #define USE_TENSORRT
const char* input_names[] = {"Input3"};
const char* output_names[] = {"Plus214_Output_0"}; #ifdef USE_CUDA
#ifdef USE_TENSORRT
session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1); sf.AppendExecutionProvider_TensorRT(OrtTensorRTProviderOptions{ 0 });
softmax(results_); #endif
result_ = std::distance(results_.begin(), std::max_element(results_.begin(), results_.end())); sf.AppendExecutionProvider_CUDA(OrtCUDAProviderOptions());
return result_; #endif
}
string path = ofToDataPath("mnist-8.onnx", true);
static constexpr const int width_ = 28; std::wstring widestr = std::wstring(path.begin(), path.end());
static constexpr const int height_ = 28; session_ = make_shared<Ort::Session>(env, widestr.c_str(), sf);
#else
std::array<float, width_ * height_> input_image_{}; // OSX
std::array<float, 10> results_{}; session_ = make_shared<Ort::Session>(
int64_t result_{0}; env, ofToDataPath("mnist-8.onnx", true).c_str(),
Ort::SessionOptions{ nullptr });
private: #endif
Ort::Env env;
Ort::Session session_{env, ofToDataPath("mnist-8.onnx", true).c_str(), Ort::SessionOptions{nullptr}}; auto memory_info =
Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
Ort::Value input_tensor_{nullptr}; input_tensor_ = Ort::Value::CreateTensor<float>(
std::array<int64_t, 4> input_shape_{1, 1, width_, height_}; memory_info, input_image_.data(), input_image_.size(),
input_shape_.data(), input_shape_.size());
Ort::Value output_tensor_{nullptr}; output_tensor_ = Ort::Value::CreateTensor<float>(
std::array<int64_t, 2> output_shape_{1, 10}; memory_info, results_.data(), results_.size(), output_shape_.data(),
output_shape_.size());
}
std::ptrdiff_t Run() {
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);
softmax(results_);
result_ = std::distance(results_.begin(),
std::max_element(results_.begin(), results_.end()));
return result_;
}
static constexpr const int width_ = 28;
static constexpr const int height_ = 28;
std::array<float, width_ * height_> input_image_{};
std::array<float, 10> results_{};
int64_t result_{ 0 };
private:
Ort::Env env;
shared_ptr<Ort::Session>
session_; // {env, (const wchar_t*)ofToDataPath("mnist-8.onnx",
// true).c_str(), Ort::SessionOptions{ nullptr }};
Ort::Value input_tensor_{ nullptr };
std::array<int64_t, 4> input_shape_{ 1, 1, width_, height_ };
Ort::Value output_tensor_{ nullptr };
std::array<int64_t, 2> output_shape_{ 1, 10 };
}; };
class ofApp : public ofBaseApp{ class ofApp : public ofBaseApp {
shared_ptr<MNIST> mnist; shared_ptr<MNIST> mnist;
ofFbo fbo_render; ofFbo fbo_render;
ofFbo fbo_classification; ofFbo fbo_classification;
ofFloatPixels pix; ofFloatPixels pix;
bool prev_pressed = false; bool prev_pressed = false;
glm::vec2 prev_pt; glm::vec2 prev_pt;
public: public:
void setup() void setup() {
{ ofSetVerticalSync(true);
ofSetVerticalSync(true); ofSetFrameRate(60);
ofSetFrameRate(60);
mnist = make_shared<MNIST>();
mnist = make_shared<MNIST>();
fbo_render.allocate(280, 280, GL_RGB, 0);
fbo_render.allocate(280, 280, GL_RGB, 0); fbo_render.getTexture().setTextureMinMagFilter(GL_NEAREST, GL_NEAREST);
fbo_render.getTexture().setTextureMinMagFilter(GL_NEAREST, GL_NEAREST); fbo_render.begin();
fbo_render.begin(); ofClear(0);
ofClear(0); fbo_render.end();
fbo_render.end(); fbo_classification.allocate(28, 28, GL_R32F, 0);
fbo_classification.allocate(28, 28, GL_R32F, 0);
pix.setFromExternalPixels(&mnist->input_image_.front(), 28, 28, 1);
pix.setFromExternalPixels(&mnist->input_image_.front(), 28, 28, 1);
} mnist->Run();
}
void update()
{ void update() {
if (ofGetMousePressed()) { if (ofGetMousePressed()) {
auto pt = glm::vec2(ofGetMouseX(), ofGetMouseY() - 60); auto pt = glm::vec2(ofGetMouseX(), ofGetMouseY() - 60);
fbo_render.begin(); fbo_render.begin();
ofPushStyle(); ofPushStyle();
ofSetColor(255); ofSetColor(255);
if (prev_pressed) { if (prev_pressed) {
ofSetLineWidth(20); ofSetLineWidth(20);
ofDrawLine(prev_pt, pt); ofDrawLine(prev_pt, pt);
} }
ofDrawCircle(pt.x, pt.y, 10); ofDrawCircle(pt.x, pt.y, 10);
ofPopStyle(); ofPopStyle();
fbo_render.end(); fbo_render.end();
fbo_classification.begin(); fbo_classification.begin();
ofClear(0); ofClear(0);
fbo_render.draw(0, 0, fbo_classification.getWidth(), fbo_classification.getHeight()); fbo_render.draw(0, 0, fbo_classification.getWidth(),
fbo_classification.end(); fbo_classification.getHeight());
fbo_classification.readToPixels(pix); fbo_classification.end();
mnist->Run(); fbo_classification.readToPixels(pix);
prev_pt = pt; mnist->Run();
prev_pressed = true; prev_pt = pt;
} else { prev_pressed = true;
prev_pressed = false; }
} else {
} prev_pressed = false;
}
void draw() }
{
ofClear(128); void draw() {
ofClear(128);
fbo_render.draw(0, 60);
fbo_classification.draw(0, 340); fbo_render.draw(0, 60);
fbo_classification.draw(0, 340);
// render result
for (int i=0; i<10; ++i) { // render result
stringstream ss; for (int i = 0; i < 10; ++i) {
ss << i << ":" << std::fixed << std::setprecision(3) << mnist->results_[i]; stringstream ss;
ofDrawBitmapString(ss.str(), 300, 70 + i * 30); ss << i << ":" << std::fixed << std::setprecision(3)
ofPushStyle(); << mnist->results_[i];
ofSetColor(0, 255, 0); ofDrawBitmapString(ss.str(), 300, 70 + i * 30);
ofDrawRectangle(360.0, 55 + i * 30, mnist->results_[i] * 300.0, 20); ofPushStyle();
ofPopStyle(); ofSetColor(0, 255, 0);
} ofDrawRectangle(360.0, 55 + i * 30, mnist->results_[i] * 300.0, 20);
ofPopStyle();
stringstream ss; }
ss << "FPS : " << ofGetFrameRate() << endl;
ss << "Draw any digit (0-9) here" << endl; stringstream ss;
ss << "Press c to clear buffer"; ss << "FPS : " << ofGetFrameRate() << endl;
ofDrawBitmapStringHighlight(ss.str(), 10, 20); ss << "Draw any digit (0-9) here" << endl;
} ss << "Press c to clear buffer";
ofDrawBitmapStringHighlight(ss.str(), 10, 20);
void keyPressed(int key) }
{
if (key == 'c') { void keyPressed(int key) {
fbo_render.begin(); if (key == 'c') {
ofClear(0); fbo_render.begin();
fbo_render.end(); ofClear(0);
} fbo_render.end();
} }
}
void keyReleased(int key) {}
void mouseMoved(int x, int y ) {} void keyReleased(int key) {}
void mouseDragged(int x, int y, int button) {} void mouseMoved(int x, int y) {}
void mouseDragged(int x, int y, int button) {}
void mousePressed(int x, int y, int button) {
void mousePressed(int x, int y, int button) {}
}
void mouseReleased(int x, int y, int button) {}
void mouseReleased(int x, int y, int button) {} void windowResized(int w, int h) {}
void windowResized(int w, int h) {} void dragEvent(ofDragInfo dragInfo) {}
void dragEvent(ofDragInfo dragInfo) {} void gotMessage(ofMessage msg) {}
void gotMessage(ofMessage msg) {}
}; };
//======================================================================== //========================================================================
int main( ){ int main() {
ofSetupOpenGL(640,400,OF_WINDOW); // <-------- setup the GL context ofSetupOpenGL(640, 400, OF_WINDOW); // <-------- setup the GL context
// this kicks off the running of my app // this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN // can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too: // pass in width and height too:
ofRunApp(new ofApp()); ofRunApp(new ofApp());
} }

Loading…
Cancel
Save