Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP [Documentation]: C# Workflow for consuming "Augmented" Onnx model with Custom Operators #11657

Open
1 task
GeorgeS2019 opened this issue May 27, 2022 · 5 comments
Labels
documentation improvements or additions to documentation; typically submitted using template

Comments

@GeorgeS2019
Copy link

GeorgeS2019 commented May 27, 2022

3 ways to add a new operator

There is an issue to missing link

Use Case: PyTorch exports a custom_op_test.onnx with TWO custom operators

custom_op_test.onnx

  • CustomOpOne
  • CustomOpTwo

image

To consume in CSharp exported PyTorch Onnx with custom operators, it is necessary to register these Custom Operators (written in C++) and provided in a Shared Library

CSharp API for loading Shared Library with Custom Operators

Create Custom_op_library.dll

CSharp api for loading/registrating custom op shared library

RegisterCustomOps

custom_op_library.h

#pragma once
#include "onnxruntime_c_api.h"

#ifdef __cplusplus
extern "C" {
#endif

ORT_EXPORT OrtStatus* ORT_API_CALL RegisterCustomOps(OrtSessionOptions* options, const OrtApiBase* api);

#ifdef __cplusplus
}
#endif

custom_op_library.cc

  • With 2 Custom Operators
    • CustomOpOne
    • CustomOpTwo
#include "custom_op_library.h"

#define ORT_API_MANUAL_INIT
#include "onnxruntime_cxx_api.h"
#undef ORT_API_MANUAL_INIT


OrtStatus* ORT_API_CALL RegisterCustomOps(OrtSessionOptions* options, const OrtApiBase* api) {
  OrtCustomOpDomain* domain = nullptr;
  const OrtApi* ortApi = api->GetApi(ORT_API_VERSION);

  if (auto status = ortApi->CreateCustomOpDomain(c_OpDomain, &domain)) {
    return status;
  }

  AddOrtCustomOpDomainToContainer(domain, ortApi);

  if (auto status = ortApi->CustomOpDomain_Add(domain, &c_CustomOpOne)) {
    return status;
  }

  if (auto status = ortApi->CustomOpDomain_Add(domain, &c_CustomOpTwo)) {
    return status;
  }

  return ortApi->AddCustomOpDomain(options, domain);
}

In CSharp Register Custom Operators within the Shared Library: Custom_op_library.dll

CSharp UnitTest: NetCoreApp/InferenceTest.netcore.c

private void TestRegisterCustomOpLibrary()
{
    using (var option = new SessionOptions())
    {
        string libName = "custom_op_library.dll";
        string modelPath = "custom_op_test.onnx";

The c++ unit tests discussion

@natke

WIP for CSharp
[Documentation] How to register custom operator in onnxruntime

Other references:

@yuslepukhin yuslepukhin added the documentation improvements or additions to documentation; typically submitted using template label May 31, 2022
@GeorgeS2019
Copy link
Author

The c# example for testing custom operator is here.

We need c# example on how to use contributed operator

@GeorgeS2019
Copy link
Author

Is your feature request related to a problem? Please describe.

The main build instruction page on Build ONNX Runtime from source does not provide the simplest step for building for custom op development

==> In addition to what is listed below, perhaps we need a section on Build for Custom Op development

Build for inferencing
Build for training
Build with different EPs
Build for Custom Op development <======

image

@GeorgeS2019 GeorgeS2019 changed the title [Documentation, Windows, c#] Add an entry on Build for Custom Op development [WIP Documentation, Windows, c#] Add an entry on Build for Custom Op development Sep 12, 2022
@GeorgeS2019 GeorgeS2019 changed the title [WIP Documentation, Windows, c#] Add an entry on Build for Custom Op development WIP [Documentation]: C# Workflow for consuming "Augmented" Onnx model with Custom Operators Sep 12, 2022
@GeorgeS2019
Copy link
Author

GeorgeS2019 commented Oct 18, 2022

FYI: Classes of torchvision\ops
@xhuan8 @kaiidams @NiklasGustafsson @natke @luisquintanilla

Reusability of PyTorch/OnnxExtension C++ Operators

in ML.NET, TorchSharp, Onnxruntime and PyTorch

flowchart TB
    Operators\nstaticLibrary1-->Operators\nstaticLibrary2
Operators\nDynamicLibrary1-->Operators\nDynamicLibrary2
Operators\nDynamicLibrary1-->Operators\nDynamicLibrary3
    subgraph ML.NET-Or-ORT
    Onnx-->C#-register
C#-register-->Operators\nDynamicLibrary3
  Operators\nDynamicLibrary3-->Augmented\nORT\nInference
   end
    subgraph ORT-Extension
    Custom\nOperators\nC++-->Operators\nDynamicLibrary1
    end
    subgraph TorchSharp-TorchVision
    C#Interop-->Operators\nstaticLibrary2
    C#Interop\nRegister-->Operators\nDynamicLibrary2
Operators\nstaticLibrary2-->Augmented\nTorchSharp\nModel
Operators\nDynamicLibrary2-->Augmented\nTorchSharp\nModel
    end
    subgraph PyTorch-TorchVision
    Operators\nC++-->Operators\nstaticLibrary1
    Operators\nstaticLibrary1-->PyBind
    PyBind-->Augmented\nPyTorch\nModel
    end
Loading

@GeorgeS2019
Copy link
Author

@natke

If I understand correctly, most of the contributed Ops in ORT, (some of them) come from experimental Custom Ops development in ORT Extension.

If these contributed Ops could be "Reversed" back to Custom Ops and made available through ORT Extension, then other projects e.g. ML.NET and TorchSharp could benefit from the Ops reusability!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation improvements or additions to documentation; typically submitted using template
Projects
None yet
Development

No branches or pull requests

2 participants