diff options
Diffstat (limited to 'tools/tflitefile_tool/ir')
-rw-r--r-- | tools/tflitefile_tool/ir/README.md | 5 | ||||
-rw-r--r-- | tools/tflitefile_tool/ir/__init__.py | 0 | ||||
-rwxr-xr-x | tools/tflitefile_tool/ir/graph_stats.py | 59 | ||||
-rw-r--r-- | tools/tflitefile_tool/ir/operator.py | 108 | ||||
-rw-r--r-- | tools/tflitefile_tool/ir/subgraph.py | 170 | ||||
-rw-r--r-- | tools/tflitefile_tool/ir/tensor.py | 120 |
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 |