From 679f5978408ab3f6c01f8f72684cba96de99ab07 Mon Sep 17 00:00:00 2001 From: Yelin Jeong Date: Wed, 11 Sep 2024 21:24:04 +0900 Subject: [PATCH] [MachineLearning.Inference] Add MlInformation and MlInformationList This patch newly adds the MlInformation and MlInformationList class. These class manages information based on key-value. Added: - MlInformation - MlInformationList Signed-off-by: Yelin Jeong --- .../Interop/Interop.Nnstreamer.cs | 63 ++++ .../MlInformation.cs | 286 ++++++++++++++++++ .../MlInformationList.cs | 130 ++++++++ 3 files changed, 479 insertions(+) create mode 100644 src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformation.cs create mode 100644 src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformationList.cs diff --git a/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs b/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs index b8c0c4ec94d..d152f65beb2 100755 --- a/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs +++ b/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs @@ -291,6 +291,10 @@ internal static partial class Util [DllImport(Libraries.MlCommon, EntryPoint = "ml_tensors_data_set_tensor_data", CallingConvention = CallingConvention.Cdecl)] internal static extern NNStreamerError SetTensorData(IntPtr data, int index, byte[] raw_data, int data_size); + /* int ml_tensors_data_get_info (const ml_tensors_data_h data, ml_tensors_info_h *info) */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_tensors_data_get_info", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError GetInfo(IntPtr data, out IntPtr info); + /* int ml_check_nnfw_availability (ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw, bool *available); */ [DllImport(Libraries.MlSingle, EntryPoint = "ml_check_nnfw_availability", CallingConvention = CallingConvention.Cdecl)] internal static extern NNStreamerError CheckNNFWAvailability(NNFWType nnfw, HWType hw, out bool available); @@ -306,5 +310,64 @@ internal static string IntPtrToString(IntPtr val) { return (val != IntPtr.Zero) ? Marshal.PtrToStringAnsi(val) : string.Empty; } + + internal static int IntPtrToInt(IntPtr val) + { + return (val != IntPtr.Zero) ? Marshal.ReadInt32(val) : 0; + } + + internal static IntPtr StringToIntPtr(string str) + { + return string.IsNullOrEmpty(str) ? IntPtr.Zero : Marshal.StringToHGlobalAnsi(str); + } + + internal static IntPtr IntToIntPtr(int val) + { + IntPtr handle = Marshal.AllocHGlobal(sizeof(int)); + + byte[] byteVal = BitConverter.GetBytes(val); + Marshal.Copy(byteVal, 0, handle, byteVal.Length); + return handle; + } + + /* int ml_information_destroy (ml_information_h ml_info); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_information_destroy", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError DestroyInformation(IntPtr info); + + /* int ml_information_get (ml_information_h ml_info, const char *key, void **value); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_information_get", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError GetInformationValue(IntPtr info, IntPtr key, out IntPtr value); + + /* int ml_information_list_destroy (ml_information_list_h ml_info_list); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_information_list_destroy", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError DestroyInformationList(IntPtr info_list); + + /* int ml_information_list_length (ml_information_list_h ml_info_list, unsigned int *length); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_information_list_length", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError GetInformationListLength(IntPtr info_list, out int length); + + /* int ml_information_list_get (ml_information_list_h ml_info_list, unsigned int index, ml_information_h *ml_info); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_information_list_get", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError GetInformation(IntPtr info_list, int index, out IntPtr info); + + /* typedef void (*ml_data_destroy_cb) (void *data);*/ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DataDestroyCallback(IntPtr user_data); + + /* int ml_option_create (ml_option_h *option); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_option_create", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError CreateOption(out IntPtr option); + + /* int ml_option_destroy (ml_option_h option); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_option_destroy", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError DestroyOption(IntPtr option); + + /* int ml_option_set (ml_option_h option, const char *key, void *value, ml_data_destroy_cb destroy); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_option_set", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError SetOptionValue(IntPtr option, IntPtr key, IntPtr value, DataDestroyCallback cb); + + /* int ml_option_get (ml_option_h option, const char *key, void **value); */ + [DllImport(Libraries.MlCommon, EntryPoint = "ml_option_get", CallingConvention = CallingConvention.Cdecl)] + internal static extern NNStreamerError GetOptionValue(IntPtr option, IntPtr key, out IntPtr value); } } diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformation.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformation.cs new file mode 100644 index 00000000000..6a187d9c9e4 --- /dev/null +++ b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformation.cs @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2024 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. + */ + +using System; + +namespace Tizen.MachineLearning.Inference +{ + /// + /// The MlInformation class manages information based on key-value. + /// + /// 13 + public class MlInformation : IDisposable + { + private IntPtr _handle = IntPtr.Zero; + private bool _disposed = false; + private InfoType _type; + private bool _fromList = false; + + internal enum InfoType + { + Option = 0, + Information = 1, + } + + /// + /// Creates a MlInformation instance. + /// + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the feature is not supported. + /// 13 + public MlInformation() { + NNStreamer.CheckNNStreamerSupport(); + + NNStreamerError ret = Interop.Util.CreateOption(out _handle); + NNStreamer.CheckException(ret, "Failed to create information handle"); + + _type = InfoType.Option; + } + + /// + /// Creates a MlInformation instance from native handle. + /// + /// Native handle of MlInformation. + /// Types of MlInformation. + /// Created from MlInformationList, no need to release native handle. + /// 13 + internal MlInformation(IntPtr handle, InfoType type, bool fromList) { + NNStreamer.CheckNNStreamerSupport(); + + if (handle == IntPtr.Zero) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The information handle is null"); + + _handle = handle; + _type = type; + _fromList = fromList; + } + + /// + /// Destroys the MlInformation resource. + /// + /// 13 + ~MlInformation() { + Dispose(false); + } + + /// + /// Releases any unmanaged resources used by this object. + /// + /// 13 + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects. + /// + /// If true, disposes any disposable objects. If false, does not dispose disposable objects. + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + // release managed object + } + + // release unmanaged objects + if (_handle != IntPtr.Zero) + { + NNStreamerError ret = NNStreamerError.InvalidParameter; + + switch(_type) + { + case InfoType.Option: + ret = Interop.Util.DestroyOption(_handle); + break; + case InfoType.Information: + if (!_fromList) { + ret = Interop.Util.DestroyInformation(_handle); + } else { + /* Information handle is from MlInformationList should not be released */ + ret = NNStreamerError.None; + } + break; + } + + NNStreamer.CheckException(ret, "Failed to destroy the information"); + + _handle = IntPtr.Zero; + } + + _disposed = true; + } + + /// + /// Internal method to get the native handle of MlInformation. + /// + /// The native handle + /// 13 + internal IntPtr GetHandle() + { + return _handle; + } + + /// + /// Sets a new key-value in MlInformation instance. + /// + /// The key to be set. + /// The value to be set. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public void SetString(string key, string value) + { + if (string.IsNullOrEmpty(key)) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The property key is invalid"); + + if (string.IsNullOrEmpty(value)) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The property value is invalid"); + + NNStreamerError ret = NNStreamerError.InvalidParameter; + + switch(_type) + { + case InfoType.Option: + IntPtr valuePtr = Interop.Util.StringToIntPtr(value); + ret = Interop.Util.SetOptionValue(_handle, Interop.Util.StringToIntPtr(key), valuePtr, null); + break; + case InfoType.Information: + ret = NNStreamerError.NotSupported; + Log.Error(NNStreamer.TAG, "InfoType Information does not support set value"); + break; + } + + NNStreamer.CheckException(ret, "Failed to set string value"); + } + + /// + /// Sets a new key-value in MlInformation instance. + /// + /// The key to be set. + /// The value to be set. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public void SetInteger(string key, int value) + { + if (string.IsNullOrEmpty(key)) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The property key is invalid"); + + NNStreamerError ret = NNStreamerError.InvalidParameter; + + switch(_type) + { + case InfoType.Option: + ret = Interop.Util.SetOptionValue(_handle, Interop.Util.StringToIntPtr(key), Interop.Util.IntToIntPtr(value), null); + break; + case InfoType.Information: + ret = NNStreamerError.NotSupported; + Log.Error(NNStreamer.TAG, "InfoType Information does not support set value"); + break; + } + + NNStreamer.CheckException(ret, "Failed to set integer value"); + } + + private IntPtr GetValue(string key) + { + if (string.IsNullOrEmpty(key)) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The property key is invalid"); + + IntPtr value = IntPtr.Zero; + NNStreamerError ret = NNStreamerError.InvalidParameter; + + switch(_type) + { + case InfoType.Option: + ret = Interop.Util.GetOptionValue(_handle, Interop.Util.StringToIntPtr(key), out value); + break; + case InfoType.Information: + ret = Interop.Util.GetInformationValue(_handle, Interop.Util.StringToIntPtr(key), out value); + break; + } + + NNStreamer.CheckException(ret, "Failed to get value of key from information handle"); + + return value; + } + + /// + /// Gets a string value of key in MlInformation instance. + /// + /// The key to get the corresponding value. + /// The string value of the key. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public string GetString(string key) + { + IntPtr value = GetValue(key); + if (value == IntPtr.Zero) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "Could not find value of key from information handle"); + + return Interop.Util.IntPtrToString(value); + } + + /// + /// Gets an int value of key in MlInformation instance. + /// + /// The key to get the corresponding value. + /// The integer value of the key. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public int GetInteger(string key) + { + IntPtr value = GetValue(key); + if (value == IntPtr.Zero) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "Could not find value of key from information handle"); + + return Interop.Util.IntPtrToInt(value); + } + + /// + /// Gets a TensorsData value of key in MlInformation instance. + /// + /// The key to get TensorsData. + /// The TensorsData value of the key. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public TensorsData GetTensorsData(string key) + { + IntPtr value = GetValue(key); + IntPtr infoHandle = IntPtr.Zero; + + NNStreamerError ret = Interop.Util.GetInfo(value, out infoHandle); + NNStreamer.CheckException(ret, "Failed to get value of key from information handle"); + + TensorsData data = TensorsData.CreateFromNativeHandle(value, infoHandle, true, false); + + return data; + } + } +} diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformationList.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformationList.cs new file mode 100644 index 00000000000..3e8768a9bfb --- /dev/null +++ b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/MlInformationList.cs @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2024 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. + */ + +using System; + +namespace Tizen.MachineLearning.Inference +{ + /// + /// The MlInformationList class manages list of MlInformation. + /// + /// 13 + public class MlInformationList : IDisposable + { + private IntPtr _handle = IntPtr.Zero; + private bool _disposed = false; + + /// + /// Creates a MlInformationList instance. + /// + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the feature is not supported. + /// Thrown when the method failed due to an invalid parameter. + /// 13 + internal MlInformationList(IntPtr handle) { + NNStreamer.CheckNNStreamerSupport(); + + if (handle == IntPtr.Zero) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The information list handle is null"); + + _handle = handle; + } + + /// + /// Destroys the MlInformationList resource. + /// + /// 13 + ~MlInformationList() { + Dispose(false); + } + + /// + /// Releases any unmanaged resources used by this object. + /// + /// 13 + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects. + /// + /// If true, disposes any disposable objects. If false, does not dispose disposable objects. + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + // release managed object + } + + // release unmanaged objects + if (_handle != IntPtr.Zero) + { + NNStreamerError ret = Interop.Util.DestroyInformationList(_handle); + NNStreamer.CheckException(ret, "Failed to destroy the information list"); + + _handle = IntPtr.Zero; + } + + _disposed = true; + } + + /// + /// Gets a MlInformation value from the MlInformationList instance. + /// + /// The index of MlInformation in MlInformationList. + /// The MlInformation of given index. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public MlInformation GetInformation(int index) + { + int length = GetLength(); + + if (index >= length) + throw NNStreamerExceptionFactory.CreateException(NNStreamerError.InvalidParameter, "The property index is out of bound"); + + IntPtr infoHandle = IntPtr.Zero; + NNStreamerError ret = Interop.Util.GetInformation(_handle, index, out infoHandle); + NNStreamer.CheckException(ret, "Failed to get information from list"); + + return new MlInformation(infoHandle, MlInformation.InfoType.Information, true); + } + + /// + /// Gets the number of MlInformation in the MlInformationList instance. + /// + /// The number of MlInformation in the MlInformationList instance. + /// http://tizen.org/feature/machine_learning.inference + /// Thrown when the method failed due to an invalid parameter. + /// Thrown when the feature is not supported. + /// 13 + public int GetLength() + { + int value = 0; + + NNStreamerError ret = Interop.Util.GetInformationListLength(_handle, out value); + NNStreamer.CheckException(ret, "Failed to get the length of information list"); + return value; + } + } +}