blob: 3620c1654ed9fa987ea28a3016386e6941532705 [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
Kevin Chenge6563f52021-10-20 12:12:02 -0700406 TosaVersion::compat_t is_compat = read_version.is_compatible(GetVersion());
407 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;
411 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
412 printf("WARNING: Read flatbuffer version %s is partially compatible with serializer version %s\n",
413 read_version.to_string().c_str(), GetVersion().to_string().c_str());
414 break;
415 case TosaVersion::compat_t::NOT_COMPATIBLE:
416 printf("ERROR: Read flatbuffer version %s is not compatible with serializer version %s\n",
417 read_version.to_string().c_str(), GetVersion().to_string().c_str());
418 return TOSA_VERSION_MISMATCH;
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700419 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700420
Jerry Ge13c78a62022-10-04 20:32:39 -0700421 for (size_t i = 0; i < fb_tosa_regions->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700422 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700423 auto curr_region = fb_tosa_regions->Get(i);
424 auto region_name = curr_region->name()->str();
425 auto fb_tosa_blocks = curr_region->blocks();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700426
Tai Lycfcb20d2023-03-13 21:04:11 +0000427 new_region = new TosaSerializationRegion(curr_region->name()->str(), {});
Jerry Ge13c78a62022-10-04 20:32:39 -0700428 this->GetRegions().push_back(new_region);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700429
Jerry Ge13c78a62022-10-04 20:32:39 -0700430 for (size_t i = 0; i < fb_tosa_blocks->size(); i++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700431 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000432 std::vector<TosaSerializationOperator*> block_operators_container;
433 std::vector<TosaSerializationTensor*> block_tensors_container;
434 std::vector<std::string> block_inputs_container;
435 std::vector<std::string> block_outputs_container;
436
Jerry Ge13c78a62022-10-04 20:32:39 -0700437 auto curr_block = fb_tosa_blocks->Get(i);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700438
Jerry Ge13c78a62022-10-04 20:32:39 -0700439 auto block_name = curr_block->name()->str();
Eric Kunze2364dcd2021-04-26 11:06:57 -0700440
Jerry Ge13c78a62022-10-04 20:32:39 -0700441 auto fb_tosa_operators = curr_block->operators();
Jerry Ge13c78a62022-10-04 20:32:39 -0700442 for (size_t j = 0; j < fb_tosa_operators->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700443 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700444 auto curr_operator = fb_tosa_operators->Get(j);
445
446 auto operator_op = curr_operator->op();
447 auto attribute_type = curr_operator->attribute_type();
448 auto attribute = curr_operator->attribute();
449
Tai Lycfcb20d2023-03-13 21:04:11 +0000450 std::vector<std::string> operator_inputs_container;
451 std::vector<std::string> operator_outputs_container;
452
Jerry Ge13c78a62022-10-04 20:32:39 -0700453 // input tensors
454 auto operator_inputs = curr_operator->inputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700455 if (operator_inputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700456 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700457 for (size_t k = 0; k < operator_inputs->size(); k++)
458 {
459 auto curr_input = operator_inputs->Get(k);
460 operator_inputs_container.push_back(curr_input->str());
461 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700462 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700463
Jerry Ge13c78a62022-10-04 20:32:39 -0700464 // output tensors
465 auto operator_outputs = curr_operator->outputs();
Jerry Ge13c78a62022-10-04 20:32:39 -0700466 if (operator_outputs)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700467 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700468 for (size_t k = 0; k < operator_outputs->size(); k++)
469 {
470 auto curr_output = operator_outputs->Get(k);
471 operator_outputs_container.push_back(curr_output->str());
472 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700473 }
Eric Kunze2364dcd2021-04-26 11:06:57 -0700474
Jerry Ge13c78a62022-10-04 20:32:39 -0700475 switch (attribute_type)
476 {
477 case Attribute_NONE:
478 typed_attribute = new TosaNoneAttribute();
479 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700480#define DEF_ATTRIBUTE(NAME, ...) \
481 case Attribute_##NAME##Attribute: \
482 typed_attribute = new Tosa##NAME##Attribute(attribute); \
483 break;
484#include "attribute.def"
485#undef DEF_ATTRIBUTE
Jerry Ge13c78a62022-10-04 20:32:39 -0700486 default:
487 printf("TosaSerializationHandler::Deserialize(): Attribute %s not implemented yet\n",
488 EnumNamesAttribute()[attribute_type]);
489 return TOSA_INTERNAL_ERROR;
490 }
491
492 new_operator = new TosaSerializationOperator(operator_op, attribute_type, typed_attribute,
493 operator_inputs_container, operator_outputs_container);
494 if (new_operator)
495 {
496 block_operators_container.push_back(new_operator);
497 }
498 else
499 {
500 return TOSA_MEMORY_ERROR;
501 }
502
503 if (typed_attribute)
504 delete typed_attribute;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700505 }
506
Jerry Ge13c78a62022-10-04 20:32:39 -0700507 auto block_inputs = curr_block->inputs();
508 auto block_outputs = curr_block->outputs();
509
Jerry Ge13c78a62022-10-04 20:32:39 -0700510 for (size_t j = 0; j < block_inputs->size(); j++)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700511 {
Jerry Ge13c78a62022-10-04 20:32:39 -0700512 auto curr_block_input = block_inputs->Get(j);
513 block_inputs_container.push_back(curr_block_input->str());
514 }
515 for (size_t j = 0; j < block_outputs->size(); j++)
516 {
517 auto curr_block_output = block_outputs->Get(j);
518 block_outputs_container.push_back(curr_block_output->str());
519 }
520
521 auto fb_tosa_tensors = curr_block->tensors();
Jerry Ge13c78a62022-10-04 20:32:39 -0700522 for (size_t j = 0; j < fb_tosa_tensors->size(); j++)
523 {
524 auto curr_tensor = fb_tosa_tensors->Get(j);
525
Tai Lyc6939a42023-08-21 17:00:29 +0000526 auto tensor_name = curr_tensor->name();
527 auto tensor_shape = curr_tensor->shape();
528 auto tensor_type = curr_tensor->type();
529 auto tensor_variable = curr_tensor->variable();
530 auto tensor_data = curr_tensor->data();
531 auto tensor_is_unranked = curr_tensor->is_unranked();
Jerry Ge13c78a62022-10-04 20:32:39 -0700532
Tai Lyc6939a42023-08-21 17:00:29 +0000533 new_tensor = new TosaSerializationTensor(tensor_name, tensor_shape, tensor_type, tensor_data,
534 tensor_variable, tensor_is_unranked);
Jerry Ge13c78a62022-10-04 20:32:39 -0700535 if (new_tensor)
536 {
537 block_tensors_container.push_back(new_tensor);
538 }
539 else
540 {
541 return TOSA_MEMORY_ERROR;
542 }
543 }
544 new_block = new TosaSerializationBasicBlock(block_name, region_name, block_operators_container,
545 block_tensors_container, block_inputs_container,
546 block_outputs_container);
547 if (new_block)
548 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000549 new_region->GetBlocks().push_back(new_block);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700550 }
551 else
552 {
553 return TOSA_MEMORY_ERROR;
554 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700555 } // end block for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700556 }
557
558 return TOSA_OK;
559}
560
James Ward80905bb2023-01-25 15:51:27 +0000561std::vector<uint8_t> float_to_u8_helper(float f_in)
James Wardc15f7d52022-12-07 15:38:01 +0000562{
James Ward80905bb2023-01-25 15:51:27 +0000563 // Push back a single float value to the buffer with *NO PADDING*
564 // Therefore ConvertF32toU8 function not used
James Wardc15f7d52022-12-07 15:38:01 +0000565 std::vector<uint8_t> u8_out;
James Ward80905bb2023-01-25 15:51:27 +0000566 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&f_in);
567 u8_out.push_back(*val_u32 & 0xFF);
568 u8_out.push_back((*val_u32 >> 8) & 0xFF);
569 u8_out.push_back((*val_u32 >> 16) & 0xFF);
570 u8_out.push_back((*val_u32 >> 24) & 0xFF);
James Wardc15f7d52022-12-07 15:38:01 +0000571 return u8_out;
572}
573
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700574tosa_err_t TosaSerializationHandler::Serialize()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700575{
Jerry Ge13c78a62022-10-04 20:32:39 -0700576 // regions
577 std::vector<flatbuffers::Offset<TosaRegion>> fboffset_regions;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700578
Eric Kunze2364dcd2021-04-26 11:06:57 -0700579 // translate TosaFlatbufferOperator to flatbuffers::Offset<TosaOperator>
Jerry Ge13c78a62022-10-04 20:32:39 -0700580 for (auto region : GetRegions())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700581 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000582 std::vector<flatbuffers::Offset<TosaBasicBlock>> fboffset_blocks;
Jerry Ge13c78a62022-10-04 20:32:39 -0700583 for (auto block : region->GetBlocks())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700584 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000585 std::vector<flatbuffers::Offset<TosaOperator>> fboffset_block_operators;
586 std::vector<flatbuffers::Offset<TosaTensor>> fboffset_block_tensors;
587 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_inputs;
588 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_block_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700589 auto block_name = _builder.CreateString(block->GetName().c_str());
590 for (auto tensor_str : block->GetInputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700591 {
592 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700593 fboffset_block_inputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700594 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700595 for (auto tensor_str : block->GetOutputs())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700596 {
597 auto tensor_name = _builder.CreateString(tensor_str.c_str());
Jerry Ge13c78a62022-10-04 20:32:39 -0700598 fboffset_block_outputs.push_back(tensor_name);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700599 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700600 auto fb_block_inputs = _builder.CreateVector(fboffset_block_inputs);
601 auto fb_block_outputs = _builder.CreateVector(fboffset_block_outputs);
602 for (auto op : block->GetOperators())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700603 {
Tai Lycfcb20d2023-03-13 21:04:11 +0000604 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_inputs;
605 std::vector<flatbuffers::Offset<flatbuffers::String>> fboffset_operator_outputs;
Jerry Ge13c78a62022-10-04 20:32:39 -0700606 auto operator_op = op->GetOp();
607 auto attribute_type = op->GetAttributeType();
608 for (auto tensor_str : op->GetInputTensorNames())
609 {
610 auto tensor_name = _builder.CreateString(tensor_str.c_str());
611 fboffset_operator_inputs.push_back(tensor_name);
612 }
613 for (auto tensor_str : op->GetOutputTensorNames())
614 {
615 auto tensor_name = _builder.CreateString(tensor_str.c_str());
616 fboffset_operator_outputs.push_back(tensor_name);
617 }
618 auto fb_operator_inputs = _builder.CreateVector(fboffset_operator_inputs);
619 auto fb_operator_outputs = _builder.CreateVector(fboffset_operator_outputs);
620 flatbuffers::Offset<void> fb_attribute;
621 switch (attribute_type)
622 {
623 case Attribute_NONE:
624 fb_attribute = 0;
625 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700626#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 +0000627#define DEF_ARGS_S_FP_as_U8(NAME, V) \
James Ward80905bb2023-01-25 15:51:27 +0000628 , _builder.CreateVector<uint8_t>(float_to_u8_helper(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()))
Eric Kunze2364dcd2021-04-26 11:06:57 -0700629#define DEF_ARGS_S_DEFAULT(NAME, V) , reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V()
Eric Kunze2364dcd2021-04-26 11:06:57 -0700630#define DEF_ARGS_S_int32_t(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Wardc15f7d52022-12-07 15:38:01 +0000631#define DEF_ARGS_S_float(NAME, V) DEF_ARGS_S_FP_as_U8(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700632#define DEF_ARGS_S_bool(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
633#define DEF_ARGS_S_ResizeMode(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
James Ward485a11d2022-08-05 13:48:37 +0100634#define DEF_ARGS_S_DType(NAME, V) DEF_ARGS_S_DEFAULT(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700635#define DEF_ARGS_S_string(NAME, V) DEF_ARGS_S_STR(NAME, V)
Eric Kunze2364dcd2021-04-26 11:06:57 -0700636#define DEF_ARGS_S(NAME, T, V) DEF_ARGS_S_##T(NAME, V)
637#define DEF_ARGS_V(NAME, T, V) , _builder.CreateVector<T>(reinterpret_cast<Tosa##NAME*>(op->GetAttribute())->V())
Eric Kunze2364dcd2021-04-26 11:06:57 -0700638#define DEF_ARGS_1(NAME, T0, F0, V0) DEF_ARGS_##F0(NAME, T0, V0)
639#define DEF_ARGS_2(NAME, T0, F0, V0, T1, F1, V1) DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1)
640#define DEF_ARGS_3(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2) \
641 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2)
642#define DEF_ARGS_4(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3) \
643 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3)
644#define DEF_ARGS_5(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4) \
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 DEF_ARGS_##F4(NAME, T4, V4)
647#define DEF_ARGS_6(NAME, T0, F0, V0, T1, F1, V1, T2, F2, V2, T3, F3, V3, T4, F4, V4, T5, F5, V5) \
648 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
649 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5)
650#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) \
651 DEF_ARGS_##F0(NAME, T0, V0) DEF_ARGS_##F1(NAME, T1, V1) DEF_ARGS_##F2(NAME, T2, V2) DEF_ARGS_##F3(NAME, T3, V3) \
652 DEF_ARGS_##F4(NAME, T4, V4) DEF_ARGS_##F5(NAME, T5, V5) DEF_ARGS_##F6(NAME, T6, V6)
653#define DEF_ATTRIBUTE(NAME, NUM_ARGS, ...) \
654 case Attribute_##NAME##Attribute: \
655 fb_attribute = Create##NAME##Attribute(_builder DEF_ARGS_##NUM_ARGS(NAME##Attribute, __VA_ARGS__)).Union(); \
656 break;
Eric Kunze2364dcd2021-04-26 11:06:57 -0700657#include "attribute.def"
658#undef DEF_ATTRIBUTE
659#undef DEF_ARGS_1
660#undef DEF_ARGS_2
661#undef DEF_ARGS_3
662#undef DEF_ARGS_4
663#undef DEF_ARGS_5
664#undef DEF_ARGS_6
665#undef DEF_ARGS_7
666#undef DEF_ARGS_S
667#undef DEF_ARGS_V
668#undef DEF_ARGS_S_int32_t
669#undef DEF_ARGS_S_float
670#undef DEF_ARGS_S_bool
671#undef DEF_ARGS_S_ResizeMode
James Ward485a11d2022-08-05 13:48:37 +0100672#undef DEF_ARGS_S_DType
Eric Kunze2364dcd2021-04-26 11:06:57 -0700673#undef DEF_ARGS_S_string
674#undef DEF_ARGS_S_STR
675#undef DEF_ARGS_S_DEFAULT
Jerry Ge13c78a62022-10-04 20:32:39 -0700676 default:
677 printf("TosaSerializationHandler::Serialize(): Attribute %s not implemented yet\n",
678 EnumNamesAttribute()[attribute_type]);
679 return TOSA_INTERNAL_ERROR;
680 }
681 auto fboffset_operator = CreateTosaOperator(_builder, operator_op, attribute_type, fb_attribute,
682 fb_operator_inputs, fb_operator_outputs);
683 fboffset_block_operators.push_back(fboffset_operator);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700684 }
Jerry Ge13c78a62022-10-04 20:32:39 -0700685 auto fb_block_operators = _builder.CreateVector(fboffset_block_operators);
686 for (auto tensor : block->GetTensors())
687 {
Tai Lyc6939a42023-08-21 17:00:29 +0000688 auto tensor_name = _builder.CreateString(tensor->GetName().c_str());
689 auto tensor_shape = _builder.CreateVector(tensor->GetShape());
690 auto tensor_dtype = tensor->GetDtype();
691 bool tensor_variable = tensor->GetVariable();
692 auto tensor_data = _builder.CreateVector(tensor->GetData());
693 auto tensor_is_unranked = tensor->GetIsUnranked();
694 auto fboffset_tensor = CreateTosaTensor(_builder, tensor_name, tensor_shape, tensor_dtype, tensor_data,
695 tensor_variable, tensor_is_unranked);
Jerry Ge13c78a62022-10-04 20:32:39 -0700696 fboffset_block_tensors.push_back(fboffset_tensor);
697 }
698 auto fb_block_tensors = _builder.CreateVector(fboffset_block_tensors);
699 auto fboffset_block = CreateTosaBasicBlock(_builder, block_name, fb_block_operators, fb_block_tensors,
Won Jeoncb4bbf42023-08-10 08:50:15 +0000700 fb_block_inputs, fb_block_outputs);
Jerry Ge13c78a62022-10-04 20:32:39 -0700701 fboffset_blocks.push_back(fboffset_block);
702 } // end block for_loop
703 auto fb_blocks = _builder.CreateVector(fboffset_blocks);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700704
Jerry Ge13c78a62022-10-04 20:32:39 -0700705 auto region_name = _builder.CreateString(region->GetName().c_str());
706 auto fboffset_region = CreateTosaRegion(_builder, region_name, fb_blocks);
707 fboffset_regions.push_back(fboffset_region);
708 } // end region for_loop
Eric Kunze2364dcd2021-04-26 11:06:57 -0700709
Jerry Ge13c78a62022-10-04 20:32:39 -0700710 auto fb_regions = _builder.CreateVector(fboffset_regions);
Eric Kunze2364dcd2021-04-26 11:06:57 -0700711
Kevin Chengb97cb1d2021-10-14 11:53:39 -0700712 auto fb_version =
713 CreateVersion(_builder, TOSA_VERSION_MAJOR, TOSA_VERSION_MINOR, TOSA_VERSION_PATCH, TOSA_VERSION_DRAFT);
Jerry Ge13c78a62022-10-04 20:32:39 -0700714 auto fb_graph = CreateTosaGraph(_builder, fb_version, fb_regions);
Eric Kunzee6596402022-06-09 21:27:36 +0000715 _builder.Finish(fb_graph, TosaGraphIdentifier());
Eric Kunze2364dcd2021-04-26 11:06:57 -0700716
717 return TOSA_OK;
718}
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700719
Jerry Ge442261b2022-09-09 13:38:56 -0700720void TosaSerializationHandler::ForceAlignTensorData(std::vector<uint8_t>& buf)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700721{
722 while ((buf.size() % TENSOR_BUFFER_FORCE_ALIGNMENT) != 0)
723 {
724 buf.push_back(0);
725 }
726}
727
James Ward485a11d2022-08-05 13:48:37 +0100728tosa_err_t TosaSerializationHandler::ConvertF16toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
729{
730 // Note: Converts fp32->fp16 before converting to uint8_t
731 out.clear();
732 for (auto val : in)
733 {
734 half_float::half val_f16 = half_float::half_cast<half_float::half, float>(val);
735 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val_f16);
736 out.push_back(*val_u16 & 0xFF);
737 out.push_back((*val_u16 >> 8) & 0xFF);
738 }
Jerry Ge442261b2022-09-09 13:38:56 -0700739 ForceAlignTensorData(out);
James Ward485a11d2022-08-05 13:48:37 +0100740 return TOSA_OK;
741}
742
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700743tosa_err_t TosaSerializationHandler::ConvertF32toU8(const std::vector<float>& in, std::vector<uint8_t>& out)
744{
745 out.clear();
746 for (auto val : in)
747 {
748 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
749 out.push_back(*val_u32 & 0xFF);
750 out.push_back((*val_u32 >> 8) & 0xFF);
751 out.push_back((*val_u32 >> 16) & 0xFF);
752 out.push_back((*val_u32 >> 24) & 0xFF);
753 }
Jerry Ge442261b2022-09-09 13:38:56 -0700754 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700755 return TOSA_OK;
756}
757
758tosa_err_t TosaSerializationHandler::ConvertI48toU8(const std::vector<int64_t>& in, std::vector<uint8_t>& out)
759{
760 out.clear();
761 for (auto val : in)
762 {
763 uint64_t* val_u64 = reinterpret_cast<uint64_t*>(&val);
764 out.push_back(*val_u64 & 0xFF);
765 out.push_back((*val_u64 >> 8) & 0xFF);
766 out.push_back((*val_u64 >> 16) & 0xFF);
767 out.push_back((*val_u64 >> 24) & 0xFF);
768 out.push_back((*val_u64 >> 32) & 0xFF);
769 out.push_back((*val_u64 >> 40) & 0xFF);
770 }
Jerry Ge442261b2022-09-09 13:38:56 -0700771 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700772 return TOSA_OK;
773}
774
775tosa_err_t TosaSerializationHandler::ConvertI32toU8(const std::vector<int32_t>& in, std::vector<uint8_t>& out)
776{
777 out.clear();
778 for (auto val : in)
779 {
780 uint32_t* val_u32 = reinterpret_cast<uint32_t*>(&val);
781 out.push_back(*val_u32 & 0xFF);
782 out.push_back((*val_u32 >> 8) & 0xFF);
783 out.push_back((*val_u32 >> 16) & 0xFF);
784 out.push_back((*val_u32 >> 24) & 0xFF);
785 }
Jerry Ge442261b2022-09-09 13:38:56 -0700786 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700787 return TOSA_OK;
788}
789
790tosa_err_t TosaSerializationHandler::ConvertI16toU8(const std::vector<int16_t>& in, std::vector<uint8_t>& out)
791{
792 out.clear();
793 for (auto val : in)
794 {
795 uint16_t* val_u16 = reinterpret_cast<uint16_t*>(&val);
796 out.push_back(*val_u16 & 0xFF);
797 out.push_back((*val_u16 >> 8) & 0xFF);
798 }
Jerry Ge442261b2022-09-09 13:38:56 -0700799 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700800 return TOSA_OK;
801}
802
803tosa_err_t TosaSerializationHandler::ConvertI8toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
804{
805 out.clear();
806 for (auto val : in)
807 {
808 uint8_t* val_u8 = reinterpret_cast<uint8_t*>(&val);
809 out.push_back(*val_u8);
810 }
Jerry Ge442261b2022-09-09 13:38:56 -0700811 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700812 return TOSA_OK;
813}
814
Kevin Cheng3ce56342021-07-28 13:42:29 -0700815// Two int4 values are packed into one byte out.
816// For given input value val_0 = in[2*i], and val_1 = in[2*i+1],
817// they'll be packed as out[3:0] = val_0, and out[7:4] = val_1
818tosa_err_t TosaSerializationHandler::ConvertI4toU8(const std::vector<int8_t>& in, std::vector<uint8_t>& out)
819{
820 out.clear();
821 uint32_t in_size = in.size();
822 uint32_t out_size = (in_size % 2 == 0) ? (in_size / 2) : ((in_size + 1) / 2);
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800823 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700824 {
825 int8_t val_0 = in[2 * i];
826 int8_t val_1 = 0;
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800827 if (2u * i + 1u < in_size)
Kevin Cheng3ce56342021-07-28 13:42:29 -0700828 {
829 val_1 = in[2 * i + 1];
830 }
831 // In TOSA spec, int4 ranges [-7, 7]
832 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
833 {
834 printf("TosaSerializationHandler::ConvertI4toU8(): element in input array (%d or %d) exceeds int4 range.\n",
835 val_0, val_1);
836 return TOSA_USER_ERROR;
837 }
838 int8_t val_packed = (val_0 & 0xF) | ((val_1 & 0xF) << 4);
839 uint8_t val_u8 = static_cast<uint8_t>(val_packed);
840 out.push_back(val_u8);
841 }
Jerry Ge442261b2022-09-09 13:38:56 -0700842 ForceAlignTensorData(out);
Kevin Cheng3ce56342021-07-28 13:42:29 -0700843 return TOSA_OK;
844}
845
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700846tosa_err_t TosaSerializationHandler::ConvertBooltoU8(const std::vector<bool>& in, std::vector<uint8_t>& out)
847{
848 out.clear();
849 for (auto val : in)
850 {
Eric Kunze4417b422022-06-20 07:27:42 -0700851 uint8_t val_u8 = val;
852 out.push_back(val_u8);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700853 }
Jerry Ge442261b2022-09-09 13:38:56 -0700854 ForceAlignTensorData(out);
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700855 return TOSA_OK;
856}
857
858tosa_err_t
James Ward485a11d2022-08-05 13:48:37 +0100859 TosaSerializationHandler::ConvertU8toF16(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
860{
861 // Note: fp16 values returned in fp32 type
862 out.clear();
863 if (in.size() < out_size * sizeof(int16_t))
864 {
865 printf("TosaSerializationHandler::ConvertU8toF16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
866 out_size * sizeof(int16_t));
867 return TOSA_USER_ERROR;
868 }
869
870 for (uint32_t i = 0; i < out_size; i++)
871 {
872 uint16_t f16_byte0 = in[i * sizeof(int16_t)];
873 uint16_t f16_byte1 = in[i * sizeof(int16_t) + 1];
874 uint16_t val_u16 = f16_byte0 + (f16_byte1 << 8);
875
876 // Reinterpret u16 byte as fp16 then convert to fp32
877 half_float::half val_f16 = *(half_float::half*)&val_u16;
878 float val_fp32 = half_float::half_cast<float, half_float::half>(val_f16);
879 out.push_back(val_fp32);
880 }
881 return TOSA_OK;
882}
883
884tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700885 TosaSerializationHandler::ConvertU8toF32(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<float>& out)
886{
887 out.clear();
888 if (in.size() < out_size * sizeof(float))
889 {
890 printf("TosaSerializationHandler::ConvertU8toF32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
891 out_size * sizeof(float));
892 return TOSA_USER_ERROR;
893 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800894 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700895 {
896 uint32_t byte0 = in[i * sizeof(float)];
897 uint32_t byte1 = in[i * sizeof(float) + 1];
898 uint32_t byte2 = in[i * sizeof(float) + 2];
899 uint32_t byte3 = in[i * sizeof(float) + 3];
900 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
901 float* val_fp32 = reinterpret_cast<float*>(&val_u32);
902 out.push_back(*val_fp32);
903 }
904 return TOSA_OK;
905}
906
907tosa_err_t TosaSerializationHandler::ConvertU8toI48(const std::vector<uint8_t>& in,
908 uint32_t out_size,
909 std::vector<int64_t>& out)
910{
911 out.clear();
912 if (in.size() < out_size * 6 /* sizeof(int48) */)
913 {
914 printf("TosaSerializationHandler::ConvertU8toI48(): uint8 buffer size %ld must >= target size %d\n", in.size(),
915 out_size * 6);
916 return TOSA_USER_ERROR;
917 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800918 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700919 {
920 uint64_t byte0 = in[i * 6];
921 uint64_t byte1 = in[i * 6 + 1];
922 uint64_t byte2 = in[i * 6 + 2];
923 uint64_t byte3 = in[i * 6 + 3];
924 uint64_t byte4 = in[i * 6 + 4];
925 uint64_t byte5 = in[i * 6 + 5];
926 bool sign = ((byte5 >> 7) & 1) == 1 ? true : false;
927 uint64_t val_u64 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24) + (byte4 << 32) + (byte5 << 40);
928 if (sign)
929 {
930 uint64_t sext_mask = (0xFFFFUL << 48);
931 val_u64 |= sext_mask;
932 }
933 int64_t* val_i64 = reinterpret_cast<int64_t*>(&val_u64);
934 out.push_back(*val_i64);
935 }
936 return TOSA_OK;
937}
938
939tosa_err_t TosaSerializationHandler::ConvertU8toI32(const std::vector<uint8_t>& in,
940 uint32_t out_size,
941 std::vector<int32_t>& out)
942{
943 out.clear();
944 if (in.size() < out_size * sizeof(int32_t))
945 {
946 printf("TosaSerializationHandler::ConvertU8toI32(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
947 out_size * sizeof(int32_t));
948 return TOSA_USER_ERROR;
949 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800950 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700951 {
952 uint32_t byte0 = in[i * sizeof(int32_t)];
953 uint32_t byte1 = in[i * sizeof(int32_t) + 1];
954 uint32_t byte2 = in[i * sizeof(int32_t) + 2];
955 uint32_t byte3 = in[i * sizeof(int32_t) + 3];
956 uint32_t val_u32 = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
957 int32_t* val_i32 = reinterpret_cast<int32_t*>(&val_u32);
958 out.push_back(*val_i32);
959 }
960 return TOSA_OK;
961}
962
963tosa_err_t TosaSerializationHandler::ConvertU8toI16(const std::vector<uint8_t>& in,
964 uint32_t out_size,
965 std::vector<int16_t>& out)
966{
967 out.clear();
968 if (in.size() < out_size * sizeof(int16_t))
969 {
970 printf("TosaSerializationHandler::ConvertU8toI16(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
971 out_size * sizeof(int16_t));
972 return TOSA_USER_ERROR;
973 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800974 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700975 {
976 uint16_t byte0 = in[i * sizeof(int16_t)];
977 uint16_t byte1 = in[i * sizeof(int16_t) + 1];
978 uint16_t val_u16 = byte0 + (byte1 << 8);
979 int16_t* val_i16 = reinterpret_cast<int16_t*>(&val_u16);
980 out.push_back(*val_i16);
981 }
982 return TOSA_OK;
983}
984
985tosa_err_t
986 TosaSerializationHandler::ConvertU8toI8(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
987{
988 out.clear();
989 if (in.size() < out_size * sizeof(int8_t))
990 {
991 printf("TosaSerializationHandler::ConvertU8toI8(): uint8 buffer size %ld must >= target size %ld\n", in.size(),
Kevin Cheng3ce56342021-07-28 13:42:29 -0700992 out_size * sizeof(int8_t));
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700993 return TOSA_USER_ERROR;
994 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -0800995 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -0700996 {
997 uint8_t val_u8 = in[i];
998 int8_t* val_i8 = reinterpret_cast<int8_t*>(&val_u8);
999 out.push_back(*val_i8);
1000 }
1001 return TOSA_OK;
1002}
1003
1004tosa_err_t
Kevin Cheng3ce56342021-07-28 13:42:29 -07001005 TosaSerializationHandler::ConvertU8toI4(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<int8_t>& out)
1006{
1007 out.clear();
1008 if (out_size > in.size() * 2)
1009 {
1010 printf("TosaSerializationHandler::ConvertU8toI4(): output size %u must <= uint8 buffer size %ld x 2.\n",
1011 out_size, in.size());
1012 return TOSA_USER_ERROR;
1013 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001014 for (size_t i = 0; i < in.size(); i++)
Kevin Cheng3ce56342021-07-28 13:42:29 -07001015 {
1016 uint8_t val_u8 = in[i];
1017 uint8_t val_0_u4 = val_u8 & 0xF;
1018 uint8_t val_1_u4 = val_u8 >> 4;
1019 uint8_t val_0_u8_sext = (val_0_u4 & 0x08) ? (val_0_u4 | 0xF0) : val_0_u4;
1020 uint8_t val_1_u8_sext = (val_1_u4 & 0x08) ? (val_1_u4 | 0xF0) : val_1_u4;
1021 int8_t val_0 = static_cast<int8_t>(val_0_u8_sext);
1022 int8_t val_1 = static_cast<int8_t>(val_1_u8_sext);
1023 // In TOSA spec, int4 ranges [-7, 7]
1024 if (val_0 < -7 || val_0 > 7 || val_1 < -7 || val_1 > 7)
1025 {
1026 printf(
1027 "TosaSerializationHandler::ConvertU8toI4(): element in output array (%d or %d) exceeds int4 range.\n",
1028 val_0, val_1);
1029 return TOSA_USER_ERROR;
1030 }
1031 out.push_back(val_0);
1032 if (2 * i + 1 < out_size)
1033 out.push_back(val_1);
1034 }
1035 return TOSA_OK;
1036}
1037
1038tosa_err_t
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001039 TosaSerializationHandler::ConvertU8toBool(const std::vector<uint8_t>& in, uint32_t out_size, std::vector<bool>& out)
1040{
1041 out.clear();
1042 if (in.size() < out_size * sizeof(bool))
1043 {
1044 printf("TosaSerializationHandler::ConvertU8toBool(): uint8 buffer size %ld must >= target size %ld\n",
1045 in.size(), out_size * sizeof(bool));
1046 return TOSA_USER_ERROR;
1047 }
Eric Kunzeb13fe8f2022-02-17 17:14:25 -08001048 for (uint32_t i = 0; i < out_size; i++)
Kevin Cheng3bb1bc12021-06-17 15:57:08 -07001049 {
1050 uint8_t val_u8 = in[i];
1051 bool* val_bool = reinterpret_cast<bool*>(&val_u8);
1052 out.push_back(*val_bool);
1053 }
1054 return TOSA_OK;
1055}