summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorKshitiz Bansal/Advanced SW Team /SRI-Delhi/Engineer/삼성전자 <kshitiz.b@samsung.com>2018-06-11 10:54:00 +0530
committer서상민/동작제어Lab(SR)/Staff Engineer/삼성전자 <sangmin7.seo@samsung.com>2018-06-11 14:24:00 +0900
commitf4f50aa4217ceb8adf737ab87f310f2c230a27d8 (patch)
tree07336c72c5bb44068c209f8c03ebba3b6ae308a5 /contrib
parente46c083fc87f90a79a3cb2ea10adb3a85bfef901 (diff)
downloadnnfw-f4f50aa4217ceb8adf737ab87f310f2c230a27d8.tar.gz
nnfw-f4f50aa4217ceb8adf737ab87f310f2c230a27d8.tar.bz2
nnfw-f4f50aa4217ceb8adf737ab87f310f2c230a27d8.zip
TFLiteSharp code for running model inference with test App (#1486)
This patch contains code for the TFLiteSharp's Run function. Currently it supports only one dimensional inputs of the types INT32, INT64, FLOAT32 and UINT8. A new VS project for testing the TFLiteSharp wrapper functions is also added. The project is a xamarin app that creates an interpreter instance using preloaded mobilenet model and runs the inference using a bitmap image as an input. Signed-off-by: Kshitiz Bansal <kshitiz.b@samsung.com>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/TFLiteSharp/TFLiteNative/include/tflite_nativewrapper.h17
-rw-r--r--contrib/TFLiteSharp/TFLiteNative/src/tflite_nativewrapper.cpp73
-rw-r--r--contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/Interop/Interop.TFLite.cs9
-rw-r--r--contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Datatype.cs31
-rw-r--r--contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Interpreter.cs117
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp.csproj54
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_App.cs65
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_Main.cs20
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/res/mobilenet_v1_1.0_224.tflitebin0 -> 16900960 bytes
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/res/mouse1.bmpbin0 -> 2764854 bytes
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/res/mouse_224.bmpbin0 -> 150582 bytes
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/shared/res/TFLiteTestApp.pngbin0 -> 10097 bytes
-rw-r--r--contrib/TFLiteSharp/TFLiteTestApp/tizen-manifest.xml14
13 files changed, 387 insertions, 13 deletions
diff --git a/contrib/TFLiteSharp/TFLiteNative/include/tflite_nativewrapper.h b/contrib/TFLiteSharp/TFLiteNative/include/tflite_nativewrapper.h
index b8f49781c..7fddb5400 100644
--- a/contrib/TFLiteSharp/TFLiteNative/include/tflite_nativewrapper.h
+++ b/contrib/TFLiteSharp/TFLiteNative/include/tflite_nativewrapper.h
@@ -26,12 +26,29 @@
extern "C" {
#endif /*__cplusplus*/
+typedef enum
+{
+ /** 32-bit signed integer. */
+ INT32 = 1,
+
+ /** 32-bit single precision floating point. */
+ FLOAT32 = 2,
+
+ /** 8-bit unsigned integer. */
+ UINT8 = 3,
+
+ /** 64-bit signed integer. */
+ INT64 = 4
+} TFLiteNativeType;
+
void tflite_interpreter_setNumThreads(long* interpreterHandle, int numThreads);
long long tflite_flatbuffermodel_BuildFromFile(char* modelPath);
long long tflite_builder_interpreterBuilder(long* modelHandle);
+void* tflite_interpreter_run(long* interpreterHandle, void* values, int inputLength, int dataType);
+
#ifdef __cplusplus
}
#endif /*__cplusplus*/
diff --git a/contrib/TFLiteSharp/TFLiteNative/src/tflite_nativewrapper.cpp b/contrib/TFLiteSharp/TFLiteNative/src/tflite_nativewrapper.cpp
index 88a177ec0..413304637 100644
--- a/contrib/TFLiteSharp/TFLiteNative/src/tflite_nativewrapper.cpp
+++ b/contrib/TFLiteSharp/TFLiteNative/src/tflite_nativewrapper.cpp
@@ -17,10 +17,27 @@
#include <iostream>
#include "tflite_nativewrapper.h"
#include "tflite_log.h"
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
+int getNumBytes(TFLiteNativeType dataType)
+{
+ switch (dataType) {
+ case INT32:
+ return 4;
+ case FLOAT32:
+ return 4;
+ case UINT8:
+ return 1;
+ case INT64:
+ return 8;
+ default:
+ return 1;
+ }
+}
+
/// <summary>
/// Set the number of threads available to the interpreter.
/// </summary>
@@ -28,12 +45,12 @@
/// <param name="numThreads">Number of threads.</param>
void tflite_interpreter_setNumThreads(long* interpreterHandle, int numThreads)
{
- assert(interpreterHandle!=nullptr);
+ assert(interpreterHandle != nullptr);
tflite::Interpreter* interpreter = reinterpret_cast<tflite::Interpreter*>(*interpreterHandle);
interpreter->SetNumThreads(numThreads);
- TFLITE_NATIVE_LOG(DEBUG, "Number of threads: %d",numThreads);
+ TFLITE_NATIVE_LOG(DEBUG, "Number of threads: %d", numThreads);
return;
}
@@ -41,7 +58,8 @@ void tflite_interpreter_setNumThreads(long* interpreterHandle, int numThreads)
/// Creates a Flat Buffer Model from the given .tflite model.
/// </summary>
/// <param name="modelPath">Path of the model.</param>
-long long tflite_flatbuffermodel_BuildFromFile(char* modelPath)
+long long
+tflite_flatbuffermodel_BuildFromFile(char* modelPath)
{
if (modelPath == nullptr) {
TFLITE_NATIVE_LOG(ERROR, "Invalid parameter");
@@ -50,7 +68,8 @@ long long tflite_flatbuffermodel_BuildFromFile(char* modelPath)
TFLITE_NATIVE_LOG(ERROR, "Model Path: %s", modelPath);
if (access(modelPath, F_OK) == -1) {
- TFLITE_NATIVE_LOG(ERROR, "Failed to access model [%s]", strerror(errno));
+ TFLITE_NATIVE_LOG(ERROR, "Failed to access model [%s]",
+ strerror(errno));
return 0;
}
@@ -64,9 +83,10 @@ long long tflite_flatbuffermodel_BuildFromFile(char* modelPath)
/// Creates an interpreter instance taking the flatbuffer model as input.
/// </summary>
/// <param name="modelHandle">Address of the flatbuffer model.</param>
-long long tflite_builder_interpreterBuilder(long* modelHandle)
+long long
+tflite_builder_interpreterBuilder(long* modelHandle)
{
- assert(modelHandle!=nullptr);
+ assert(modelHandle != nullptr);
tflite::FlatBufferModel* model = reinterpret_cast<tflite::FlatBufferModel*>(*modelHandle);
tflite::ops::builtin::BuiltinOpResolver resolver;
@@ -78,6 +98,45 @@ long long tflite_builder_interpreterBuilder(long* modelHandle)
TFLITE_NATIVE_LOG(DEBUG, "Cannot create interpreter");
return 0;
}
-
+ TFLITE_NATIVE_LOG(DEBUG, "CheckPoint interpreter");
return reinterpret_cast<long>(interpreter.release());
}
+
+/// <summary>
+/// Runs the inference given the inputs.
+/// </summary>
+/// <param name="interpreterHandle">Address of the interpreter instance.</param>
+/// <param name="values">Input values for the model.</param>
+/// <param name="inpLength">Length of the input.</param>
+/// <param name="dataType">Data type key of the input.</param>
+void* tflite_interpreter_run(long* interpreterHandle, void* values, int inputLength,
+ int dataType)
+{
+ assert(interpreterHandle != nullptr);
+ tflite::Interpreter* interpreter = reinterpret_cast<tflite::Interpreter*>(*interpreterHandle);
+
+ int inputTensorIndex = interpreter->inputs()[0];
+
+ //TODO:: input tensor size will be passed as a parameter. It is hardcoded for now.
+ interpreter->ResizeInputTensor(inputTensorIndex,
+ { 1, 224, 224, 3 });
+
+ if (interpreter->AllocateTensors() != kTfLiteOk) {
+ TFLITE_NATIVE_LOG(ERROR, "Failed to allocate tensors!");
+ return nullptr;
+ }
+
+ float* inputTensorPointer = interpreter->typed_tensor<float>(inputTensorIndex);
+
+ int numBytes = getNumBytes((TFLiteNativeType) dataType);
+
+ memcpy(inputTensorPointer, values, inputLength * numBytes);
+
+ if (interpreter->Invoke() != kTfLiteOk) {
+ TFLITE_NATIVE_LOG(ERROR, "Failed to invoke");
+ }
+
+ float* output = interpreter->typed_output_tensor<float>(0);
+ return output;
+}
+
diff --git a/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/Interop/Interop.TFLite.cs b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/Interop/Interop.TFLite.cs
index b0f11b14c..c7c7b24aa 100644
--- a/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/Interop/Interop.TFLite.cs
+++ b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/Interop/Interop.TFLite.cs
@@ -23,8 +23,15 @@ internal static partial class Interop
{
[DllImport(Libraries.TFLite, EntryPoint = "tflite_flatbuffermodel_BuildFromFile")]
internal static extern IntPtr TFLiteFlatBufferModelBuildFromFile(string path);
-
+
[DllImport(Libraries.TFLite, EntryPoint = "tflite_builder_interpreterBuilder")]
internal static extern IntPtr TFLiteBuilderInterpreterBuilder(ref IntPtr modelHandle);
+
+ [DllImport(Libraries.TFLite, EntryPoint = "tflite_interpreter_setNumThreads")]
+ internal static extern void TFLiteInterpreterSetNumThreads(int numThreads);
+
+ [DllImport(Libraries.TFLite, EntryPoint = "tflite_interpreter_run")]
+ internal static extern IntPtr TFLiteInterpreterRun(ref IntPtr interpreterHandle, IntPtr values, int inpLen, int dataType);
+
}
}
diff --git a/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Datatype.cs b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Datatype.cs
new file mode 100644
index 000000000..404d1663e
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Datatype.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** Type of elements in a {@link TfLiteTensor}. */
+enum DataType
+{
+ /** 32-bit signed integer. */
+ INT32 = 1,
+
+ /** 32-bit single precision floating point. */
+ FLOAT32 = 2,
+
+ /** 8-bit unsigned integer. */
+ UINT8 = 3,
+
+ /** 64-bit signed integer. */
+ INT64 = 4
+}
diff --git a/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Interpreter.cs b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Interpreter.cs
index 1b528f76f..f1b4a8e07 100644
--- a/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Interpreter.cs
+++ b/contrib/TFLiteSharp/TFLiteSharp/TFLiteSharp/src/Interpreter.cs
@@ -16,6 +16,7 @@
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
namespace TFLite
{
@@ -31,7 +32,7 @@ namespace TFLite
private IntPtr m_modelHandle;
// Handle to hold the interpreter instance
private IntPtr m_interpreterHandle;
-
+
/// <summary>
/// Interpreter Constructor. Inititalizes an interpreter.
/// </summary>
@@ -57,6 +58,7 @@ namespace TFLite
/// <param name="numThreads">Number of threads.</param>
public void SetNumThreads(int numThreads)
{
+ Interop.TFLite.TFLiteInterpreterSetNumThreads(numThreads);
return;
}
@@ -66,9 +68,14 @@ namespace TFLite
/// </summary>
/// <param name="input">input an array or multidimensional array.</param>
/// <param name="output">outputs a multidimensional array of output data.</param>
- public void Run(Array input, out Array output)
+ public void Run(Array input, ref Array output)
{
- output = null;
+ Array[] inputs = { input };
+ Dictionary<int, Array> outputs = new Dictionary<int, Array>();
+
+ RunForMultipleInputsOutputs(inputs, ref outputs);
+ output = outputs[0];
+
return;
}
@@ -79,12 +86,112 @@ namespace TFLite
/// <param name="inputs">input an array of input data.</param>
/// <param name="outputs">outputs a map mapping output indices to multidimensional
/// arrays of output data.</param>
- public void RunForMultipleInputsOutputs(Array inputs, out Dictionary<int, Array> outputs)
+ public void RunForMultipleInputsOutputs(Array[] inputs, ref Dictionary<int, Array> outputs)
{
- outputs = null;
+ if(m_interpreterHandle == IntPtr.Zero)
+ {
+ //TODO:: exception handling
+ }
+
+ if (inputs == null || inputs.Length == 0)
+ {
+ //TODO::throw new IllegalArgumentException("Input error: Inputs should not be null or empty.");
+ }
+
+ DataType[] dataTypes = new DataType[inputs.Length];//To be used in multi-dimensional case
+
+ for (int i = 0; i < inputs.Length; ++i)
+ {
+ dataTypes[i] = DataTypeOf(inputs[i]);
+ }
+
+ //TODO:: Support for multi dimesional array to be added.
+ IntPtr pnt = Marshal.AllocHGlobal(inputs[0].Length);
+
+ switch (dataTypes[0])
+ {
+ case DataType.INT32:
+ Marshal.Copy((int[])inputs[0], 0, pnt, inputs[0].Length);
+ break;
+ case DataType.FLOAT32:
+ Marshal.Copy((float[])inputs[0], 0, pnt, inputs[0].Length);
+ break;
+ case DataType.UINT8:
+ Marshal.Copy((byte[])inputs[0], 0, pnt, inputs[0].Length);
+ break;
+ case DataType.INT64:
+ Marshal.Copy((long[])inputs[0], 0, pnt, inputs[0].Length);
+ break;
+ default:
+ Marshal.Copy((byte[])inputs[0], 0, pnt, inputs[0].Length);
+ break;
+ }
+
+ //Currently this handles only single input with single dimension.
+ IntPtr outputsHandles = Interop.TFLite.TFLiteInterpreterRun(ref m_interpreterHandle, pnt, inputs[0].Length, (int)dataTypes[0]);
+
+ if (outputsHandles == null)
+ {
+ //throw new IllegalStateException("Internal error: Interpreter has no outputs.");
+ }
+
+ switch (dataTypes[0])
+ {
+ case DataType.INT32:
+ int[] managedArrayInt = new int[inputs[0].Length];
+ Marshal.Copy(outputsHandles, managedArrayInt, 0, inputs[0].Length);
+ outputs.Add(0, managedArrayInt);
+ break;
+ case DataType.FLOAT32:
+ float[] managedArrayFloat = new float[inputs[0].Length];
+ Marshal.Copy(outputsHandles, managedArrayFloat, 0, inputs[0].Length);
+ outputs.Add(0, managedArrayFloat);
+ break;
+ case DataType.UINT8:
+ byte[] managedArrayByte = new byte[inputs[0].Length];
+ Marshal.Copy(outputsHandles, managedArrayByte, 0, inputs[0].Length);
+ outputs.Add(0, managedArrayByte);
+ break;
+ case DataType.INT64:
+ long[] managedArrayLong = new long[inputs[0].Length];
+ Marshal.Copy(outputsHandles, managedArrayLong, 0, inputs[0].Length);
+ outputs.Add(0, managedArrayLong);
+ break;
+ default:
+ byte[] managedArrayDefault = new byte[inputs[0].Length];
+ Marshal.Copy(outputsHandles, managedArrayDefault, 0, inputs[0].Length);
+ outputs.Add(0, managedArrayDefault);
+ break;
+ }
return;
}
+ static DataType DataTypeOf(Array a)
+ {
+ if (a.GetValue(0).GetType()==typeof(int))
+ {
+ return DataType.INT32;
+ }
+ else if (a.GetValue(0).GetType() == typeof(float))
+ {
+ return DataType.FLOAT32;
+ }
+ else if (a.GetValue(0).GetType() == typeof(byte))
+ {
+ return DataType.UINT8;
+ }
+ else if(a.GetValue(0).GetType() == typeof(long))
+ {
+ return DataType.INT64;
+ }
+ else
+ {
+ return DataType.UINT8;
+ //TODO: throw exception
+ }
+
+ }
+
/// <summary>
/// Resizes idx-th input of the native model to the given dims.
/// </summary>
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp.csproj b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp.csproj
new file mode 100644
index 000000000..1c9ed6037
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp.csproj
@@ -0,0 +1,54 @@
+<Project>
+ <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
+
+ <!-- Setting Tizen Extension Path -->
+ <PropertyGroup Label="Globals">
+ <TizenProjectExtensionsPath>$(MSBuildExtensionsPath)\Tizen\VisualStudio\</TizenProjectExtensionsPath>
+ </PropertyGroup>
+
+ <!-- Import Tizen property in Tizen.NET SDK -->
+ <Import Project="$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.props" Condition="Exists('$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.props')" />
+
+ <!-- Property Group for .NET Core Project -->
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ </PropertyGroup>
+
+ <!-- Property Group for Tizen Project -->
+ <PropertyGroup>
+ <TizenCreateTpkOnBuild>true</TizenCreateTpkOnBuild>
+ <PackageTargetFallback>$(PackageTargetFallback);portable-net45+wp80+win81+wpa81</PackageTargetFallback>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>portable</DebugType>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>None</DebugType>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Folder Include="lib\" />
+ <Folder Include="res\" />
+ </ItemGroup>
+
+ <!-- Include Nuget Package for Tizen Project building -->
+ <ItemGroup>
+ <PackageReference Include="Tizen.NET" Version="3.0.0" />
+ <PackageReference Include="Tizen.NET.Sdk" Version="1.0.1" />
+ <PackageReference Include="Xamarin.Forms.Platform.Tizen" Version="2.3.5-r256-001" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\TFLiteSharp\TFLiteSharp\TFLiteSharp.csproj" />
+ </ItemGroup>
+
+ <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
+ <Import Project="$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.targets" Condition="Exists('$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.targets')" />
+
+ <!-- Install Check 'Visual Studio for Tizen' for developing on Visual Studio -->
+ <Target Name="TizenVsixInstallCheck" BeforeTargets="CompileDesignTime">
+ <Warning Condition="!Exists('$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.props')" Text="$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.props is not exist.&#xA; you need to check if 'Visual Studio for Tizen' is installed" />
+ <Warning Condition="!Exists('$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.targets')" Text="$(TizenProjectExtensionsPath)Tizen.NET.ProjectType.targets is not exist.\&#xA; you need to check if 'Visual Studio for Tizen' is installed" />
+ </Target>
+</Project>
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_App.cs b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_App.cs
new file mode 100644
index 000000000..49a08604d
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_App.cs
@@ -0,0 +1,65 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using Xamarin.Forms;
+
+namespace TFLiteTestApp
+{
+ public class App : Application
+ {
+ public App()
+ {
+ TFLite.Interpreter interpreter = null;
+ try
+ {
+ interpreter = new TFLite.Interpreter(Tizen.Applications.Application.Current.DirectoryInfo.Resource + "mobilenet_v1_1.0_224.tflite");
+ }
+ catch(Exception e)
+ {
+ Tizen.Log.Debug("tflite", "Error: " + e);
+ }
+
+ Tizen.Log.Debug("tflite", "Interpreter Initialised");
+ Array Output = new byte[1000];
+
+ Array input = new byte[150582];
+ input = File.ReadAllBytes(Tizen.Applications.Application.Current.DirectoryInfo.Resource + "mouse_224.bmp");
+
+ interpreter.Run(input, ref Output);
+ //val variable to check if the Output array is being populated or not.
+ byte val = ((byte[])Output)[0];
+ // The root page of your application
+ MainPage = new ContentPage
+ {
+ Content = new StackLayout
+ {
+ VerticalOptions = LayoutOptions.Center,
+ Children = {
+ new Label {
+ HorizontalTextAlignment = TextAlignment.Center,
+ Text = "Welcome to Xamarin Forms!"
+ }
+ }
+ }
+ };
+ }
+
+ protected override void OnStart()
+ {
+ // Handle when your app starts
+ }
+
+ protected override void OnSleep()
+ {
+ // Handle when your app sleeps
+ }
+
+ protected override void OnResume()
+ {
+ // Handle when your app resumes
+ }
+ }
+}
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_Main.cs b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_Main.cs
new file mode 100644
index 000000000..2a8f747a4
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/TFLiteTestApp_Main.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace TFLiteTestApp
+{
+ class Program : global::Xamarin.Forms.Platform.Tizen.FormsApplication
+ {
+ protected override void OnCreate()
+ {
+ base.OnCreate();
+ LoadApplication(new App());
+ }
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ global::Xamarin.Forms.Platform.Tizen.Forms.Init(app);
+ app.Run(args);
+ }
+ }
+}
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/res/mobilenet_v1_1.0_224.tflite b/contrib/TFLiteSharp/TFLiteTestApp/res/mobilenet_v1_1.0_224.tflite
new file mode 100644
index 000000000..d34691eb6
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/res/mobilenet_v1_1.0_224.tflite
Binary files differ
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/res/mouse1.bmp b/contrib/TFLiteSharp/TFLiteTestApp/res/mouse1.bmp
new file mode 100644
index 000000000..1734ca318
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/res/mouse1.bmp
Binary files differ
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/res/mouse_224.bmp b/contrib/TFLiteSharp/TFLiteTestApp/res/mouse_224.bmp
new file mode 100644
index 000000000..ccfed6ad3
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/res/mouse_224.bmp
Binary files differ
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/shared/res/TFLiteTestApp.png b/contrib/TFLiteSharp/TFLiteTestApp/shared/res/TFLiteTestApp.png
new file mode 100644
index 000000000..9f3cb9860
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/shared/res/TFLiteTestApp.png
Binary files differ
diff --git a/contrib/TFLiteSharp/TFLiteTestApp/tizen-manifest.xml b/contrib/TFLiteSharp/TFLiteTestApp/tizen-manifest.xml
new file mode 100644
index 000000000..62a8d4c7c
--- /dev/null
+++ b/contrib/TFLiteSharp/TFLiteTestApp/tizen-manifest.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="4" package="org.tizen.example.TFLiteTestApp" version="1.0.0">
+ <profile name="common" />
+ <ui-application appid="org.tizen.example.TFLiteTestApp"
+ exec="TFLiteTestApp.dll"
+ type="dotnet"
+ multiple="false"
+ taskmanage="true"
+ nodisplay="false"
+ launch_mode="single">
+ <label>TFLiteTestApp</label>
+ <icon>TFLiteTestApp.png</icon>
+ </ui-application>
+</manifest>