test_generator.py revision 3ed926a99e4057d573807e5fc4eb8acc6295f635
1dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung#!/usr/bin/python3
2dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
3dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Copyright 2017, The Android Open Source Project
4dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung#
5dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Licensed under the Apache License, Version 2.0 (the "License");
6dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# you may not use this file except in compliance with the License.
7dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# You may obtain a copy of the License at
8dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung#
9dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# http://www.apache.org/licenses/LICENSE-2.0
10dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung#
11dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Unless required by applicable law or agreed to in writing, software
12dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# distributed under the License is distributed on an "AS IS" BASIS,
13dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# See the License for the specific language governing permissions and
15dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# limitations under the License.
16dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
17dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung"""NN model compiler
18dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
19dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) SungCompile models and examples into NDK-based unit tests
20dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung"""
21dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
22dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungfrom __future__ import absolute_import
23dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungfrom __future__ import division
24dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungfrom __future__ import print_function
25dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungimport argparse
264c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungfrom functools import reduce
273ed926a99e4057d573807e5fc4eb8acc6295f635Dong Chenimport math
28dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungimport os
294c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungimport struct
30dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungimport sys
31dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungimport contextlib
32dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
33dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung@contextlib.contextmanager
34dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungdef smart_open(filename=None):
35dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  if filename and filename != '-':
36dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    fh = open(filename, 'w')
37dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  else:
38dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    fh = sys.stdout
39dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
40dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  try:
41dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    yield fh
42dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  finally:
43dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if fh is not sys.stdout:
44dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      fh.close()
45dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
46dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Phase(object):
47dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self):
484c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    self.__objects = []
49dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__contents = []
506a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    self.__dict_of_objects = {}
51dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
524c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def append(self, obj, x):
534c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    self.__objects.append(obj)
54dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__contents.append(x)
556a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    self.__dict_of_objects[obj.ID()] = obj
56dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
57dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def dump(self, filename):
58dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for x in self.__contents:
59dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      print ("  " + x + ";", file=filename)
60dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
614c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def objects(self):
624c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return self.__objects
634c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
646a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  def search(self, i):
656a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    return self.__dict_of_objects[i]
666a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
67dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Tracking objects inside a model with a not necessarily unique name and
68dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# an unique number
69dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass NamedObject(object):
70dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __serial = 0
71dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
72dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name = "NamedObject"):
73dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__name = name
74dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__id = NamedObject.serial()
75dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    NamedObject.__serial += 1
76dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
77dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def ID(self):
78dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__id
79dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
80dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def serial():
81dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return NamedObject.__serial
82dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
83dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_name(self):
84dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__name
85dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
86dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __str__(self):
87dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.get_name()
88dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
89dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __hash__(self):
90dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__id
91dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
92dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Object that can be traversed during topological sorting phase
93dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Traversable(object):
94dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def traversable(self):
95dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return True
96dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
97dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Nontraversable(object):
98dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def traversable(self):
99dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return False
100dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
101dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Object that can take input from other objects
102dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Uses(object):
103dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  all_uses = set()
104dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, ins = []):
105dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.ins = ins.copy()
106dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Uses.all_uses.add(self)
107dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for i in ins:
108dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      i.outs.add(self)
109dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
110dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Object that other objects takes its definition from
111dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Definitions(object):
112dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, outs = []):
113dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.outs = set(outs)
114dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for o in outs:
115dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      o.ins.append(self)
116dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
1174c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungclass TypeLookup:
1184c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  __type_lookup = {
1194c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "INT32": "int32_t",
1204c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "FLOAT32": "float",
1214c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "TENSOR_INT32": "int32_t",
1224c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "TENSOR_FLOAT32": "float",
1234c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "TENSOR_QUANT8_ASYMM": "uint8_t",
1244c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }
1254c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
1264c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def get_cpptype(nnapi_type):
1274c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return TypeLookup.__type_lookup[nnapi_type]
1284c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
1294c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def is_float(nnapi_type):
1304c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return TypeLookup.get_cpptype(nnapi_type) == "float"
1314c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
1324c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def get_size(nnapi_type):
1334c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return 1 if TypeLookup.get_cpptype(nnapi_type) == "uint8_t" else 4
1344c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
1354c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
136dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Type(object):
137dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __types =  {}
138dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __type_serial = 0 # types have their own numbering
139dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, vt = None, shape = None):
140dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__vt = vt
141dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__shape = shape
142dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if vt is None or shape is None:
143dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      self.__name = None
144dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      return
145dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
146dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    key = str(self)
147dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if key not in Type.__types:
148dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      self.__id = Type.__type_serial
149dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      Type.__types[str(self)] = self
150dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      Type.__type_serial += 1
151dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    else:
152dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      self.__id = Type.__types[key].__id
153dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__name = "type" + str(self.__id)
154dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
1554c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def get_shape(self):
1564c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return self.__shape
1574c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
158ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung  def get_element_type(self):
159ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung    return self.__vt
160ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung
161dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_name(self):
162dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__name
163dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
164dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __str__(self):
165dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return (", ".join([self.__vt, self.__shape]))
166dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
167dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __hash__(self):
168dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__id
169dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
170dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def dump(filename):
171dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for key, value in sorted(Type.__types.items()):
172dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      print ("  OperandType " + str(value.__name) + "(Type::" + str(key) + ");", file=filename)
173dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
174420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  def get_parsed_shape(self):
1754c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    # Parse shape
1764c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    if (self.__shape != "" and self.__shape != "{}"):
1774c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      left, sep, right = self.__shape.partition('{')
1784c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      real_shape, sep, right = right.partition('}')
1794c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      shape = [int(x) for x in real_shape.split(",")]
180420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung      # left now looks like "0.0f, 127.5f, "
1819fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang      scale, sep, zero_point = right.rpartition(',')
1829fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang      if scale == "":
1839fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang        if zero_point == "":
1849fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang          return real_shape, "0", "0"
1859fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang        return real_shape, zero_point, "0"
1869fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang      left, sep, scale = scale.partition(',')
1879fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang      return real_shape, scale.replace("f", ""), zero_point
188420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    else:
1899fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang      return "", "0", "0"
190420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung
191420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  def get_size(self):
192420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    element_size = TypeLookup.get_size(self.__vt)
193420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    # Parse shape
194420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    nr_elements = 1
1959fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang    real_shape, scale, zero_point = self.get_parsed_shape()
196420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung
197420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    if (real_shape != "" and real_shape != "{}"):
198420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung      shape = [int(x) for x in real_shape.split(",")]
1994c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      nr_elements = reduce((lambda x, y: x*y), shape)
2004c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return element_size * nr_elements
201dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
202dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# A value is a typed, named object
203dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Value(NamedObject):
204dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt):
205dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    NamedObject.__init__(self, name)
206dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.type = vt
207dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
208dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# An operand that can be fed into operations. Also, an operand is always
209dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# declared before operations.
210dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Operand(Value):
211dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # All operand declarations in string
212dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  operands = Phase()
213dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
214dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt):
215dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Value.__init__(self, name, vt)
216dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    def_string = (
217dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung        "auto " + self.get_name() + " = "\
218dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung            "model->addOperand(&" + vt.get_name() + ")")
2194c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    Operand.operands.append(self, def_string)
220dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
221dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # By default, produce nothing (when asked by the Topological Sort phase)
222dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Definition(self):
223dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    pass
224dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
225dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Reference(self):
226dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return NamedObject.__str__(self)
227dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
228dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # Print a set of operands in curly braces
229dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def print_operands(operands):
230dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return [ x.Reference() for x in operands ]
231dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
2324c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  # Defined with the model or not
2334c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def is_weight(self):
2344c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return False
2354c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
236dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# A user-declared input operand
237dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Input(Operand, Definitions, Traversable):
238cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung  # for enumerating inputs
239cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung  __next_number = 0
240dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # Holds reference to all Inputs; used by Topoligcal sort as starting nodes.
241dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __inputs = set()
242dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
243dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt, shape):
244dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Operand.__init__(self, name, Type(vt, shape))
245dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Definitions.__init__(self)
246dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Input.__inputs.add(self)
247cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung    self.number = Input.__next_number
248cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung    Input.__next_number += 1
249dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
250a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
251a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "MODEL_INPUT"
252a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet
253dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def is_internal(self):
254dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return False
255dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
256dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_inputs(exclude_internal = None):
257dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if exclude_internal is not None:
258dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      external = { x for x in Input.__inputs if not x.is_internal() }
259dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      return external
260dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    else:
261dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      return Input.__inputs
262dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
263dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# A user-declared output operand
264dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Output(Operand, Uses, Nontraversable):
265cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung  # for enumerating outputs
266cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung  __next_number = 0
267dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __outputs = set()
268dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
269dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt, shape):
270dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Operand.__init__(self, name, Type(vt, shape))
271dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Uses.__init__(self)
272dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Output.__outputs.add(self)
273cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung    self.number = Output.__next_number
274cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung    Output.__next_number += 1
275dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
276a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
277a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "MODEL_OUTPUT"
278a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet
279dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_outputs():
280dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return Output.__outputs
281dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
282ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung# An output that we don't want to compare the results
283ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sungclass IgnoredOutput(Output):
284ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung  __ignored = set()
285ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung  def __init__(self, name, vt, shape):
286ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung    Output.__init__(self, name, vt, shape)
287ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung    IgnoredOutput.__ignored.add(self)
288ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung  def gen_ignored():
289ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung    ignored_func = """
290ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sungbool is_ignored(int i) {
291ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung  static std::set<int> ignore = {%s};
292ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung  return ignore.find(i) != ignore.end();
293ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung}""" % ", ".join([str(x.number) for x in IgnoredOutput.__ignored])
294ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung    return ignored_func
295ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung
296dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass ModelArgument:
297dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __arguments = []
298dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
299dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, arg_type, arg_name):
300dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__arg_type = arg_type
301dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__arg_name = arg_name
302dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ModelArgument.__arguments.append(" ".join([arg_type, arg_name]))
303dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
304dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_arg_type(self):
305dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__arg_type
306dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
307dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_arg_name(self):
308dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self.__arg_name
309dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
310dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def get_arguments():
311dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return ModelArgument.__arguments
312dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
313a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
314a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "CONSTANT_COPY"
315ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung
316ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sungclass Parameter(Input):
317a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  # TODO seems wrong that's an Input.
318dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt, shape, initializer):
319dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Input.__init__(self, name, vt, shape)
320dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.initializer = initializer
321ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung    self.cpptype = TypeLookup.get_cpptype(vt)
322dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def is_internal(self):
323dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return True
324dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Definition(self):
325dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    init_name = self.get_name() + "_init"
326dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    initializer = [str(x) for x in self.initializer]
327dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if self.cpptype == "float":
328dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      initializer = [ x+"f" for x in initializer]
329dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    init = self.cpptype + " " + init_name + "[]"
330dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    init = "static " + init + " = {" + ", ".join(initializer) + "};"
331dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    args = [ self.get_name(), init_name,
332dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung            "sizeof(" + self.cpptype + ") * " + str(len(self.initializer)) ]
333dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    stmt = "\n  ".join([init,
334dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung                      "model->setOperandValue(" + ", ".join(args)+");"])
335dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return stmt
3364c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def is_weight(self):
3374c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return True
338a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
339a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "CONSTANT_COPY"
340dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
341cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sungclass Int32Scalar(Parameter):
342dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, value):
3434c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    Parameter.__init__(self, name, "INT32", "{}", [value])
344dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
345cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sungclass Float32Scalar(Parameter):
346dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, value):
3474c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    Parameter.__init__(self, name, "FLOAT32", "{}", [value])
348dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
349dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# A compiler-generated intermediate result from an operation
350dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass IntermediateResult(Operand, Definitions, Uses, Traversable):
351dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, src: Value):
352dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    tmp_name = "tmp" + str(NamedObject.serial())
353dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Operand.__init__(self, tmp_name, src.type)
354dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Definitions.__init__(self)
355dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Uses.__init__(self, [src])
356dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
357a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
358a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "TEMPORARY_VARIABLE"
359a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet
360dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# An explicitly declared intermediate result
361dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Internal(Operand, Definitions, Uses, Traversable):
362dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, name, vt, shape):
363dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Operand.__init__(self, name, Type(vt, shape))
364dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Definitions.__init__(self)
365dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Uses.__init__(self)
366dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
367a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet  def lifetime(self):
368a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    return "TEMPORARY_VARIABLE"
369a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet
370dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# An operation in a model
3714c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungclass Operation(Definitions, Uses, Traversable):
372dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, optype, ins, outs):
3734c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    self.type = ins[0].type
374dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Definitions.__init__(self, outs)
375dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Uses.__init__(self, ins)
376dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.optype = optype
377dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
378dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __str__(self):
379dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    inputs = [ str(x) for x in self.ins ]
380dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return "Operation:" + self.optype + " " + ", ".join(inputs)
381dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
382dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Reference(self):
383dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return "operation" + str(self.ID());
384dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
385dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Definition(self):
386dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    inputs = Operand.print_operands(self.ins);
387dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outputs = Operand.print_operands(self.outs);
388dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return "model->addOperation(ANEURALNETWORKS_"+self.optype+", " + \
389dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung        "{"+", ".join(inputs)+"}, {" + ", ".join(outputs) + "});"
390dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
391dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Main interface
392dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Model(object):
393dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self):
394dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = None
395dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
396dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # TODO turn this into generic binary operations
397dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Add(self, i1: Value, i2 = None) -> Operation:
398dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [i1]
399dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if i2 is not None:
400dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      ins.append(i2)
401dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if self.__currentOp is not None:
402dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      ir = IntermediateResult(self.__currentOp)
403dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      self.__currentOp = ir
404dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      ins.append(self.__currentOp)
405dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
406dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("ADD", ins, [])
407dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
408dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
409dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
410dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
411dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Operation(self, op_name, *args):
412dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [i for i in args]
413dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
414dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation(op_name, ins, outs)
415dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
416dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
417dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
418dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def RawAdd(self, i1: Value, i2: Value, o = None) -> Operation:
419dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [i1, i2]
420dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
421dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if o is not None:
422dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      outs = [o]
423dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("ADD", ins, outs)
424dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
425dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
426dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
427dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
428dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # See CpuExecutor::executeOperation() for the arguments of each op
429dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def AveragePool(self, input, padding, stride_width, stride_height, filter_width, filter_height, activation):
430dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input, padding, stride_width,
431dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung           stride_height, filter_width, filter_height, activation]
432dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
43355cef2193279a646292fdeb355399627dd8990c8Miao Wang    op = Operation("AVERAGE_POOL_2D", ins, outs)
434dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
435dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
436dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
437dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Concatenation(self, *args):
438dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [i for i in args]
439dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
440dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("CONCATENATION", ins, outs)
441dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
442dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
443dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
444dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Conv(self, filter, bias, input, padding, stride_width, stride_height, activation):
445dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [filter, bias, input, padding, stride_width,
446dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung           stride_height, activation]
447dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
44855cef2193279a646292fdeb355399627dd8990c8Miao Wang    op = Operation("CONV_2D", ins, outs)
449dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
450dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
451dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
452dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def DepthWiseConv(self, filter, bias, input, padding, stride_width, stride_height, depth_multiplier, activation):
453dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [filter, bias, input, padding, stride_width,
454dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung           stride_height, depth_multiplier, activation]
455dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
45655cef2193279a646292fdeb355399627dd8990c8Miao Wang    op = Operation("DEPTHWISE_CONV_2D", ins, outs)
457dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
458dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
459dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
460dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def FullyConnected(self, input, weights, bias, activation):
461dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input, weights, bias, activation]
462dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
463dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("FULLY_CONNECTED", ins, outs)
464dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
465dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
466dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
467dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def Logistic(self, input):
468dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input]
469dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
470dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("LOGISTIC", ins, outs)
471dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
472dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
473dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
474dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def L2Pool(self, input, padding, stride_width, stride_height, filter_width, filter_height, activation):
475dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input, padding, stride_width,
476dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung           stride_height, filter_width, filter_height, activation]
477dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
47855cef2193279a646292fdeb355399627dd8990c8Miao Wang    op = Operation("L2_POOL_2D", ins, outs)
479dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
480dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
481dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
482dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def MaxPool(self, input, padding, stride_width, stride_height, filter_width, filter_height, activation):
483dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input, padding, stride_width,
484dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung           stride_height, filter_width, filter_height, activation]
485dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
48655cef2193279a646292fdeb355399627dd8990c8Miao Wang    op = Operation("MAX_POOL_2D", ins, outs)
487dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
488dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
489dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
490dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def SoftMax(self, input, beta):
491dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ins = [input, beta]
492dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    outs = []
493dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    op = Operation("SOFTMAX", ins, outs)
494dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = op
495dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
496dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
497b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang  def Reshape(self, input, shape):
498b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang    ins = [input, shape]
499b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang    outs = []
500b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang    op = Operation("RESHAPE", ins, outs)
501b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang    self.__currentOp = op
502b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang    return self
503b3ea13a8e7b607d78cceae07a000df073e1520eaMiao Wang
5046a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  def Out(self, o):
5056a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    if (type(o) is list or type(o) is tuple):
5066a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      for i in o:
5076a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        self.__currentOp.outs.add(i)
5086a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        i.ins.append(self.__currentOp)
5096a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    else:
5106a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      self.__currentOp.outs.add(o)
5116a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      o.ins.append(self.__currentOp)
512dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
513dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
514dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def To(self, o:Value):
515dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ret = Model.Out(self, o)
516dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    self.__currentOp = None
517dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return self
518dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
519ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sungclass FileNames:
520ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung  SpecFile = ""
521ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung
522dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungclass Example():
523dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  __examples = []
524dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def __init__(self, list_of_examples):
525dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Example.__examples.append(list_of_examples)
526dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
527dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def dump_dict(d):
528dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    ret = []
529dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for k, v in d.items():
530cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung      key = str(k)
531ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung      suffix = "f"
532cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung      if type(k) is not int:
533cfe77f9ed8a14f97c7f18e4097492a2776a05d2aI-Jui (Ray) Sung        key = str(k.number)
534ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung        if not TypeLookup.is_float(k.type.get_element_type()):
535ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung          suffix = ""
5366a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      init = ", ".join(
5376a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung          [str(i) + (suffix if str(i).find(".") != -1 else "") for i in v])
5386a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      ret.append("{%s, {%s}}" % (key, init))
539dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    return ", ".join(ret)
540dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
5416a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  def dump_mixed_types(d):
5426a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    ret = []
5436a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
5446a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    float32_dict = {}
5456a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    int32_dict = {}
5466a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    uint8_dict = {}
5476a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
5486a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    for k, v in d.items():
5496a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      ty = Operand.operands.search(k.ID()).type.get_element_type()
5506a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      # find out type of the operand addressed by the key
5516a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      if (ty == "TENSOR_FLOAT32"):
5526a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        float32_dict[k] = v
5536a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      elif (ty == "TENSOR_INT32"):
5546a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        int32_dict[k] = v
5556a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      elif (ty == "TENSOR_QUANT8_ASYMM"):
5566a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        uint8_dict[k] = v
5576a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      else:
5586a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        print ("Unhandled type %s"%ty,  file = sys.stderr)
5596a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        assert 0 and "unsupported example type"
5606a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
5616a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    tuple_init = """\
5626a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung{{ // See tools/test_generator/include/TestHarness.h:MixedTyped
5636a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  // int -> FLOAT32 map
5646a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  {{{float32_dict}}},
5656a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  // int -> INT32 map
5666a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  {{{int32_dict}}},
5676a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  // int -> QUANT8_ASYMM map
5686a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung  {{{uint8_dict}}}
5696a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung}}"""
5706a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    tuple_contents = {
5716a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        'float32_dict': Example.dump_dict(float32_dict),
5726a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        'int32_dict': Example.dump_dict(int32_dict),
5736a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung        'uint8_dict': Example.dump_dict(uint8_dict)
5746a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    }
5756a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung    return tuple_init.format(**tuple_contents)
5766a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
5776a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung
578dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  def dump(example_file):
579dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    if len(Example.__examples) > 0:
580ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung      spec_file = " (from: %s)" % (FileNames.SpecFile)
581ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung      print ('// Generated file%s. Do not edit' % (spec_file),
582ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung             file = example_file)
583dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for i, o in Example.__examples:
584dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      print ('// Begin of an example', file = example_file)
585dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      print ('{', file = example_file)
5866a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      inputs = Example.dump_mixed_types(i)
5876a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      outputs = Example.dump_mixed_types(o)
5886a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      print ('//Input(s)\n%s,' % inputs , file = example_file)
5896a0d306cf902e13ab147c7533b2cb02540ee66d5I-Jui (Ray) Sung      print ('//Output(s)\n%s' % outputs, file = example_file)
590dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      print ('}, // End of an example', file = example_file)
591dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
5924c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef TopologicalSort(format_op):
593dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  start = Input.get_inputs().copy()
594dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  deps = { x: set(x.ins) for x in Uses.all_uses }
595dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
596dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  while len(start) > 0:
597dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    cur = start.pop()
5984c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    format_op(cur) #cur.Definition()
599dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    for o in cur.outs:
600dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      deps[o].remove(cur)
601dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung      if len(deps[o]) == 0 and o.traversable():
602dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung        start.add(o)
603dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
6044c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungclass Configuration:
6054c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  vts = False
606ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung
607dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung# Take a model from command line
608dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungdef import_source():
609dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  parser = argparse.ArgumentParser()
6104c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  parser.add_argument("spec", help="the spec file")
6114c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  parser.add_argument(
6124c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "-v",
6134c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "--vts",
6144c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      help="generate VTS model instead",
6154c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      default=False,
6164c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      action="store_true")
6174c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  parser.add_argument(
6184c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "-m", "--model", help="the output model file", default="-")
6194c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  parser.add_argument(
6204c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "-e", "--example", help="the output example file", default="-")
621dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  args = parser.parse_args()
622dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
6234c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  Configuration.vts = args.vts
6244c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
625dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  if os.path.exists(args.spec):
626ad36b7a0dd7468bbe6a0433a52cbf89561ff5538I-Jui (Ray) Sung    FileNames.SpecFile = os.path.basename(args.spec)
6274c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    exec (open(args.spec).read())
628dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
629dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  return (args.model, args.example)
630dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
631420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung
632420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung# Print in C float literal format
633420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sungdef pretty_print_as_float(x):
634420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  s = str(float(x))
635420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  if s.find(".") >= 0:
636420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    return s + "f"
637420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  else:
638420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    return s + ".0f"
639420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung
6404c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung# Generate operands in VTS format
6414c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef generate_vts_operands():
6424c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  # Dump operand definitions
6434c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  op_def = """\
6444c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        {{
6454c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung            .type = OperandType::{operand_type},
6464c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung            .dimensions = {shape},
6474c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung            .numberOfConsumers = {no_consumers},
6484c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung            .scale = {scale},
6494c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung            .zeroPoint = {zero_point},
650a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet            .lifetime = OperandLifeTime::{lifetime},
651420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung            .location = {{.poolIndex = 0, .offset = {offset}, .length = {length}}},
6524c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        }}"""
6534c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  offset = 0
6544c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  op_definitions = []
6554c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  for o in Operand.operands.objects():
6564c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    ty = o.type
6574c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    no_consumers = len(o.outs) if o.traversable() else 0
658a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet    lifetime = o.lifetime()
6594c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    length = ty.get_size() if o.is_weight() else 0
6609fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang    real_shape, scale, zero_point = ty.get_parsed_shape()
6619fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang    scale = float(scale)
6629fd99905f7dcb2cd4195d2670aded45fc49cc1cbMiao Wang    zero_point = int(zero_point)
6634c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    op = {
6644c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        "operand_type": ty.get_element_type(),
665420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        "shape": "{%s}" % real_shape,
6664c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        "no_consumers": no_consumers,
667420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        "scale": pretty_print_as_float(scale),
668420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        "zero_point": str(int(zero_point)),
669a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet        "lifetime": lifetime,
6704c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        "offset": offset if o.is_weight() else 0,
6714c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        "length": length
6724c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }
6734c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    offset += length
6744c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    op_definitions.append(op_def.format(**op))
6754c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
6764c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  op_vec = """\
6774c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    const std::vector<Operand> operands = {{
6784c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung{0}
6794c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }};""".format(",\n".join(op_definitions))
6804c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  return op_vec
6814c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
6824c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung# Generate VTS operand values
6834c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef generate_vts_operand_values():
6844c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  weights = [o for o in Operand.operands.objects() if o.is_weight()]
6854c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  binit = []
6864c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  for w in weights:
6874c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    ty = w.type.get_element_type()
6884c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    if ty == "TENSOR_QUANT8_ASYMM":
6894c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      binit += w.initializer
690b5f8d97277d5c30c4ae3efc884649703ec643f78I-Jui (Ray) Sung    elif ty in {"TENSOR_FLOAT32", "FLOAT32", "TENSOR_INT32", "INT32"}:
691b5f8d97277d5c30c4ae3efc884649703ec643f78I-Jui (Ray) Sung      fmt = "f" if (ty == "TENSOR_FLOAT32" or ty == "FLOAT32") else "i"
6924c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      for f in w.initializer:
6934c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        binit += [int(x) for x in struct.pack(fmt, f)]
6944c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    else:
6954c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      assert 0 and "Unsupported VTS operand type"
6964c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
6974c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  init_defs = ", ".join([str(x) for x in binit])
698420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung  if (init_defs != ""):
699420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    init_defs = "\n      %s\n    " % init_defs
7004c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  byte_vec_fmt = """\
701420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung    std::vector<uint8_t> operandValues = {%s};""" % init_defs
7024c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  return byte_vec_fmt
7034c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7044c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung# Generate VTS operations
7054c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungclass VTSOps(object):
7064c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  vts_ops = []
7074c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  def generate_vts_operation(op):
7084c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    try:
7094c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      opcode =op.optype
7104c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    except AttributeError: # not an op, but things like weights
7114c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      return
7124c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    op_fmt = """\
713420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        {{
7147d6ac906f000f3afe418e92c0a4ae36b2ea1143eJean-Luc Brouillet            .type = OperationType::{op_code},
715420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung            .inputs = {{{ins}}},
716420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung            .outputs = {{{outs}}},
717420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        }}"""
7184c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    op_content = {
7194c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        'op_code': op.optype,
720420cf7bdb689bc53b2a4e8c5f9eca42f7a06c1c0I-Jui (Ray) Sung        'op_type': op.type.get_element_type(),
7214c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        'ins': ", ".join([str(x.ID()) for x in op.ins]),
7224c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        'outs': ", ".join([str(x.ID()) for x in op.outs]),
7234c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }
7244c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    VTSOps.vts_ops.append(op_fmt.format(**op_content))
7254c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7264c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef generate_vts_operations(model_file):
7274c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  TopologicalSort(lambda x: VTSOps.generate_vts_operation(x))
7284c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  return ",\n".join(VTSOps.vts_ops)
7294c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7304c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef generate_vts_model(model_file):
7314c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  model_fmt = """\
7324c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung// Generated code. Do not edit
7334c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung// Create the model
7344c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) SungModel createTestModel() {{
7354c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung{operand_decls}
7364c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7374c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    const std::vector<Operation> operations = {{
7384c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung{operations}
7394c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }};
7404c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7414c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    const std::vector<uint32_t> inputIndexes = {{{input_indices}}};
7424c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    const std::vector<uint32_t> outputIndexes = {{{output_indices}}};
7434c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung{operand_values}
7444c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    const std::vector<hidl_memory> pools = {{}};
7454c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7464c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    return {{
7474c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .operands = operands,
7484c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .operations = operations,
7494c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .inputIndexes = inputIndexes,
7504c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .outputIndexes = outputIndexes,
7514c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .operandValues = operandValues,
7524c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung        .pools = pools,
7534c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    }};
7544c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung}}"""
7554c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  model = {
7564c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "operations": generate_vts_operations(sys.stdout),
7574c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "operand_decls": generate_vts_operands(),
7584c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "operand_values": generate_vts_operand_values(),
7594c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "output_indices": ", ".join([str(i.ID()) for i in Output.get_outputs()]),
7604c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "input_indices": ", ".join([str(i.ID()) for i in Input.get_inputs(True)])
7614c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  }
7624c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  print(model_fmt.format(**model), file = model_file)
7634c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7644c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef generate_vts(model_file):
7654c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  generate_vts_model(model_file)
766b6b3dc4cc7a45b61fcfa503f776f658148b5a2a4I-Jui (Ray) Sung  print (IgnoredOutput.gen_ignored(), file=model_file)
7674c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7684c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sungdef print_cts_op(model_file, op):
7694c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  fmt = op.Definition()
7704c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  if fmt is not None:
7714c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    print ("  %s" % fmt, file = model_file)
7724c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
773dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sungif __name__ == '__main__':
774dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  (model, example) = import_source()
775dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  # Boilerplate
776dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  args = ""
777dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  if len(ModelArgument.get_arguments()) > 0:
778dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    args = ", " + ", ".join(ModelArgument.get_arguments())
779dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
7804c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  print(
7814c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      "Output %s model: %s" % ("VTS" if Configuration.vts else "CTS", model),
7824c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      file=sys.stderr)
783dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  print ("Output example:" + example, file = sys.stderr)
784dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
7854c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  if Configuration.vts:
7864c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    with smart_open(model) as model_file:
7874c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      generate_vts(model_file)
7884c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung  else:
7894c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung    with smart_open(model) as model_file:
7904c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      spec_file = " (from: %s)" % (FileNames.SpecFile)
7914c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7924c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ('// Generated file%s. Do not edit'%(spec_file), file = model_file)
7934c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("void CreateModel(Model *model" + args + ") {", file=model_file)
7944c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
7954c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      # Phase 0: types
7964c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      Type.dump(model_file)
7974c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      # Phase 1: add operands
7984c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("  // Phase 1, operands", file=model_file)
7994c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      Operand.operands.dump(model_file)
8004c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
8014c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      # Phase 2: operations
8024c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("  // Phase 2, operations", file=model_file)
8034c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      TopologicalSort(lambda x: print_cts_op(model_file, x))
8044c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung
8054c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      # Phase 3: add inputs and outputs
8064c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("  // Phase 3, inputs and outputs", file=model_file)
8074c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      inputs = Operand.print_operands(Input.get_inputs(True));
8084c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      outputs = Operand.print_operands(Output.get_outputs());
8094c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("  model->setInputsAndOutputs(\n" +
8104c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung             "    {"+", ".join(inputs)+"},\n    {" + ", ".join(outputs) + "});",
8114c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung             file=model_file)
8124c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      # Boilerplate
8134c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("  assert(model->isValid());", file=model_file);
8144c7a55a8c2d7da34c3c2df27508a043a957b1c0cI-Jui (Ray) Sung      print ("}", file=model_file)
815ec8e1c71d11f7b5abe306e0c9c6af7da755bd46bI-Jui (Ray) Sung      print (IgnoredOutput.gen_ignored(), file=model_file)
816dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung
817dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung  with smart_open(example) as example_file:
818dcd2fbf1da7ebdc1aa1b57c74db4fffd2911e3b8I-Jui (Ray) Sung    Example.dump(example_file)
819