blob: 7e96313332656a61472dd6694e0b340a6b66ff06 [file] [log] [blame]
Eric Kunze2364dcd2021-04-26 11:06:57 -07001
Jerry Ge442261b2022-09-09 13:38:56 -07002// Copyright (c) 2020-2023, ARM Limited.
Eric Kunze2364dcd2021-04-26 11:06:57 -07003//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#include "tosa_serialization_handler.h"
James Ward485a11d2022-08-05 13:48:37 +010017#include "half.hpp"
Eric Kunze2364dcd2021-04-26 11:06:57 -070018
19#include <iostream>
20using namespace tosa;
21
22TosaSerializationTensor::TosaSerializationTensor(const flatbuffers::String* name,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070023 const flatbuffers::Vector<int32_t>* shape,
Eric Kunze2364dcd2021-04-26 11:06:57 -070024 DType dtype,
Jerry Ge442261b2022-09-09 13:38:56 -070025 const flatbuffers::Vector<uint8_t>* data,
Tai Lyc6939a42023-08-21 17:00:29 +000026 const bool variable,
27 const bool is_unranked)
Eric Kunze2364dcd2021-04-26 11:06:57 -070028{
Jerry Ge442261b2022-09-09 13:38:56 -070029 _dtype = dtype;
30 _variable = variable;
Jerry Geb413a952023-05-08 19:17:22 +000031 if (shape)
32 {
33 std::copy(shape->begin(), shape->end(), std::back_inserter(_shape));
34 }
Eric Kunze2364dcd2021-04-26 11:06:57 -070035
36 assert(name);
37 _name = name->str();
38
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070039 if (data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070040 {
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070041 std::copy(data->begin(), data->end(), std::back_inserter(_data));
Eric Kunze2364dcd2021-04-26 11:06:57 -070042 }
Tai Lyc6939a42023-08-21 17:00:29 +000043 _is_unranked = is_unranked;
Eric Kunze2364dcd2021-04-26 11:06:57 -070044}
45
Kevin Cheng545a5082021-11-11 01:36:33 +000046TosaSerializationTensor::TosaSerializationTensor(const std::string& name,
Eric Kunze2364dcd2021-04-26 11:06:57 -070047 const std::vector<int32_t>& shape,
48 DType dtype,
Jerry Ge442261b2022-09-09 13:38:56 -070049 const std::vector<uint8_t>& data,
Tai Lyc6939a42023-08-21 17:00:29 +000050 const bool variable,
51 const bool is_unranked)
Eric Kunze2364dcd2021-04-26 11:06:57 -070052{
Tai Lyc6939a42023-08-21 17:00:29 +000053 _dtype = dtype;
54 _variable = variable;
55 _shape = shape;
56 _name = name;
57 _data = data;
58 _is_unranked = is_unranked;
Eric Kunze2364dcd2021-04-26 11:06:57 -070059}
60
61TosaSerializationTensor::TosaSerializationTensor()
62{
Tai Lyc6939a42023-08-21 17:00:29 +000063 _dtype = DType_UNKNOWN;
64 _variable = false;
65 _name = "UNKNOWN";
66 _is_unranked = false;
Eric Kunze2364dcd2021-04-26 11:06:57 -070067}
68
69TosaSerializationTensor::~TosaSerializationTensor()
70{}
71
Eric Kunzebdcc3fe2022-06-07 05:17:37 +000072void TosaSerializationOperator::InitializeAttribute(Attribute attribute_type, const TosaAttributeBase* attribute)
Eric Kunze2364dcd2021-04-26 11:06:57 -070073{
Eric Kunze2364dcd2021-04-26 11:06:57 -070074 _attribute_type = attribute_type;
75
76 switch (attribute_type)
77 {
78 case Attribute_NONE:
79 _attribute = new TosaNoneAttribute();
80 break;
81#define DEF_ATTRIBUTE(NAME, ...) \
82 case Attribute_##NAME##Attribute: \
83 _attribute = new Tosa##NAME##Attribute(attribute); \
84 break;
85#include "attribute.def"
86#undef DEF_ATTRIBUTE
87 default:
88 printf("TosaSerializationOperator::TosaSerializationOperator(): Attribute %s not implemented yet\n",
89 EnumNamesAttribute()[attribute_type]);
90 assert(0);
91 }
92
Eric Kunzebdcc3fe2022-06-07 05:17:37 +000093 assert(_attribute);
Kevin Cheng545a5082021-11-11 01:36:33 +000094}
Eric Kunze2364dcd2021-04-26 11:06:57 -070095
Kevin Cheng545a5082021-11-11 01:36:33 +000096TosaSerializationOperator::TosaSerializationOperator(Op op,
97 Attribute attribute_type,
98 const TosaAttributeBase* attribute,
Kevin Cheng545a5082021-11-11 01:36:33 +000099 const std::vector<std::string>& input_tensor_names,
100 const std::vector<std::string>& output_tensor_names)
101{
102 _op = op;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700103 _input_tensor_names = input_tensor_names;
104 _output_tensor_names = output_tensor_names;
Kevin Cheng545a5082021-11-11 01:36:33 +0000105
Eric Kunzebdcc3fe2022-06-07 05:17:37 +0000106 InitializeAttribute(attribute_type, attribute);
Kevin Cheng545a5082021-11-11 01:36:33 +0000107}
108
109TosaSerializationOperator::TosaSerializationOperator(Op op,
110 Attribute attribute_type,
111 const TosaAttributeBase* attribute,
Kevin Cheng545a5082021-11-11 01:36:33 +0000112 std::vector<std::string>&& input_tensor_names,
113 std::vector<std::string>&& output_tensor_names)
114{
115 _op = op;
116 _input_tensor_names = std::move(input_tensor_names);
117 _output_tensor_names = std::move(output_tensor_names);
118
Eric Kunzebdcc3fe2022-06-07 05:17:37 +0000119 InitializeAttribute(attribute_type, attribute);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700120}
121
122TosaSerializationOperator::~TosaSerializationOperator()
123{
124 delete _attribute;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700125}
126
Kevin Cheng545a5082021-11-11 01:36:33 +0000127TosaSerializationBasicBlock::TosaSerializationBasicBlock(const std::string& name,
Jerry Ge13c78a62022-10-04 20:32:39 -0700128 const std::string& region_name,
Kevin Cheng545a5082021-11-11 01:36:33 +0000129 const std::vector<TosaSerializationOperator*>& operators,
130 const std::vector<TosaSerializationTensor*>& tensors,
131 const std::vector<std::string>& inputs,
132 const std::vector<std::string>& outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700133{
Jerry Ge13c78a62022-10-04 20:32:39 -0700134 _name = name;
135 _region_name = region_name;
136 _operators = operators;
137 _tensors = tensors;
138 _inputs = inputs;
139 _outputs = outputs;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700140}
141
Kevin Cheng545a5082021-11-11 01:36:33 +0000142TosaSerializationBasicBlock::TosaSerializationBasicBlock(std::string&& name,
Jerry Ge13c78a62022-10-04 20:32:39 -0700143 std::string&& region_name,
Kevin Cheng545a5082021-11-11 01:36:33 +0000144 std::vector<TosaSerializationOperator*>&& operators,
145 std::vector<TosaSerializationTensor*>&& tensors,
146 std::vector<std::string>&& inputs,
147 std::vector<std::string>&& outputs)
148{
Jerry Ge13c78a62022-10-04 20:32:39 -0700149 _name = std::move(name);
150 _region_name = std::move(region_name);
151 _operators = std::move(operators);
152 _tensors = std::move(tensors);
153 _inputs = std::move(inputs);
154 _outputs = std::move(outputs);
Kevin Cheng545a5082021-11-11 01:36:33 +0000155}
156
Eric Kunze2364dcd2021-04-26 11:06:57 -0700157TosaSerializationBasicBlock::~TosaSerializationBasicBlock()
158{
159 // deallocate all operators
160 for (auto op : GetOperators())
161 {
162 delete op; // ~TosaSerializationOperator()
163 }
164
165 // deallocate all tensors
166 for (auto ts : GetTensors())
167 {
168 delete ts; // ~TosaSerializationTensor()
169 }
170}
171
Jerry Ge13c78a62022-10-04 20:32:39 -0700172TosaSerializationRegion::TosaSerializationRegion(const std::string& name,
173 const std::vector<TosaSerializationBasicBlock*>& blocks)
174{
175 _name = name;
176 _blocks = blocks;
177}
178
179TosaSerializationRegion::TosaSerializationRegion(const std::string&& name,
180 const std::vector<TosaSerializationBasicBlock*>&& blocks)
181{
182 _name = std::move(name);
183 _blocks = std::move(blocks);
184}
185
186TosaSerializationRegion::~TosaSerializationRegion()
187{
188 // deallocate all blocks
189 for (auto block : GetBlocks())
190 {
191 delete block; // ~TosaSerializationBasicBlock()
192 }
193}
194
Eric Kunze2364dcd2021-04-26 11:06:57 -0700195TosaSerializationHandler::TosaSerializationHandler()
196{
197 _schemaLoaded = false;
Kevin Chenge6563f52021-10-20 12:12:02 -0700198 _version = TosaVersion(TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700199}
200
201TosaSerializationHandler::~TosaSerializationHandler()
202{
203 Clear(); // deallocate all basic blocks
204}
205
Eric Kunze2364dcd2021-04-26 11:06:57 -0700206tosa_err_t TosaSerializationHandler::LoadFileSchema(const char* schema_filename)
207{
208 std::string schema;
209 bool ok;
210
211 ok = flatbuffers::LoadFile(schema_filename, false, &schema);
212 if (!ok)
213 {
214 printf("Error loading schema file: %s\n", schema_filename);
215 return TOSA_FILE_ERROR;
216 }
217
218 ok = _parser.Parse(schema.c_str());
Kevin Chenga81a7a12021-11-10 14:07:34 -0800219
Eric Kunze2364dcd2021-04-26 11:06:57 -0700220 if (!ok)
221 {
222 printf("Error parsing ISA schema file: %s\n", schema_filename);
223 return TOSA_FILE_ERROR;
224 }
225 _schemaLoaded = true;
226
227 return TOSA_OK;
228}
229
230tosa_err_t TosaSerializationHandler::LoadFileJson(const char* filename)
231{
232 std::string jsonfile;
233 bool ok;
234 tosa_err_t err;
235
236 if (!_schemaLoaded)
237 {
238 return TOSA_SCHEMA_MISSING;
239 }
240
241 ok = flatbuffers::LoadFile(filename, false, &jsonfile);
242 if (!ok)
243 {
244 printf("Error loading json file: %s\n", filename);
245 return TOSA_FILE_ERROR;
246 }
247
248 ok = _parser.Parse(jsonfile.c_str());
249 if (!ok)
250 {
251 printf("Error parsing json file: %s\n", filename);
252 return TOSA_FILE_ERROR;
253 }
254
255 uint8_t* buf = _parser.builder_.GetBufferPointer();
256
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700257 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700258 if (err != TOSA_OK)
259 {
260 return err;
261 }
262
263 return TOSA_OK;
264}
265
266tosa_err_t TosaSerializationHandler::SaveFileJson(const char* filename)
267{
268 std::string jsongen;
269 tosa_err_t err;
270
271 if (!_schemaLoaded)
272 {
273 return TOSA_SCHEMA_MISSING;
274 }
275
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700276 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700277 if (err != TOSA_OK)
278 {
279 return err;
280 }
281
282 uint8_t* buf = _builder.GetBufferPointer();
283
Tai Ly89963aa2023-07-03 22:14:05 +0000284 if (GenText(_parser, buf, &jsongen))
Eric Kunze2364dcd2021-04-26 11:06:57 -0700285 {
286 printf("Couldn't serialize parsed data to JSON!\n");
287 return TOSA_FILE_ERROR;
288 }
289
290 FILE* file = fopen(filename, "wb");
291
292 if (!file)
293 {
294 printf("Couldn't open output file: %s\n", filename);
295 return TOSA_FILE_ERROR;
296 }
297
298 if (fwrite(jsongen.c_str(), sizeof(char), jsongen.size(), file) != jsongen.size())
299 {
300 printf("Error writing to json output file: %s\n", filename);
301 fclose(file);
302 return TOSA_FILE_ERROR;
303 }
304
305 if (file)
306 fclose(file);
307
308 return TOSA_OK;
309}
310
311tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const char* filename)
312{
313 std::string read_buffer;
314 tosa_err_t err;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800315 const uint8_t* buf;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700316 bool ok;
317
318 ok = flatbuffers::LoadFile(filename, false, &read_buffer);
319 if (!ok)
320 {
321 printf("Error loading flatbuffer file: %s\n", filename);
322 return TOSA_FILE_ERROR;
323 }
324
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800325 buf = reinterpret_cast<const uint8_t*>(read_buffer.data());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700326
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700327 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700328 if (err != TOSA_OK)
329 {
330 return err;
331 }
332
333 return TOSA_OK;
334}
335
Aaron DeBattista8b3903a2021-11-18 16:38:11 +0000336tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const void* input, int in_size)
337{
338 tosa_err_t err;
339
340 const uint8_t* buf = (const uint8_t*)input;
341 err = Deserialize(buf);
342 if (err != TOSA_OK)
343 {
344 return err;
345 }
346
347 return TOSA_OK;
348}
349
Eric Kunze2364dcd2021-04-26 11:06:57 -0700350tosa_err_t TosaSerializationHandler::SaveFileTosaFlatbuffer(const char* filename)
351{
352 tosa_err_t err;
353
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700354 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700355 if (err != TOSA_OK)
356 {
357 return err;
358 }
359
360 uint8_t* buf = _builder.GetBufferPointer();
361
362 bool ok = flatbuffers::SaveFile(filename, (const char*)buf, _builder.GetSize(), false);
363 if (!ok)
364 {
365 printf("Error saving floatbuffer file: %s\n", filename);
366 return TOSA_FILE_ERROR;
367 }
368
369 return TOSA_OK;
370}
371
372tosa_err_t TosaSerializationHandler::Clear()
373{
374 // deallocate all basic blocks
Jerry Ge13c78a62022-10-04 20:32:39 -0700375 for (auto region : GetRegions())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700376 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700377 delete region;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700378 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700379 _regions.clear();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700380
381 return TOSA_OK;
382}
383
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700384tosa_err_t TosaSerializationHandler::Deserialize(const uint8_t* buf)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700385{
Eric Kunzee6596402022-06-09 21:27:36 +0000386 if (!TosaGraphBufferHasIdentifier(buf))
387 {
388 printf("WARNING: TOSA file does not have TOSA file identifier\n");
389 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700390 auto fb_tosa_graph = GetTosaGraph(buf);
391 auto fb_tosa_version = fb_tosa_graph->version();
Jerry Ge13c78a62022-10-04 20:32:39 -0700392 auto fb_tosa_regions = fb_tosa_graph->regions();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700393
Eric Kunze2364dcd2021-04-26 11:06:57 -0700394 TosaAttributeBase* typed_attribute = NULL;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700395 TosaSerializationOperator* new_operator = NULL;
396 TosaSerializationBasicBlock* new_block = NULL;
397 TosaSerializationTensor* new_tensor = NULL;
Jerry Ge13c78a62022-10-04 20:32:39 -0700398 TosaSerializationRegion* new_region = NULL;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700399
400 // erase container
401 Clear();
402
Kevin Chenge6563f52021-10-20 12:12:02 -0700403 TosaVersion read_version(fb_tosa_version->_major(), fb_tosa_version->_minor(), fb_tosa_version->_patch(),
404 fb_tosa_version->_draft());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700405
Jerry Gec4733b02023-08-02 21:48:39 +0000406 TosaVersion::compat_t is_compat = TosaVersion::is_compatible(read_version, GetVersion());
Kevin Chenge6563f52021-10-20 12:12:02 -0700407 switch (is_compat)
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700408 {
Kevin Chenge6563f52021-10-20 12:12:02 -0700409 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
410 break;
Jerry Gec4733b02023-08-02 21:48:39 +0000411 case TosaVersion::compat_t::BACKWARD_COMPATIBLE:
412 printf("WARNING: Different Tosa flatbuffer and serializer versions detected. Read Tosa flatbuffer version "
413 "%s is backward "
414 "compatible with serializer version %s\n",
Kevin Chenge6563f52021-10-20 12:12:02 -0700415 read_version.to_string().c_str(), GetVersion().to_string().c_str());
416 break;
417 case TosaVersion::compat_t::NOT_COMPATIBLE:
Jerry Gec4733b02023-08-02 21:48:39 +0000418 printf("ERROR: Read Tosa flatbuffer version %s is not compatible with serializer version %s\n",
Kevin Chenge6563f52021-10-20 12:12:02 -0700419 read_version.to_string().c_str(), GetVersion().to_string().c_str());
420 return TOSA_VERSION_MISMATCH;
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700421 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700422
Jerry Ge13c78a62022-10-04 20:32:39 -0700423 for (size_t i = 0; i < fb_tosa_regions->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700424 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700425 auto curr_region = fb_tosa_regions->Get(i);
426 auto region_name = curr_region->name()->str();
427 auto fb_tosa_blocks = curr_region->blocks();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700428
Tai Lycfcb20d2023-03-13 21:04:11 +0000429 new_region = new TosaSerializationRegion(curr_region->name()->str(), {});
Jerry Ge13c78a62022-10-04 20:32:39 -0700430 this->GetRegions().push_back(new_region);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700431
Jerry Ge13c78a62022-10-04 20:32:39 -0700432 for (size_t i = 0; i < fb_tosa_blocks->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700433 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000434 std::vector<TosaSerializationOperator*> block_operators_container;
435 std::vector<TosaSerializationTensor*> block_tensors_container;
436 std::vector<std::string> block_inputs_container;
437 std::vector<std::string> block_outputs_container;
438
Jerry Ge13c78a62022-10-04 20:32:39 -0700439 auto curr_block = fb_tosa_blocks->Get(i);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700440
Jerry Ge13c78a62022-10-04 20:32:39 -0700441 auto block_name = curr_block->name()->str();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700442
Jerry Ge13c78a62022-10-04 20:32:39 -0700443 auto fb_tosa_operators = curr_block->operators();
Jerry Ge13c78a62022-10-04 20:32:39 -0700444 for (size_t j = 0; j < fb_tosa_operators->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700445 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700446 auto curr_operator = fb_tosa_operators->Get(j);
447
448 auto operator_op = curr_operator->op();
449 auto attribute_type = curr_operator->attribute_type();
450 auto attribute = curr_operator->attribute();
451
Tai Lycfcb20d2023-03-13 21:04:11 +0000452 std::vector<std::string> operator_inputs_container;
453 std::vector<std::string> operator_outputs_container;
454
Jerry Ge13c78a62022-10-04 20:32:39 -0700455 // input tensors
456 auto operator_inputs = curr_operator->inputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700457 if (operator_inputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700458 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700459 for (size_t k = 0; k < operator_inputs->size(); k++)
460 {
461 auto curr_input = operator_inputs->Get(k);
462 operator_inputs_container.push_back(curr_input->str());
463 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700464 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700465
Jerry Ge13c78a62022-10-04 20:32:39 -0700466 // output tensors
467 auto operator_outputs = curr_operator->outputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700468 if (operator_outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700469 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700470 for (size_t k = 0; k < operator_outputs->size(); k++)
471 {
472 auto curr_output = operator_outputs->Get(k);
473 operator_outputs_container.push_back(curr_output->str());
474 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700475 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700476
Jerry Ge13c78a62022-10-04 20:32:39 -0700477 switch (attribute_type)
478 {
479 case Attribute_NONE:
480 typed_attribute = new TosaNoneAttribute();
481 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700482#define DEF_ATTRIBUTE(NAME, ...) \
483 case Attribute_##NAME##Attribute: \
484 typed_attribute = new Tosa##NAME##Attribute(attribute); \
485 break;
486#include "attribute.def"
487#undef DEF_ATTRIBUTE
Jerry Ge13c78a62022-10-04 20:32:39 -0700488 default:
489 printf("TosaSerializationHandler::Deserialize(): Attribute %s not implemented yet\n",
490 EnumNamesAttribute()[attribute_type]);
491 return TOSA_INTERNAL_ERROR;
492 }
493
494 new_operator = new TosaSerializationOperator(operator_op, attribute_type, typed_attribute,
495 operator_inputs_container, operator_outputs_container);
496 if (new_operator)
497 {
498 block_operators_container.push_back(new_operator);
499 }
500 else
501 {
502 return TOSA_MEMORY_ERROR;
503 }
504
505 if (typed_attribute)
506 delete typed_attribute;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700507 }
508
Jerry Ge13c78a62022-10-04 20:32:39 -0700509 auto block_inputs = curr_block->inputs();
510 auto block_outputs = curr_block->outputs();
511
Jerry Ge13c78a62022-10-04 20:32:39 -0700512 for (size_t j = 0; j < block_inputs->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700513 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700514 auto curr_block_input = block_inputs->Get(j);
515 block_inputs_container.push_back(curr_block_input->str());
516 }
517 for (size_t j = 0; j < block_outputs->size(); j++)
518 {
519 auto curr_block_output = block_outputs->Get(j);
520 block_outputs_container.push_back(curr_block_output->str());
521 }
522
523 auto fb_tosa_tensors = curr_block->tensors();
Jerry Ge13c78a62022-10-04 20:32:39 -0700524 for (size_t j = 0; j < fb_tosa_tensors->size(); j++)
525 {
526 auto curr_tensor = fb_tosa_tensors->Get(j);
527
Tai Lyc6939a42023-08-21 17:00:29 +0000528 auto tensor_name = curr_tensor->name();
529 auto tensor_shape = curr_tensor->shape();
530 auto tensor_type = curr_tensor->type();
531 auto tensor_variable = curr_tensor->variable();
532 auto tensor_data = curr_tensor->data();
533 auto tensor_is_unranked = curr_tensor->is_unranked();
Jerry Ge13c78a62022-10-04 20:32:39 -0700534
Tai Lyc6939a42023-08-21 17:00:29 +0000535 new_tensor = new TosaSerializationTensor(tensor_name, tensor_shape, tensor_type, tensor_data,
536 tensor_variable, tensor_is_unranked);
Jerry Ge13c78a62022-10-04 20:32:39 -0700537 if (new_tensor)
538 {
539 block_tensors_container.push_back(new_tensor);
540 }
541 else
542 {
543 return TOSA_MEMORY_ERROR;
544 }
545 }
546 new_block = new TosaSerializationBasicBlock(block_name, region_name, block_operators_container,
547 block_tensors_container, block_inputs_container,
548 block_outputs_container);
549 if (new_block)
550 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000551 new_region->GetBlocks().push_back(new_block);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700552 }
553 else
554 {
555 return TOSA_MEMORY_ERROR;
556 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700557 } // end block for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700558 }
559
560 return TOSA_OK;
561}
562
James Ward80905bb2023-01-25 15:51:27 +0000563std::vector<uint8_t> float_to_u8_helper(float f_in)
James Wardc15f7d52022-12-07 15:38:01 +0000564{
James Ward80905bb2023-01-25 15:51:27 +0000565 // Push back a single float value to the buffer with *NO PADDING*
566 // Therefore ConvertF32toU8 function not used
James Wardc15f7d52022-12-07 15:38:01 +0000567 std::vector<uint8_t> u8_out;
James Ward80905bb2023-01-25 15:51:27 +0000568 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&f_in);
569 u8_out.push_back(*val_u32 & 0xFF);
570 u8_out.push_back((*val_u32 >> 8) & 0xFF);
571 u8_out.push_back((*val_u32 >> 16) & 0xFF);
572 u8_out.push_back((*val_u32 >> 24) & 0xFF);
James Wardc15f7d52022-12-07 15:38:01 +0000573 return u8_out;
574}
575
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700576tosa_err_t TosaSerializationHandler::Serialize()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700577{
Jerry Ge13c78a62022-10-04 20:32:39 -0700578 // regions
579 std::vector<flatbuffers::Offset<TosaRegion>> fboffset_regions;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700580
Eric Kunze2364dcd2021-04-26 11:06:57 -0700581 // translate TosaFlatbufferOperator to flatbuffers::Offset<TosaOperator>
Jerry Ge13c78a62022-10-04 20:32:39 -0700582 for (auto region : GetRegions())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700583 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000584 std::vector<flatbuffers::Offset<TosaBasicBlock>> fboffset_blocks;
Jerry Ge13c78a62022-10-04 20:32:39 -0700585 for (auto block : region->GetBlocks())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700586 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000587 std::vector<flatbuffers::Offset<TosaOperator>> fboffset_block_operators;
588 std::vector<flatbuffers::Offset<TosaTensor>> fboffset_block_tensors;
589 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_inputs;
590 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700591 auto block_name = _builder.CreateString(block->GetName().c_str());
592 for (auto tensor_str : block->GetInputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700593 {
594 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700595 fboffset_block_inputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700596 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700597 for (auto tensor_str : block->GetOutputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700598 {
599 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700600 fboffset_block_outputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700601 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700602 auto fb_block_inputs = _builder.CreateVector(fboffset_block_inputs);
603 auto fb_block_outputs = _builder.CreateVector(fboffset_block_outputs);
604 for (auto op : block->GetOperators())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700605 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000606 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_inputs;
607 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700608 auto operator_op = op->GetOp();
609 auto attribute_type = op->GetAttributeType();
610 for (auto tensor_str : op->GetInputTensorNames())
611 {
612 auto tensor_name = _builder.CreateString(tensor_str.c_str());
613 fboffset_operator_inputs.push_back(tensor_name);
614 }
615 for (auto tensor_str : op->GetOutputTensorNames())
616 {
617 auto tensor_name = _builder.CreateString(tensor_str.c_str());
618 fboffset_operator_outputs.push_back(tensor_name);
619 }
620 auto fb_operator_inputs = _builder.CreateVector(fboffset_operator_inputs);
621 auto fb_operator_outputs = _builder.CreateVector(fboffset_operator_outputs);
622 flatbuffers::Offset<void> fb_attribute;
623 switch (attribute_type)
624 {
625 case Attribute_NONE:
626 fb_attribute = 0;
627 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700628#define DEF_ARGS_S_STR(NAME, V) , _builder.CreateString(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V().c_str())
James Wardc15f7d52022-12-07 15:38:01 +0000629#define DEF_ARGS_S_FP_as_U8(NAME, V) \
James Ward80905bb2023-01-25 15:51:27 +0000630 , _builder.CreateVector<uint8_t>(float_to_u8_helper(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()))
Eric Kunze2364dcd2021-04-26 11:06:57 -0700631#define DEF_ARGS_S_DEFAULT(NAME, V) , reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700632#define DEF_ARGS_S_int32_t(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Wardc15f7d52022-12-07 15:38:01 +0000633#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_FP_as_U8(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700634#define DEF_ARGS_S_bool(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
635#define DEF_ARGS_S_ResizeMode(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Ward485a11d2022-08-05 13:48:37 +0100636#define DEF_ARGS_S_DType(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700637#define DEF_ARGS_S_string(NAME, V) DEF_ARGS_S_STR(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700638#define DEF_ARGS_S(NAME, T, V) DEF_ARGS_S_##T(NAME, V)
639#define DEF_ARGS_V(NAME, T, V) , _builder.CreateVector<T>(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700640#define DEF_ARGS_1(NAME, T0, F0, V0) DEF_ARGS_##F0(NAME, T0, V0)
641#define DEF_ARGS_2(NAME, T0, F0, V0, T1, F1, V1) DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1)
642#define DEF_ARGS_3(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2) \
643 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2)
644#define DEF_ARGS_4(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3) \
645 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3)
646#define DEF_ARGS_5(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4) \
647 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
648 DEF_ARGS_##F4(NAME, T4, V4)
649#define DEF_ARGS_6(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5) \
650 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
651 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5)
652#define DEF_ARGS_7(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5, T6, F6, V6) \
653 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
654 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6)
Eric Kunze9601cbd2023-08-17 20:44:39 +0000655#define DEF_ARGS_8(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5, T6, F6, V6, T7, F7, \
656 V7) \
657 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
658 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6) \
659 DEF_ARGS_##F7(NAME, T7, V7)
660#define DEF_ARGS_9(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5, T6, F6, V6, T7, F7, \
661 V7, T8, F8, V8) \
662 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
663 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6) \
664 DEF_ARGS_##F7(NAME, T7, V7) DEF_ARGS_##F8(NAME, T8, V8)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700665#define DEF_ATTRIBUTE(NAME, NUM_ARGS, ...) \
666 case Attribute_##NAME##Attribute: \
667 fb_attribute = Create##NAME##Attribute(_builder DEF_ARGS_##NUM_ARGS(NAME##Attribute, __VA_ARGS__)).Union(); \
668 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700669#include "attribute.def"
670#undef DEF_ATTRIBUTE
671#undef DEF_ARGS_1
672#undef DEF_ARGS_2
673#undef DEF_ARGS_3
674#undef DEF_ARGS_4
675#undef DEF_ARGS_5
676#undef DEF_ARGS_6
677#undef DEF_ARGS_7
678#undef DEF_ARGS_S
679#undef DEF_ARGS_V
680#undef DEF_ARGS_S_int32_t
681#undef DEF_ARGS_S_float
682#undef DEF_ARGS_S_bool
683#undef DEF_ARGS_S_ResizeMode
James Ward485a11d2022-08-05 13:48:37 +0100684#undef DEF_ARGS_S_DType
Eric Kunze2364dcd2021-04-26 11:06:57 -0700685#undef DEF_ARGS_S_string
686#undef DEF_ARGS_S_STR
687#undef DEF_ARGS_S_DEFAULT
Jerry Ge13c78a62022-10-04 20:32:39 -0700688 default:
689 printf("TosaSerializationHandler::Serialize(): Attribute %s not implemented yet\n",
690 EnumNamesAttribute()[attribute_type]);
691 return TOSA_INTERNAL_ERROR;
692 }
693 auto fboffset_operator = CreateTosaOperator(_builder, operator_op, attribute_type, fb_attribute,
694 fb_operator_inputs, fb_operator_outputs);
695 fboffset_block_operators.push_back(fboffset_operator);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700696 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700697 auto fb_block_operators = _builder.CreateVector(fboffset_block_operators);
698 for (auto tensor : block->GetTensors())
699 {
Tai Lyc6939a42023-08-21 17:00:29 +0000700 auto tensor_name = _builder.CreateString(tensor->GetName().c_str());
701 auto tensor_shape = _builder.CreateVector(tensor->GetShape());
702 auto tensor_dtype = tensor->GetDtype();
703 bool tensor_variable = tensor->GetVariable();
704 auto tensor_data = _builder.CreateVector(tensor->GetData());
705 auto tensor_is_unranked = tensor->GetIsUnranked();
706 auto fboffset_tensor = CreateTosaTensor(_builder, tensor_name, tensor_shape, tensor_dtype, tensor_data,
707 tensor_variable, tensor_is_unranked);
Jerry Ge13c78a62022-10-04 20:32:39 -0700708 fboffset_block_tensors.push_back(fboffset_tensor);
709 }
710 auto fb_block_tensors = _builder.CreateVector(fboffset_block_tensors);
711 auto fboffset_block = CreateTosaBasicBlock(_builder, block_name, fb_block_operators, fb_block_tensors,
Won Jeoncb4bbf42023-08-10 08:50:15 +0000712 fb_block_inputs, fb_block_outputs);
Jerry Ge13c78a62022-10-04 20:32:39 -0700713 fboffset_blocks.push_back(fboffset_block);
714 } // end block for_loop
715 auto fb_blocks = _builder.CreateVector(fboffset_blocks);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700716
Jerry Ge13c78a62022-10-04 20:32:39 -0700717 auto region_name = _builder.CreateString(region->GetName().c_str());
718 auto fboffset_region = CreateTosaRegion(_builder, region_name, fb_blocks);
719 fboffset_regions.push_back(fboffset_region);
720 } // end region for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700721
Jerry Ge13c78a62022-10-04 20:32:39 -0700722 auto fb_regions = _builder.CreateVector(fboffset_regions);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700723
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700724 auto fb_version =
725 CreateVersion(_builder, TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Jerry Ge13c78a62022-10-04 20:32:39 -0700726 auto fb_graph = CreateTosaGraph(_builder, fb_version, fb_regions);
Eric Kunzee6596402022-06-09 21:27:36 +0000727 _builder.Finish(fb_graph, TosaGraphIdentifier());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700728
729 return TOSA_OK;
730}
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700731
Jerry Ge442261b2022-09-09 13:38:56 -0700732void TosaSerializationHandler::ForceAlignTensorData(std::vector<uint8_t>& buf)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700733{
734 while ((buf.size() % TENSOR_BUFFER_FORCE_ALIGNMENT) != 0)
735 {
736 buf.push_back(0);
737 }
738}
739
James Ward485a11d2022-08-05 13:48:37 +0100740tosa_err_t TosaSerializationHandler::ConvertF16toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
741{
742 // Note: Converts fp32->fp16 before converting to uint8_t
743 out.clear();
744 for (auto val : in)
745 {
746 half_float::half val_f16 = half_float::half_cast<half_float::half, float>(val);
747 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val_f16);
748 out.push_back(*val_u16 & 0xFF);
749 out.push_back((*val_u16 >> 8) & 0xFF);
750 }
Jerry Ge442261b2022-09-09 13:38:56 -0700751 ForceAlignTensorData(out);
James Ward485a11d2022-08-05 13:48:37 +0100752 return TOSA_OK;
753}
754
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700755tosa_err_t TosaSerializationHandler::ConvertF32toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
756{
757 out.clear();
758 for (auto val : in)
759 {
760 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
761 out.push_back(*val_u32 & 0xFF);
762 out.push_back((*val_u32 >> 8) & 0xFF);
763 out.push_back((*val_u32 >> 16) & 0xFF);
764 out.push_back((*val_u32 >> 24) & 0xFF);
765 }
Jerry Ge442261b2022-09-09 13:38:56 -0700766 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700767 return TOSA_OK;
768}
769
770tosa_err_t TosaSerializationHandler::ConvertI48toU8(const std::vector<int64_t>& in, std::vector<uint8_t>& out)
771{
772 out.clear();
773 for (auto val : in)
774 {
775 uint64_t* val_u64 = reinterpret_cast<uint64_t*>(&val);
776 out.push_back(*val_u64 & 0xFF);
777 out.push_back((*val_u64 >> 8) & 0xFF);
778 out.push_back((*val_u64 >> 16) & 0xFF);
779 out.push_back((*val_u64 >> 24) & 0xFF);
780 out.push_back((*val_u64 >> 32) & 0xFF);
781 out.push_back((*val_u64 >> 40) & 0xFF);
782 }
Jerry Ge442261b2022-09-09 13:38:56 -0700783 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700784 return TOSA_OK;
785}
786
787tosa_err_t TosaSerializationHandler::ConvertI32toU8(const std::vector<int32_t>& in, std::vector<uint8_t>& out)
788{
789 out.clear();
790 for (auto val : in)
791 {
792 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
793 out.push_back(*val_u32 & 0xFF);
794 out.push_back((*val_u32 >> 8) & 0xFF);
795 out.push_back((*val_u32 >> 16) & 0xFF);
796 out.push_back((*val_u32 >> 24) & 0xFF);
797 }
Jerry Ge442261b2022-09-09 13:38:56 -0700798 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700799 return TOSA_OK;
800}
801
802tosa_err_t TosaSerializationHandler::ConvertI16toU8(const std::vector<int16_t>& in, std::vector<uint8_t>& out)
803{
804 out.clear();
805 for (auto val : in)
806 {
807 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val);
808 out.push_back(*val_u16 & 0xFF);
809 out.push_back((*val_u16 >> 8) & 0xFF);
810 }
Jerry Ge442261b2022-09-09 13:38:56 -0700811 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700812 return TOSA_OK;
813}
814
815tosa_err_t TosaSerializationHandler::ConvertI8toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
816{
817 out.clear();
818 for (auto val : in)
819 {
820 uint8_t* val_u8 = reinterpret_cast<uint8_t*>(&val);
821 out.push_back(*val_u8);
822 }
Jerry Ge442261b2022-09-09 13:38:56 -0700823 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700824 return TOSA_OK;
825}
826
Kevin Cheng3ce56342021-07-28 13:42:29 -0700827// Two int4 values are packed into one byte out.
828// For given input value val_0 = in[2*i], and val_1 = in[2*i+1],
829// they'll be packed as out[3:0] = val_0, and out[7:4] = val_1
830tosa_err_t TosaSerializationHandler::ConvertI4toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
831{
832 out.clear();
833 uint32_t in_size = in.size();
834 uint32_t out_size = (in_size % 2 == 0) ? (in_size / 2) : ((in_size + 1) / 2);
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800835 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700836 {
837 int8_t val_0 = in[2 * i];
838 int8_t val_1 = 0;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800839 if (2u * i + 1u < in_size)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700840 {
841 val_1 = in[2 * i + 1];
842 }
843 // In TOSA spec, int4 ranges [-7, 7]
844 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
845 {
846 printf("TosaSerializationHandler::ConvertI4toU8(): element in input array (%d or %d) exceeds int4 range.\n",
847 val_0, val_1);
848 return TOSA_USER_ERROR;
849 }
850 int8_t val_packed = (val_0 & 0xF) | ((val_1 & 0xF) << 4);
851 uint8_t val_u8 = static_cast<uint8_t>(val_packed);
852 out.push_back(val_u8);
853 }
Jerry Ge442261b2022-09-09 13:38:56 -0700854 ForceAlignTensorData(out);
Kevin Cheng3ce56342021-07-28 13:42:29 -0700855 return TOSA_OK;
856}
857
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700858tosa_err_t TosaSerializationHandler::ConvertBooltoU8(const std::vector<bool>& in, std::vector<uint8_t>& out)
859{
860 out.clear();
861 for (auto val : in)
862 {
Eric Kunze4417b422022-06-20 07:27:42 -0700863 uint8_t val_u8 = val;
864 out.push_back(val_u8);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700865 }
Jerry Ge442261b2022-09-09 13:38:56 -0700866 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700867 return TOSA_OK;
868}
869
870tosa_err_t
James Ward485a11d2022-08-05 13:48:37 +0100871 TosaSerializationHandler::ConvertU8toF16(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
872{
873 // Note: fp16 values returned in fp32 type
874 out.clear();
875 if (in.size() < out_size * sizeof(int16_t))
876 {
877 printf("TosaSerializationHandler::ConvertU8toF16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
878 out_size * sizeof(int16_t));
879 return TOSA_USER_ERROR;
880 }
881
882 for (uint32_t i = 0; i < out_size; i++)
883 {
884 uint16_t f16_byte0 = in[i * sizeof(int16_t)];
885 uint16_t f16_byte1 = in[i * sizeof(int16_t) + 1];
886 uint16_t val_u16 = f16_byte0 + (f16_byte1 << 8);
887
888 // Reinterpret u16 byte as fp16 then convert to fp32
889 half_float::half val_f16 = *(half_float::half*)&val_u16;
890 float val_fp32 = half_float::half_cast<float, half_float::half>(val_f16);
891 out.push_back(val_fp32);
892 }
893 return TOSA_OK;
894}
895
896tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700897 TosaSerializationHandler::ConvertU8toF32(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
898{
899 out.clear();
900 if (in.size() < out_size * sizeof(float))
901 {
902 printf("TosaSerializationHandler::ConvertU8toF32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
903 out_size * sizeof(float));
904 return TOSA_USER_ERROR;
905 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800906 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700907 {
908 uint32_t byte0 = in[i * sizeof(float)];
909 uint32_t byte1 = in[i * sizeof(float) + 1];
910 uint32_t byte2 = in[i * sizeof(float) + 2];
911 uint32_t byte3 = in[i * sizeof(float) + 3];
912 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
913 float* val_fp32 = reinterpret_cast<float*>(&val_u32);
914 out.push_back(*val_fp32);
915 }
916 return TOSA_OK;
917}
918
919tosa_err_t TosaSerializationHandler::ConvertU8toI48(const std::vector<uint8_t>& in,
920 uint32_t out_size,
921 std::vector<int64_t>& out)
922{
923 out.clear();
924 if (in.size() < out_size * 6 /* sizeof(int48) */)
925 {
926 printf("TosaSerializationHandler::ConvertU8toI48(): uint8 buffer size %ld must >= target size %d\n", in.size(),
927 out_size * 6);
928 return TOSA_USER_ERROR;
929 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800930 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700931 {
932 uint64_t byte0 = in[i * 6];
933 uint64_t byte1 = in[i * 6 + 1];
934 uint64_t byte2 = in[i * 6 + 2];
935 uint64_t byte3 = in[i * 6 + 3];
936 uint64_t byte4 = in[i * 6 + 4];
937 uint64_t byte5 = in[i * 6 + 5];
938 bool sign = ((byte5 >> 7) & 1) == 1 ? true : false;
939 uint64_t val_u64 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24) + (byte4 << 32) + (byte5 << 40);
940 if (sign)
941 {
942 uint64_t sext_mask = (0xFFFFUL << 48);
943 val_u64 |= sext_mask;
944 }
945 int64_t* val_i64 = reinterpret_cast<int64_t*>(&val_u64);
946 out.push_back(*val_i64);
947 }
948 return TOSA_OK;
949}
950
951tosa_err_t TosaSerializationHandler::ConvertU8toI32(const std::vector<uint8_t>& in,
952 uint32_t out_size,
953 std::vector<int32_t>& out)
954{
955 out.clear();
956 if (in.size() < out_size * sizeof(int32_t))
957 {
958 printf("TosaSerializationHandler::ConvertU8toI32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
959 out_size * sizeof(int32_t));
960 return TOSA_USER_ERROR;
961 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800962 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700963 {
964 uint32_t byte0 = in[i * sizeof(int32_t)];
965 uint32_t byte1 = in[i * sizeof(int32_t) + 1];
966 uint32_t byte2 = in[i * sizeof(int32_t) + 2];
967 uint32_t byte3 = in[i * sizeof(int32_t) + 3];
968 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
969 int32_t* val_i32 = reinterpret_cast<int32_t*>(&val_u32);
970 out.push_back(*val_i32);
971 }
972 return TOSA_OK;
973}
974
975tosa_err_t TosaSerializationHandler::ConvertU8toI16(const std::vector<uint8_t>& in,
976 uint32_t out_size,
977 std::vector<int16_t>& out)
978{
979 out.clear();
980 if (in.size() < out_size * sizeof(int16_t))
981 {
982 printf("TosaSerializationHandler::ConvertU8toI16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
983 out_size * sizeof(int16_t));
984 return TOSA_USER_ERROR;
985 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800986 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700987 {
988 uint16_t byte0 = in[i * sizeof(int16_t)];
989 uint16_t byte1 = in[i * sizeof(int16_t) + 1];
990 uint16_t val_u16 = byte0 + (byte1 << 8);
991 int16_t* val_i16 = reinterpret_cast<int16_t*>(&val_u16);
992 out.push_back(*val_i16);
993 }
994 return TOSA_OK;
995}
996
997tosa_err_t
998 TosaSerializationHandler::ConvertU8toI8(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
999{
1000 out.clear();
1001 if (in.size() < out_size * sizeof(int8_t))
1002 {
1003 printf("TosaSerializationHandler::ConvertU8toI8(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
Kevin Cheng3ce56342021-07-28 13:42:29 -07001004 out_size * sizeof(int8_t));
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001005 return TOSA_USER_ERROR;
1006 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001007 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001008 {
1009 uint8_t val_u8 = in[i];
1010 int8_t* val_i8 = reinterpret_cast<int8_t*>(&val_u8);
1011 out.push_back(*val_i8);
1012 }
1013 return TOSA_OK;
1014}
1015
1016tosa_err_t
Kevin Cheng3ce56342021-07-28 13:42:29 -07001017 TosaSerializationHandler::ConvertU8toI4(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
1018{
1019 out.clear();
1020 if (out_size > in.size() * 2)
1021 {
1022 printf("TosaSerializationHandler::ConvertU8toI4(): output size %u must <= uint8 buffer size %ld x 2.\n",
1023 out_size, in.size());
1024 return TOSA_USER_ERROR;
1025 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001026 for (size_t i = 0; i < in.size(); i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -07001027 {
1028 uint8_t val_u8 = in[i];
1029 uint8_t val_0_u4 = val_u8 & 0xF;
1030 uint8_t val_1_u4 = val_u8 >> 4;
1031 uint8_t val_0_u8_sext = (val_0_u4 & 0x08) ? (val_0_u4 | 0xF0) : val_0_u4;
1032 uint8_t val_1_u8_sext = (val_1_u4 & 0x08) ? (val_1_u4 | 0xF0) : val_1_u4;
1033 int8_t val_0 = static_cast<int8_t>(val_0_u8_sext);
1034 int8_t val_1 = static_cast<int8_t>(val_1_u8_sext);
1035 // In TOSA spec, int4 ranges [-7, 7]
1036 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
1037 {
1038 printf(
1039 "TosaSerializationHandler::ConvertU8toI4(): element in output array (%d or %d) exceeds int4 range.\n",
1040 val_0, val_1);
1041 return TOSA_USER_ERROR;
1042 }
1043 out.push_back(val_0);
1044 if (2 * i + 1 < out_size)
1045 out.push_back(val_1);
1046 }
1047 return TOSA_OK;
1048}
1049
1050tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001051 TosaSerializationHandler::ConvertU8toBool(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<bool>& out)
1052{
1053 out.clear();
1054 if (in.size() < out_size * sizeof(bool))
1055 {
1056 printf("TosaSerializationHandler::ConvertU8toBool(): uint8 buffer size %ld must >= target size %ld\n",
1057 in.size(), out_size * sizeof(bool));
1058 return TOSA_USER_ERROR;
1059 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001060 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001061 {
1062 uint8_t val_u8 = in[i];
1063 bool* val_bool = reinterpret_cast<bool*>(&val_u8);
1064 out.push_back(*val_bool);
1065 }
1066 return TOSA_OK;
1067}