with _profile(record_shapes=True, with_flops=True, use_kineto=kineto_available()) as prof:
model(inputs)
profiler_output = prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10)
- self.assertIn("FLOPS", profiler_output)
-
+ self.assertIn("Total MFLOPs", profiler_output)
if not (kineto_available() and torch.cuda.is_available()):
return
model(inputs)
profiler_output = kineto_profiler.key_averages().table(
sort_by="self_cuda_time_total", row_limit=-1)
- self.assertIn("FLOPS", profiler_output)
+ self.assertIn("Total MFLOPs", profiler_output)
def test_kineto_profiler_api(self):
called_num = [0]
collection.
with_flops (bool, optional): If with_flops is set, the profiler will estimate
- the FLOPS (floating pointer operations per second) value using the operator's input shape
- and total time. This allows one to estimate the hardware performance. Currently,
+ the FLOPs (floating point operations) value using the operator's input shape.
+ This allows one to estimate the hardware performance. Currently,
this option only works for the matrix multiplication and 2D convolution operators.
profile_memory (bool, optional): track tensor memory allocation/deallocation.
self.device_type: DeviceType = device_type
self.device_index: int = device_index
self.is_legacy: bool = is_legacy
- self.flops: Optional[float] = flops
+ self.flops: Optional[int] = flops
def append_kernel(self, name, device, duration):
assert self.device_type == DeviceType.CPU
self.cpu_parent: Optional[FunctionEvent] = None
self.device_type: DeviceType = DeviceType.CPU
self.is_legacy: bool = False
- self.flops: float = 0.0
+ self.flops: int = 0
def add(self, other):
if self.key is None:
def auto_scale_flops(flops):
flop_headers = [
- 'FLOPS',
- 'KFLOPS',
- 'MFLOPS',
- 'GFLOPS',
- 'TFLOPS',
- 'PFLOPS',
+ 'FLOPs',
+ 'KFLOPs',
+ 'MFLOPs',
+ 'GFLOPs',
+ 'TFLOPs',
+ 'PFLOPs',
]
assert flops > 0
log_flops = max(0, min(math.log10(flops) / 3, float(len(flop_headers) - 1)))
assert log_flops >= 0 and log_flops < len(flop_headers)
return (pow(10, (math.floor(log_flops) * -3.0)), flop_headers[int(log_flops)])
- def flops_rate(evt):
- US_IN_SECOND = 1000.0 * 1000.0
- if evt.flops > 0:
- if evt.cuda_time_total != 0:
- return float(evt.flops) / evt.cuda_time_total * US_IN_SECOND
- else:
- return float(evt.flops) / evt.cpu_time_total * US_IN_SECOND
- else:
- return -1
-
add_column(name_column_width)
for _ in headers[1:]:
add_column(DEFAULT_COLUMN_WIDTH)
# Auto-scaling of flops header
raw_flops = []
for evt in events:
- rate = flops_rate(evt)
- if rate > 0:
- raw_flops.append(rate)
+ if evt.flops > 0:
+ raw_flops.append(evt.flops)
if len(raw_flops) != 0:
(flops_scale, flops_header) = auto_scale_flops(min(raw_flops))
- headers.append(flops_header)
+ headers.append('Total {}'.format(flops_header))
add_column(flops_column_width)
else:
with_flops = False # can't find any valid flops
if has_input_shapes:
row_values.append(str(evt.input_shapes)[:shapes_column_width])
if with_flops:
- rate = flops_rate(evt)
- if rate <= 0.0:
+ if evt.flops <= 0:
row_values.append("--")
else:
- row_values.append('{0:8.3f}'.format(rate * flops_scale))
+ row_values.append('{0:8.3f}'.format(evt.flops * flops_scale))
if has_stack:
src_field = ""
if len(evt.stack) > 0:
record_shapes (bool): save information about operator's input shapes.
profile_memory (bool): track tensor memory allocation/deallocation.
with_stack (bool): record source information (file and line number) for the ops.
- with_flops (bool): use formula to estimate the FLOPS of specific operators
+ with_flops (bool): use formula to estimate the FLOPs (floating point operations) of specific operators
(matrix multiplication and 2D convolution).
with_modules (bool): record module hierarchy (including function names)
corresponding to the callstack of the op. e.g. If module A's forward call's