blob: cbb862f3bf38723ec931ab962cb987e07751c829 [file] [log] [blame]
Eric Kunze2364dcd2021-04-26 11:06:57 -07001
2// Copyright (c) 2020-2021, ARM Limited.
3//
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,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070025 const flatbuffers::Vector<uint8_t>* data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070026{
27 _dtype = dtype;
28
Jerry Geb413a952023-05-08 19:17:22 +000029 if (shape)
30 {
31 std::copy(shape->begin(), shape->end(), std::back_inserter(_shape));
32 }
Eric Kunze2364dcd2021-04-26 11:06:57 -070033
34 assert(name);
35 _name = name->str();
36
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070037 if (data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070038 {
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070039 std::copy(data->begin(), data->end(), std::back_inserter(_data));
Eric Kunze2364dcd2021-04-26 11:06:57 -070040 }
41}
42
Kevin Cheng545a5082021-11-11 01:36:33 +000043TosaSerializationTensor::TosaSerializationTensor(const std::string& name,
Eric Kunze2364dcd2021-04-26 11:06:57 -070044 const std::vector<int32_t>& shape,
45 DType dtype,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070046 const std::vector<uint8_t>& data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070047{
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070048 _dtype = dtype;
49 _shape = shape;
50 _name = name;
51 _data = data;
Eric Kunze2364dcd2021-04-26 11:06:57 -070052}
53
54TosaSerializationTensor::TosaSerializationTensor()
55{
56 _dtype = DType_UNKNOWN;
Kevin Cheng545a5082021-11-11 01:36:33 +000057 _name = "UNKNOWN";
Eric Kunze2364dcd2021-04-26 11:06:57 -070058}
59
60TosaSerializationTensor::~TosaSerializationTensor()
61{}
62
Eric Kunzebdcc3fe2022-06-07 05:17:37 +000063void TosaSerializationOperator::InitializeAttribute(Attribute attribute_type, const TosaAttributeBase* attribute)
Eric Kunze2364dcd2021-04-26 11:06:57 -070064{
Eric Kunze2364dcd2021-04-26 11:06:57 -070065 _attribute_type = attribute_type;
66
67 switch (attribute_type)
68 {
69 case Attribute_NONE:
70 _attribute = new TosaNoneAttribute();
71 break;
72#define DEF_ATTRIBUTE(NAME, ...) \
73 case Attribute_##NAME##Attribute: \
74 _attribute = new Tosa##NAME##Attribute(attribute); \
75 break;
76#include "attribute.def"
77#undef DEF_ATTRIBUTE
78 default:
79 printf("TosaSerializationOperator::TosaSerializationOperator(): Attribute %s not implemented yet\n",
80 EnumNamesAttribute()[attribute_type]);
81 assert(0);
82 }
83
Eric Kunzebdcc3fe2022-06-07 05:17:37 +000084 assert(_attribute);
Kevin Cheng545a5082021-11-11 01:36:33 +000085}
Eric Kunze2364dcd2021-04-26 11:06:57 -070086
Kevin Cheng545a5082021-11-11 01:36:33 +000087TosaSerializationOperator::TosaSerializationOperator(Op op,
88 Attribute attribute_type,
89 const TosaAttributeBase* attribute,
Kevin Cheng545a5082021-11-11 01:36:33 +000090 const std::vector<std::string>& input_tensor_names,
91 const std::vector<std::string>& output_tensor_names)
92{
93 _op = op;
Eric Kunze2364dcd2021-04-26 11:06:57 -070094 _input_tensor_names = input_tensor_names;
95 _output_tensor_names = output_tensor_names;
Kevin Cheng545a5082021-11-11 01:36:33 +000096
Eric Kunzebdcc3fe2022-06-07 05:17:37 +000097 InitializeAttribute(attribute_type, attribute);
Kevin Cheng545a5082021-11-11 01:36:33 +000098}
99
100TosaSerializationOperator::TosaSerializationOperator(Op op,
101 Attribute attribute_type,
102 const TosaAttributeBase* attribute,
Kevin Cheng545a5082021-11-11 01:36:33 +0000103 std::vector<std::string>&& input_tensor_names,
104 std::vector<std::string>&& output_tensor_names)
105{
106 _op = op;
107 _input_tensor_names = std::move(input_tensor_names);
108 _output_tensor_names = std::move(output_tensor_names);
109
Eric Kunzebdcc3fe2022-06-07 05:17:37 +0000110 InitializeAttribute(attribute_type, attribute);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700111}
112
113TosaSerializationOperator::~TosaSerializationOperator()
114{
115 delete _attribute;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700116}
117
Kevin Cheng545a5082021-11-11 01:36:33 +0000118TosaSerializationBasicBlock::TosaSerializationBasicBlock(const std::string& name,
Jerry Ge13c78a62022-10-04 20:32:39 -0700119 const std::string& region_name,
Kevin Cheng545a5082021-11-11 01:36:33 +0000120 const std::vector<TosaSerializationOperator*>& operators,
121 const std::vector<TosaSerializationTensor*>& tensors,
122 const std::vector<std::string>& inputs,
123 const std::vector<std::string>& outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700124{
Jerry Ge13c78a62022-10-04 20:32:39 -0700125 _name = name;
126 _region_name = region_name;
127 _operators = operators;
128 _tensors = tensors;
129 _inputs = inputs;
130 _outputs = outputs;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700131}
132
Kevin Cheng545a5082021-11-11 01:36:33 +0000133TosaSerializationBasicBlock::TosaSerializationBasicBlock(std::string&& name,
Jerry Ge13c78a62022-10-04 20:32:39 -0700134 std::string&& region_name,
Kevin Cheng545a5082021-11-11 01:36:33 +0000135 std::vector<TosaSerializationOperator*>&& operators,
136 std::vector<TosaSerializationTensor*>&& tensors,
137 std::vector<std::string>&& inputs,
138 std::vector<std::string>&& outputs)
139{
Jerry Ge13c78a62022-10-04 20:32:39 -0700140 _name = std::move(name);
141 _region_name = std::move(region_name);
142 _operators = std::move(operators);
143 _tensors = std::move(tensors);
144 _inputs = std::move(inputs);
145 _outputs = std::move(outputs);
Kevin Cheng545a5082021-11-11 01:36:33 +0000146}
147
Eric Kunze2364dcd2021-04-26 11:06:57 -0700148TosaSerializationBasicBlock::~TosaSerializationBasicBlock()
149{
150 // deallocate all operators
151 for (auto op : GetOperators())
152 {
153 delete op; // ~TosaSerializationOperator()
154 }
155
156 // deallocate all tensors
157 for (auto ts : GetTensors())
158 {
159 delete ts; // ~TosaSerializationTensor()
160 }
161}
162
Jerry Ge13c78a62022-10-04 20:32:39 -0700163TosaSerializationRegion::TosaSerializationRegion(const std::string& name,
164 const std::vector<TosaSerializationBasicBlock*>& blocks)
165{
166 _name = name;
167 _blocks = blocks;
168}
169
170TosaSerializationRegion::TosaSerializationRegion(const std::string&& name,
171 const std::vector<TosaSerializationBasicBlock*>&& blocks)
172{
173 _name = std::move(name);
174 _blocks = std::move(blocks);
175}
176
177TosaSerializationRegion::~TosaSerializationRegion()
178{
179 // deallocate all blocks
180 for (auto block : GetBlocks())
181 {
182 delete block; // ~TosaSerializationBasicBlock()
183 }
184}
185
Eric Kunze2364dcd2021-04-26 11:06:57 -0700186TosaSerializationHandler::TosaSerializationHandler()
187{
188 _schemaLoaded = false;
Kevin Chenge6563f52021-10-20 12:12:02 -0700189 _version = TosaVersion(TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700190}
191
192TosaSerializationHandler::~TosaSerializationHandler()
193{
194 Clear(); // deallocate all basic blocks
195}
196
Eric Kunze2364dcd2021-04-26 11:06:57 -0700197tosa_err_t TosaSerializationHandler::LoadFileSchema(const char* schema_filename)
198{
199 std::string schema;
200 bool ok;
201
202 ok = flatbuffers::LoadFile(schema_filename, false, &schema);
203 if (!ok)
204 {
205 printf("Error loading schema file: %s\n", schema_filename);
206 return TOSA_FILE_ERROR;
207 }
208
209 ok = _parser.Parse(schema.c_str());
Kevin Chenga81a7a12021-11-10 14:07:34 -0800210
Eric Kunze2364dcd2021-04-26 11:06:57 -0700211 if (!ok)
212 {
213 printf("Error parsing ISA schema file: %s\n", schema_filename);
214 return TOSA_FILE_ERROR;
215 }
216 _schemaLoaded = true;
217
218 return TOSA_OK;
219}
220
221tosa_err_t TosaSerializationHandler::LoadFileJson(const char* filename)
222{
223 std::string jsonfile;
224 bool ok;
225 tosa_err_t err;
226
227 if (!_schemaLoaded)
228 {
229 return TOSA_SCHEMA_MISSING;
230 }
231
232 ok = flatbuffers::LoadFile(filename, false, &jsonfile);
233 if (!ok)
234 {
235 printf("Error loading json file: %s\n", filename);
236 return TOSA_FILE_ERROR;
237 }
238
239 ok = _parser.Parse(jsonfile.c_str());
240 if (!ok)
241 {
242 printf("Error parsing json file: %s\n", filename);
243 return TOSA_FILE_ERROR;
244 }
245
246 uint8_t* buf = _parser.builder_.GetBufferPointer();
247
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700248 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700249 if (err != TOSA_OK)
250 {
251 return err;
252 }
253
254 return TOSA_OK;
255}
256
257tosa_err_t TosaSerializationHandler::SaveFileJson(const char* filename)
258{
259 std::string jsongen;
260 tosa_err_t err;
261
262 if (!_schemaLoaded)
263 {
264 return TOSA_SCHEMA_MISSING;
265 }
266
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700267 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700268 if (err != TOSA_OK)
269 {
270 return err;
271 }
272
273 uint8_t* buf = _builder.GetBufferPointer();
274
Tai Ly89963aa2023-07-03 22:14:05 +0000275 if (GenText(_parser, buf, &jsongen))
Eric Kunze2364dcd2021-04-26 11:06:57 -0700276 {
277 printf("Couldn't serialize parsed data to JSON!\n");
278 return TOSA_FILE_ERROR;
279 }
280
281 FILE* file = fopen(filename, "wb");
282
283 if (!file)
284 {
285 printf("Couldn't open output file: %s\n", filename);
286 return TOSA_FILE_ERROR;
287 }
288
289 if (fwrite(jsongen.c_str(), sizeof(char), jsongen.size(), file) != jsongen.size())
290 {
291 printf("Error writing to json output file: %s\n", filename);
292 fclose(file);
293 return TOSA_FILE_ERROR;
294 }
295
296 if (file)
297 fclose(file);
298
299 return TOSA_OK;
300}
301
302tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const char* filename)
303{
304 std::string read_buffer;
305 tosa_err_t err;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800306 const uint8_t* buf;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700307 bool ok;
308
309 ok = flatbuffers::LoadFile(filename, false, &read_buffer);
310 if (!ok)
311 {
312 printf("Error loading flatbuffer file: %s\n", filename);
313 return TOSA_FILE_ERROR;
314 }
315
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800316 buf = reinterpret_cast<const uint8_t*>(read_buffer.data());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700317
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700318 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700319 if (err != TOSA_OK)
320 {
321 return err;
322 }
323
324 return TOSA_OK;
325}
326
Aaron DeBattista8b3903a2021-11-18 16:38:11 +0000327tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const void* input, int in_size)
328{
329 tosa_err_t err;
330
331 const uint8_t* buf = (const uint8_t*)input;
332 err = Deserialize(buf);
333 if (err != TOSA_OK)
334 {
335 return err;
336 }
337
338 return TOSA_OK;
339}
340
Eric Kunze2364dcd2021-04-26 11:06:57 -0700341tosa_err_t TosaSerializationHandler::SaveFileTosaFlatbuffer(const char* filename)
342{
343 tosa_err_t err;
344
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700345 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700346 if (err != TOSA_OK)
347 {
348 return err;
349 }
350
351 uint8_t* buf = _builder.GetBufferPointer();
352
353 bool ok = flatbuffers::SaveFile(filename, (const char*)buf, _builder.GetSize(), false);
354 if (!ok)
355 {
356 printf("Error saving floatbuffer file: %s\n", filename);
357 return TOSA_FILE_ERROR;
358 }
359
360 return TOSA_OK;
361}
362
363tosa_err_t TosaSerializationHandler::Clear()
364{
365 // deallocate all basic blocks
Jerry Ge13c78a62022-10-04 20:32:39 -0700366 for (auto region : GetRegions())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700367 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700368 delete region;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700369 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700370 _regions.clear();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700371
372 return TOSA_OK;
373}
374
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700375tosa_err_t TosaSerializationHandler::Deserialize(const uint8_t* buf)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700376{
Eric Kunzee6596402022-06-09 21:27:36 +0000377 if (!TosaGraphBufferHasIdentifier(buf))
378 {
379 printf("WARNING: TOSA file does not have TOSA file identifier\n");
380 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700381 auto fb_tosa_graph = GetTosaGraph(buf);
382 auto fb_tosa_version = fb_tosa_graph->version();
Jerry Ge13c78a62022-10-04 20:32:39 -0700383 auto fb_tosa_regions = fb_tosa_graph->regions();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700384
Eric Kunze2364dcd2021-04-26 11:06:57 -0700385 TosaAttributeBase* typed_attribute = NULL;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700386 TosaSerializationOperator* new_operator = NULL;
387 TosaSerializationBasicBlock* new_block = NULL;
388 TosaSerializationTensor* new_tensor = NULL;
Jerry Ge13c78a62022-10-04 20:32:39 -0700389 TosaSerializationRegion* new_region = NULL;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700390
391 // erase container
392 Clear();
393
Kevin Chenge6563f52021-10-20 12:12:02 -0700394 TosaVersion read_version(fb_tosa_version->_major(), fb_tosa_version->_minor(), fb_tosa_version->_patch(),
395 fb_tosa_version->_draft());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700396
Kevin Chenge6563f52021-10-20 12:12:02 -0700397 TosaVersion::compat_t is_compat = read_version.is_compatible(GetVersion());
398 switch (is_compat)
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700399 {
Kevin Chenge6563f52021-10-20 12:12:02 -0700400 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
401 break;
402 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
403 printf("WARNING: Read flatbuffer version %s is partially compatible with serializer version %s\n",
404 read_version.to_string().c_str(), GetVersion().to_string().c_str());
405 break;
406 case TosaVersion::compat_t::NOT_COMPATIBLE:
407 printf("ERROR: Read flatbuffer version %s is not compatible with serializer version %s\n",
408 read_version.to_string().c_str(), GetVersion().to_string().c_str());
409 return TOSA_VERSION_MISMATCH;
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700410 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700411
Jerry Ge13c78a62022-10-04 20:32:39 -0700412 for (size_t i = 0; i < fb_tosa_regions->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700413 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700414 auto curr_region = fb_tosa_regions->Get(i);
415 auto region_name = curr_region->name()->str();
416 auto fb_tosa_blocks = curr_region->blocks();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700417
Tai Lycfcb20d2023-03-13 21:04:11 +0000418 new_region = new TosaSerializationRegion(curr_region->name()->str(), {});
Jerry Ge13c78a62022-10-04 20:32:39 -0700419 this->GetRegions().push_back(new_region);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700420
Jerry Ge13c78a62022-10-04 20:32:39 -0700421 for (size_t i = 0; i < fb_tosa_blocks->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700422 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000423 std::vector<TosaSerializationOperator*> block_operators_container;
424 std::vector<TosaSerializationTensor*> block_tensors_container;
425 std::vector<std::string> block_inputs_container;
426 std::vector<std::string> block_outputs_container;
427
Jerry Ge13c78a62022-10-04 20:32:39 -0700428 auto curr_block = fb_tosa_blocks->Get(i);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700429
Jerry Ge13c78a62022-10-04 20:32:39 -0700430 auto block_name = curr_block->name()->str();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700431
Jerry Ge13c78a62022-10-04 20:32:39 -0700432 auto fb_tosa_operators = curr_block->operators();
Jerry Ge13c78a62022-10-04 20:32:39 -0700433 for (size_t j = 0; j < fb_tosa_operators->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700434 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700435 auto curr_operator = fb_tosa_operators->Get(j);
436
437 auto operator_op = curr_operator->op();
438 auto attribute_type = curr_operator->attribute_type();
439 auto attribute = curr_operator->attribute();
440
Tai Lycfcb20d2023-03-13 21:04:11 +0000441 std::vector<std::string> operator_inputs_container;
442 std::vector<std::string> operator_outputs_container;
443
Jerry Ge13c78a62022-10-04 20:32:39 -0700444 // input tensors
445 auto operator_inputs = curr_operator->inputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700446 if (operator_inputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700447 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700448 for (size_t k = 0; k < operator_inputs->size(); k++)
449 {
450 auto curr_input = operator_inputs->Get(k);
451 operator_inputs_container.push_back(curr_input->str());
452 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700453 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700454
Jerry Ge13c78a62022-10-04 20:32:39 -0700455 // output tensors
456 auto operator_outputs = curr_operator->outputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700457 if (operator_outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700458 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700459 for (size_t k = 0; k < operator_outputs->size(); k++)
460 {
461 auto curr_output = operator_outputs->Get(k);
462 operator_outputs_container.push_back(curr_output->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 switch (attribute_type)
467 {
468 case Attribute_NONE:
469 typed_attribute = new TosaNoneAttribute();
470 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700471#define DEF_ATTRIBUTE(NAME, ...) \
472 case Attribute_##NAME##Attribute: \
473 typed_attribute = new Tosa##NAME##Attribute(attribute); \
474 break;
475#include "attribute.def"
476#undef DEF_ATTRIBUTE
Jerry Ge13c78a62022-10-04 20:32:39 -0700477 default:
478 printf("TosaSerializationHandler::Deserialize(): Attribute %s not implemented yet\n",
479 EnumNamesAttribute()[attribute_type]);
480 return TOSA_INTERNAL_ERROR;
481 }
482
483 new_operator = new TosaSerializationOperator(operator_op, attribute_type, typed_attribute,
484 operator_inputs_container, operator_outputs_container);
485 if (new_operator)
486 {
487 block_operators_container.push_back(new_operator);
488 }
489 else
490 {
491 return TOSA_MEMORY_ERROR;
492 }
493
494 if (typed_attribute)
495 delete typed_attribute;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700496 }
497
Jerry Ge13c78a62022-10-04 20:32:39 -0700498 auto block_inputs = curr_block->inputs();
499 auto block_outputs = curr_block->outputs();
500
Jerry Ge13c78a62022-10-04 20:32:39 -0700501 for (size_t j = 0; j < block_inputs->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700502 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700503 auto curr_block_input = block_inputs->Get(j);
504 block_inputs_container.push_back(curr_block_input->str());
505 }
506 for (size_t j = 0; j < block_outputs->size(); j++)
507 {
508 auto curr_block_output = block_outputs->Get(j);
509 block_outputs_container.push_back(curr_block_output->str());
510 }
511
512 auto fb_tosa_tensors = curr_block->tensors();
Jerry Ge13c78a62022-10-04 20:32:39 -0700513 for (size_t j = 0; j < fb_tosa_tensors->size(); j++)
514 {
515 auto curr_tensor = fb_tosa_tensors->Get(j);
516
517 auto tensor_name = curr_tensor->name();
518 auto tensor_shape = curr_tensor->shape();
519 auto tensor_type = curr_tensor->type();
520 auto tensor_data = curr_tensor->data();
521
522 new_tensor = new TosaSerializationTensor(tensor_name, tensor_shape, tensor_type, tensor_data);
523 if (new_tensor)
524 {
525 block_tensors_container.push_back(new_tensor);
526 }
527 else
528 {
529 return TOSA_MEMORY_ERROR;
530 }
531 }
532 new_block = new TosaSerializationBasicBlock(block_name, region_name, block_operators_container,
533 block_tensors_container, block_inputs_container,
534 block_outputs_container);
535 if (new_block)
536 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000537 new_region->GetBlocks().push_back(new_block);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700538 }
539 else
540 {
541 return TOSA_MEMORY_ERROR;
542 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700543 } // end block for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700544 }
545
546 return TOSA_OK;
547}
548
James Ward80905bb2023-01-25 15:51:27 +0000549std::vector<uint8_t> float_to_u8_helper(float f_in)
James Wardc15f7d52022-12-07 15:38:01 +0000550{
James Ward80905bb2023-01-25 15:51:27 +0000551 // Push back a single float value to the buffer with *NO PADDING*
552 // Therefore ConvertF32toU8 function not used
James Wardc15f7d52022-12-07 15:38:01 +0000553 std::vector<uint8_t> u8_out;
James Ward80905bb2023-01-25 15:51:27 +0000554 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&f_in);
555 u8_out.push_back(*val_u32 & 0xFF);
556 u8_out.push_back((*val_u32 >> 8) & 0xFF);
557 u8_out.push_back((*val_u32 >> 16) & 0xFF);
558 u8_out.push_back((*val_u32 >> 24) & 0xFF);
James Wardc15f7d52022-12-07 15:38:01 +0000559 return u8_out;
560}
561
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700562tosa_err_t TosaSerializationHandler::Serialize()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700563{
Jerry Ge13c78a62022-10-04 20:32:39 -0700564 // regions
565 std::vector<flatbuffers::Offset<TosaRegion>> fboffset_regions;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700566
Eric Kunze2364dcd2021-04-26 11:06:57 -0700567 // translate TosaFlatbufferOperator to flatbuffers::Offset<TosaOperator>
Jerry Ge13c78a62022-10-04 20:32:39 -0700568 for (auto region : GetRegions())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700569 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000570 std::vector<flatbuffers::Offset<TosaBasicBlock>> fboffset_blocks;
Jerry Ge13c78a62022-10-04 20:32:39 -0700571 for (auto block : region->GetBlocks())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700572 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000573 std::vector<flatbuffers::Offset<TosaOperator>> fboffset_block_operators;
574 std::vector<flatbuffers::Offset<TosaTensor>> fboffset_block_tensors;
575 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_inputs;
576 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700577 auto block_name = _builder.CreateString(block->GetName().c_str());
578 for (auto tensor_str : block->GetInputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700579 {
580 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700581 fboffset_block_inputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700582 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700583 for (auto tensor_str : block->GetOutputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700584 {
585 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700586 fboffset_block_outputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700587 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700588 auto fb_block_inputs = _builder.CreateVector(fboffset_block_inputs);
589 auto fb_block_outputs = _builder.CreateVector(fboffset_block_outputs);
590 for (auto op : block->GetOperators())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700591 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000592 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_inputs;
593 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700594 auto operator_op = op->GetOp();
595 auto attribute_type = op->GetAttributeType();
596 for (auto tensor_str : op->GetInputTensorNames())
597 {
598 auto tensor_name = _builder.CreateString(tensor_str.c_str());
599 fboffset_operator_inputs.push_back(tensor_name);
600 }
601 for (auto tensor_str : op->GetOutputTensorNames())
602 {
603 auto tensor_name = _builder.CreateString(tensor_str.c_str());
604 fboffset_operator_outputs.push_back(tensor_name);
605 }
606 auto fb_operator_inputs = _builder.CreateVector(fboffset_operator_inputs);
607 auto fb_operator_outputs = _builder.CreateVector(fboffset_operator_outputs);
608 flatbuffers::Offset<void> fb_attribute;
609 switch (attribute_type)
610 {
611 case Attribute_NONE:
612 fb_attribute = 0;
613 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700614#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 +0000615#define DEF_ARGS_S_FP_as_U8(NAME, V) \
James Ward80905bb2023-01-25 15:51:27 +0000616 , _builder.CreateVector<uint8_t>(float_to_u8_helper(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()))
Eric Kunze2364dcd2021-04-26 11:06:57 -0700617#define DEF_ARGS_S_DEFAULT(NAME, V) , reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700618#define DEF_ARGS_S_int32_t(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Wardc15f7d52022-12-07 15:38:01 +0000619#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_FP_as_U8(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700620#define DEF_ARGS_S_bool(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
621#define DEF_ARGS_S_ResizeMode(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Ward485a11d2022-08-05 13:48:37 +0100622#define DEF_ARGS_S_DType(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700623#define DEF_ARGS_S_string(NAME, V) DEF_ARGS_S_STR(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700624#define DEF_ARGS_S(NAME, T, V) DEF_ARGS_S_##T(NAME, V)
625#define DEF_ARGS_V(NAME, T, V) , _builder.CreateVector<T>(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700626#define DEF_ARGS_1(NAME, T0, F0, V0) DEF_ARGS_##F0(NAME, T0, V0)
627#define DEF_ARGS_2(NAME, T0, F0, V0, T1, F1, V1) DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1)
628#define DEF_ARGS_3(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2) \
629 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2)
630#define DEF_ARGS_4(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3) \
631 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3)
632#define DEF_ARGS_5(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4) \
633 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
634 DEF_ARGS_##F4(NAME, T4, V4)
635#define DEF_ARGS_6(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5) \
636 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
637 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5)
638#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) \
639 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
640 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6)
641#define DEF_ATTRIBUTE(NAME, NUM_ARGS, ...) \
642 case Attribute_##NAME##Attribute: \
643 fb_attribute = Create##NAME##Attribute(_builder DEF_ARGS_##NUM_ARGS(NAME##Attribute, __VA_ARGS__)).Union(); \
644 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700645#include "attribute.def"
646#undef DEF_ATTRIBUTE
647#undef DEF_ARGS_1
648#undef DEF_ARGS_2
649#undef DEF_ARGS_3
650#undef DEF_ARGS_4
651#undef DEF_ARGS_5
652#undef DEF_ARGS_6
653#undef DEF_ARGS_7
654#undef DEF_ARGS_S
655#undef DEF_ARGS_V
656#undef DEF_ARGS_S_int32_t
657#undef DEF_ARGS_S_float
658#undef DEF_ARGS_S_bool
659#undef DEF_ARGS_S_ResizeMode
James Ward485a11d2022-08-05 13:48:37 +0100660#undef DEF_ARGS_S_DType
Eric Kunze2364dcd2021-04-26 11:06:57 -0700661#undef DEF_ARGS_S_string
662#undef DEF_ARGS_S_STR
663#undef DEF_ARGS_S_DEFAULT
Jerry Ge13c78a62022-10-04 20:32:39 -0700664 default:
665 printf("TosaSerializationHandler::Serialize(): Attribute %s not implemented yet\n",
666 EnumNamesAttribute()[attribute_type]);
667 return TOSA_INTERNAL_ERROR;
668 }
669 auto fboffset_operator = CreateTosaOperator(_builder, operator_op, attribute_type, fb_attribute,
670 fb_operator_inputs, fb_operator_outputs);
671 fboffset_block_operators.push_back(fboffset_operator);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700672 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700673 auto fb_block_operators = _builder.CreateVector(fboffset_block_operators);
674 for (auto tensor : block->GetTensors())
675 {
676 auto tensor_name = _builder.CreateString(tensor->GetName().c_str());
677 auto tensor_shape = _builder.CreateVector(tensor->GetShape());
678 auto tensor_dtype = tensor->GetDtype();
679 auto tensor_data = _builder.CreateVector(tensor->GetData());
680 auto fboffset_tensor = CreateTosaTensor(_builder, tensor_name, tensor_shape, tensor_dtype, tensor_data);
681 fboffset_block_tensors.push_back(fboffset_tensor);
682 }
683 auto fb_block_tensors = _builder.CreateVector(fboffset_block_tensors);
684 auto fboffset_block = CreateTosaBasicBlock(_builder, block_name, fb_block_operators, fb_block_tensors,
Won Jeoncb4bbf42023-08-10 08:50:15 +0000685 fb_block_inputs, fb_block_outputs);
Jerry Ge13c78a62022-10-04 20:32:39 -0700686 fboffset_blocks.push_back(fboffset_block);
687 } // end block for_loop
688 auto fb_blocks = _builder.CreateVector(fboffset_blocks);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700689
Jerry Ge13c78a62022-10-04 20:32:39 -0700690 auto region_name = _builder.CreateString(region->GetName().c_str());
691 auto fboffset_region = CreateTosaRegion(_builder, region_name, fb_blocks);
692 fboffset_regions.push_back(fboffset_region);
693 } // end region for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700694
Jerry Ge13c78a62022-10-04 20:32:39 -0700695 auto fb_regions = _builder.CreateVector(fboffset_regions);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700696
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700697 auto fb_version =
698 CreateVersion(_builder, TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Jerry Ge13c78a62022-10-04 20:32:39 -0700699 auto fb_graph = CreateTosaGraph(_builder, fb_version, fb_regions);
Eric Kunzee6596402022-06-09 21:27:36 +0000700 _builder.Finish(fb_graph, TosaGraphIdentifier());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700701
702 return TOSA_OK;
703}
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700704
705void zero_pad(std::vector<uint8_t>& buf)
706{
707 while ((buf.size() % TENSOR_BUFFER_FORCE_ALIGNMENT) != 0)
708 {
709 buf.push_back(0);
710 }
711}
712
James Ward485a11d2022-08-05 13:48:37 +0100713tosa_err_t TosaSerializationHandler::ConvertF16toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
714{
715 // Note: Converts fp32->fp16 before converting to uint8_t
716 out.clear();
717 for (auto val : in)
718 {
719 half_float::half val_f16 = half_float::half_cast<half_float::half, float>(val);
720 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val_f16);
721 out.push_back(*val_u16 & 0xFF);
722 out.push_back((*val_u16 >> 8) & 0xFF);
723 }
724 zero_pad(out);
725 return TOSA_OK;
726}
727
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700728tosa_err_t TosaSerializationHandler::ConvertF32toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
729{
730 out.clear();
731 for (auto val : in)
732 {
733 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
734 out.push_back(*val_u32 & 0xFF);
735 out.push_back((*val_u32 >> 8) & 0xFF);
736 out.push_back((*val_u32 >> 16) & 0xFF);
737 out.push_back((*val_u32 >> 24) & 0xFF);
738 }
739 zero_pad(out);
740 return TOSA_OK;
741}
742
743tosa_err_t TosaSerializationHandler::ConvertI48toU8(const std::vector<int64_t>& in, std::vector<uint8_t>& out)
744{
745 out.clear();
746 for (auto val : in)
747 {
748 uint64_t* val_u64 = reinterpret_cast<uint64_t*>(&val);
749 out.push_back(*val_u64 & 0xFF);
750 out.push_back((*val_u64 >> 8) & 0xFF);
751 out.push_back((*val_u64 >> 16) & 0xFF);
752 out.push_back((*val_u64 >> 24) & 0xFF);
753 out.push_back((*val_u64 >> 32) & 0xFF);
754 out.push_back((*val_u64 >> 40) & 0xFF);
755 }
756 zero_pad(out);
757 return TOSA_OK;
758}
759
760tosa_err_t TosaSerializationHandler::ConvertI32toU8(const std::vector<int32_t>& in, std::vector<uint8_t>& out)
761{
762 out.clear();
763 for (auto val : in)
764 {
765 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
766 out.push_back(*val_u32 & 0xFF);
767 out.push_back((*val_u32 >> 8) & 0xFF);
768 out.push_back((*val_u32 >> 16) & 0xFF);
769 out.push_back((*val_u32 >> 24) & 0xFF);
770 }
771 zero_pad(out);
772 return TOSA_OK;
773}
774
775tosa_err_t TosaSerializationHandler::ConvertI16toU8(const std::vector<int16_t>& in, std::vector<uint8_t>& out)
776{
777 out.clear();
778 for (auto val : in)
779 {
780 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val);
781 out.push_back(*val_u16 & 0xFF);
782 out.push_back((*val_u16 >> 8) & 0xFF);
783 }
784 zero_pad(out);
785 return TOSA_OK;
786}
787
788tosa_err_t TosaSerializationHandler::ConvertI8toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
789{
790 out.clear();
791 for (auto val : in)
792 {
793 uint8_t* val_u8 = reinterpret_cast<uint8_t*>(&val);
794 out.push_back(*val_u8);
795 }
796 zero_pad(out);
797 return TOSA_OK;
798}
799
Kevin Cheng3ce56342021-07-28 13:42:29 -0700800// Two int4 values are packed into one byte out.
801// For given input value val_0 = in[2*i], and val_1 = in[2*i+1],
802// they'll be packed as out[3:0] = val_0, and out[7:4] = val_1
803tosa_err_t TosaSerializationHandler::ConvertI4toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
804{
805 out.clear();
806 uint32_t in_size = in.size();
807 uint32_t out_size = (in_size % 2 == 0) ? (in_size / 2) : ((in_size + 1) / 2);
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800808 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700809 {
810 int8_t val_0 = in[2 * i];
811 int8_t val_1 = 0;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800812 if (2u * i + 1u < in_size)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700813 {
814 val_1 = in[2 * i + 1];
815 }
816 // In TOSA spec, int4 ranges [-7, 7]
817 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
818 {
819 printf("TosaSerializationHandler::ConvertI4toU8(): element in input array (%d or %d) exceeds int4 range.\n",
820 val_0, val_1);
821 return TOSA_USER_ERROR;
822 }
823 int8_t val_packed = (val_0 & 0xF) | ((val_1 & 0xF) << 4);
824 uint8_t val_u8 = static_cast<uint8_t>(val_packed);
825 out.push_back(val_u8);
826 }
827 zero_pad(out);
828 return TOSA_OK;
829}
830
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700831tosa_err_t TosaSerializationHandler::ConvertBooltoU8(const std::vector<bool>& in, std::vector<uint8_t>& out)
832{
833 out.clear();
834 for (auto val : in)
835 {
Eric Kunze4417b422022-06-20 07:27:42 -0700836 uint8_t val_u8 = val;
837 out.push_back(val_u8);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700838 }
839 zero_pad(out);
840 return TOSA_OK;
841}
842
843tosa_err_t
James Ward485a11d2022-08-05 13:48:37 +0100844 TosaSerializationHandler::ConvertU8toF16(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
845{
846 // Note: fp16 values returned in fp32 type
847 out.clear();
848 if (in.size() < out_size * sizeof(int16_t))
849 {
850 printf("TosaSerializationHandler::ConvertU8toF16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
851 out_size * sizeof(int16_t));
852 return TOSA_USER_ERROR;
853 }
854
855 for (uint32_t i = 0; i < out_size; i++)
856 {
857 uint16_t f16_byte0 = in[i * sizeof(int16_t)];
858 uint16_t f16_byte1 = in[i * sizeof(int16_t) + 1];
859 uint16_t val_u16 = f16_byte0 + (f16_byte1 << 8);
860
861 // Reinterpret u16 byte as fp16 then convert to fp32
862 half_float::half val_f16 = *(half_float::half*)&val_u16;
863 float val_fp32 = half_float::half_cast<float, half_float::half>(val_f16);
864 out.push_back(val_fp32);
865 }
866 return TOSA_OK;
867}
868
869tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700870 TosaSerializationHandler::ConvertU8toF32(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
871{
872 out.clear();
873 if (in.size() < out_size * sizeof(float))
874 {
875 printf("TosaSerializationHandler::ConvertU8toF32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
876 out_size * sizeof(float));
877 return TOSA_USER_ERROR;
878 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800879 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700880 {
881 uint32_t byte0 = in[i * sizeof(float)];
882 uint32_t byte1 = in[i * sizeof(float) + 1];
883 uint32_t byte2 = in[i * sizeof(float) + 2];
884 uint32_t byte3 = in[i * sizeof(float) + 3];
885 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
886 float* val_fp32 = reinterpret_cast<float*>(&val_u32);
887 out.push_back(*val_fp32);
888 }
889 return TOSA_OK;
890}
891
892tosa_err_t TosaSerializationHandler::ConvertU8toI48(const std::vector<uint8_t>& in,
893 uint32_t out_size,
894 std::vector<int64_t>& out)
895{
896 out.clear();
897 if (in.size() < out_size * 6 /* sizeof(int48) */)
898 {
899 printf("TosaSerializationHandler::ConvertU8toI48(): uint8 buffer size %ld must >= target size %d\n", in.size(),
900 out_size * 6);
901 return TOSA_USER_ERROR;
902 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800903 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700904 {
905 uint64_t byte0 = in[i * 6];
906 uint64_t byte1 = in[i * 6 + 1];
907 uint64_t byte2 = in[i * 6 + 2];
908 uint64_t byte3 = in[i * 6 + 3];
909 uint64_t byte4 = in[i * 6 + 4];
910 uint64_t byte5 = in[i * 6 + 5];
911 bool sign = ((byte5 >> 7) & 1) == 1 ? true : false;
912 uint64_t val_u64 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24) + (byte4 << 32) + (byte5 << 40);
913 if (sign)
914 {
915 uint64_t sext_mask = (0xFFFFUL << 48);
916 val_u64 |= sext_mask;
917 }
918 int64_t* val_i64 = reinterpret_cast<int64_t*>(&val_u64);
919 out.push_back(*val_i64);
920 }
921 return TOSA_OK;
922}
923
924tosa_err_t TosaSerializationHandler::ConvertU8toI32(const std::vector<uint8_t>& in,
925 uint32_t out_size,
926 std::vector<int32_t>& out)
927{
928 out.clear();
929 if (in.size() < out_size * sizeof(int32_t))
930 {
931 printf("TosaSerializationHandler::ConvertU8toI32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
932 out_size * sizeof(int32_t));
933 return TOSA_USER_ERROR;
934 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800935 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700936 {
937 uint32_t byte0 = in[i * sizeof(int32_t)];
938 uint32_t byte1 = in[i * sizeof(int32_t) + 1];
939 uint32_t byte2 = in[i * sizeof(int32_t) + 2];
940 uint32_t byte3 = in[i * sizeof(int32_t) + 3];
941 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
942 int32_t* val_i32 = reinterpret_cast<int32_t*>(&val_u32);
943 out.push_back(*val_i32);
944 }
945 return TOSA_OK;
946}
947
948tosa_err_t TosaSerializationHandler::ConvertU8toI16(const std::vector<uint8_t>& in,
949 uint32_t out_size,
950 std::vector<int16_t>& out)
951{
952 out.clear();
953 if (in.size() < out_size * sizeof(int16_t))
954 {
955 printf("TosaSerializationHandler::ConvertU8toI16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
956 out_size * sizeof(int16_t));
957 return TOSA_USER_ERROR;
958 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800959 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700960 {
961 uint16_t byte0 = in[i * sizeof(int16_t)];
962 uint16_t byte1 = in[i * sizeof(int16_t) + 1];
963 uint16_t val_u16 = byte0 + (byte1 << 8);
964 int16_t* val_i16 = reinterpret_cast<int16_t*>(&val_u16);
965 out.push_back(*val_i16);
966 }
967 return TOSA_OK;
968}
969
970tosa_err_t
971 TosaSerializationHandler::ConvertU8toI8(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
972{
973 out.clear();
974 if (in.size() < out_size * sizeof(int8_t))
975 {
976 printf("TosaSerializationHandler::ConvertU8toI8(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
Kevin Cheng3ce56342021-07-28 13:42:29 -0700977 out_size * sizeof(int8_t));
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700978 return TOSA_USER_ERROR;
979 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800980 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700981 {
982 uint8_t val_u8 = in[i];
983 int8_t* val_i8 = reinterpret_cast<int8_t*>(&val_u8);
984 out.push_back(*val_i8);
985 }
986 return TOSA_OK;
987}
988
989tosa_err_t
Kevin Cheng3ce56342021-07-28 13:42:29 -0700990 TosaSerializationHandler::ConvertU8toI4(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
991{
992 out.clear();
993 if (out_size > in.size() * 2)
994 {
995 printf("TosaSerializationHandler::ConvertU8toI4(): output size %u must <= uint8 buffer size %ld x 2.\n",
996 out_size, in.size());
997 return TOSA_USER_ERROR;
998 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800999 for (size_t i = 0; i < in.size(); i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -07001000 {
1001 uint8_t val_u8 = in[i];
1002 uint8_t val_0_u4 = val_u8 & 0xF;
1003 uint8_t val_1_u4 = val_u8 >> 4;
1004 uint8_t val_0_u8_sext = (val_0_u4 & 0x08) ? (val_0_u4 | 0xF0) : val_0_u4;
1005 uint8_t val_1_u8_sext = (val_1_u4 & 0x08) ? (val_1_u4 | 0xF0) : val_1_u4;
1006 int8_t val_0 = static_cast<int8_t>(val_0_u8_sext);
1007 int8_t val_1 = static_cast<int8_t>(val_1_u8_sext);
1008 // In TOSA spec, int4 ranges [-7, 7]
1009 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
1010 {
1011 printf(
1012 "TosaSerializationHandler::ConvertU8toI4(): element in output array (%d or %d) exceeds int4 range.\n",
1013 val_0, val_1);
1014 return TOSA_USER_ERROR;
1015 }
1016 out.push_back(val_0);
1017 if (2 * i + 1 < out_size)
1018 out.push_back(val_1);
1019 }
1020 return TOSA_OK;
1021}
1022
1023tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001024 TosaSerializationHandler::ConvertU8toBool(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<bool>& out)
1025{
1026 out.clear();
1027 if (in.size() < out_size * sizeof(bool))
1028 {
1029 printf("TosaSerializationHandler::ConvertU8toBool(): uint8 buffer size %ld must >= target size %ld\n",
1030 in.size(), out_size * sizeof(bool));
1031 return TOSA_USER_ERROR;
1032 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001033 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001034 {
1035 uint8_t val_u8 = in[i];
1036 bool* val_bool = reinterpret_cast<bool*>(&val_u8);
1037 out.push_back(*val_bool);
1038 }
1039 return TOSA_OK;
1040}