Files
test/tests/performance/tests/cycles.py
Alaska 7a47762c20 Benchmark: Enable OSL in Cycles performance benchmark tool
This commit gives users of the Cycles performance benchmark tool the
option to run performance benchmarks with OSL enabled for CPUs
and OptiX devices.

This can be done by adding `-OSL` to the device name:
`CPU-OSL`
`OPTIX-OSL_0`

Pull Request: https://projects.blender.org/blender/blender/pulls/136506
2025-03-26 23:52:14 +01:00

130 lines
4.0 KiB
Python

# SPDX-FileCopyrightText: 2021-2022 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
import api
def _run(args):
import bpy
device_info = args['device_type'].split("-")
device_type = device_info[0]
device_suffixes = device_info[1:]
use_hwrt = "RT" in device_suffixes
use_osl = "OSL" in device_suffixes
for suffix in device_suffixes:
if suffix not in {"RT", "OSL"}:
raise SystemExit(f"Unknown device type suffix {suffix}")
device_index = args['device_index']
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
scene.render.filepath = args['render_filepath']
scene.render.image_settings.file_format = 'PNG'
scene.cycles.device = 'CPU' if device_type == 'CPU' else 'GPU'
if scene.cycles.use_adaptive_sampling:
# Render samples specified in file, no other way to measure
# adaptive sampling performance reliably.
scene.cycles.time_limit = 0.0
else:
# Render for fixed amount of time so it's adaptive to the
# machine and devices.
scene.cycles.samples = 16384
scene.cycles.time_limit = 10.0
if use_osl:
scene.cycles.shading_system = True
if scene.cycles.device == 'GPU':
# Enable specified GPU in preferences.
prefs = bpy.context.preferences
cprefs = prefs.addons['cycles'].preferences
cprefs.compute_device_type = device_type
devices = cprefs.get_devices_for_type(device_type)
for device in devices:
device.use = False
index = 0
for device in devices:
if device.type == device_type:
if index == device_index:
device.use = True
break
else:
index += 1
cprefs.use_hiprt = use_hwrt
cprefs.use_oneapirt = use_hwrt
cprefs.metalrt = 'ON' if use_hwrt else 'OFF'
# Render
bpy.ops.render.render(write_still=True)
return None
class CyclesTest(api.Test):
def __init__(self, filepath):
self.filepath = filepath
def name(self):
return self.filepath.stem
def category(self):
return "cycles"
def use_device(self):
return True
def run(self, env, device_id):
tokens = device_id.split('_')
device_type = tokens[0]
device_index = int(tokens[1]) if len(tokens) > 1 else 0
args = {'device_type': device_type,
'device_index': device_index,
'render_filepath': str(env.log_file.parent / (env.log_file.stem + '.png'))}
_, lines = env.run_in_blender(_run, args, ['--debug-cycles', '--verbose', '2', self.filepath])
# Parse render time from output
prefix_time = "Render time (without synchronization): "
prefix_memory = "Peak: "
prefix_time_per_sample = "Average time per sample: "
time = None
time_per_sample = None
memory = None
for line in lines:
line = line.strip()
offset = line.find(prefix_time)
if offset != -1:
time = line[offset + len(prefix_time):]
time = float(time)
offset = line.find(prefix_time_per_sample)
if offset != -1:
time_per_sample = line[offset + len(prefix_time_per_sample):]
time_per_sample = time_per_sample.split()[0]
time_per_sample = float(time_per_sample)
offset = line.find(prefix_memory)
if offset != -1:
memory = line[offset + len(prefix_memory):]
memory = memory.split()[0].replace(',', '')
memory = float(memory)
if time_per_sample:
time = time_per_sample
if not (time and memory):
raise Exception("Error parsing render time output")
return {'time': time, 'peak_memory': memory}
def generate(env):
filepaths = env.find_blend_files('cycles/*')
return [CyclesTest(filepath) for filepath in filepaths]