Skip to content

Commit e2aa464

Browse files
committed
Merge branch 're-arch-support' into tutorials
2 parents 199247b + dfd1a39 commit e2aa464

File tree

6 files changed

+51
-42
lines changed

6 files changed

+51
-42
lines changed

utensor_cgen/backend/transformer.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ def __init__(self, config):
2222
def transform(self, ugraph):
2323
logger.info("Transforming graph: %s", ugraph.name)
2424
logger.info("Transform pipeline: %s", ' -> '.join(self.trans_methods))
25-
self._check_non_quantized(ugraph)
25+
if not self._check_generic(ugraph):
26+
raise ValueError(
27+
'the given graph is not generic:\n{}'.format(ugraph)
28+
)
2629
new_ugraph = self.transformer.transform(ugraph)
2730
new_ugraph.name = ugraph.name
2831
logger.info('Graph transormation done')
@@ -35,26 +38,9 @@ def transform(self, ugraph):
3538
return new_ugraph
3639

3740
@classmethod
38-
def _check_non_quantized(cls, ugraph):
39-
is_quantized = False
40-
quant_ops = set([
41-
"Dequantize", "QuantizedMaxPool",
42-
"QuantizeV2", "QuantizedMatMul",
43-
"QuantizedRelu", "QuantizedAdd",
44-
"RequantizationRange",
45-
"Requantize",
46-
"QuantizedReshape",
47-
"QuantizedConv2D"
48-
])
49-
for op_info in ugraph.ops_info.values():
50-
if op_info.op_type in quant_ops:
51-
is_quantized = True
52-
break
53-
if is_quantized:
54-
logger.warning((
55-
"Expecting non-quantized graph, "
56-
"graph transformation/optimization might not work properly"
57-
))
41+
def _check_generic(cls, ugraph):
42+
# TODO: do the real check once we have full list of generic ops
43+
return True
5844

5945
@class_property
6046
def default_config(cls):

utensor_cgen/backend/utensor/_graph_lower/_op_lower.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ def apply(cls, ugraph):
5656
op_info.op_type = 'QuantizedDepthwiseSeparableConvOperator'
5757
for op_info in ugraph.get_ops_by_type('FullyConnectedOperator'):
5858
op_info.op_type = 'QuantizedFullyConnectedOperator'
59+
for op_info in ugraph.get_ops_by_type('DequantizeOperator'):
60+
op_info.code_gen_attributes['namespaces'] = ('TFLM',)
61+
for op_info in ugraph.get_ops_by_type('QuantizeOperator'):
62+
op_info.code_gen_attributes['namespaces'] = ('TFLM',)
5963

6064
@classmethod
6165
def _check_quantized(cls, ugraph):

utensor_cgen/backend/utensor/code_generator/rearch/_code_generator.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import re
2+
from collections import defaultdict
23
from itertools import chain
34
from pathlib import Path
4-
from collections import defaultdict
55

66
from utensor_cgen.backend.base import BackendPart
7+
from utensor_cgen.backend.graph_lower.generic_graph_lower import \
8+
TopoOrderTensorTimeslotPlanner
79
from utensor_cgen.backend.utensor.snippets.composer import Composer
810
from utensor_cgen.backend.utensor.snippets.legacy import (
911
ContextGlobalArrayContainer, WeightSnippet)
1012
from utensor_cgen.backend.utensor.snippets.rearch import (
11-
DeclareRamTensorSnippet, DeclareRomTensorSnippet,
12-
FreeTensorSnippet, SimpleContainer, TimeSlotContainer
13-
)
13+
DeclareRamTensorSnippet, DeclareRomTensorSnippet, FreeTensorSnippet,
14+
SimpleContainer, TimeSlotContainer)
1415
from utensor_cgen.backend.utensor.snippets.template_env import env
15-
from utensor_cgen.backend.graph_lower.generic_graph_lower import TopoOrderTensorTimeslotPlanner
1616
from utensor_cgen.logger import logger
1717
from utensor_cgen.utils import Configuration, class_property
1818

@@ -183,8 +183,10 @@ def _time_slot_generate_files(
183183
):
184184
template_vars = {}
185185
template_vars['model_name'] = ugraph.name
186-
template_vars['meta_data_pool_size'] = self._compute_meta_data_size(ugraph)
187-
template_vars['ram_data_pool_size'] = self._compute_ram_data_size(ugraph)
186+
(template_vars['meta_data_pool_size'],
187+
template_vars['meta_dtype']) = self._compute_meta_data_size(ugraph)
188+
(template_vars['ram_data_pool_size'],
189+
template_vars['ram_dtype']) = self._compute_ram_data_size(ugraph)
188190
template_vars['placeholders'] = placeholders
189191
template_vars['out_tensor_var_names'] = [
190192
tensor_var_map[tensor.name] for tensor in chain(*[
@@ -349,16 +351,23 @@ def default_config(cls):
349351
return config
350352

351353
def _compute_meta_data_size(self, ugraph):
352-
# TODO: if mem_optimizer is None, use a default mem optimizer
353354
if self.meta_data_pool_size == 'auto':
354-
# TODO: compute actual meta data size with ugraph
355-
size = 2048
355+
# NOTE: simple heuristic, num of tensors * 64, maybe more or less depending on target platform
356+
# NOTE: assuming user is using localCircularArenaAllocator
357+
# TODO: target aware estimation
358+
tensors = set()
359+
for op_info in ugraph.ops_info.values():
360+
tensors.update(op_info.input_tensors)
361+
tensors.update(op_info.output_tensors)
362+
size = len(tensors) * 64
356363
else:
357364
size = self.meta_data_pool_size
358-
return size
365+
dtype_str = self._get_mem_pool_dtype_str(size)
366+
return size, dtype_str
359367

360368
def _compute_ram_data_size(self, ugraph):
361-
# TODO: if mem_optimizer is None, use a default mem optimizer
369+
# TODO: if tensor alloc plan is None, use a default mem estimator
370+
# NOTE: assuming user is using localCircularArenaAllocator
362371
if self.ram_data_pool_size == 'auto':
363372
# TODO: compute actual ram data size with ugraph
364373
if '_tensor_alloc' in ugraph.attributes:
@@ -367,4 +376,12 @@ def _compute_ram_data_size(self, ugraph):
367376
size = 256
368377
else:
369378
size = self.ram_data_pool_size
370-
return size
379+
dtype_str = self._get_mem_pool_dtype_str(size)
380+
return size, dtype_str
381+
382+
@staticmethod
383+
def _get_mem_pool_dtype_str(size):
384+
# NOTE: assuming user is using localCircularArenaAllocator
385+
if size > 2**15:
386+
return 'uint32_t'
387+
return 'uint16_t'

utensor_cgen/backend/utensor/code_generator/rearch/_operators/_impls.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ def get_eval_snippet(self, op_var_name, op_info, tensor_var_map):
123123
@OperatorFactory.register
124124
class _QuantizeOperator(_Operator):
125125
op_type = "QuantizeOperator"
126+
namespaces = ('TFLM',)
126127

127128
def get_declare_snippet(self, op_var_name, tensor_var_map):
128129
return DeclareOpSnippet(
129130
op=self,
130131
templ_dtypes=[self.out_dtypes[0], self.in_dtypes[0]],
131132
op_var_name=op_var_name,
132-
nested_namespaces=['TFLM'],
133+
nested_namespaces=self.namespaces,
133134
)
134135

135136
def get_eval_snippet(self, op_var_name, op_info, tensor_var_map):
@@ -138,20 +139,21 @@ def get_eval_snippet(self, op_var_name, op_info, tensor_var_map):
138139
templ_dtypes=[self.out_dtypes[0], self.in_dtypes[0]],
139140
op_name=op_var_name,
140141
tensor_var_map=tensor_var_map,
141-
nested_namespaces=['TFLM'],
142+
nested_namespaces=self.namespaces,
142143
)
143144

144145

145146
@OperatorFactory.register
146147
class _DequantizeOperator(_Operator):
147148
op_type = "DequantizeOperator"
149+
namespaces = ('TFLM',)
148150

149151
def get_declare_snippet(self, op_var_name, tensor_var_map):
150152
return DeclareOpSnippet(
151153
op=self,
152154
templ_dtypes=[self.out_dtypes[0], self.in_dtypes[0]],
153155
op_var_name=op_var_name,
154-
nested_namespaces=['TFLM'],
156+
nested_namespaces=self.namespaces,
155157
)
156158

157159
def get_eval_snippet(self, op_var_name, op_info, tensor_var_map):
@@ -160,7 +162,7 @@ def get_eval_snippet(self, op_var_name, op_info, tensor_var_map):
160162
templ_dtypes=[self.out_dtypes[0], self.in_dtypes[0]],
161163
op_name=op_var_name,
162164
tensor_var_map=tensor_var_map,
163-
nested_namespaces=['TFLM'],
165+
nested_namespaces=self.namespaces,
164166
)
165167

166168

utensor_cgen/backend/utensor/snippets/templates/snippets/rearch/simple.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
#include "uTensor/core/tensor.hpp"
55

6-
// estimated ram usage: {{ram_data_pool_size}} bytes
7-
// estimated meta data uage: {{meta_data_pool_size}} bytes
6+
constexpr {{ram_dtype}} estimated_ram_usage = {{ram_data_pool_size}};
7+
constexpr {{meta_dtype}} estimated_meta_usage = {{meta_data_pool_size}};
88

99
void compute_{{model_name}}({%for pl in placeholders%}uTensor::Tensor& {{pl}}, {%endfor%}{%for out_tensor in out_tensor_var_names%}uTensor::Tensor& {{out_tensor}}{%if not loop.last%}, {%endif%}{%endfor%});
1010

utensor_cgen/cli/backend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ def list_trans_methods(verbose):
4343

4444
@cli.command(name='list-support-ops', help='list all supported op in the backend')
4545
@click.help_option('-h', '--help')
46-
@click.option('--target', default='utensor')
47-
@click.option('--config', default='utensor_cli.toml')
46+
@click.option('--target', default='utensor', show_default=True)
47+
@click.option('--config', default='utensor_cli.toml', show_default=True)
4848
def list_support_ops(target, config):
4949
from utensor_cgen.backend.api import BackendManager
5050
if os.path.exists(config):

0 commit comments

Comments
 (0)