112 lines
4.5 KiB
Python
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(
|
|
".*(Rendered|Path Tracing Tile) ([0-9]+)/([0-9]+)( Tiles)?" +
|
|
"(, Sample ([0-9]+)\/([0-9]+))?$")
|
|
self.re_total_render_time = re.compile(
|
|
".*Total render time: ([0-9]+(\.[0-9]+)?)")
|
|
self.re_render_time_no_sync = re.compile(
|
|
".*Render time \(without synchronization\): ([0-9]+(\.[0-9]+)?)")
|
|
self.re_pipeline_time = re.compile(
|
|
"Time: ([0-9:\.]+) \(Saving: ([0-9:\.]+)\)")
|
|
self.re_cycles_memory = re.compile(
|
|
".*\| 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(1))
|
|
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 \
|
|
mem > self.device_peak_memory:
|
|
self.device_peak_memory = mem
|
|
|
|
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}
|