From e40db5b712122aa094df52ea5863bb66cb72fbc3 Mon Sep 17 00:00:00 2001 From: Jaeyun Date: Wed, 5 Dec 2018 17:14:33 +0900 Subject: [PATCH] [Transform] apply orc functions 1. add flags to check orc support 2. add property to set orc acceleration 3. apply orc functions for arith/typecast Signed-off-by: Jaeyun Jung --- gst/tensor_transform/tensor_transform.c | 151 ++++++++++++++++++++++++++++++++ gst/tensor_transform/tensor_transform.h | 5 +- 2 files changed, 155 insertions(+), 1 deletion(-) diff --git a/gst/tensor_transform/tensor_transform.c b/gst/tensor_transform/tensor_transform.c index 8f4034f..6834d08 100644 --- a/gst/tensor_transform/tensor_transform.c +++ b/gst/tensor_transform/tensor_transform.c @@ -51,6 +51,10 @@ #include #include "tensor_transform.h" +#ifdef HAVE_ORC +#include "transform-orc.h" +#endif + /** * @brief Macro for debug mode. */ @@ -96,6 +100,7 @@ enum PROP_SILENT, PROP_MODE, PROP_OPTION, + PROP_ACCELERATION }; static const gchar *gst_tensor_transform_mode_string[] = { @@ -187,6 +192,9 @@ gst_tensor_transform_class_init (GstTensorTransformClass * klass) g_object_class_install_property (gobject_class, PROP_OPTION, g_param_spec_string ("option", "Option", "Option for the tensor transform mode ?", "", G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_ACCELERATION, + g_param_spec_boolean ("acceleration", "Acceleration", "Orc acceleration", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gst_element_class_set_details_simple (gstelement_class, "TensorTransform", @@ -230,6 +238,12 @@ gst_tensor_transform_init (GstTensorTransform * filter) filter->option = NULL; filter->loaded = FALSE; filter->operators = NULL; +#ifdef HAVE_ORC + filter->acceleration = TRUE; + filter->orc_supported = FALSE; +#else + filter->acceleration = FALSE; +#endif gst_tensor_config_init (&filter->in_config); gst_tensor_config_init (&filter->out_config); @@ -280,6 +294,87 @@ gst_tensor_transform_get_mode (const gchar * str) return (index < 0) ? GTT_END : index; } +#ifdef HAVE_ORC +/* define macros for orc */ +#define orc_supported(filter) (filter->acceleration && filter->orc_supported) + +#define orc_func_conv(intype,outtype) nns_orc_conv_ ## intype ## _to_ ## outtype +#define orc_func_add(intype) nns_orc_add_c_ ## intype +#define orc_func_mul(intype) nns_orc_mul_c_ ## intype +#define orc_func_div(intype) nns_orc_div_c_ ## intype + +#define orc_typecast_to(i,o,n,intype,otype) do { \ + switch (otype) { \ + case _NNS_INT32: orc_func_conv (intype, s32) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_UINT32: orc_func_conv (intype, u32) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_INT16: orc_func_conv (intype, s16) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_UINT16: orc_func_conv (intype, u16) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_INT8: orc_func_conv (intype, s8) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_UINT8: orc_func_conv (intype, u8) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_FLOAT64: orc_func_conv (intype, f64) ((gpointer) o, (gpointer) i, n); break; \ + case _NNS_FLOAT32: orc_func_conv (intype, f32) ((gpointer) o, (gpointer) i, n); break; \ + default: GST_ERROR_OBJECT (filter, "Unsupported type %d", otype); g_assert (0); break; \ + } \ + } while (0) + +#define orc_typecast(i,o,n,itype,otype) do { \ + switch (itype) { \ + case _NNS_INT32: orc_typecast_to (i, o, n, s32, otype); break; \ + case _NNS_UINT32: orc_typecast_to (i, o, n, u32, otype); break; \ + case _NNS_INT16: orc_typecast_to (i, o, n, s16, otype); break; \ + case _NNS_UINT16: orc_typecast_to (i, o, n, u16, otype); break; \ + case _NNS_INT8: orc_typecast_to (i, o, n, s8, otype); break; \ + case _NNS_UINT8: orc_typecast_to (i, o, n, u8, otype); break; \ + case _NNS_FLOAT64: orc_typecast_to (i, o, n, f64, otype); break; \ + case _NNS_FLOAT32: orc_typecast_to (i, o, n, f32, otype); break; \ + default: GST_ERROR_OBJECT (filter, "Unsupported type %d", itype); g_assert (0); break; \ + } \ + } while (0) + +#define orc_operator_func(i,n,v,opfunc) do { \ + switch ((v)->type) { \ + case _NNS_INT32: opfunc (s32) ((gpointer) i, (v)->data._int32_t, n); break; \ + case _NNS_UINT32: opfunc (u32) ((gpointer) i, (v)->data._uint32_t, n); break; \ + case _NNS_INT16: opfunc (s16) ((gpointer) i, (v)->data._int16_t, n); break; \ + case _NNS_UINT16: opfunc (u16) ((gpointer) i, (v)->data._uint16_t, n); break; \ + case _NNS_INT8: opfunc (s8) ((gpointer) i, (v)->data._int8_t, n); break; \ + case _NNS_UINT8: opfunc (u8) ((gpointer) i, (v)->data._uint8_t, n); break; \ + case _NNS_FLOAT64: opfunc (f64) ((gpointer) i, (v)->data._double, n); break; \ + case _NNS_FLOAT32: opfunc (f32) ((gpointer) i, (v)->data._float, n); break; \ + default: GST_ERROR_OBJECT (filter, "Unsupported type %d", (v)->type); g_assert (0); break; \ + } \ + } while (0) + +#define orc_operator_div_loop(i,n,val,typename) do { \ + gsize idx; \ + typename *data_array = (typename *) (i); \ + for (idx = 0; idx < (n); ++idx) { \ + data_array[idx] /= (val); \ + } \ + } while (0) + +#define orc_operator(i,n,v,op) do { \ + switch (op) { \ + case GTT_OP_ADD: orc_operator_func (i, n, v, orc_func_add); break; \ + case GTT_OP_MUL: orc_operator_func (i, n, v, orc_func_mul); break; \ + case GTT_OP_DIV: \ + switch ((v)->type) { \ + case _NNS_INT32: orc_operator_div_loop (i, n, (v)->data._int32_t, int32_t); break; \ + case _NNS_UINT32: orc_operator_div_loop (i, n, (v)->data._uint32_t, uint32_t); break; \ + case _NNS_INT16: orc_operator_div_loop (i, n, (v)->data._int16_t, int16_t); break; \ + case _NNS_UINT16: orc_operator_div_loop (i, n, (v)->data._uint16_t, uint16_t); break; \ + case _NNS_INT8: orc_operator_div_loop (i, n, (v)->data._int8_t, int8_t); break; \ + case _NNS_UINT8: orc_operator_div_loop (i, n, (v)->data._uint8_t, uint8_t); break; \ + case _NNS_FLOAT64: orc_func_div (f64) ((gpointer) i, (v)->data._double, n); break; \ + case _NNS_FLOAT32: orc_func_div (f32) ((gpointer) i, (v)->data._float, n); break; \ + default: GST_ERROR_OBJECT (filter, "Unsupported type %d", (v)->type); g_assert (0); break; \ + } \ + break; \ + default: GST_ERROR_OBJECT (filter, "Unknown operator %d", op); break; \ + } \ + } while (0) +#endif /* HAVE_ORC */ + /** * @brief Macro to set operand */ @@ -793,6 +888,15 @@ gst_tensor_transform_set_property (GObject * object, guint prop_id, silent_debug ("Option = %s\n", filter->option); gst_tensor_transform_set_option_data (filter); break; + case PROP_ACCELERATION: +#ifdef HAVE_ORC + filter->acceleration = g_value_get_boolean (value); + silent_debug ("acceleration = %d\n", filter->acceleration); +#else + GST_WARNING_OBJECT (filter, "Orc acceleration is not supported"); + filter->acceleration = FALSE; +#endif + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -819,6 +923,9 @@ gst_tensor_transform_get_property (GObject * object, guint prop_id, case PROP_OPTION: g_value_set_string (value, filter->option); break; + case PROP_ACCELERATION: + g_value_set_boolean (value, filter->acceleration); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -945,6 +1052,13 @@ gst_tensor_transform_typecast (GstTensorTransform * filter, tensor_transform_operand_s value; size_t i, data_idx; +#ifdef HAVE_ORC + if (orc_supported (filter)) { + orc_typecast (inptr, outptr, num, in_tensor_type, out_tensor_type); + return GST_FLOW_OK; + } +#endif + for (i = 0; i < num; ++i) { /* init value with input tensor type */ data_idx = tensor_element_size[in_tensor_type] * i; @@ -984,6 +1098,32 @@ gst_tensor_transform_arithmetic (GstTensorTransform * filter, tensor_transform_operand_s value; size_t i, data_idx; +#ifdef HAVE_ORC + if (orc_supported (filter)) { + walk = filter->operators; + + /** + * Typecast should be called at the first. + * Do the typecast. If in/out type is same, this will copy the input array to output. + */ + orc_typecast (inptr, outptr, num, in_tensor_type, out_tensor_type); + + while (walk) { + op_s = (tensor_transform_operator_s *) walk->data; + + if (op_s->op != GTT_OP_TYPECAST) { + gst_tensor_transform_typecast_value (filter, &op_s->value, + out_tensor_type); + orc_operator (outptr, num, &op_s->value, op_s->op); + } + + walk = g_slist_next (walk); + } + + return GST_FLOW_OK; + } +#endif + for (i = 0; i < num; ++i) { /* init value with input tensor type */ data_idx = tensor_element_size[in_tensor_type] * i; @@ -1512,6 +1652,17 @@ gst_tensor_transform_set_caps (GstBaseTransform * trans, filter->in_config = in_config; filter->out_config = out_config; +#ifdef HAVE_ORC + /** + * @todo support 64bit integer and remove the flag orc_supported + */ + if (in_config.info.type != _NNS_INT64 && + in_config.info.type != _NNS_UINT64 && + out_config.info.type != _NNS_INT64 && + out_config.info.type != _NNS_UINT64) { + filter->orc_supported = TRUE; + } +#endif return TRUE; error: GST_ERROR_OBJECT (filter, "Set Caps Failed!\n"); diff --git a/gst/tensor_transform/tensor_transform.h b/gst/tensor_transform/tensor_transform.h index 90c9fd9..50105f1 100644 --- a/gst/tensor_transform/tensor_transform.h +++ b/gst/tensor_transform/tensor_transform.h @@ -148,7 +148,10 @@ struct _GstTensorTransform tensor_transform_stand data_stand; /**< Parsed option value for "stand" mode. */ }; gboolean loaded; /**< TRUE if mode & option are loaded */ - + gboolean acceleration; /**< TRUE to set orc acceleration */ +#ifdef HAVE_ORC + gboolean orc_supported; /**< TRUE if orc supported */ +#endif GSList *operators; /**< operators list */ GstTensorConfig in_config; /**< input tensor info */ -- 2.7.4