Various test infra updates from testing Azure ops with MAUI test app (#17262)

### Description
<!-- Describe your changes. -->
- fix issue with handling string input
- set minSdkVersion
  - otherwise defaults to 19 which we don't support and the build breaks
- comment out the debug logging hook
  - enabling it breaks the Android native logging
  - can be enabled if you need to debug C# code
- update test data tools to allow creating input data for raw file
contents (e.g. audio) and from strings (e.g. auth token value)
- fix some warnings

### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
Improve test setup
This commit is contained in:
Scott McKay 2023-08-27 09:35:00 +10:00 committed by GitHub
parent ddcd46174e
commit ca0159b45d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 14 deletions

View file

@ -38,7 +38,9 @@ public partial class MainPage : ContentPage
_currentExecutionProvider = ExecutionProviders.CPU;
// start creating session in background.
#pragma warning disable CS4014 // intentionally not awaiting this task
CreateInferenceSession();
#pragma warning restore CS4014
}
private async Task CreateInferenceSession()
@ -79,13 +81,17 @@ public partial class MainPage : ContentPage
private void ExecutionProviderOptions_SelectedIndexChanged(object sender, EventArgs e)
{
// update in background
#pragma warning disable CS4014 // intentionally not awaiting this task
UpdateExecutionProvider();
#pragma warning restore CS4014
}
private void OnRunClicked(object sender, EventArgs e)
{
// run in background
#pragma warning disable CS4014 // intentionally not awaiting this task
RunAsync();
#pragma warning restore CS4014
}
private async Task UpdateExecutionProvider()

View file

@ -53,13 +53,13 @@
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.16.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="Microsoft.ML.OnnxRuntime" Version="1.16.0-dev-20230707-1222-2a11f29eaa" />
<PackageReference Include="Microsoft.ML.OnnxRuntime.Extensions" Version="0.8.0" />
<PackageReference Include="Microsoft.ML.OnnxRuntime" Version="1.16.0-dev-20230821-1235-cbaa008391" />
<PackageReference Include="Microsoft.ML.OnnxRuntime.Extensions" Version="0.9.0-dev-20230823-0618-3f1ce5ef" />
</ItemGroup>
<!-- Project loaded by MauiModelTester.sln. Use the nightly package. -->
<ItemGroup Condition="'$(SolutionName)'=='MauiModelTester'">
<PackageReference Include="Microsoft.ML.OnnxRuntime.Managed" Version="1.16.0-dev-20230707-1224-2a11f29eaa" />
<PackageReference Include="Microsoft.ML.OnnxRuntime.Managed" Version="1.16.0-dev-20230821-1246-cbaa008391" />
</ItemGroup>
<!-- Project loaded by the ORT C# solution in /csharp. Use the local build of the C# wrapper -->

View file

@ -14,9 +14,14 @@ public static class MauiProgram
});
#if DEBUG
// NOTE: Enabling this does allow Debug.WriteLine to work for debugging C# code.
// However it seems to kill native logging on Android using __android_log_print that ORT and
// onnxruntime-extensions use, at least in the emulator. Due to that, enabled if you want to debug C#
// code and disable to debug native code.
//
// Add the extension debug logger so Debug.WriteLine output shows up in the Output window when running in VS
builder.Logging.AddDebug();
System.Diagnostics.Debug.WriteLine("Debug output enabled.");
// builder.Logging.AddDebug();
// System.Diagnostics.Debug.WriteLine("Debug output enabled.");
#endif
return builder.Build();

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="false" android:icon="@mipmap/onnxruntime_icon" android:supportsRtl="true"></application>
<application android:allowBackup="false" android:icon="@mipmap/onnxruntime_icon" android:supportsRtl="true" android:label="MauiOnnxModelTester"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
<uses-permission android:name="android.permission.DIAGNOSTIC" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
</manifest>

View file

@ -70,7 +70,7 @@ namespace MauiModelTester
int idx = 0;
foreach (var str in tensorProto.StringData)
{
ortValue.FillStringTensorElement(str.Span, idx++);
ortValue.StringTensorSetElementAt(str.Span, idx++);
}
}
else
@ -111,7 +111,7 @@ namespace MauiModelTester
case TensorElementType.Int8:
return typeof(sbyte);
case TensorElementType.String:
return typeof(byte);
return typeof(string);
case TensorElementType.Bool:
return typeof(bool);
default:
@ -120,6 +120,7 @@ namespace MauiModelTester
}
static OrtValue TensorProtoToOrtValue<T>(Onnx.TensorProto tensorProto)
where T : unmanaged
{
unsafe
{
@ -141,7 +142,7 @@ namespace MauiModelTester
private delegate ReadOnlySpan<T> GetDataFn<T>(OrtValue ortValue);
private static ReadOnlySpan<T> GetData<T>(OrtValue ortValue)
where T : struct
where T : unmanaged
{
return ortValue.GetTensorDataAsSpan<T>();
}
@ -186,7 +187,7 @@ namespace MauiModelTester
private static void CheckEqual<T>(string name, OrtValue expected, OrtValue actual,
IEqualityComparer<T> comparer)
where T : struct
where T : unmanaged
{
CheckEqual(name, expected, actual, comparer, GetData<T>);
}

View file

@ -61,7 +61,7 @@ def parse_args():
"-m",
help="Path to ONNX model to use. Model will be copied into the test app",
type=Path,
Required=True,
required=True,
)
args = parser.parse_args()

View file

@ -111,6 +111,8 @@ def get_arg_parser():
numpy_to_pb: Convert numpy array saved to a file with numpy.save() to a TensorProto, and serialize to a pb file.
image_to_pb: Convert data from an image file into a TensorProto, and serialize to a pb file.
random_to_pb: Create a TensorProto with random data, and serialize to a pb file.
raw_to_pb: Create a uint8 TensorProto with raw data from a file, and serialize to a pb file.
string_to_pb: Create a string TensorProto with the input string, and serialize to a pb file.
update_name_in_pb: Update the TensorProto.name value in a pb file.
Updates the input file unless --output <filename> is specified.
""",
@ -120,11 +122,19 @@ def get_arg_parser():
parser.add_argument(
"--action",
help="Action to perform",
choices=["dump_pb", "numpy_to_pb", "image_to_pb", "random_to_pb", "update_name_in_pb"],
choices=[
"dump_pb",
"numpy_to_pb",
"image_to_pb",
"random_to_pb",
"raw_to_pb",
"string_to_pb",
"update_name_in_pb",
],
required=True,
)
parser.add_argument("--input", help="The input filename or directory name")
parser.add_argument("--input", help="The input filename, directory name or string.")
parser.add_argument("--name", help="The value to set TensorProto.name to if creating/updating one.")
parser.add_argument("--output", help="Filename to serialize the TensorProto to.")
@ -210,6 +220,21 @@ if __name__ == "__main__":
data = create_random_data(args.shape, args.datatype, args.min_value, args.max_value, args.seed)
numpy_to_pb(args.name, data, args.output)
elif args.action == "raw_to_pb":
if not args.input or not args.output or not args.name:
print("Missing argument. Need input, output and name to be specified.", file=sys.stderr)
sys.exit(-1)
data = np.fromfile(args.input, dtype=np.ubyte)
numpy_to_pb(args.name, data, args.output)
elif args.action == "string_to_pb":
if not args.input or not args.output or not args.name:
print("Missing argument. Need input, output and name to be specified.", file=sys.stderr)
sys.exit(-1)
data = np.ndarray((1), dtype=object)
data[0] = args.input
numpy_to_pb(args.name, data, args.output)
elif args.action == "update_name_in_pb":
if not args.input or not args.name:
print("Missing argument. Need input and name to be specified.", file=sys.stderr)