aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Ward <james.ward@arm.com>2022-12-07 15:38:01 +0000
committerEric Kunze <eric.kunze@arm.com>2023-01-18 01:04:54 +0000
commitc15f7d52aa4f360eba2344449baa418b7608ac7c (patch)
treeb0322cb02004e9e0a325c847c0bd332051b8389b
parent5e268097917825ddaa00a86ee95a4a6c4f50124b (diff)
downloadserialization_lib-c15f7d52aa4f360eba2344449baa418b7608ac7c.tar.gz
Schema changes for CLAMP, PAD float attributes
* Float attributes now serialized as uint8 vectors, but treated as floats at input/output to serialization Signed-off-by: James Ward <james.ward@arm.com> Change-Id: I417b0fabe0ef11fea263fe937b57d49bbfdb00da
-rw-r--r--include/attribute.h30
-rw-r--r--include/tosa_generated.h63
-rw-r--r--python/serializer/tosa_serializer.py38
-rw-r--r--python/tosa/ClampAttribute.py62
-rw-r--r--python/tosa/PadAttribute.py31
-rw-r--r--schema/tosa.fbs6
-rw-r--r--src/tosa_serialization_handler.cpp12
7 files changed, 196 insertions, 46 deletions
diff --git a/include/attribute.h b/include/attribute.h
index 1178ee4..5371130 100644
--- a/include/attribute.h
+++ b/include/attribute.h
@@ -40,11 +40,39 @@ public:
{}
};
+inline int convertFlatbuffersU8toF32(const flatbuffers::Vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
+{
+ out.clear();
+ if (in.size() < out_size * sizeof(float))
+ {
+ printf("convertFlatbuffersU8toF32(): uint8 Flatbuffers buffer size %u must be >= target size %ld\n", in.size(),
+ out_size * sizeof(float));
+ return 1;
+ }
+ for (uint32_t i = 0; i < out_size; i++)
+ {
+ uint32_t byte0 = in[i * sizeof(float)];
+ uint32_t byte1 = in[i * sizeof(float) + 1];
+ uint32_t byte2 = in[i * sizeof(float) + 2];
+ uint32_t byte3 = in[i * sizeof(float) + 3];
+ uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
+ float* val_fp32 = reinterpret_cast<float*>(&val_u32);
+ out.push_back(*val_fp32);
+ }
+ return 0;
+}
+
#define DEF_ARGS_VER0_S_STR(V) _##V = p->V()->str();
#define DEF_ARGS_VER0_S_DEFAULT(V) _##V = p->V();
+#define DEF_ARGS_VER0_S_float_as_bytes(V) \
+ { \
+ std::vector<float> attr_vec; \
+ assert(!convertFlatbuffersU8toF32(*(p->V()), 1, attr_vec)); \
+ _##V = attr_vec[0]; \
+ }
#define DEF_ARGS_VER0_S_int32_t(V) DEF_ARGS_VER0_S_DEFAULT(V)
-#define DEF_ARGS_VER0_S_float(V) DEF_ARGS_VER0_S_DEFAULT(V)
+#define DEF_ARGS_VER0_S_float(V) DEF_ARGS_VER0_S_float_as_bytes(V)
#define DEF_ARGS_VER0_S_bool(V) DEF_ARGS_VER0_S_DEFAULT(V)
#define DEF_ARGS_VER0_S_ResizeMode(V) DEF_ARGS_VER0_S_DEFAULT(V)
#define DEF_ARGS_VER0_S_DType(V) DEF_ARGS_VER0_S_DEFAULT(V)
diff --git a/include/tosa_generated.h b/include/tosa_generated.h
index 1a79453..b34875f 100644
--- a/include/tosa_generated.h
+++ b/include/tosa_generated.h
@@ -968,15 +968,16 @@ struct PadAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t pad_const_int() const {
return GetField<int32_t>(VT_PAD_CONST_INT, 0);
}
- float pad_const_fp() const {
- return GetField<float>(VT_PAD_CONST_FP, 0.0f);
+ const flatbuffers::Vector<uint8_t> *pad_const_fp() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_PAD_CONST_FP);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_PADDING) &&
verifier.VerifyVector(padding()) &&
VerifyField<int32_t>(verifier, VT_PAD_CONST_INT, 4) &&
- VerifyField<float>(verifier, VT_PAD_CONST_FP, 4) &&
+ VerifyOffset(verifier, VT_PAD_CONST_FP) &&
+ verifier.VerifyVector(pad_const_fp()) &&
verifier.EndTable();
}
};
@@ -991,8 +992,8 @@ struct PadAttributeBuilder {
void add_pad_const_int(int32_t pad_const_int) {
fbb_.AddElement<int32_t>(PadAttribute::VT_PAD_CONST_INT, pad_const_int, 0);
}
- void add_pad_const_fp(float pad_const_fp) {
- fbb_.AddElement<float>(PadAttribute::VT_PAD_CONST_FP, pad_const_fp, 0.0f);
+ void add_pad_const_fp(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pad_const_fp) {
+ fbb_.AddOffset(PadAttribute::VT_PAD_CONST_FP, pad_const_fp);
}
explicit PadAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
@@ -1009,7 +1010,7 @@ inline flatbuffers::Offset<PadAttribute> CreatePadAttribute(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
int32_t pad_const_int = 0,
- float pad_const_fp = 0.0f) {
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pad_const_fp = 0) {
PadAttributeBuilder builder_(_fbb);
builder_.add_pad_const_fp(pad_const_fp);
builder_.add_pad_const_int(pad_const_int);
@@ -1021,13 +1022,15 @@ inline flatbuffers::Offset<PadAttribute> CreatePadAttributeDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const std::vector<int32_t> *padding = nullptr,
int32_t pad_const_int = 0,
- float pad_const_fp = 0.0f) {
+ const std::vector<uint8_t> *pad_const_fp = nullptr) {
auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
+ if (pad_const_fp) { _fbb.ForceVectorAlignment(pad_const_fp->size(), sizeof(uint8_t), 8); }
+ auto pad_const_fp__ = pad_const_fp ? _fbb.CreateVector<uint8_t>(*pad_const_fp) : 0;
return tosa::CreatePadAttribute(
_fbb,
padding__,
pad_const_int,
- pad_const_fp);
+ pad_const_fp__);
}
struct AxisAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -1343,18 +1346,20 @@ struct ClampAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t max_int() const {
return GetField<int32_t>(VT_MAX_INT, 0);
}
- float min_fp() const {
- return GetField<float>(VT_MIN_FP, 0.0f);
+ const flatbuffers::Vector<uint8_t> *min_fp() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_MIN_FP);
}
- float max_fp() const {
- return GetField<float>(VT_MAX_FP, 0.0f);
+ const flatbuffers::Vector<uint8_t> *max_fp() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_MAX_FP);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_MIN_INT, 4) &&
VerifyField<int32_t>(verifier, VT_MAX_INT, 4) &&
- VerifyField<float>(verifier, VT_MIN_FP, 4) &&
- VerifyField<float>(verifier, VT_MAX_FP, 4) &&
+ VerifyOffset(verifier, VT_MIN_FP) &&
+ verifier.VerifyVector(min_fp()) &&
+ VerifyOffset(verifier, VT_MAX_FP) &&
+ verifier.VerifyVector(max_fp()) &&
verifier.EndTable();
}
};
@@ -1369,11 +1374,11 @@ struct ClampAttributeBuilder {
void add_max_int(int32_t max_int) {
fbb_.AddElement<int32_t>(ClampAttribute::VT_MAX_INT, max_int, 0);
}
- void add_min_fp(float min_fp) {
- fbb_.AddElement<float>(ClampAttribute::VT_MIN_FP, min_fp, 0.0f);
+ void add_min_fp(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> min_fp) {
+ fbb_.AddOffset(ClampAttribute::VT_MIN_FP, min_fp);
}
- void add_max_fp(float max_fp) {
- fbb_.AddElement<float>(ClampAttribute::VT_MAX_FP, max_fp, 0.0f);
+ void add_max_fp(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> max_fp) {
+ fbb_.AddOffset(ClampAttribute::VT_MAX_FP, max_fp);
}
explicit ClampAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
@@ -1390,8 +1395,8 @@ inline flatbuffers::Offset<ClampAttribute> CreateClampAttribute(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t min_int = 0,
int32_t max_int = 0,
- float min_fp = 0.0f,
- float max_fp = 0.0f) {
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> min_fp = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> max_fp = 0) {
ClampAttributeBuilder builder_(_fbb);
builder_.add_max_fp(max_fp);
builder_.add_min_fp(min_fp);
@@ -1400,6 +1405,24 @@ inline flatbuffers::Offset<ClampAttribute> CreateClampAttribute(
return builder_.Finish();
}
+inline flatbuffers::Offset<ClampAttribute> CreateClampAttributeDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int32_t min_int = 0,
+ int32_t max_int = 0,
+ const std::vector<uint8_t> *min_fp = nullptr,
+ const std::vector<uint8_t> *max_fp = nullptr) {
+ if (min_fp) { _fbb.ForceVectorAlignment(min_fp->size(), sizeof(uint8_t), 8); }
+ auto min_fp__ = min_fp ? _fbb.CreateVector<uint8_t>(*min_fp) : 0;
+ if (max_fp) { _fbb.ForceVectorAlignment(max_fp->size(), sizeof(uint8_t), 8); }
+ auto max_fp__ = max_fp ? _fbb.CreateVector<uint8_t>(*max_fp) : 0;
+ return tosa::CreateClampAttribute(
+ _fbb,
+ min_int,
+ max_int,
+ min_fp__,
+ max_fp__);
+}
+
struct RescaleAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef RescaleAttributeBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
diff --git a/python/serializer/tosa_serializer.py b/python/serializer/tosa_serializer.py
index e8311ce..f579df2 100644
--- a/python/serializer/tosa_serializer.py
+++ b/python/serializer/tosa_serializer.py
@@ -13,10 +13,11 @@
# limitations under the License.
import os
+import struct
+import serializer.tosa_serializer as ts
import json
import flatbuffers
import numpy as np
-import struct
from enum import IntEnum, unique
from tosa import (
TosaGraph,
@@ -197,7 +198,7 @@ class TosaSerializerAttribute(TosaSerializerUnion):
self.ints.append((a.AddWeightZp, weight_zp))
self.ints.append((a.AddAccumDtype, accum_dtype))
- def PadAttribute(self, padding, pad_const_int, pad_const_fp):
+ def PadAttribute(self, serializer_builder, padding, pad_const_int, pad_const_fp):
from tosa import PadAttribute as a, Attribute
self.utype = Attribute.Attribute().PadAttribute
@@ -205,7 +206,14 @@ class TosaSerializerAttribute(TosaSerializerUnion):
self.intvecs.append((a.AddPadding, padding))
self.ints.append((a.AddPadConstInt, pad_const_int))
- self.floats.append((a.AddPadConstFp, pad_const_fp))
+
+ # pad_const_fp attribute serialized as uint8 vector
+ pad_const_float_as_bytes = struct.pack("<f", pad_const_fp)
+ serialized_pad_const_fp = ts.TosaSerializer.serializeUint8Vec(
+ serializer_builder, pad_const_float_as_bytes
+ )
+
+ self.floats.append((a.AddPadConstFp, serialized_pad_const_fp))
def AxisAttribute(self, axis):
from tosa import AxisAttribute as a, Attribute
@@ -251,7 +259,7 @@ class TosaSerializerAttribute(TosaSerializerUnion):
self.int16vecs.append((a.AddBorder, border))
self.ints.append((a.AddMode, mode))
- def ClampAttribute(self, minint, maxint, minfp, maxfp):
+ def ClampAttribute(self, serializer_builder, minint, maxint, minfp, maxfp):
from tosa import ClampAttribute as a, Attribute
self.utype = Attribute.Attribute().ClampAttribute
@@ -260,8 +268,18 @@ class TosaSerializerAttribute(TosaSerializerUnion):
self.ints.append((a.AddMinInt, minint))
self.ints.append((a.AddMaxInt, maxint))
- self.ints.append((a.AddMinFp, minfp))
- self.ints.append((a.AddMaxFp, maxfp))
+ # min/max float attributes serialized as uint8 vectors
+ minfp_bytes = struct.pack("<f", minfp)
+ maxfp_bytes = struct.pack("<f", maxfp)
+ serialized_minfp_bytes = ts.TosaSerializer.serializeUint8Vec(
+ serializer_builder, minfp_bytes
+ )
+ serialized_maxfp_bytes = ts.TosaSerializer.serializeUint8Vec(
+ serializer_builder, maxfp_bytes
+ )
+
+ self.floats.append((a.AddMinFp, serialized_minfp_bytes))
+ self.floats.append((a.AddMaxFp, serialized_maxfp_bytes))
def RescaleAttribute(
self, input_zp, output_zp, multiplier, shift, scale32, double_round, per_channel
@@ -477,9 +495,11 @@ class TosaSerializerTensor:
np_arr = np.array(self.data, dtype=np.float16)
u8_data.extend(np_arr.view(np.uint8))
elif self.dtype == DType.FP32 or self.dtype == DType.BF16:
- for val in self.data:
- b = struct.pack("!f", val)
- u8_data.extend([b[3], b[2], b[1], b[0]])
+ # for val in self.data:
+ # b = struct.pack("!f", val)
+ # u8_data.extend([b[3], b[2], b[1], b[0]])
+ np_arr = np.array(self.data, dtype=np.float32)
+ u8_data.extend(np_arr.view(np.uint8))
elif self.dtype == TosaDType.DType:
# Serialize DType enum data as uint8 bytes
for val in self.data:
diff --git a/python/tosa/ClampAttribute.py b/python/tosa/ClampAttribute.py
index 58d1f0a..7937944 100644
--- a/python/tosa/ClampAttribute.py
+++ b/python/tosa/ClampAttribute.py
@@ -43,18 +43,58 @@ class ClampAttribute(object):
return 0
# ClampAttribute
- def MinFp(self):
+ def MinFp(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
- return 0.0
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+ return 0
+
+ # ClampAttribute
+ def MinFpAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+ return 0
+
+ # ClampAttribute
+ def MinFpLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ClampAttribute
+ def MinFpIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ return o == 0
# ClampAttribute
- def MaxFp(self):
+ def MaxFp(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
- return 0.0
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+ return 0
+
+ # ClampAttribute
+ def MaxFpAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+ return 0
+
+ # ClampAttribute
+ def MaxFpLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ClampAttribute
+ def MaxFpIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
+ return o == 0
def ClampAttributeStart(builder): builder.StartObject(4)
def Start(builder):
@@ -65,12 +105,18 @@ def AddMinInt(builder, minInt):
def ClampAttributeAddMaxInt(builder, maxInt): builder.PrependInt32Slot(1, maxInt, 0)
def AddMaxInt(builder, maxInt):
return ClampAttributeAddMaxInt(builder, maxInt)
-def ClampAttributeAddMinFp(builder, minFp): builder.PrependFloat32Slot(2, minFp, 0.0)
+def ClampAttributeAddMinFp(builder, minFp): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(minFp), 0)
def AddMinFp(builder, minFp):
return ClampAttributeAddMinFp(builder, minFp)
-def ClampAttributeAddMaxFp(builder, maxFp): builder.PrependFloat32Slot(3, maxFp, 0.0)
+def ClampAttributeStartMinFpVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def StartMinFpVector(builder, numElems):
+ return ClampAttributeStartMinFpVector(builder, numElems)
+def ClampAttributeAddMaxFp(builder, maxFp): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(maxFp), 0)
def AddMaxFp(builder, maxFp):
return ClampAttributeAddMaxFp(builder, maxFp)
+def ClampAttributeStartMaxFpVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def StartMaxFpVector(builder, numElems):
+ return ClampAttributeStartMaxFpVector(builder, numElems)
def ClampAttributeEnd(builder): return builder.EndObject()
def End(builder):
return ClampAttributeEnd(builder) \ No newline at end of file
diff --git a/python/tosa/PadAttribute.py b/python/tosa/PadAttribute.py
index 8d49d5a..23698d1 100644
--- a/python/tosa/PadAttribute.py
+++ b/python/tosa/PadAttribute.py
@@ -63,11 +63,31 @@ class PadAttribute(object):
return 0
# PadAttribute
- def PadConstFp(self):
+ def PadConstFp(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
- return 0.0
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+ return 0
+
+ # PadAttribute
+ def PadConstFpAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
+ return 0
+
+ # PadAttribute
+ def PadConstFpLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # PadAttribute
+ def PadConstFpIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
+ return o == 0
def PadAttributeStart(builder): builder.StartObject(3)
def Start(builder):
@@ -81,9 +101,12 @@ def StartPaddingVector(builder, numElems):
def PadAttributeAddPadConstInt(builder, padConstInt): builder.PrependInt32Slot(1, padConstInt, 0)
def AddPadConstInt(builder, padConstInt):
return PadAttributeAddPadConstInt(builder, padConstInt)
-def PadAttributeAddPadConstFp(builder, padConstFp): builder.PrependFloat32Slot(2, padConstFp, 0.0)
+def PadAttributeAddPadConstFp(builder, padConstFp): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(padConstFp), 0)
def AddPadConstFp(builder, padConstFp):
return PadAttributeAddPadConstFp(builder, padConstFp)
+def PadAttributeStartPadConstFpVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def StartPadConstFpVector(builder, numElems):
+ return PadAttributeStartPadConstFpVector(builder, numElems)
def PadAttributeEnd(builder): return builder.EndObject()
def End(builder):
return PadAttributeEnd(builder) \ No newline at end of file
diff --git a/schema/tosa.fbs b/schema/tosa.fbs
index ff8697b..e4a2498 100644
--- a/schema/tosa.fbs
+++ b/schema/tosa.fbs
@@ -173,7 +173,7 @@ table TransposeConvAttribute {
table PadAttribute {
padding: [int32];
pad_const_int: int32;
- pad_const_fp: float;
+ pad_const_fp: [ubyte] (force_align: 8);
}
table AxisAttribute {
@@ -203,8 +203,8 @@ table ResizeAttribute {
table ClampAttribute {
min_int: int32;
max_int: int32;
- min_fp: float;
- max_fp: float;
+ min_fp: [ubyte] (force_align: 8);
+ max_fp: [ubyte] (force_align: 8);
}
table RescaleAttribute {
diff --git a/src/tosa_serialization_handler.cpp b/src/tosa_serialization_handler.cpp
index a4410f2..2062522 100644
--- a/src/tosa_serialization_handler.cpp
+++ b/src/tosa_serialization_handler.cpp
@@ -619,6 +619,14 @@ tosa_err_t TosaSerializationHandler::Deserialize(const uint8_t* buf)
return TOSA_OK;
}
+std::vector<uint8_t> float_to_u8_wrapper(float f_in)
+{
+ const std::vector<float> f_vec{ f_in };
+ std::vector<uint8_t> u8_out;
+ TosaSerializationHandler::ConvertF32toU8(f_vec, u8_out);
+ return u8_out;
+}
+
tosa_err_t TosaSerializationHandler::Serialize()
{
// regions
@@ -682,9 +690,11 @@ tosa_err_t TosaSerializationHandler::Serialize()
fb_attribute = 0;
break;
#define DEF_ARGS_S_STR(NAME, V) , _builder.CreateString(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V().c_str())
+#define DEF_ARGS_S_FP_as_U8(NAME, V) \
+ , _builder.CreateVector<uint8_t>(float_to_u8_wrapper(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()))
#define DEF_ARGS_S_DEFAULT(NAME, V) , reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()
#define DEF_ARGS_S_int32_t(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
-#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
+#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_FP_as_U8(NAME, V)
#define DEF_ARGS_S_bool(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
#define DEF_ARGS_S_ResizeMode(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
#define DEF_ARGS_S_DType(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)