xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/delegates/gpu/gl/serialization.cc (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #include "tensorflow/lite/delegates/gpu/gl/serialization.h"
17 
18 #include <string>
19 #include <utility>
20 #include <variant>
21 
22 #include "absl/types/variant.h"
23 #include "tensorflow/lite/delegates/gpu/common/data_type.h"
24 #include "tensorflow/lite/delegates/gpu/common/status.h"
25 #include "tensorflow/lite/delegates/gpu/common/types.h"
26 #include "tensorflow/lite/delegates/gpu/gl/variable.h"
27 
28 namespace tflite {
29 namespace gpu {
30 namespace gl {
31 
32 using flatbuffers::Offset;
33 using flatbuffers::Vector;
34 
35 namespace {
36 
37 struct ParameterValueGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter38   Offset<void> operator()(int32_t value) {
39     auto offset = builder->CreateVector(std::vector<int32_t>{value});
40     data::DataInt32Builder data(*builder);
41     data.add_data(offset);
42     return data.Finish().Union();
43   }
44 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter45   Offset<void> operator()(const int2& value) {
46     auto offset = builder->CreateVector(std::vector<int32_t>{value.x, value.y});
47     data::DataInt32Builder data(*builder);
48     data.add_data(offset);
49     return data.Finish().Union();
50   }
51 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter52   Offset<void> operator()(const int4& value) {
53     auto offset = builder->CreateVector(
54         std::vector<int32_t>{value.x, value.y, value.z, value.w});
55     data::DataInt32Builder data(*builder);
56     data.add_data(offset);
57     return data.Finish().Union();
58   }
59 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter60   Offset<void> operator()(const std::vector<int2>& value) {
61     std::vector<int32_t> d(value.size() * 2);
62     for (size_t i = 0; i < value.size(); ++i) {
63       d[i * 2] = value[i].x;
64       d[i * 2 + 1] = value[i].y;
65     }
66     auto offset = builder->CreateVector(d);
67     data::DataInt32Builder data(*builder);
68     data.add_data(offset);
69     return data.Finish().Union();
70   }
71 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter72   Offset<void> operator()(uint32_t value) {
73     auto offset = builder->CreateVector(std::vector<uint32_t>{value});
74     data::DataUint32Builder data(*builder);
75     data.add_data(offset);
76     return data.Finish().Union();
77   }
78 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter79   Offset<void> operator()(const uint4& value) {
80     auto offset = builder->CreateVector(
81         std::vector<uint32_t>{value.x, value.y, value.z, value.w});
82     data::DataUint32Builder data(*builder);
83     data.add_data(offset);
84     return data.Finish().Union();
85   }
86 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter87   Offset<void> operator()(float value) {
88     auto offset = builder->CreateVector(std::vector<float>{value});
89     data::DataFloatBuilder data(*builder);
90     data.add_data(offset);
91     return data.Finish().Union();
92   }
93 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter94   Offset<void> operator()(const float2& value) {
95     auto offset = builder->CreateVector(std::vector<float>{value.x, value.y});
96     data::DataFloatBuilder data(*builder);
97     data.add_data(offset);
98     return data.Finish().Union();
99   }
100 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter101   Offset<void> operator()(const float4& value) {
102     auto offset = builder->CreateVector(
103         std::vector<float>{value.x, value.y, value.z, value.w});
104     data::DataFloatBuilder data(*builder);
105     data.add_data(offset);
106     return data.Finish().Union();
107   }
108 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterValueGetter109   Offset<void> operator()(const std::vector<float4>& value) {
110     std::vector<float> d(value.size() * 4);
111     for (size_t i = 0; i < value.size(); ++i) {
112       d[i * 4] = value[i].x;
113       d[i * 4 + 1] = value[i].y;
114       d[i * 4 + 2] = value[i].z;
115       d[i * 4 + 3] = value[i].w;
116     }
117     auto offset = builder->CreateVector(d);
118     data::DataFloatBuilder data(*builder);
119     data.add_data(offset);
120     return data.Finish().Union();
121   }
122 
123   ::flatbuffers::FlatBufferBuilder* builder;
124 };
125 
126 struct DataVariantTypeGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter127   data::DataVariant operator()(int32_t) const {
128     return data::DataVariant::DataInt32;
129   }
130 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter131   data::DataVariant operator()(const int2&) const {
132     return data::DataVariant::DataInt32;
133   }
134 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter135   data::DataVariant operator()(const int4&) const {
136     return data::DataVariant::DataInt32;
137   }
138 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter139   data::DataVariant operator()(const std::vector<int2>&) const {
140     return data::DataVariant::DataInt32;
141   }
142 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter143   data::DataVariant operator()(uint32_t) const {
144     return data::DataVariant::DataUint32;
145   }
146 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter147   data::DataVariant operator()(const uint4&) const {
148     return data::DataVariant::DataUint32;
149   }
150 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter151   data::DataVariant operator()(float) const {
152     return data::DataVariant::DataFloat;
153   }
154 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter155   data::DataVariant operator()(const float2&) const {
156     return data::DataVariant::DataFloat;
157   }
158 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter159   data::DataVariant operator()(const float4&) const {
160     return data::DataVariant::DataFloat;
161   }
162 
operator ()tflite::gpu::gl::__anon4ee706940111::DataVariantTypeGetter163   data::DataVariant operator()(const std::vector<float4>&) const {
164     return data::DataVariant::DataFloat;
165   }
166 };
167 
168 struct ParameterTypeGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter169   data::ParameterType operator()(int32_t) const {
170     return data::ParameterType::INT32;
171   }
172 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter173   data::ParameterType operator()(const int2&) const {
174     return data::ParameterType::INT32;
175   }
176 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter177   data::ParameterType operator()(const int4&) const {
178     return data::ParameterType::INT32;
179   }
180 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter181   data::ParameterType operator()(const std::vector<int2>&) const {
182     return data::ParameterType::INT32_2;
183   }
184 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter185   data::ParameterType operator()(uint32_t) const {
186     return data::ParameterType::UINT32;
187   }
188 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter189   data::ParameterType operator()(const uint4&) const {
190     return data::ParameterType::UINT32;
191   }
192 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter193   data::ParameterType operator()(float) const {
194     return data::ParameterType::FLOAT32;
195   }
196 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter197   data::ParameterType operator()(const float2&) const {
198     return data::ParameterType::FLOAT32;
199   }
200 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter201   data::ParameterType operator()(const float4&) const {
202     return data::ParameterType::FLOAT32;
203   }
204 
operator ()tflite::gpu::gl::__anon4ee706940111::ParameterTypeGetter205   data::ParameterType operator()(const std::vector<float4>&) const {
206     return data::ParameterType::FLOAT32;
207   }
208 };
209 
ToFB(DataType type)210 data::DataType ToFB(DataType type) {
211   switch (type) {
212     case DataType::INT16:
213       return data::DataType::INT16;
214     case DataType::INT32:
215       return data::DataType::INT32;
216     case DataType::FLOAT16:
217       return data::DataType::FLOAT16;
218     case DataType::FLOAT32:
219       return data::DataType::FLOAT32;
220     default:
221       return data::DataType::UNKNOWN;
222   }
223 }
224 
ToFB(ObjectType type)225 data::ObjectType ToFB(ObjectType type) {
226   switch (type) {
227     case ObjectType::TEXTURE:
228       return data::ObjectType::TEXTURE;
229     case ObjectType::BUFFER:
230       return data::ObjectType::BUFFER;
231     default:
232       return data::ObjectType::UNKNOWN;
233   }
234 }
235 
236 struct ObjectSizeGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeGetter237   Offset<void> operator()(const uint3& shape) {
238     data::Uint3Builder shape_builder(*builder);
239     shape_builder.add_x(shape.x);
240     shape_builder.add_y(shape.y);
241     shape_builder.add_z(shape.z);
242     return shape_builder.Finish().Union();
243   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeGetter244   Offset<void> operator()(const uint2& shape) {
245     data::Uint2Builder shape_builder(*builder);
246     shape_builder.add_x(shape.x);
247     shape_builder.add_y(shape.y);
248     return shape_builder.Finish().Union();
249   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeGetter250   Offset<void> operator()(uint32_t shape) {
251     data::Uint1Builder shape_builder(*builder);
252     shape_builder.add_x(shape);
253     return shape_builder.Finish().Union();
254   }
255 
256   ::flatbuffers::FlatBufferBuilder* builder;
257 };
258 
259 struct ObjectSizeTypeGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeTypeGetter260   data::ObjectSize operator()(const uint3&) const {
261     return data::ObjectSize::Uint3;
262   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeTypeGetter263   data::ObjectSize operator()(const uint2&) const {
264     return data::ObjectSize::Uint2;
265   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectSizeTypeGetter266   data::ObjectSize operator()(const uint32_t) const {
267     return data::ObjectSize::Uint1;
268   }
269 };
270 
271 struct ObjectGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectGetter272   Offset<void> operator()(const ObjectData& data) {
273     auto fb_data = builder->CreateVector(data);
274     data::ObjectDataBuilder data_builder(*builder);
275     data_builder.add_data(fb_data);
276     return data_builder.Finish().Union();
277   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectGetter278   Offset<void> operator()(ObjectRef ref) {
279     data::ObjectRefBuilder ref_builder(*builder);
280     ref_builder.add_global_id(ref);
281     return ref_builder.Finish().Union();
282   }
283 
284   ::flatbuffers::FlatBufferBuilder* builder;
285 };
286 
287 struct ObjectTypeGetter {
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectTypeGetter288   data::ObjectVariant operator()(const ObjectData&) const {
289     return data::ObjectVariant::ObjectData;
290   }
operator ()tflite::gpu::gl::__anon4ee706940111::ObjectTypeGetter291   data::ObjectVariant operator()(const ObjectRef&) const {
292     return data::ObjectVariant::ObjectRef;
293   }
294 };
295 
ToFB(AccessType type)296 data::AccessType ToFB(AccessType type) {
297   switch (type) {
298     case AccessType::READ:
299       return data::AccessType::READ;
300     case AccessType::WRITE:
301       return data::AccessType::WRITE;
302     case AccessType::READ_WRITE:
303       return data::AccessType::READ_WRITE;
304   }
305 }
306 
Encode(const uint3 & v,::flatbuffers::FlatBufferBuilder * builder)307 Offset<data::Uint3> Encode(const uint3& v,
308                            ::flatbuffers::FlatBufferBuilder* builder) {
309   data::Uint3Builder uint3_builder(*builder);
310   uint3_builder.add_x(v.x);
311   uint3_builder.add_y(v.y);
312   uint3_builder.add_z(v.z);
313   return uint3_builder.Finish();
314 }
315 
Encode(const CompiledModelOptions & options,::flatbuffers::FlatBufferBuilder * builder)316 Offset<data::Parameters> Encode(const CompiledModelOptions& options,
317                                 ::flatbuffers::FlatBufferBuilder* builder) {
318   data::ParametersBuilder params_builder(*builder);
319   params_builder.add_dynamic_batch(options.dynamic_batch);
320   return params_builder.Finish();
321 }
322 
323 }  // namespace
324 
AddShader(const std::string & shader_src)325 void SerializedCompiledModelBuilder::AddShader(const std::string& shader_src) {
326   shaders_.push_back(builder_.CreateString(shader_src));
327 }
328 
AddProgram(const std::vector<Variable> & parameters,const std::vector<Object> & objects,const uint3 & workgroup_size,const uint3 & num_workgroups,size_t shader_index)329 void SerializedCompiledModelBuilder::AddProgram(
330     const std::vector<Variable>& parameters, const std::vector<Object>& objects,
331     const uint3& workgroup_size, const uint3& num_workgroups,
332     size_t shader_index) {
333   Offset<data::Uint3> fb_workgroups = Encode(num_workgroups, &builder_);
334   Offset<data::Uint3> fb_workgroup_size = Encode(workgroup_size, &builder_);
335 
336   Offset<Vector<Offset<data::UniformParameter>>> fb_params;
337   {
338     std::vector<Offset<data::UniformParameter>> offsets;
339     for (const Variable& param : parameters) {
340       auto name = builder_.CreateString(param.name);
341       auto data = std::visit(ParameterValueGetter{&builder_}, param.value);
342       data::UniformParameterBuilder builder(builder_);
343       builder.add_name(name);
344       builder.add_data_type(std::visit(DataVariantTypeGetter{}, param.value));
345       builder.add_data(data);
346       builder.add_type(std::visit(ParameterTypeGetter{}, param.value));
347       offsets.push_back(builder.Finish());
348     }
349     fb_params = builder_.CreateVector(offsets);
350   }
351 
352   Offset<Vector<Offset<data::Object>>> fb_objects;
353   {
354     std::vector<Offset<data::Object>> offsets;
355     for (const Object& object : objects) {
356       auto object_variant = std::visit(ObjectGetter{&builder_}, object.object);
357       auto size = std::visit(ObjectSizeGetter{&builder_}, object.size);
358 
359       data::ObjectBuilder builder(builder_);
360       builder.add_access(ToFB(object.access));
361       builder.add_binding(object.binding);
362       builder.add_type(ToFB(object.object_type));
363       builder.add_data_type(ToFB(object.data_type));
364       builder.add_size_type(std::visit(ObjectSizeTypeGetter{}, object.size));
365       builder.add_size(size);
366       builder.add_object_type(std::visit(ObjectTypeGetter{}, object.object));
367       builder.add_object(object_variant);
368       offsets.push_back(builder.Finish());
369     }
370     fb_objects = builder_.CreateVector(offsets);
371   }
372 
373   data::ProgramBuilder program_builder(builder_);
374   program_builder.add_number_workgroups(fb_workgroups);
375   program_builder.add_workgroup_size(fb_workgroup_size);
376   program_builder.add_parameters(fb_params);
377   program_builder.add_objects(fb_objects);
378   program_builder.add_shader_index(shader_index);
379   programs_.push_back(program_builder.Finish());
380 }
381 
Finalize(const CompiledModelOptions & options)382 absl::Span<const uint8_t> SerializedCompiledModelBuilder::Finalize(
383     const CompiledModelOptions& options) {
384   auto shaders = builder_.CreateVector(shaders_);
385   auto programs = builder_.CreateVector(programs_);
386   auto parameters = Encode(options, &builder_);
387   data::CompiledModelBuilder model_builder(builder_);
388   model_builder.add_shaders(shaders);
389   model_builder.add_programs(programs);
390   model_builder.add_parameters(parameters);
391   data::FinishCompiledModelBuffer(builder_, model_builder.Finish());
392   return absl::MakeConstSpan(builder_.GetBufferPointer(), builder_.GetSize());
393 }
394 
395 namespace {
396 
ParseParameter(const data::UniformParameter & fb_parameter,Variable * parameter)397 absl::Status ParseParameter(const data::UniformParameter& fb_parameter,
398                             Variable* parameter) {
399   parameter->name = fb_parameter.name()->str();
400   switch (fb_parameter.type()) {
401     case data::ParameterType::INT32: {
402       auto* ptr = fb_parameter.data_as_DataInt32();
403       if (ptr == nullptr) {
404         return absl::InvalidArgumentError("Unexpected data type '" +
405                                           parameter->name + "'");
406       }
407       switch (ptr->data()->size()) {
408         case 1:
409           parameter->value = (*ptr->data())[0];
410           break;
411         case 2:
412           parameter->value = int2((*ptr->data())[0], (*ptr->data())[1]);
413           break;
414         case 4:
415           parameter->value = int4((*ptr->data())[0], (*ptr->data())[1],
416                                   (*ptr->data())[2], (*ptr->data())[3]);
417           break;
418         default:
419           return absl::InvalidArgumentError("Unexpected size for parameter '" +
420                                             parameter->name + "'");
421       }
422       break;
423     }
424     case data::ParameterType::UINT32: {
425       auto* ptr = fb_parameter.data_as_DataUint32();
426       if (ptr == nullptr) {
427         return absl::InvalidArgumentError("Unexpected data type '" +
428                                           parameter->name + "'");
429       }
430       switch (ptr->data()->size()) {
431         case 1:
432           parameter->value = (*ptr->data())[0];
433           break;
434         case 4:
435           parameter->value = uint4((*ptr->data())[0], (*ptr->data())[1],
436                                    (*ptr->data())[2], (*ptr->data())[3]);
437           break;
438         default:
439           return absl::InvalidArgumentError("Unexpected size for parameter '" +
440                                             parameter->name + "'");
441       }
442       break;
443     }
444     case data::ParameterType::FLOAT32: {
445       auto* ptr = fb_parameter.data_as_DataFloat();
446       if (ptr == nullptr) {
447         return absl::InvalidArgumentError("Unexpected data type '" +
448                                           parameter->name + "'");
449       }
450       switch (ptr->data()->size()) {
451         case 1:
452           parameter->value = (*ptr->data())[0];
453           break;
454         case 2:
455           parameter->value = float2((*ptr->data())[0], (*ptr->data())[1]);
456           break;
457         case 4:
458           parameter->value = float4((*ptr->data())[0], (*ptr->data())[1],
459                                     (*ptr->data())[2], (*ptr->data())[3]);
460           break;
461         default:
462           return absl::InvalidArgumentError("Unexpected size for parameter '" +
463                                             parameter->name + "'");
464       }
465       break;
466     }
467     case data::ParameterType::INT32_2: {
468       auto* ptr = fb_parameter.data_as_DataInt32();
469       if (ptr == nullptr) {
470         return absl::InvalidArgumentError("Unexpected data type '" +
471                                           parameter->name + "'");
472       }
473 
474       if (ptr->data()->size() % 2 != 0) {
475         return absl::InvalidArgumentError("Unexpected size for parameter '" +
476                                           parameter->name + "'");
477       }
478 
479       std::vector<int2> values(ptr->data()->size() / 2);
480       for (int i = 0; i < values.size(); ++i) {
481         values[i] = int2((*ptr->data())[i * 2], (*ptr->data())[i * 2 + 1]);
482       }
483       parameter->value = values;
484       break;
485     }
486   }
487   return absl::OkStatus();
488 }
489 
ToEnum(data::DataType type)490 DataType ToEnum(data::DataType type) {
491   switch (type) {
492     case data::DataType::INT16:
493       return DataType::INT16;
494     case data::DataType::INT32:
495       return DataType::INT32;
496     case data::DataType::FLOAT16:
497       return DataType::FLOAT16;
498     case data::DataType::FLOAT32:
499       return DataType::FLOAT32;
500     default:
501       return DataType::UNKNOWN;
502   }
503 }
504 
ToEnum(data::ObjectType type)505 ObjectType ToEnum(data::ObjectType type) {
506   switch (type) {
507     case data::ObjectType::TEXTURE:
508       return ObjectType::TEXTURE;
509     case data::ObjectType::BUFFER:
510       return ObjectType::BUFFER;
511     default:
512       return ObjectType::UNKNOWN;
513   }
514 }
515 
ToEnum(data::AccessType type)516 AccessType ToEnum(data::AccessType type) {
517   switch (type) {
518     case data::AccessType::READ:
519       return AccessType::READ;
520     case data::AccessType::WRITE:
521       return AccessType::WRITE;
522     case data::AccessType::READ_WRITE:
523       return AccessType::READ_WRITE;
524   }
525 }
526 
ParseObject(const data::Object & fb_object,Object * object)527 absl::Status ParseObject(const data::Object& fb_object, Object* object) {
528   object->access = ToEnum(fb_object.access());
529   object->binding = fb_object.binding();
530   object->object_type = ToEnum(fb_object.type());
531   object->data_type = ToEnum(fb_object.data_type());
532 
533   switch (fb_object.size_type()) {
534     case data::ObjectSize::Uint3: {
535       auto* size = fb_object.size_as_Uint3();
536       object->size = uint3(size->x(), size->y(), size->z());
537       break;
538     }
539     case data::ObjectSize::Uint2: {
540       auto* size = fb_object.size_as_Uint2();
541       object->size = uint2(size->x(), size->y());
542       break;
543     }
544     case data::ObjectSize::Uint1: {
545       auto* size = fb_object.size_as_Uint1();
546       object->size = size->x();
547       break;
548     }
549     case data::ObjectSize::NONE:
550       return absl::InvalidArgumentError("Texture size is not set");
551   }
552 
553   switch (fb_object.object_type()) {
554     case data::ObjectVariant::ObjectData: {
555       auto* fb_data = fb_object.object_as_ObjectData();
556       object->object = std::vector<uint8_t>(
557           fb_data->data()->data(),
558           fb_data->data()->data() + fb_data->data()->size());
559       break;
560     }
561     case data::ObjectVariant::ObjectRef: {
562       auto* fb_ref = fb_object.object_as_ObjectRef();
563       object->object = fb_ref->global_id();
564       break;
565     }
566     case data::ObjectVariant::NONE: {
567       return absl::InvalidArgumentError("Object is not set");
568     }
569   }
570   return absl::OkStatus();
571 }
572 
ParseParameters(const data::Parameters & fb_parameters)573 CompiledModelOptions ParseParameters(const data::Parameters& fb_parameters) {
574   CompiledModelOptions options;
575   options.dynamic_batch = fb_parameters.dynamic_batch();
576   return options;
577 }
578 
579 }  // namespace
580 
DeserializeCompiledModel(absl::Span<const uint8_t> serialized,DeserializationHandler * handler)581 absl::Status DeserializeCompiledModel(absl::Span<const uint8_t> serialized,
582                                       DeserializationHandler* handler) {
583   flatbuffers::Verifier verifier(serialized.data(), serialized.size());
584   if (!data::VerifyCompiledModelBuffer(verifier)) {
585     return absl::InvalidArgumentError("Serialized model is corrupted.");
586   }
587 
588   auto model = data::GetCompiledModel(serialized.data());
589   for (auto shader : *model->shaders()) {
590     RETURN_IF_ERROR(
591         handler->OnShader(absl::MakeSpan(shader->c_str(), shader->size())));
592   }
593   std::vector<Variable> parameters;
594   std::vector<Object> objects;
595   for (auto program : *model->programs()) {
596     parameters.clear();
597     objects.clear();
598     for (auto fb_parameter : *program->parameters()) {
599       Variable parameter;
600       RETURN_IF_ERROR(ParseParameter(*fb_parameter, &parameter));
601       parameters.push_back(std::move(parameter));
602     }
603     for (auto fb_object : *program->objects()) {
604       Object object;
605       RETURN_IF_ERROR(ParseObject(*fb_object, &object));
606       objects.push_back(std::move(object));
607     }
608     uint3 workgroup_size(program->workgroup_size()->x(),
609                          program->workgroup_size()->y(),
610                          program->workgroup_size()->z());
611     uint3 num_workgroups(program->number_workgroups()->x(),
612                          program->number_workgroups()->y(),
613                          program->number_workgroups()->z());
614     RETURN_IF_ERROR(handler->OnProgram(parameters, objects, workgroup_size,
615                                        num_workgroups,
616                                        program->shader_index()));
617   }
618   handler->OnOptions(ParseParameters(*model->parameters()));
619   return absl::OkStatus();
620 }
621 
622 }  // namespace gl
623 }  // namespace gpu
624 }  // namespace tflite
625