269 lines
9.1 KiB
Python
269 lines
9.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import bpy
|
|
|
|
def getUserPreferences(context):
|
|
preferences = getattr(context, 'user_preferences', None)
|
|
if preferences is None:
|
|
preferences = context.preferences
|
|
return preferences
|
|
|
|
|
|
def getAllAvailableDevices():
|
|
import _cycles
|
|
all_devices = []
|
|
blender_version = bpy.app.version
|
|
if bpy.app.version < (2, 80, 0):
|
|
return _cycles.available_devices()
|
|
all_devices.extend(_cycles.available_devices('CPU'))
|
|
all_devices.extend(_cycles.available_devices('CUDA'))
|
|
all_devices.extend(_cycles.available_devices('OPENCL'))
|
|
return all_devices
|
|
|
|
def setDeviceCPU(context, cpref):
|
|
cpref.compute_device_type = 'NONE'
|
|
return True
|
|
|
|
|
|
def isDisplayDevice(device):
|
|
return "(Display)" in device.name
|
|
|
|
|
|
def setUseRequestedDevice(context,
|
|
cpref,
|
|
device_type,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index):
|
|
import _cycles
|
|
# Empty device type means we'l ltry to render on a single card,
|
|
# preferably non-display one.
|
|
if requested_device == "":
|
|
device_found = False
|
|
display_device = None
|
|
# Try to enable first non-display card.
|
|
for device in cpref.devices:
|
|
if device.type != device_type:
|
|
device.use = False
|
|
continue
|
|
if isDisplayDevice(device):
|
|
device.use = False
|
|
display_device = device
|
|
elif not device_found or not device_single:
|
|
# Enable first non-display GPU.
|
|
device_found = True
|
|
device.use = True
|
|
else:
|
|
# Keep disabling rest of GPUs.
|
|
device.use = False
|
|
if not device_found:
|
|
# Only display devices, enable first of them.
|
|
display_device.use = True
|
|
device_found = True
|
|
else:
|
|
device_found = False
|
|
device_index = 0
|
|
for device in cpref.devices:
|
|
device_name = device.name.replace(" (Display)", "")
|
|
if device_name == requested_device:
|
|
if requested_device_index != -1:
|
|
if device_index == requested_device_index:
|
|
device.use = True
|
|
device_found = True
|
|
else:
|
|
device.use = False
|
|
elif not device_found or not device_single:
|
|
device.use = True
|
|
device_found = True
|
|
else:
|
|
device.use = False
|
|
device_index += 1
|
|
else:
|
|
device.use = False
|
|
return device_found
|
|
|
|
|
|
def setDeviceCUDA(context,
|
|
cpref,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index):
|
|
cpref.compute_device_type = 'CUDA'
|
|
return setUseRequestedDevice(context,
|
|
cpref,
|
|
'CUDA',
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index)
|
|
|
|
|
|
def setDeviceOpenCL(context,
|
|
cpref,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index):
|
|
cpref.compute_device_type = 'OPENCL'
|
|
return setUseRequestedDevice(context,
|
|
cpref,
|
|
'OPENCL',
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index)
|
|
|
|
|
|
def setDeviceGPU(context,
|
|
cpref,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index):
|
|
import _cycles
|
|
has_cuda = has_opencl = False
|
|
for device in _cycles.available_devices():
|
|
if device[1] == 'CUDA':
|
|
has_cuda = True
|
|
if device[1] == 'OPENCL':
|
|
has_opencl = True
|
|
|
|
if has_cuda:
|
|
return setDeviceCUDA(context,
|
|
cpref,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index)
|
|
if has_opencl:
|
|
return setDeviceOpenCL(context,
|
|
cpref,
|
|
requested_device,
|
|
device_single,
|
|
requested_device_index)
|
|
return False
|
|
|
|
|
|
def logComputeDevices(cpref):
|
|
import json
|
|
device_type = cpref.compute_device_type
|
|
if device_type == 'NONE':
|
|
device_type = 'CPU'
|
|
print("Compute device type: {}" . format(device_type))
|
|
if device_type == 'CPU':
|
|
import _cycles
|
|
for device in _cycles.available_devices():
|
|
if device[1] == 'CPU':
|
|
info = {'name': device[0]}
|
|
print("Using compute device: {}" . format(json.dumps(info, sort_keys=True)))
|
|
else:
|
|
for device in cpref.devices:
|
|
if device.type != device_type or not device.use:
|
|
continue
|
|
|
|
info = {
|
|
'name': device.name.replace(' (Display)', ''),
|
|
'is_display': '(Display)' in device.name,
|
|
}
|
|
print("Using compute device: {}" . format(json.dumps(info, sort_keys=True)))
|
|
|
|
|
|
def logSystemInfo(cpref):
|
|
import json
|
|
info_devices = []
|
|
for device in getAllAvailableDevices():
|
|
info_device = {
|
|
"name": device[0].replace(" (Display)", ""),
|
|
"type": device[1],
|
|
}
|
|
if device[1] != 'CPU':
|
|
info_device["is_display"] = '(Display)' in device[0]
|
|
info_devices.append(info_device)
|
|
print("Benchmark Devices: {}" . format(json.dumps(info_devices, sort_keys=True)))
|
|
|
|
|
|
def main():
|
|
import argparse
|
|
import sys
|
|
|
|
argv = sys.argv
|
|
if "--" not in argv:
|
|
return
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="Cycles benchmark helper script.")
|
|
parser.add_argument("--benchmark-warmup",
|
|
help="Do quick warm-up render pass",
|
|
action='store_true',
|
|
default=False)
|
|
parser.add_argument("--benchmark-device-type",
|
|
help="Device type to be rendered on",
|
|
default="CPU")
|
|
parser.add_argument("--benchmark-device",
|
|
help="Device to be rendered on",
|
|
default="")
|
|
parser.add_argument("--benchmark-device-single",
|
|
help="Use single device when multiple are found",
|
|
action='store_true',
|
|
default=False)
|
|
parser.add_argument("--benchmark-device-index",
|
|
help="Use device of a given index whe nusing single device",
|
|
default=-1)
|
|
parser.add_argument("--benchmark-system-info",
|
|
help="Dump whole system information",
|
|
action='store_true',
|
|
default=False)
|
|
|
|
argv = argv[argv.index("--") + 1:]
|
|
args = parser.parse_args(argv)
|
|
|
|
context = bpy.context
|
|
cpref = getUserPreferences(context).addons['cycles'].preferences
|
|
|
|
# Adjust samples so we render real quick.
|
|
if args.benchmark_warmup:
|
|
for scene in bpy.data.scenes:
|
|
scene.cycles.samples = 1
|
|
scene.cycles.aa_samples = 1
|
|
|
|
# Cycles device.
|
|
device = 'CPU' if args.benchmark_device_type == 'CPU' else 'GPU'
|
|
tile_size = 16 if device == 'CPU' else 512
|
|
for scene in bpy.data.scenes:
|
|
scene.cycles.device = device
|
|
scene.render.tile_x = scene.render.tile_y = tile_size
|
|
|
|
# Report number of CPU threads used.
|
|
for scene in bpy.data.scenes:
|
|
print("CPU threads used: {}" . format(scene.render.threads))
|
|
# TODO(sergey): What to do if there are multiple scenes?
|
|
break
|
|
|
|
# Configure the compute device.
|
|
if args.benchmark_device_type == 'CPU':
|
|
device_ok = setDeviceCPU(context, cpref)
|
|
elif args.benchmark_device_type == 'CUDA':
|
|
device_ok = setDeviceCUDA(context,
|
|
cpref,
|
|
args.benchmark_device,
|
|
args.benchmark_device_single,
|
|
int(args.benchmark_device_index))
|
|
elif args.benchmark_device_type == 'OPENCL':
|
|
device_ok = setDeviceOpenCL(context,
|
|
cpref,
|
|
args.benchmark_device,
|
|
args.benchmark_device_single,
|
|
int(args.benchmark_device_index))
|
|
elif args.benchmark_device_type == 'GPU':
|
|
device_ok = setDeviceGPU(context,
|
|
cpref,
|
|
args.benchmark_device,
|
|
args.benchmark_device_single,
|
|
int(args.benchmark_device_index))
|
|
if not device_ok:
|
|
sys.exit(1)
|
|
|
|
if args.benchmark_system_info:
|
|
logSystemInfo(cpref)
|
|
else:
|
|
logComputeDevices(cpref)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|