summaryrefslogtreecommitdiff
path: root/tools/tflitefile_tool/ir
diff options
context:
space:
mode:
Diffstat (limited to 'tools/tflitefile_tool/ir')
-rw-r--r--tools/tflitefile_tool/ir/README.md5
-rw-r--r--tools/tflitefile_tool/ir/__init__.py0
-rwxr-xr-xtools/tflitefile_tool/ir/graph_stats.py59
-rw-r--r--tools/tflitefile_tool/ir/operator.py108
-rw-r--r--tools/tflitefile_tool/ir/subgraph.py170
-rw-r--r--tools/tflitefile_tool/ir/tensor.py120
6 files changed, 462 insertions, 0 deletions
diff --git a/tools/tflitefile_tool/ir/README.md b/tools/tflitefile_tool/ir/README.md
new file mode 100644
index 000000000..2625dfb91
--- /dev/null
+++ b/tools/tflitefile_tool/ir/README.md
@@ -0,0 +1,5 @@
+# IR
+
+A model has a subgraph or subgraphs. A subgraph has operators and tensors.
+
+Parser will use these IRs as data.
diff --git a/tools/tflitefile_tool/ir/__init__.py b/tools/tflitefile_tool/ir/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tools/tflitefile_tool/ir/__init__.py
diff --git a/tools/tflitefile_tool/ir/graph_stats.py b/tools/tflitefile_tool/ir/graph_stats.py
new file mode 100755
index 000000000..5aebdbeaa
--- /dev/null
+++ b/tools/tflitefile_tool/ir/graph_stats.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+# Copyright (c) 2020 Samsung Electronics Co., Ltd. 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.
+
+
+class GraphStats():
+ def __init__(self):
+ from collections import Counter
+ from collections import defaultdict
+ self.op_counts = Counter()
+ self.filled_memory = 0
+ self.total_memory = 0
+
+ def accumulate_op_count(self, op_str, count):
+ self.op_counts[op_str] += count
+
+ def accumulate_filled_memory(self, size):
+ self.filled_memory += size
+
+ def accumulate_total_memory(self, size):
+ self.total_memory += size
+
+ def __iadd__(self, other):
+ self.op_counts += other.op_counts
+ self.filled_memory += other.filled_memory
+ self.total_memory += other.total_memory
+ return self
+
+
+def CalcGraphStats(subg):
+ stats = GraphStats()
+
+ for type_str, oper_list in subg.optypes_map.items():
+ # number of occurrence of this operator type
+ occur = len(oper_list)
+ stats.accumulate_op_count(type_str, occur)
+
+ total_memory = 0
+ filled_memory = 0 # only memory for constant
+ for index, tensor in subg.tensors_map.items():
+ if tensor.buffer is not None:
+ filled_memory += tensor.memory_size
+ total_memory += tensor.memory_size
+ stats.accumulate_filled_memory(filled_memory)
+ stats.accumulate_total_memory(total_memory)
+
+ return stats
diff --git a/tools/tflitefile_tool/ir/operator.py b/tools/tflitefile_tool/ir/operator.py
new file mode 100644
index 000000000..0601e6119
--- /dev/null
+++ b/tools/tflitefile_tool/ir/operator.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+# Copyright (c) 2021 Samsung Electronics Co., Ltd. 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.
+"""
+NOTE
+- This class expresses a wrapping class for a native class.
+- Just use this class as an interface.
+"""
+
+
+class Operator(object):
+ def __init__(self):
+ self._index = -1
+ self._inputs = []
+ self._outputs = []
+ self._op_name = ""
+ self._actviation = ""
+ self._options = ""
+
+ '''index'''
+
+ @property
+ def index(self):
+ '''operator's int type index'''
+ return self._index
+
+ @index.setter
+ def index(self, value):
+ if not isinstance(value, int):
+ raise TypeError("must be set to an integer")
+ self._index = value
+
+ '''inputs'''
+
+ @property
+ def inputs(self):
+ '''Operators's input tensors as a list which consists of Tensors'''
+ return self._inputs
+
+ @inputs.setter
+ def inputs(self, value):
+ if not isinstance(value, list):
+ raise TypeError("must be set to a list")
+ self._inputs = value
+
+ '''outputs'''
+
+ @property
+ def outputs(self):
+ '''Operators's output tensors as a list which consists of Tensors'''
+ return self._outputs
+
+ @outputs.setter
+ def outputs(self, value):
+ if not isinstance(value, list):
+ raise TypeError("must be set to a list")
+ self._outputs = value
+
+ '''op_name'''
+
+ @property
+ def op_name(self):
+ '''Operator's name str'''
+ return self._op_name
+
+ @op_name.setter
+ def op_name(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._op_name = value
+
+ '''actviation'''
+
+ @property
+ def actviation(self):
+ '''Operator's actviation str'''
+ return self._actviation
+
+ @actviation.setter
+ def actviation(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._actviation = value
+
+ '''options'''
+
+ @property
+ def options(self):
+ '''Operator's options str'''
+ return self._options
+
+ @options.setter
+ def options(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._options = value
diff --git a/tools/tflitefile_tool/ir/subgraph.py b/tools/tflitefile_tool/ir/subgraph.py
new file mode 100644
index 000000000..e68713480
--- /dev/null
+++ b/tools/tflitefile_tool/ir/subgraph.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+
+# Copyright (c) 2021 Samsung Electronics Co., Ltd. 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.
+
+from collections.abc import MutableMapping
+'''optype -> Operator Index List'''
+
+
+class OpTypesMap(MutableMapping):
+ def __init__(self, *args, **kwargs):
+ self.store = dict()
+ self.update(dict(*args, **kwargs))
+
+ def __getitem__(self, key):
+ return self.store[self._keytransform(key)]
+
+ def __setitem__(self, key, value):
+ k = self._keytransform(key)
+ if not k in self.store.keys():
+ self.store[k] = []
+ self.store[k].append(value)
+
+ def __delitem__(self, key):
+ del self.store[self._keytransform(key)]
+
+ def __iter__(self):
+ return iter(self.store)
+
+ def __len__(self):
+ return len(self.store)
+
+ def _keytransform(self, key):
+ if not isinstance(key, str):
+ raise TypeError("must be set to a str")
+ return key
+
+
+"""
+NOTE
+- This class expresses a wrapping class for a native class.
+- Just use this class as an interface.
+"""
+
+
+class Subgraph(object):
+ def __init__(self):
+ self._index = -1
+ self._inputs = []
+ self._outputs = []
+ self._subg_name = ""
+ self._model_name = ""
+ self._tensors_map = {}
+ self._operators_map = {}
+ self._optypes_map = OpTypesMap()
+
+ '''index'''
+
+ @property
+ def index(self):
+ '''Subgraph's int type index'''
+ return self._index
+
+ @index.setter
+ def index(self, value):
+ if not isinstance(value, int):
+ raise TypeError("must be set to an integer")
+ self._index = value
+
+ '''inputs'''
+
+ @property
+ def inputs(self):
+ '''Subgraph's input tensors as a list which consists of Tensors'''
+ return self._inputs
+
+ @inputs.setter
+ def inputs(self, value):
+ if not isinstance(value, list):
+ raise TypeError("must be set to a list")
+ self._inputs = value
+
+ '''outputs'''
+
+ @property
+ def outputs(self):
+ '''Subgraph's output tensors as a list which consists of Tensors'''
+ return self._outputs
+
+ @outputs.setter
+ def outputs(self, value):
+ if not isinstance(value, list):
+ raise TypeError("must be set to a list")
+ self._outputs = value
+
+ '''subg_name'''
+
+ @property
+ def subg_name(self):
+ '''Subgraph's name str'''
+ return self._subg_name
+
+ @subg_name.setter
+ def subg_name(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._subg_name = value
+
+ '''model_name'''
+
+ @property
+ def model_name(self):
+ '''Model name str'''
+ return self._model_name
+
+ @model_name.setter
+ def model_name(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._model_name = value
+
+ '''tensors_map'''
+
+ @property
+ def tensors_map(self):
+ '''Subgraph's all tensors(key:index, value:Tensor)'''
+ return self._tensors_map
+
+ @tensors_map.setter
+ def tensors_map(self, value):
+ if not isinstance(value, dict):
+ raise TypeError("must be set to a dict")
+ self._tensors_map = value
+
+ '''operators_map'''
+
+ @property
+ def operators_map(self):
+ '''Subgraph's operators(key:index, value:Operator)'''
+ return self._operators_map
+
+ @operators_map.setter
+ def operators_map(self, value):
+ if not isinstance(value, dict):
+ raise TypeError("must be set to a dict")
+ self._operators_map = value
+
+ '''optypes_map'''
+
+ @property
+ def optypes_map(self):
+ '''Subgraph's operators per type(key:optype, value:[op_indice])'''
+ return self._optypes_map
+
+ @optypes_map.setter
+ def optypes_map(self, value):
+ if not isinstance(value, OpTypesMap):
+ raise TypeError("must be set to a OpTypesMap")
+ self._optypes_map = value
diff --git a/tools/tflitefile_tool/ir/tensor.py b/tools/tflitefile_tool/ir/tensor.py
new file mode 100644
index 000000000..f0f35a74b
--- /dev/null
+++ b/tools/tflitefile_tool/ir/tensor.py
@@ -0,0 +1,120 @@
+#!/usr/bin/python
+
+# Copyright (c) 2021 Samsung Electronics Co., Ltd. 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.
+"""
+NOTE
+- This class expresses a wrapping class for a native class.
+- Just use this class as an interface.
+"""
+
+
+class Tensor(object):
+ def __init__(self):
+ self._index = -1
+ self._tensor_name = ""
+ self._buffer = None
+ self._buffer_index = -1
+ self._type_name = ""
+ self._shape = []
+ self._memory_size = -1
+
+ '''index'''
+
+ @property
+ def index(self):
+ '''Tensor's int type index'''
+ return self._index
+
+ @index.setter
+ def index(self, value):
+ if not isinstance(value, int):
+ raise TypeError("must be set to an integer")
+ self._index = value
+
+ '''tensor_name'''
+
+ @property
+ def tensor_name(self):
+ '''Tensor's name str'''
+ return self._tensor_name
+
+ @tensor_name.setter
+ def tensor_name(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._tensor_name = value
+
+ '''buffer'''
+
+ @property
+ def buffer(self):
+ '''Tensor's buffer as a numpy instance type'''
+ return self._buffer
+
+ @buffer.setter
+ def buffer(self, value):
+ self._buffer = value
+
+ '''buffer_index'''
+
+ @property
+ def buffer_index(self):
+ '''Tensor's int type buffer index'''
+ return self._buffer_index
+
+ @buffer_index.setter
+ def buffer_index(self, value):
+ if not isinstance(value, int):
+ raise TypeError("must be set to an integer")
+ self._buffer_index = value
+
+ '''type_name'''
+
+ @property
+ def type_name(self):
+ '''Tensor's type name str'''
+ return self._type_name
+
+ @type_name.setter
+ def type_name(self, value):
+ if not isinstance(value, str):
+ raise TypeError("must be set to a str")
+ self._type_name = value
+
+ '''shape'''
+
+ @property
+ def shape(self):
+ '''Tensor's shape as a list'''
+ return self._shape
+
+ @shape.setter
+ def shape(self, value):
+ if not isinstance(value, list):
+ raise TypeError("must be set to a list")
+ self._shape = value
+
+ '''memory_size'''
+
+ @property
+ def memory_size(self):
+ '''Tensor's memory size as int type'''
+ return self._memory_size
+
+ @memory_size.setter
+ def memory_size(self, value):
+ if not isinstance(value, int):
+ raise TypeError("must be set to an integer")
+ self._memory_size = value