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, ¶meter));
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