This repository has been archived on 2023-02-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-benchmark-bundle/benchmark/foundation/stats.py

112 lines
4.5 KiB
Python

import re
from . import util
class Stats:
def __init__(self):
# Pepare some regex for parsing
self.re_path_tracing = re.compile(
r".*(Rendered|Path Tracing Tile) ([0-9]+)/([0-9]+)( Tiles)?" +
r"(, Sample ([0-9]+)/([0-9]+))?$")
self.re_total_render_time = re.compile(
r".*Total render time: ([0-9]+(\.[0-9]+)?)")
self.re_render_time_no_sync = re.compile(
r".*Render time \(without synchronization\): ([0-9]+(\.[0-9]+)?)")
self.re_pipeline_time = re.compile(
r"Time: ([0-9:.]+) \(Saving: ([0-9:.]+)\)")
self.re_cycles_memory = re.compile(
r".*\| Mem:([0-9.]+[KM]?), Peak:([0-9.]+[KM]?) \|.*")
# Render time stats.
self.total_render_time = "N/A"
self.render_time_no_sync = "N/A"
self.pipeline_render_time = "N/A"
# Render memory stats.
self.device_peak_memory = "N/A"
self.device_memory_usage = "N/A"
# Current stats.
self.path_tracing = ""
self.current_tiles = 0
self.total_tiles = 0
self.current_sample = None
self.total_samples = None
def update(self, line):
# Current tile progress.
match = self.re_path_tracing.match(line)
if match:
self.path_tracing = match.group(1)
self.current_tiles = int(match.group(2))
self.total_tiles = int(match.group(3))
self.current_sample = match.group(6)
if self.current_sample is not None:
self.current_sample = int(self.current_sample)
self.total_samples = match.group(7)
if self.total_samples is not None:
self.total_samples = int(self.total_samples)
# Total render time.
match = self.re_total_render_time.match(line)
if match:
self.total_render_time = float(match.group(1))
# Render time without sync.
match = self.re_render_time_no_sync.match(line)
if match:
self.render_time_no_sync = float(match.group(1))
# Total pipeline time.
match = self.re_pipeline_time.match(line)
if match:
self.pipeline_render_time = \
util.humanReadableTimeToSeconds(match.group(1))
# Memory usage.
match = self.re_cycles_memory.match(line)
if match:
mem = util.humanReadableSizeToMegabytes(match.group(1))
peak = util.humanReadableSizeToMegabytes(match.group(2))
if self.device_memory_usage == "N/A" or \
mem > self.device_memory_usage:
self.device_memory_usage = mem
if self.device_peak_memory == "N/A" or \
peak > self.device_peak_memory:
self.device_peak_memory = peak
def getCurrentProgress(self):
if self.total_tiles == 0:
return 0
if not self.total_samples:
return float(self.current_tiles) / float(self.total_tiles) * 100
current_tile = self.current_tiles
# Workaround for current master.
if self.total_samples == self.current_sample:
current_tile = max(current_tile - 1, 0)
total_samples = self.total_tiles * self.total_samples
current_sample = current_tile * self.total_samples + self.current_sample
return float(current_sample) / float(total_samples) * 100
def print(self):
# TODO(sergey): Check that all stats are available.
print("Total pipeline render time: {} ({} sec)"
. format(util.humanReadableTimeDifference(
self.pipeline_render_time),
self.pipeline_render_time))
print("Total Cycles render time: {} ({} sec)"
. format(util.humanReadableTimeDifference(
self.total_render_time),
self.total_render_time))
print("Pure Cycles render time (without sync): {} ({} sec)"
. format(util.humanReadableTimeDifference(
self.render_time_no_sync),
self.render_time_no_sync))
print("Cycles memoty usage: {} ({} peak)"
. format(self.device_memory_usage,
self.device_peak_memory))
def asDict(self):
return {'total_render_time': self.total_render_time,
'render_time_no_sync': self.render_time_no_sync,
'pipeline_render_time': self.pipeline_render_time,
'device_peak_memory': self.device_peak_memory,
'device_memory_usage': self.device_memory_usage}