blob: bd2cbb4851bf1e79f683198cfc0b0d0df3022ce2 [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"
17
18#include <iostream>
19using namespace tosa;
20
21TosaSerializationTensor::TosaSerializationTensor(const flatbuffers::String* name,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070022 const flatbuffers::Vector<int32_t>* shape,
Eric Kunze2364dcd2021-04-26 11:06:57 -070023 DType dtype,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070024 const flatbuffers::Vector<uint8_t>* data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070025{
26 _dtype = dtype;
27
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070028 std::copy(shape->begin(), shape->end(), std::back_inserter(_shape));
Eric Kunze2364dcd2021-04-26 11:06:57 -070029
30 assert(name);
31 _name = name->str();
32
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070033 if (data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070034 {
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070035 std::copy(data->begin(), data->end(), std::back_inserter(_data));
Eric Kunze2364dcd2021-04-26 11:06:57 -070036 }
37}
38
Kevin Cheng545a5082021-11-11 01:36:33 +000039TosaSerializationTensor::TosaSerializationTensor(const std::string& name,
Eric Kunze2364dcd2021-04-26 11:06:57 -070040 const std::vector<int32_t>& shape,
41 DType dtype,
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070042 const std::vector<uint8_t>& data)
Eric Kunze2364dcd2021-04-26 11:06:57 -070043{
Kevin Cheng3bb1bc12021-06-17 15:57:08 -070044 _dtype = dtype;
45 _shape = shape;
46 _name = name;
47 _data = data;
Eric Kunze2364dcd2021-04-26 11:06:57 -070048}
49
50TosaSerializationTensor::TosaSerializationTensor()
51{
52 _dtype = DType_UNKNOWN;
Kevin Cheng545a5082021-11-11 01:36:33 +000053 _name = "UNKNOWN";
Eric Kunze2364dcd2021-04-26 11:06:57 -070054}
55
56TosaSerializationTensor::~TosaSerializationTensor()
57{}
58
Kevin Cheng545a5082021-11-11 01:36:33 +000059void TosaSerializationOperator::InitializeAttributeQinfo(Attribute attribute_type,
60 const TosaAttributeBase* attribute,
61 QuantInfo qinfo_type,
62 const TosaQuantInfoBase* qinfo)
Eric Kunze2364dcd2021-04-26 11:06:57 -070063{
Eric Kunze2364dcd2021-04-26 11:06:57 -070064 _attribute_type = attribute_type;
65
66 switch (attribute_type)
67 {
68 case Attribute_NONE:
69 _attribute = new TosaNoneAttribute();
70 break;
71#define DEF_ATTRIBUTE(NAME, ...) \
72 case Attribute_##NAME##Attribute: \
73 _attribute = new Tosa##NAME##Attribute(attribute); \
74 break;
75#include "attribute.def"
76#undef DEF_ATTRIBUTE
77 default:
78 printf("TosaSerializationOperator::TosaSerializationOperator(): Attribute %s not implemented yet\n",
79 EnumNamesAttribute()[attribute_type]);
80 assert(0);
81 }
82
83 _qinfo_type = qinfo_type;
84 switch (qinfo_type)
85 {
86 case QuantInfo_NONE:
87 _qinfo = new TosaNoneQuantInfo();
88 break;
89#define DEF_QUANTIZATION_INFO(NAME, ...) \
90 case QuantInfo_##NAME##QuantInfo: \
91 _qinfo = new Tosa##NAME##QuantInfo(qinfo); \
92 break;
93#include "quant_info.def"
94#undef DEF_QUANTIZATION_INFO
95 default:
96 printf("TosaSerializationOperator::TosaSerializationOperator(): QuantInfo %s not implemented yet\n",
97 EnumNamesQuantInfo()[qinfo_type]);
98 assert(0);
99 }
100
101 assert(_attribute && _qinfo);
Kevin Cheng545a5082021-11-11 01:36:33 +0000102}
Eric Kunze2364dcd2021-04-26 11:06:57 -0700103
Kevin Cheng545a5082021-11-11 01:36:33 +0000104TosaSerializationOperator::TosaSerializationOperator(Op op,
105 Attribute attribute_type,
106 const TosaAttributeBase* attribute,
107 QuantInfo qinfo_type,
108 const TosaQuantInfoBase* qinfo,
109 const std::vector<std::string>& input_tensor_names,
110 const std::vector<std::string>& output_tensor_names)
111{
112 _op = op;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700113 _input_tensor_names = input_tensor_names;
114 _output_tensor_names = output_tensor_names;
Kevin Cheng545a5082021-11-11 01:36:33 +0000115
116 InitializeAttributeQinfo(attribute_type, attribute, qinfo_type, qinfo);
117}
118
119TosaSerializationOperator::TosaSerializationOperator(Op op,
120 Attribute attribute_type,
121 const TosaAttributeBase* attribute,
122 QuantInfo qinfo_type,
123 const TosaQuantInfoBase* qinfo,
124 std::vector<std::string>&& input_tensor_names,
125 std::vector<std::string>&& output_tensor_names)
126{
127 _op = op;
128 _input_tensor_names = std::move(input_tensor_names);
129 _output_tensor_names = std::move(output_tensor_names);
130
131 InitializeAttributeQinfo(attribute_type, attribute, qinfo_type, qinfo);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700132}
133
134TosaSerializationOperator::~TosaSerializationOperator()
135{
136 delete _attribute;
137 delete _qinfo;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700138}
139
Kevin Cheng545a5082021-11-11 01:36:33 +0000140TosaSerializationBasicBlock::TosaSerializationBasicBlock(const std::string& name,
141 const std::vector<TosaSerializationOperator*>& operators,
142 const std::vector<TosaSerializationTensor*>& tensors,
143 const std::vector<std::string>& inputs,
144 const std::vector<std::string>& outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700145{
Eric Kunze2364dcd2021-04-26 11:06:57 -0700146 _name = name;
147 _operators = operators;
148 _tensors = tensors;
149 _inputs = inputs;
150 _outputs = outputs;
151}
152
Kevin Cheng545a5082021-11-11 01:36:33 +0000153TosaSerializationBasicBlock::TosaSerializationBasicBlock(std::string&& name,
154 std::vector<TosaSerializationOperator*>&& operators,
155 std::vector<TosaSerializationTensor*>&& tensors,
156 std::vector<std::string>&& inputs,
157 std::vector<std::string>&& outputs)
158{
159 _name = std::move(name);
160 _operators = std::move(operators);
161 _tensors = std::move(tensors);
162 _inputs = std::move(inputs);
163 _outputs = std::move(outputs);
164}
165
Eric Kunze2364dcd2021-04-26 11:06:57 -0700166TosaSerializationBasicBlock::~TosaSerializationBasicBlock()
167{
168 // deallocate all operators
169 for (auto op : GetOperators())
170 {
171 delete op; // ~TosaSerializationOperator()
172 }
173
174 // deallocate all tensors
175 for (auto ts : GetTensors())
176 {
177 delete ts; // ~TosaSerializationTensor()
178 }
179}
180
181TosaSerializationHandler::TosaSerializationHandler()
182{
183 _schemaLoaded = false;
Kevin Chenge6563f52021-10-20 12:12:02 -0700184 _version = TosaVersion(TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700185}
186
187TosaSerializationHandler::~TosaSerializationHandler()
188{
189 Clear(); // deallocate all basic blocks
190}
191
Kevin Chenga81a7a12021-11-10 14:07:34 -0800192TosaVersion TosaSerializationHandler::ParseTosaSchemaVersion(std::string schema)
193{
194 // Parse all 4 version fields in schema file
195 static const char* keywords[4] = { "major: int32 = ", "minor: int32 = ", "patch: int32 = ", "draft: bool = " };
196 string keyword_str[4];
197 size_t search_pos = 0;
198 size_t keyword_pos;
199 size_t semicolon_pos;
200 // parse integer field first
201 for (int32_t i = 0; i < 4; i++)
202 {
203 keyword_pos = schema.find(keywords[i], search_pos);
204 if (keyword_pos == std::string::npos)
205 {
206 printf("ERROR: can't find keyword \"%s\" in schema\n", keywords[i]);
207 assert(0);
208 }
209 semicolon_pos = schema.find(';', keyword_pos);
210 if (keyword_pos == std::string::npos)
211 {
212 printf("ERROR: can't find ';' in schema\n");
213 assert(0);
214 }
215 keyword_str[i] =
216 schema.substr(keyword_pos + strlen(keywords[i]), semicolon_pos - keyword_pos - strlen(keywords[i]));
217 search_pos = semicolon_pos;
218 }
219
220 int32_t schema_major = 0;
221 int32_t schema_minor = 0;
222 int32_t schema_patch = 0;
223 bool schema_draft = false;
224 try
225 {
226 schema_major = stoi(keyword_str[0]);
227 schema_minor = stoi(keyword_str[1]);
228 schema_patch = stoi(keyword_str[2]);
229 schema_draft = (keyword_str[3] == "true") ? true : false;
230 }
231 catch (std::invalid_argument& e)
232 {
233 printf("ERROR: fail at stoi(): %s\n", e.what());
234 assert(0);
235 }
236
237 TosaVersion schema_version(schema_major, schema_minor, schema_patch, schema_draft);
238
239 return schema_version;
240}
241
Eric Kunze2364dcd2021-04-26 11:06:57 -0700242tosa_err_t TosaSerializationHandler::LoadFileSchema(const char* schema_filename)
243{
244 std::string schema;
245 bool ok;
246
247 ok = flatbuffers::LoadFile(schema_filename, false, &schema);
248 if (!ok)
249 {
250 printf("Error loading schema file: %s\n", schema_filename);
251 return TOSA_FILE_ERROR;
252 }
253
254 ok = _parser.Parse(schema.c_str());
Kevin Chenga81a7a12021-11-10 14:07:34 -0800255
256 TosaVersion schema_version = ParseTosaSchemaVersion(schema);
257
258 TosaVersion::compat_t is_compat = schema_version.is_compatible(GetVersion());
259 switch (is_compat)
260 {
261 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
262 break;
263 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
264 printf("WARNING: Schema flatbuffer version %s is partially compatible with serializer version %s\n",
265 schema_version.to_string().c_str(), GetVersion().to_string().c_str());
266 break;
267 case TosaVersion::compat_t::NOT_COMPATIBLE:
268 printf("ERROR: Schema flatbuffer version %s is not compatible with serializer version %s\n",
269 schema_version.to_string().c_str(), GetVersion().to_string().c_str());
270 return TOSA_VERSION_MISMATCH;
271 }
272
Eric Kunze2364dcd2021-04-26 11:06:57 -0700273 if (!ok)
274 {
275 printf("Error parsing ISA schema file: %s\n", schema_filename);
276 return TOSA_FILE_ERROR;
277 }
278 _schemaLoaded = true;
279
280 return TOSA_OK;
281}
282
283tosa_err_t TosaSerializationHandler::LoadFileJson(const char* filename)
284{
285 std::string jsonfile;
286 bool ok;
287 tosa_err_t err;
288
289 if (!_schemaLoaded)
290 {
291 return TOSA_SCHEMA_MISSING;
292 }
293
294 ok = flatbuffers::LoadFile(filename, false, &jsonfile);
295 if (!ok)
296 {
297 printf("Error loading json file: %s\n", filename);
298 return TOSA_FILE_ERROR;
299 }
300
301 ok = _parser.Parse(jsonfile.c_str());
302 if (!ok)
303 {
304 printf("Error parsing json file: %s\n", filename);
305 return TOSA_FILE_ERROR;
306 }
307
308 uint8_t* buf = _parser.builder_.GetBufferPointer();
309
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700310 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700311 if (err != TOSA_OK)
312 {
313 return err;
314 }
315
316 return TOSA_OK;
317}
318
319tosa_err_t TosaSerializationHandler::SaveFileJson(const char* filename)
320{
321 std::string jsongen;
322 tosa_err_t err;
323
324 if (!_schemaLoaded)
325 {
326 return TOSA_SCHEMA_MISSING;
327 }
328
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700329 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700330 if (err != TOSA_OK)
331 {
332 return err;
333 }
334
335 uint8_t* buf = _builder.GetBufferPointer();
336
337 if (!GenerateText(_parser, buf, &jsongen))
338 {
339 printf("Couldn't serialize parsed data to JSON!\n");
340 return TOSA_FILE_ERROR;
341 }
342
343 FILE* file = fopen(filename, "wb");
344
345 if (!file)
346 {
347 printf("Couldn't open output file: %s\n", filename);
348 return TOSA_FILE_ERROR;
349 }
350
351 if (fwrite(jsongen.c_str(), sizeof(char), jsongen.size(), file) != jsongen.size())
352 {
353 printf("Error writing to json output file: %s\n", filename);
354 fclose(file);
355 return TOSA_FILE_ERROR;
356 }
357
358 if (file)
359 fclose(file);
360
361 return TOSA_OK;
362}
363
364tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const char* filename)
365{
366 std::string read_buffer;
367 tosa_err_t err;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800368 const uint8_t* buf;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700369 bool ok;
370
371 ok = flatbuffers::LoadFile(filename, false, &read_buffer);
372 if (!ok)
373 {
374 printf("Error loading flatbuffer file: %s\n", filename);
375 return TOSA_FILE_ERROR;
376 }
377
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800378 buf = reinterpret_cast<const uint8_t*>(read_buffer.data());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700379
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700380 err = Deserialize(buf);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700381 if (err != TOSA_OK)
382 {
383 return err;
384 }
385
386 return TOSA_OK;
387}
388
Aaron DeBattista8b3903a2021-11-18 16:38:11 +0000389tosa_err_t TosaSerializationHandler::LoadFileTosaFlatbuffer(const void* input, int in_size)
390{
391 tosa_err_t err;
392
393 const uint8_t* buf = (const uint8_t*)input;
394 err = Deserialize(buf);
395 if (err != TOSA_OK)
396 {
397 return err;
398 }
399
400 return TOSA_OK;
401}
402
Eric Kunze2364dcd2021-04-26 11:06:57 -0700403tosa_err_t TosaSerializationHandler::SaveFileTosaFlatbuffer(const char* filename)
404{
405 tosa_err_t err;
406
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700407 err = Serialize();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700408 if (err != TOSA_OK)
409 {
410 return err;
411 }
412
413 uint8_t* buf = _builder.GetBufferPointer();
414
415 bool ok = flatbuffers::SaveFile(filename, (const char*)buf, _builder.GetSize(), false);
416 if (!ok)
417 {
418 printf("Error saving floatbuffer file: %s\n", filename);
419 return TOSA_FILE_ERROR;
420 }
421
422 return TOSA_OK;
423}
424
425tosa_err_t TosaSerializationHandler::Clear()
426{
427 // deallocate all basic blocks
428 for (auto bb : GetBlocks())
429 {
430 delete bb;
431 }
432 _blocks.clear();
433
434 return TOSA_OK;
435}
436
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700437tosa_err_t TosaSerializationHandler::Deserialize(const uint8_t* buf)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700438{
439 auto fb_tosa_graph = GetTosaGraph(buf);
440 auto fb_tosa_version = fb_tosa_graph->version();
441 auto fb_tosa_blocks = fb_tosa_graph->blocks();
442
443 std::vector<std::string> operator_inputs_container;
444 std::vector<std::string> operator_outputs_container;
445
446 std::vector<TosaSerializationOperator*> block_operators_container;
447 std::vector<TosaSerializationTensor*> block_tensors_container;
448 std::vector<std::string> block_inputs_container;
449 std::vector<std::string> block_outputs_container;
450
451 TosaAttributeBase* typed_attribute = NULL;
452 TosaQuantInfoBase* typed_qinfo = NULL;
453 TosaSerializationOperator* new_operator = NULL;
454 TosaSerializationBasicBlock* new_block = NULL;
455 TosaSerializationTensor* new_tensor = NULL;
456
457 // erase container
458 Clear();
459
Kevin Chenge6563f52021-10-20 12:12:02 -0700460 TosaVersion read_version(fb_tosa_version->_major(), fb_tosa_version->_minor(), fb_tosa_version->_patch(),
461 fb_tosa_version->_draft());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700462
Kevin Chenge6563f52021-10-20 12:12:02 -0700463 TosaVersion::compat_t is_compat = read_version.is_compatible(GetVersion());
464 switch (is_compat)
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700465 {
Kevin Chenge6563f52021-10-20 12:12:02 -0700466 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
467 break;
468 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
469 printf("WARNING: Read flatbuffer version %s is partially compatible with serializer version %s\n",
470 read_version.to_string().c_str(), GetVersion().to_string().c_str());
471 break;
472 case TosaVersion::compat_t::NOT_COMPATIBLE:
473 printf("ERROR: Read flatbuffer version %s is not compatible with serializer version %s\n",
474 read_version.to_string().c_str(), GetVersion().to_string().c_str());
475 return TOSA_VERSION_MISMATCH;
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700476 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700477
478 for (size_t i = 0; i < fb_tosa_blocks->size(); i++)
479 {
480 auto curr_block = fb_tosa_blocks->Get(i);
481
482 auto block_name = curr_block->name()->str();
483
484 auto fb_tosa_operators = curr_block->operators();
485 block_operators_container.clear();
486 for (size_t j = 0; j < fb_tosa_operators->size(); j++)
487 {
488 auto curr_operator = fb_tosa_operators->Get(j);
489
490 auto operator_op = curr_operator->op();
491 auto attribute_type = curr_operator->attribute_type();
492 auto attribute = curr_operator->attribute();
493 auto operator_qinfo_type = curr_operator->quant_info_type();
494 auto operator_qinfo = curr_operator->quant_info();
495
496 // input tensors
497 auto operator_inputs = curr_operator->inputs();
498 operator_inputs_container.clear();
499 if (operator_inputs)
500 {
501 for (size_t k = 0; k < operator_inputs->size(); k++)
502 {
503 auto curr_input = operator_inputs->Get(k);
504 operator_inputs_container.push_back(curr_input->str());
505 }
506 }
507
508 // output tensors
509 auto operator_outputs = curr_operator->outputs();
510 operator_outputs_container.clear();
511 if (operator_outputs)
512 {
513 for (size_t k = 0; k < operator_outputs->size(); k++)
514 {
515 auto curr_output = operator_outputs->Get(k);
516 operator_outputs_container.push_back(curr_output->str());
517 }
518 }
519
520 switch (attribute_type)
521 {
522 case Attribute_NONE:
523 typed_attribute = new TosaNoneAttribute();
524 break;
525#define DEF_ATTRIBUTE(NAME, ...) \
526 case Attribute_##NAME##Attribute: \
527 typed_attribute = new Tosa##NAME##Attribute(attribute); \
528 break;
529#include "attribute.def"
530#undef DEF_ATTRIBUTE
531 default:
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700532 printf("TosaSerializationHandler::Deserialize(): Attribute %s not implemented yet\n",
Eric Kunze2364dcd2021-04-26 11:06:57 -0700533 EnumNamesAttribute()[attribute_type]);
534 return TOSA_INTERNAL_ERROR;
535 }
536
537 switch (operator_qinfo_type)
538 {
539 case QuantInfo_NONE:
540 typed_qinfo = new TosaNoneQuantInfo();
541 break;
542#define DEF_QUANTIZATION_INFO(NAME, ...) \
543 case QuantInfo_##NAME##QuantInfo: \
544 typed_qinfo = new Tosa##NAME##QuantInfo(operator_qinfo); \
545 break;
546
547#include "quant_info.def"
548#undef DEF_QUANTIZATION_INFO
549 default:
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700550 printf("TosaSerializationHandler::Deserialize(): QuantInfo %s not implemented yet\n",
Eric Kunze2364dcd2021-04-26 11:06:57 -0700551 EnumNamesQuantInfo()[operator_qinfo_type]);
552 return TOSA_INTERNAL_ERROR;
553 }
554
555 new_operator =
556 new TosaSerializationOperator(operator_op, attribute_type, typed_attribute, operator_qinfo_type,
557 typed_qinfo, operator_inputs_container, operator_outputs_container);
558 if (new_operator)
559 {
560 block_operators_container.push_back(new_operator);
561 }
562 else
563 {
564 return TOSA_MEMORY_ERROR;
565 }
566
567 if (typed_attribute)
568 delete typed_attribute;
569 if (typed_qinfo)
570 delete typed_qinfo;
571 }
572
573 auto fb_tosa_tensors = curr_block->tensors();
574 block_tensors_container.clear();
575 for (size_t j = 0; j < fb_tosa_tensors->size(); j++)
576 {
577 auto curr_tensor = fb_tosa_tensors->Get(j);
578
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700579 auto tensor_name = curr_tensor->name();
580 auto tensor_shape = curr_tensor->shape();
581 auto tensor_type = curr_tensor->type();
582 auto tensor_data = curr_tensor->data();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700583
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700584 new_tensor = new TosaSerializationTensor(tensor_name, tensor_shape, tensor_type, tensor_data);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700585 if (new_tensor)
586 {
587 block_tensors_container.push_back(new_tensor);
588 }
589 else
590 {
591 return TOSA_MEMORY_ERROR;
592 }
593 }
594
595 auto block_inputs = curr_block->inputs();
596 auto block_outputs = curr_block->outputs();
597
598 block_inputs_container.clear();
599 block_outputs_container.clear();
600
601 for (size_t j = 0; j < block_inputs->size(); j++)
602 {
603 auto curr_block_input = block_inputs->Get(j);
604 block_inputs_container.push_back(curr_block_input->str());
605 }
606 for (size_t j = 0; j < block_outputs->size(); j++)
607 {
608 auto curr_block_output = block_outputs->Get(j);
609 block_outputs_container.push_back(curr_block_output->str());
610 }
611
612 new_block = new TosaSerializationBasicBlock(block_name, block_operators_container, block_tensors_container,
613 block_inputs_container, block_outputs_container);
614 if (new_block)
615 {
616 this->GetBlocks().push_back(new_block);
617 }
618 else
619 {
620 return TOSA_MEMORY_ERROR;
621 }
622 }
623
624 return TOSA_OK;
625}
626
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700627tosa_err_t TosaSerializationHandler::Serialize()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700628{
629 std::vector<flatbuffers::Offset<TosaBasicBlock>> fboffset_blocks;
630
631 std::vector<flatbuffers::Offset<TosaOperator>> fboffset_block_operators;
632 std::vector<flatbuffers::Offset<TosaTensor>> fboffset_block_tensors;
633 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_inputs;
634 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_outputs;
635
636 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_inputs;
637 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_outputs;
638
639 // translate TosaFlatbufferOperator to flatbuffers::Offset<TosaOperator>
640 for (auto block : GetBlocks())
641 {
642 fboffset_block_operators.clear();
643 fboffset_block_tensors.clear();
644 fboffset_block_inputs.clear();
645 fboffset_block_outputs.clear();
646
647 auto block_name = _builder.CreateString(block->GetName().c_str());
648
649 for (auto tensor_str : block->GetInputs())
650 {
651 auto tensor_name = _builder.CreateString(tensor_str.c_str());
652 fboffset_block_inputs.push_back(tensor_name);
653 }
654
655 for (auto tensor_str : block->GetOutputs())
656 {
657 auto tensor_name = _builder.CreateString(tensor_str.c_str());
658 fboffset_block_outputs.push_back(tensor_name);
659 }
660
661 auto fb_block_inputs = _builder.CreateVector(fboffset_block_inputs);
662 auto fb_block_outputs = _builder.CreateVector(fboffset_block_outputs);
663
664 for (auto op : block->GetOperators())
665 {
666 fboffset_operator_inputs.clear();
667 fboffset_operator_outputs.clear();
668
669 auto operator_op = op->GetOp();
670 auto attribute_type = op->GetAttributeType();
671
672 for (auto tensor_str : op->GetInputTensorNames())
673 {
674 auto tensor_name = _builder.CreateString(tensor_str.c_str());
675 fboffset_operator_inputs.push_back(tensor_name);
676 }
677
678 for (auto tensor_str : op->GetOutputTensorNames())
679 {
680 auto tensor_name = _builder.CreateString(tensor_str.c_str());
681 fboffset_operator_outputs.push_back(tensor_name);
682 }
683
684 auto fb_operator_inputs = _builder.CreateVector(fboffset_operator_inputs);
685 auto fb_operator_outputs = _builder.CreateVector(fboffset_operator_outputs);
686
687 flatbuffers::Offset<void> fb_attribute;
688 switch (attribute_type)
689 {
690 case Attribute_NONE:
691 fb_attribute = 0;
692 break;
693
694#define DEF_ARGS_S_STR(NAME, V) , _builder.CreateString(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V().c_str())
695#define DEF_ARGS_S_DEFAULT(NAME, V) , reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()
696
697#define DEF_ARGS_S_int32_t(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
698#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
699#define DEF_ARGS_S_bool(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
700#define DEF_ARGS_S_ResizeMode(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
701#define DEF_ARGS_S_string(NAME, V) DEF_ARGS_S_STR(NAME, V)
702
703#define DEF_ARGS_S(NAME, T, V) DEF_ARGS_S_##T(NAME, V)
704#define DEF_ARGS_V(NAME, T, V) , _builder.CreateVector<T>(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V())
705
706#define DEF_ARGS_1(NAME, T0, F0, V0) DEF_ARGS_##F0(NAME, T0, V0)
707#define DEF_ARGS_2(NAME, T0, F0, V0, T1, F1, V1) DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1)
708#define DEF_ARGS_3(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2) \
709 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2)
710#define DEF_ARGS_4(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3) \
711 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3)
712#define DEF_ARGS_5(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4) \
713 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
714 DEF_ARGS_##F4(NAME, T4, V4)
715#define DEF_ARGS_6(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5) \
716 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
717 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5)
718#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) \
719 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
720 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6)
721#define DEF_ATTRIBUTE(NAME, NUM_ARGS, ...) \
722 case Attribute_##NAME##Attribute: \
723 fb_attribute = Create##NAME##Attribute(_builder DEF_ARGS_##NUM_ARGS(NAME##Attribute, __VA_ARGS__)).Union(); \
724 break;
725
726#include "attribute.def"
727#undef DEF_ATTRIBUTE
728#undef DEF_ARGS_1
729#undef DEF_ARGS_2
730#undef DEF_ARGS_3
731#undef DEF_ARGS_4
732#undef DEF_ARGS_5
733#undef DEF_ARGS_6
734#undef DEF_ARGS_7
735#undef DEF_ARGS_S
736#undef DEF_ARGS_V
737#undef DEF_ARGS_S_int32_t
738#undef DEF_ARGS_S_float
739#undef DEF_ARGS_S_bool
740#undef DEF_ARGS_S_ResizeMode
741#undef DEF_ARGS_S_string
742#undef DEF_ARGS_S_STR
743#undef DEF_ARGS_S_DEFAULT
744 default:
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700745 printf("TosaSerializationHandler::Serialize(): Attribute %s not implemented yet\n",
Eric Kunze2364dcd2021-04-26 11:06:57 -0700746 EnumNamesAttribute()[attribute_type]);
747 return TOSA_INTERNAL_ERROR;
748 }
749
750 auto qinfo_type = op->GetQInfoType();
751 flatbuffers::Offset<void> fb_operator_qinfo;
752 switch (qinfo_type)
753 {
754 case QuantInfo_NONE:
755 fb_operator_qinfo = 0;
756 break;
757#define DEF_ARGS_S(NAME, T, V) , reinterpret_cast<Tosa##NAME*>(op->GetQInfo())->V()
758#define DEF_ARGS_V(NAME, T, V) , _builder.CreateVector<T>(reinterpret_cast<Tosa##NAME*>(op->GetQInfo())->V())
759
760#define DEF_ARGS_1(NAME, T0, F0, V0) DEF_ARGS_##F0(NAME, T0, V0)
761#define DEF_ARGS_2(NAME, T0, F0, V0, T1, F1, V1) DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1)
762#define DEF_ARGS_3(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2) \
763 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2)
764#define DEF_ARGS_4(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3) \
765 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3)
766#define DEF_ARGS_5(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4) \
767 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
768 DEF_ARGS_##F4(NAME, T4, V4)
769#define DEF_ARGS_6(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5) \
770 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
771 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5)
772#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) \
773 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
774 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6)
775#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, \
776 V7) \
777 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
778 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6) \
779 DEF_ARGS_##F7(NAME, T7, V7)
780#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, \
781 V7, T8, F8, V8) \
782 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
783 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6) \
784 DEF_ARGS_##F7(NAME, T7, V7) DEF_ARGS_##F8(NAME, T8, V8)
785#define DEF_ARGS_10(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5, T6, F6, V6, T7, F7, \
786 V7, T8, F8, V8, T9, F9, V9) \
787 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
788 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6) \
789 DEF_ARGS_##F7(NAME, T7, V7) DEF_ARGS_##F8(NAME, T8, V8) DEF_ARGS_##F9(NAME, T9, V9)
790#define DEF_QUANTIZATION_INFO(NAME, NUM_ARGS, ...) \
791 case QuantInfo_##NAME##QuantInfo: \
792 fb_operator_qinfo = \
793 Create##NAME##QuantInfo(_builder DEF_ARGS_##NUM_ARGS(NAME##QuantInfo, __VA_ARGS__)).Union(); \
794 break;
795
796#include "quant_info.def"
797#undef DEF_QUANTIZATION_INFO
798#undef DEF_ARGS_1
799#undef DEF_ARGS_2
800#undef DEF_ARGS_3
801#undef DEF_ARGS_4
802#undef DEF_ARGS_5
803#undef DEF_ARGS_6
804#undef DEF_ARGS_7
805#undef DEF_ARGS_8
806#undef DEF_ARGS_9
807#undef DEF_ARGS_10
808#undef DEF_ARGS_S
809#undef DEF_ARGS_V
810 default:
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700811 printf("TosaSerializationHandler::Serialize(): Attribute %s not implemented yet\n",
Eric Kunze2364dcd2021-04-26 11:06:57 -0700812 EnumNamesAttribute()[attribute_type]);
813 return TOSA_INTERNAL_ERROR;
814 }
815
816 auto fboffset_operator =
817 CreateTosaOperator(_builder, operator_op, attribute_type, fb_attribute, fb_operator_inputs,
818 fb_operator_outputs, qinfo_type, fb_operator_qinfo);
819 fboffset_block_operators.push_back(fboffset_operator);
820 }
821
822 auto fb_block_operators = _builder.CreateVector(fboffset_block_operators);
823
824 for (auto tensor : block->GetTensors())
825 {
826
827 auto tensor_name = _builder.CreateString(tensor->GetName().c_str());
828 auto tensor_shape = _builder.CreateVector(tensor->GetShape());
829 auto tensor_dtype = tensor->GetDtype();
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700830 auto tensor_data = _builder.CreateVector(tensor->GetData());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700831
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700832 auto fboffset_tensor = CreateTosaTensor(_builder, tensor_name, tensor_shape, tensor_dtype, tensor_data);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700833 fboffset_block_tensors.push_back(fboffset_tensor);
834 }
835
836 auto fb_block_tensors = _builder.CreateVector(fboffset_block_tensors);
837
838 auto fboffset_block = CreateTosaBasicBlock(_builder, block_name, fb_block_operators, fb_block_tensors,
839 fb_block_inputs, fb_block_outputs);
840 fboffset_blocks.push_back(fboffset_block);
841 }
842
843 auto fb_blocks = _builder.CreateVector(fboffset_blocks);
844
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700845 auto fb_version =
846 CreateVersion(_builder, TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700847
848 auto fb_graph = CreateTosaGraph(_builder, fb_version, fb_blocks);
849 _builder.Finish(fb_graph);
850
851 return TOSA_OK;
852}
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700853
854void zero_pad(std::vector<uint8_t>& buf)
855{
856 while ((buf.size() % TENSOR_BUFFER_FORCE_ALIGNMENT) != 0)
857 {
858 buf.push_back(0);
859 }
860}
861
862tosa_err_t TosaSerializationHandler::ConvertF32toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
863{
864 out.clear();
865 for (auto val : in)
866 {
867 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
868 out.push_back(*val_u32 & 0xFF);
869 out.push_back((*val_u32 >> 8) & 0xFF);
870 out.push_back((*val_u32 >> 16) & 0xFF);
871 out.push_back((*val_u32 >> 24) & 0xFF);
872 }
873 zero_pad(out);
874 return TOSA_OK;
875}
876
877tosa_err_t TosaSerializationHandler::ConvertI48toU8(const std::vector<int64_t>& in, std::vector<uint8_t>& out)
878{
879 out.clear();
880 for (auto val : in)
881 {
882 uint64_t* val_u64 = reinterpret_cast<uint64_t*>(&val);
883 out.push_back(*val_u64 & 0xFF);
884 out.push_back((*val_u64 >> 8) & 0xFF);
885 out.push_back((*val_u64 >> 16) & 0xFF);
886 out.push_back((*val_u64 >> 24) & 0xFF);
887 out.push_back((*val_u64 >> 32) & 0xFF);
888 out.push_back((*val_u64 >> 40) & 0xFF);
889 }
890 zero_pad(out);
891 return TOSA_OK;
892}
893
894tosa_err_t TosaSerializationHandler::ConvertI32toU8(const std::vector<int32_t>& in, std::vector<uint8_t>& out)
895{
896 out.clear();
897 for (auto val : in)
898 {
899 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
900 out.push_back(*val_u32 & 0xFF);
901 out.push_back((*val_u32 >> 8) & 0xFF);
902 out.push_back((*val_u32 >> 16) & 0xFF);
903 out.push_back((*val_u32 >> 24) & 0xFF);
904 }
905 zero_pad(out);
906 return TOSA_OK;
907}
908
909tosa_err_t TosaSerializationHandler::ConvertI16toU8(const std::vector<int16_t>& in, std::vector<uint8_t>& out)
910{
911 out.clear();
912 for (auto val : in)
913 {
914 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val);
915 out.push_back(*val_u16 & 0xFF);
916 out.push_back((*val_u16 >> 8) & 0xFF);
917 }
918 zero_pad(out);
919 return TOSA_OK;
920}
921
922tosa_err_t TosaSerializationHandler::ConvertI8toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
923{
924 out.clear();
925 for (auto val : in)
926 {
927 uint8_t* val_u8 = reinterpret_cast<uint8_t*>(&val);
928 out.push_back(*val_u8);
929 }
930 zero_pad(out);
931 return TOSA_OK;
932}
933
Kevin Cheng3ce56342021-07-28 13:42:29 -0700934// Two int4 values are packed into one byte out.
935// For given input value val_0 = in[2*i], and val_1 = in[2*i+1],
936// they'll be packed as out[3:0] = val_0, and out[7:4] = val_1
937tosa_err_t TosaSerializationHandler::ConvertI4toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
938{
939 out.clear();
940 uint32_t in_size = in.size();
941 uint32_t out_size = (in_size % 2 == 0) ? (in_size / 2) : ((in_size + 1) / 2);
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800942 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700943 {
944 int8_t val_0 = in[2 * i];
945 int8_t val_1 = 0;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800946 if (2u * i + 1u < in_size)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700947 {
948 val_1 = in[2 * i + 1];
949 }
950 // In TOSA spec, int4 ranges [-7, 7]
951 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
952 {
953 printf("TosaSerializationHandler::ConvertI4toU8(): element in input array (%d or %d) exceeds int4 range.\n",
954 val_0, val_1);
955 return TOSA_USER_ERROR;
956 }
957 int8_t val_packed = (val_0 & 0xF) | ((val_1 & 0xF) << 4);
958 uint8_t val_u8 = static_cast<uint8_t>(val_packed);
959 out.push_back(val_u8);
960 }
961 zero_pad(out);
962 return TOSA_OK;
963}
964
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700965tosa_err_t TosaSerializationHandler::ConvertBooltoU8(const std::vector<bool>& in, std::vector<uint8_t>& out)
966{
967 out.clear();
968 for (auto val : in)
969 {
970 uint8_t* val_u8 = reinterpret_cast<uint8_t*>(&val);
971 out.push_back(*val_u8);
972 }
973 zero_pad(out);
974 return TOSA_OK;
975}
976
977tosa_err_t
978 TosaSerializationHandler::ConvertU8toF32(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
979{
980 out.clear();
981 if (in.size() < out_size * sizeof(float))
982 {
983 printf("TosaSerializationHandler::ConvertU8toF32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
984 out_size * sizeof(float));
985 return TOSA_USER_ERROR;
986 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800987 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700988 {
989 uint32_t byte0 = in[i * sizeof(float)];
990 uint32_t byte1 = in[i * sizeof(float) + 1];
991 uint32_t byte2 = in[i * sizeof(float) + 2];
992 uint32_t byte3 = in[i * sizeof(float) + 3];
993 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
994 float* val_fp32 = reinterpret_cast<float*>(&val_u32);
995 out.push_back(*val_fp32);
996 }
997 return TOSA_OK;
998}
999
1000tosa_err_t TosaSerializationHandler::ConvertU8toI48(const std::vector<uint8_t>& in,
1001 uint32_t out_size,
1002 std::vector<int64_t>& out)
1003{
1004 out.clear();
1005 if (in.size() < out_size * 6 /* sizeof(int48) */)
1006 {
1007 printf("TosaSerializationHandler::ConvertU8toI48(): uint8 buffer size %ld must >= target size %d\n", in.size(),
1008 out_size * 6);
1009 return TOSA_USER_ERROR;
1010 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001011 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001012 {
1013 uint64_t byte0 = in[i * 6];
1014 uint64_t byte1 = in[i * 6 + 1];
1015 uint64_t byte2 = in[i * 6 + 2];
1016 uint64_t byte3 = in[i * 6 + 3];
1017 uint64_t byte4 = in[i * 6 + 4];
1018 uint64_t byte5 = in[i * 6 + 5];
1019 bool sign = ((byte5 >> 7) & 1) == 1 ? true : false;
1020 uint64_t val_u64 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24) + (byte4 << 32) + (byte5 << 40);
1021 if (sign)
1022 {
1023 uint64_t sext_mask = (0xFFFFUL << 48);
1024 val_u64 |= sext_mask;
1025 }
1026 int64_t* val_i64 = reinterpret_cast<int64_t*>(&val_u64);
1027 out.push_back(*val_i64);
1028 }
1029 return TOSA_OK;
1030}
1031
1032tosa_err_t TosaSerializationHandler::ConvertU8toI32(const std::vector<uint8_t>& in,
1033 uint32_t out_size,
1034 std::vector<int32_t>& out)
1035{
1036 out.clear();
1037 if (in.size() < out_size * sizeof(int32_t))
1038 {
1039 printf("TosaSerializationHandler::ConvertU8toI32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
1040 out_size * sizeof(int32_t));
1041 return TOSA_USER_ERROR;
1042 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001043 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001044 {
1045 uint32_t byte0 = in[i * sizeof(int32_t)];
1046 uint32_t byte1 = in[i * sizeof(int32_t) + 1];
1047 uint32_t byte2 = in[i * sizeof(int32_t) + 2];
1048 uint32_t byte3 = in[i * sizeof(int32_t) + 3];
1049 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
1050 int32_t* val_i32 = reinterpret_cast<int32_t*>(&val_u32);
1051 out.push_back(*val_i32);
1052 }
1053 return TOSA_OK;
1054}
1055
1056tosa_err_t TosaSerializationHandler::ConvertU8toI16(const std::vector<uint8_t>& in,
1057 uint32_t out_size,
1058 std::vector<int16_t>& out)
1059{
1060 out.clear();
1061 if (in.size() < out_size * sizeof(int16_t))
1062 {
1063 printf("TosaSerializationHandler::ConvertU8toI16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
1064 out_size * sizeof(int16_t));
1065 return TOSA_USER_ERROR;
1066 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001067 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001068 {
1069 uint16_t byte0 = in[i * sizeof(int16_t)];
1070 uint16_t byte1 = in[i * sizeof(int16_t) + 1];
1071 uint16_t val_u16 = byte0 + (byte1 << 8);
1072 int16_t* val_i16 = reinterpret_cast<int16_t*>(&val_u16);
1073 out.push_back(*val_i16);
1074 }
1075 return TOSA_OK;
1076}
1077
1078tosa_err_t
1079 TosaSerializationHandler::ConvertU8toI8(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
1080{
1081 out.clear();
1082 if (in.size() < out_size * sizeof(int8_t))
1083 {
1084 printf("TosaSerializationHandler::ConvertU8toI8(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
Kevin Cheng3ce56342021-07-28 13:42:29 -07001085 out_size * sizeof(int8_t));
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001086 return TOSA_USER_ERROR;
1087 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001088 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001089 {
1090 uint8_t val_u8 = in[i];
1091 int8_t* val_i8 = reinterpret_cast<int8_t*>(&val_u8);
1092 out.push_back(*val_i8);
1093 }
1094 return TOSA_OK;
1095}
1096
1097tosa_err_t
Kevin Cheng3ce56342021-07-28 13:42:29 -07001098 TosaSerializationHandler::ConvertU8toI4(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
1099{
1100 out.clear();
1101 if (out_size > in.size() * 2)
1102 {
1103 printf("TosaSerializationHandler::ConvertU8toI4(): output size %u must <= uint8 buffer size %ld x 2.\n",
1104 out_size, in.size());
1105 return TOSA_USER_ERROR;
1106 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001107 for (size_t i = 0; i < in.size(); i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -07001108 {
1109 uint8_t val_u8 = in[i];
1110 uint8_t val_0_u4 = val_u8 & 0xF;
1111 uint8_t val_1_u4 = val_u8 >> 4;
1112 uint8_t val_0_u8_sext = (val_0_u4 & 0x08) ? (val_0_u4 | 0xF0) : val_0_u4;
1113 uint8_t val_1_u8_sext = (val_1_u4 & 0x08) ? (val_1_u4 | 0xF0) : val_1_u4;
1114 int8_t val_0 = static_cast<int8_t>(val_0_u8_sext);
1115 int8_t val_1 = static_cast<int8_t>(val_1_u8_sext);
1116 // In TOSA spec, int4 ranges [-7, 7]
1117 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
1118 {
1119 printf(
1120 "TosaSerializationHandler::ConvertU8toI4(): element in output array (%d or %d) exceeds int4 range.\n",
1121 val_0, val_1);
1122 return TOSA_USER_ERROR;
1123 }
1124 out.push_back(val_0);
1125 if (2 * i + 1 < out_size)
1126 out.push_back(val_1);
1127 }
1128 return TOSA_OK;
1129}
1130
1131tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001132 TosaSerializationHandler::ConvertU8toBool(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<bool>& out)
1133{
1134 out.clear();
1135 if (in.size() < out_size * sizeof(bool))
1136 {
1137 printf("TosaSerializationHandler::ConvertU8toBool(): uint8 buffer size %ld must >= target size %ld\n",
1138 in.size(), out_size * sizeof(bool));
1139 return TOSA_USER_ERROR;
1140 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001141 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001142 {
1143 uint8_t val_u8 = in[i];
1144 bool* val_bool = reinterpret_cast<bool*>(&val_u8);
1145 out.push_back(*val_bool);
1146 }
1147 return TOSA_OK;
1148}