def TotalCount(self):
return self.add_count + self.mul_count + self.nonlinear_count
+ def IsSupportedOperationCount(self):
+ return True
+
+
+class UnsupportedOperationCount(OperationCount):
+ def __init__(self):
+ OperationCount.__init__(self)
+
+ def IsSupportedOperationCount(self):
+ return False
+
# NOTE: How to count operations of convolution(and also pooling)?
#
return OperationCount()
-def CountOpsDummy(tf_operator, inputs, outputs):
- return OperationCount()
+def CountOpsUnsupported(tf_operator, inputs, outputs):
+ return UnsupportedOperationCount()
# TODO: can make this as a class which has above method
"CONCATENATION": CountOpsNothing,
# ADAS
- "TOPK_V2": CountOpsDummy,
- "SUB": CountOpsDummy,
- "STRIDED_SLICE": CountOpsDummy,
- "RESHAPE": CountOpsDummy,
- "GATHER": CountOpsDummy,
- "RESIZE_BILINEAR": CountOpsDummy,
- "CAST": CountOpsDummy,
- "ADD": CountOpsDummy,
- "MUL": CountOpsDummy,
- "DIV": CountOpsDummy,
- "CUSTOM(TensorFlowMax)": CountOpsDummy,
- "CUSTOM": CountOpsDummy,
+ "TOPK_V2": CountOpsUnsupported,
+ "SUB": CountOpsUnsupported,
+ "STRIDED_SLICE": CountOpsUnsupported,
+ "RESHAPE": CountOpsUnsupported,
+ "GATHER": CountOpsUnsupported,
+ "RESIZE_BILINEAR": CountOpsUnsupported,
+ "CAST": CountOpsUnsupported,
+ "ADD": CountOpsUnsupported,
+ "MUL": CountOpsUnsupported,
+ "DIV": CountOpsUnsupported,
+ "CUSTOM(TensorFlowMax)": CountOpsUnsupported,
+ "CUSTOM": CountOpsUnsupported,
}
import tflite.BuiltinOperator
from operator_wrapping import Operator, SetBuiltinOpcodeStr, BuiltinOpcodeStrList
from tensor_wrapping import Tensor, SetTensorTypeStr
-from operator_counter import OperationCount
+from operator_counter import OperationCount, UnsupportedOperationCount
class TypesCounter(object):
- def __init__(self):
+ def __init__(self, op):
self.type_count = 0
- self.op_count = OperationCount()
+ if op.IsSupportedOperationCount():
+ self.op_count = OperationCount()
+ else:
+ self.op_count = UnsupportedOperationCount()
def Update(self, op):
self.type_count = self.type_count + 1
- self.op_count.Increase(op.GetOpCount())
+ if self.op_count.IsSupportedOperationCount():
+ self.op_count.Increase(op.GetOpCount())
def GetTypeCount(self):
return self.type_count
def GetOpCount(self):
return self.op_count
+ def IsSupportedOperationCount(self):
+ return self.op_count.IsSupportedOperationCount()
+
class OperatorParser(object):
def __init__(self, tf_model, tf_subgraph, perf_predictor=None):
def CountOperator(self, op):
opcode_str = op.GetOpcodeStr()
if opcode_str not in self.op_types:
- self.op_types[opcode_str] = TypesCounter()
+ self.op_types[opcode_str] = TypesCounter(op)
self.op_types[opcode_str].Update(op)
def GetInputTensors(self, tf_operator):
total_opstr_count = 0
total_op_count = 0
for opstr, type_counter in self.op_types.items():
+ supported = type_counter.IsSupportedOperationCount()
+
opstr_count = type_counter.GetTypeCount()
op_count = type_counter.GetOpCount().TotalCount()
- print("\t{0:38}: {1:4} \t (total_ops: {2})".format(opstr, opstr_count,
- "{:,}".format(op_count)))
+ print("\t{0:38}: {1:4} \t (total_ops: {2})".format(
+ opstr, opstr_count, "{:,}".format(op_count) if supported else "???"))
total_opstr_count = total_opstr_count + opstr_count
- total_op_count = total_op_count + op_count
+ total_op_count = (total_op_count + op_count) if supported else total_op_count
- print("{0:46}: {1:4} \t (total_ops: {2})".format("Total Number of operators",
- total_opstr_count,
- "{:,}".format(total_op_count)))
+ total_op_count = "{:,}".format(total_op_count)
+ print("{0:46}: {1:4} \t (total_ops: {2})".format(
+ "Total Number of operators", total_opstr_count, total_op_count))
import tflite.OperatorCode
import tflite.BuiltinOperator
from tensor_wrapping import Tensor
-from operator_counter import OperationCount, ops_counters
+from operator_counter import OperationCount, UnsupportedOperationCount, ops_counters
from perf_predictor import PerfPredictor
BuiltinOpcodeStrList = {}
self.op_count = None # OperationCount
def PrintInfo(self, perf_predictor=None):
- cycles = (perf_predictor.PredictCycles(
- self.op_count)) if perf_predictor != None else "???"
+ supported = self.IsSupportedOperationCount()
+
+ # total op counts
+ counts = "{:,}".format(self.op_count.TotalCount()) if supported else "???"
+
+ # total op cycles
+ cycles = "{:,}".format((perf_predictor.PredictCycles(
+ self.op_count))) if supported and perf_predictor != None else "???"
+
print("Operator {0}: {1} (ops: {2}, cycls: {3})".format(
- self.operator_idx, self.opcode_str, "{:,}".format(self.op_count.TotalCount()),
- "{:,}".format(cycles)))
+ self.operator_idx, self.opcode_str, counts, cycles))
+
print("\tInput Tensors" + GetStrTensorIndex(self.inputs))
for tensor in self.inputs:
tensor.PrintInfo("\t\t")
def CountOperations(self):
opcode_str = self.opcode_str
- if opcode_str not in ops_counters:
- print("\n\t Operator {0} is not supported yet\n".format(opcode_str))
- return OperationCount()
- self.op_count = ops_counters[opcode_str](self.tf_operator, self.inputs,
- self.outputs)
+ # FIXME: if there would be a class for ops_counters, we can delete this
+ if not opcode_str in ops_counters:
+ self.op_count = UnsupportedOperationCount()
+ else:
+ self.op_count = ops_counters[opcode_str](self.tf_operator, self.inputs,
+ self.outputs)
def GetOpcodeStr(self):
return self.opcode_str
def GetOpCount(self):
return self.op_count
+
+ def IsSupportedOperationCount(self):
+ return self.op_count.IsSupportedOperationCount()