Why is only a single GPU used when using OPTIX from the python API when CUDA uses multiple when configured to do so?

As the title states, if I configure to use multiple GPUs as follows using CUDA

bpy.context.preferences.addons['cycles'].preferences.compute_device_type = "CUDA"
bpy.context.scene.cycles.device = "GPU"
for d in bpy.context.preferences.addons["cycles"].preferences.devices:
    d.use = True

nvidia-smi shows that all GPUs are being used. However, when I use optix by simply replacing CUDA with OPTIX in the above

bpy.context.preferences.addons['cycles'].preferences.compute_device_type = "OPTIX"
bpy.context.scene.cycles.device = "GPU"
for d in bpy.context.preferences.addons["cycles"].preferences.devices:
    d.use = True

Only a single GPU is used. Configuring using the GUI works fine in either case though. I can make a more fully worked example if needed, what I am currently using is from a large code base which is why I only provide the above snipets. Is further configuration required for OPTIX? I am having trouble finding the documentation for Addons(‘CYCLES’). Thanks

Copied from stack exchange

This doesn’t do anything, it constructs a list which is then unused. You need to actually set use to True.

[ d.use for d in bpy.context.preferences.addons["cycles"].preferences.devices ]

Sorry for the bad example, I fixed it above. Nothing seems to be changed.

edit: I assume there isn’t something else obviously wrong then, I’ll try to put something together a more extensive example.

Maybe a call to get_devices() is needed to refresh the device list.

I’ve copied a full example below, switching between OPTIX and CUDA can be done on line 6. It seems like the cause is coming from the following

bpy.context.scene.render.threads_mode = "FIXED"
bpy.context.scene.render.threads = 1

Is there a reason this causes multiple GPU rendering to be disabled on OPTIX but not CUDA? I didn’t write the code in the original code base that sets this configure so I’m not really sure why it’s being done this way.



import bpy
import bpy
import mathutils

bpy.context.preferences.addons['cycles'].preferences.compute_device_type = "OPTIX"
bpy.context.scene.cycles.device = "GPU"
bpy.context.scene.render.engine = 'CYCLES'
prefs = bpy.context.preferences.addons['cycles'].preferences

# might be needed for getting devices
for device_type in prefs.get_device_types(bpy.context):
    prefs.get_devices_for_type(device_type[0])

# enable all devices
for group in prefs.get_devices():
    print(group)
    for idx,d in enumerate(group):
        d.use = True

# show enabled / disabled devices
for group in prefs.get_devices():
    for idx,d in enumerate(group):
        print("{} : {}".format(d.name,d.use))

scene = bpy.context.scene

# Create a cube
mesh = bpy.data.meshes.new('cube')
ob = bpy.data.objects.new('cube', mesh)

scene.collection.objects.link(ob)

import bmesh
bm = bmesh.new()
bmesh.ops.create_cube(bm, size=1.0)
bm.to_mesh(mesh)
bm.free()

# Create a light
light_data = bpy.data.lights.new('light', type='POINT')
light = bpy.data.objects.new('light', light_data)
scene.collection.objects.link(light)
light.location = mathutils.Vector((3, -4.2, 5))

# Create a camera
cam_data = bpy.data.cameras.new('camera')
cam = bpy.data.objects.new('camera', cam_data)
scene.collection.objects.link(cam)
scene.camera = cam

cam.location = mathutils.Vector((6, -3, 5))
cam.rotation_euler = mathutils.Euler((0.9, 0.0, 1.1))

# set to single CPU thread, seems to disable multiple GPU rendering on OPTIX but not CUDA
bpy.context.scene.render.threads_mode = "FIXED"
bpy.context.scene.render.threads = 1

# set a high resolution so there is plenty of time to see work being done
for scene in bpy.data.scenes:
  scene.render.resolution_x = 4000
  scene.render.resolution_y = 4000

# render settings
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = "./image.png"
for i in range(1):
    bpy.ops.render.render(write_still = 1)
1 Like