2
$\begingroup$

I'm running a number of benchmarks on Linux (Ubuntu 18.04) cloud VMs that have multiple GPUs attached, however I can only ever render on a single GPU. I'm not using the standard Blender benchmark executable as I kept running into checksum errors, rather I'm installing Blender locally and following the instructions to run offline benchmarks here.

I've tried adding this script to my command line to force-enable all my GPUs, but I'm still only getting a single GPU rendering. My command line is:

  /usr/bin/blender \
    --background \
    --factory-startup \
    -noaudio \
    --enable-autoexec \
    --engine \
    CYCLES \
    /path/to/scenes/main.blend \
    --python \
    /path/to/scripts/use_gpus.py \
    --python \
    /path/to/scripts/main.py \
    -- \
    --device-type=CUDA

Am I missing something? Is the GPU device ID baked into the benchmark scenefiles, not to be overridden?

$\endgroup$
1
$\begingroup$

The benchmark script sets the enabled devices itself, hence the script to enable all GPUs has no effect. Since the purpose of the benchmark is to evaluate the performance of a specific CPU or GPU, it only enables one (compute) device at a time. This can be seen by taking a look at the benchmark scripts.

In main.py it first parses the supplied arguments and starts the benchmark. You can specify which device shall be used through the optional -d, --device argument. The _benchmark() function gets the requested device as an argument and calls the render() function from the render.py script. It enables the requested device either through _enable_device() which in turn calls _enable_compute_device() or _enable_cpu_device(), depending whether the benchmark should be performed for a GPU or CPU. In your case it would be using the former function. _enable_compute_device() first disables all enabled graphics cards. If you supplied a specific GPU, it will try to enabled it. If no GPU was given as an argument (requested_device.name is None), it first tries to find one that isn't used as display device and if no such GPU exists, it picks the first one available. In both cases it only enables one GPU and it's the first one that matches the criteria.

Therefore you need to call the benchmark script multiple times and supply the GPU name through the --device argument for each run. The available device names can be printed to the terminal by using the -l or --list-devices argument.

Alternatively you would have to modify the script. However, this would also break the JSON reporting function since it expects exactly one device to be enabled. The report format could be modified as well, but it would not be possible to upload the modified reports to the Open Data platform.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks for this. Cycles (the command line implementation, at least) seems to be the only GPU-capable renderer which does not take advantage of all GPU resources as default behavior. Is there a reason for this? $\endgroup$ – Adrian Graham Mar 6 at 16:42
  • $\begingroup$ @AdrianGraham CPU rendering is the default. The reason for this is that there are several configuration options when using GPUs. Depending on your hardware you have to decide whether CUDA, OptiX or OpenCL shall be used. Additionally you can decide what GPUs of the specific kind shall be used and if you want to use the GPUs only or perform CPU + GPU rendering. All of this would usually be configured in the user preferences (Edit > Preferences > System) when using the GUI. Additionally you have to set the Device in the Render Properties to GPU Compute. $\endgroup$ – Robert Gützkow Mar 6 at 17:08
  • $\begingroup$ The script performs the steps you would usually do when initially configuring Blender for GPU rendering. $\endgroup$ – Robert Gützkow Mar 6 at 17:09
0
$\begingroup$

To make this work, I modified the script by @robert-gützkow. It's a bit hacky, but it allows the render to return proper JSON structured output.

As you iterate over each device, cast each returned GPU into a ComputeDevice thusly:

ComputeDevice(
  name=device.name,
  type=DeviceType('CUDA'),
  is_display=False,
  cycles_device=device
)

Then, in render.py in the scripts dir, I replaced:

enabled_devices = _enable_device(requested_device)

with

enabled_devices = enable_gpus.enable_gpus('CUDA')

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.