// Copyright 2020 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace tflite.gpu.cl.data;

table Int4 {
  x:int32;
  y:int32;
  z:int32;
  w:int32;
}

table Int3 {
  x:int32;
  y:int32;
  z:int32;
}

table Int2 {
  x:int32;
  y:int32;
}

table IntValue {
  name:string;
  value:int32;
  active:bool;
  offset:uint32;
}

table FloatValue {
  name:string;
  value:float;
  active:bool;
  offset:uint32;
}

table HalfValue {
  name:string;
  value:float;
  active:bool;
  store_as_f32:bool;
  offset:uint32;
}

enum AccessType : byte {
  READ = 0,
  WRITE = 1,
  READ_WRITE = 2,
}

enum DataType : byte {
  UNKNOWN = 0,
  FLOAT32 = 1,
  FLOAT16 = 2,
}

enum MemoryType : byte {
  GLOBAL = 0,
  CONSTANT = 1,
  LOCAL = 2,
}

table StateVariable {
  key:string;
  value:string;
}

table GPUObjectDescriptor {
  state_vars:[StateVariable];
  access_type:AccessType;
}

table BufferDescriptor {
  base_obj:GPUObjectDescriptor;
  element_type:DataType;
  element_size:int32;
  memory_type:MemoryType;
  attributes:[string];
  size:int32;
  data:[uint8];
}

table Texture2DDescriptor {
  base_obj:GPUObjectDescriptor;
  element_type:DataType;
  normalized:bool;
  normalized_type:DataType;
  size:Int2;
  data:[uint8];
}

enum LinearStorageType : byte {
  BUFFER = 0,
  TEXTURE_2D = 1,
}

table TensorLinearDescriptor {
  base_obj:GPUObjectDescriptor;
  storage_type:LinearStorageType;
  element_type:DataType;
  memory_type:MemoryType;
  size:int32;
  data:[uint8];
}

enum TensorStorageType : byte {
  UNKNOWN = 0,
  BUFFER = 1,
  IMAGE_BUFFER = 2,
  TEXTURE_2D = 3,
  TEXTURE_3D = 4,
  TEXTURE_ARRAY = 5,
  SINGLE_TEXTURE_2D = 6,
}

enum Layout : byte {
  UNKNOWN = 0,
  HWC = 1,
  BHWC = 2,
  HWDC = 3,
  BHWDC = 4,
}

table BHWDC {
  b:int32;
  h:int32;
  w:int32;
  d:int32;
  c:int32;
}

table TensorDescriptor {
  base_obj:GPUObjectDescriptor;
  data_type:DataType;
  storage_type:TensorStorageType;
  layout:Layout;
  shape:BHWDC;
  data:[uint8];
}

table BufferDescriptorMapValue {
  key:string;
  value:BufferDescriptor;
}

table Texture2DDescriptorMapValue {
  key:string;
  value:Texture2DDescriptor;
}

table TensorLinearDescriptorMapValue {
  key:string;
  value:TensorLinearDescriptor;
}

table TensorDescriptorMapValue {
  key:string;
  value:TensorDescriptor;
}

table Arguments {
  int_values:[IntValue];
  shared_int4s:[int32];

  float_values:[FloatValue];
  shared_float4s:[float];

  half_values:[HalfValue];
  shared_half4s:[float];

  buffer_refs:[BufferDescriptorMapValue];
  texture2d_refs:[Texture2DDescriptorMapValue];
  tensor_linear_refs:[TensorLinearDescriptorMapValue];
  tensor_refs:[TensorDescriptorMapValue];

  buffer_objects:[BufferDescriptorMapValue];
  texture2d_objects:[Texture2DDescriptorMapValue];
  tensor_linear_objects:[TensorLinearDescriptorMapValue];
  tensor_objects:[TensorDescriptorMapValue];
}

enum CalculationsPrecision : byte {
  F32 = 0,
  F32_F16 = 1,
  F16 = 2,
}

enum TensorToGrid : byte {
  CUSTOM = 0,
  WB_TO_X_HD_TO_Y_S_TO_Z = 1,
  WB_TO_X_HD_TO_Y_Z_IS_1 = 2,
  WB_TO_X_H_TO_Y_D_TO_Z = 3,
  B_TO_X_Y_IS_1_Z_IS_1 = 4,
}

enum CompilerOptions : byte {
  ADRENO_FULL_SIMD_LINE = 0,
  ADRENO_MORE_WAVES = 1,
  POWERVR_FP16 = 2,
  CL_OPT_DISABLE = 3,
  CL_2_0 = 4,
  CL_3_0 = 5,
}

table OperationDef {
  precision:CalculationsPrecision;
  src_tensors:[TensorDescriptor];
  dst_tensors:[TensorDescriptor];
}

table CompilerOption {
  option:CompilerOptions;
}

table GPUOperation {
  arguments:Arguments;
  code:string;
  work_group_size:Int3;
  compiler_options:[CompilerOption];
  tensor_to_grid:TensorToGrid;
  elementwise:bool;
  linkable:bool;
  check_src_channels_size:bool;
  definition:OperationDef;
  grid_dimension:int32;
  work_group_launch_order:Int3;
  grid_size:Int3;
  src_tensors_names:[string];
  dst_tensors_names:[string];
  work_groups_count:Int3;
  linkable_count:int32;
  elementwise_code:string;
}

table TensorDescWithId {
  desc:TensorDescriptor;
  id:int32;
}

table CLNode {
  gpu_op:GPUOperation;
  input_ids:[int32];
  output_ids:[int32];
  name:string;
}

table PairOfValueIds {
  first:int32;
  second:int32;
}

table InferenceContext {
  need_flush:bool;
  flush_periodically:bool;
  flush_period:int32;
  need_manual_release:bool;
  precision:CalculationsPrecision;
  storage_type:TensorStorageType;
  nodes:[CLNode];
  tensors:[TensorDescWithId];
  input_ids:[int32];
  variable_ids_and_refs:[PairOfValueIds];
  output_ids:[int32];
}

root_type InferenceContext;
