Forcing Blender to use GPU

Hi,

I’ve followed the steps here but I’m getting the following error. I believe it’s something to do with the python version but I’m not a programmer. Does anyone know now to resolve this?

(for context, I’m trying to render with Blender 3.6 using GPU on Deadline)

Here’s the error:

2023-10-09 21:36:06: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

2023-10-09 21:36:06: Exception Details

2023-10-09 21:36:06: RenderPluginException – The Deadline Plugin was not properly initialized. Application plugins must explicitly call super().__init__() in the Python constructor: def __init__().

2023-10-09 21:36:06: RenderPluginException.Cause: JobError (2)

2023-10-09 21:36:06: RenderPluginException.Level: Major (1)

2023-10-09 21:36:06: RenderPluginException.HasSlaveLog: True

2023-10-09 21:36:06: RenderPluginException.SlaveLogFileName: C:\ProgramData\Thinkbox\Deadline10\logs\deadlineslave_renderthread_0-DA-0000.log

2023-10-09 21:36:06: Exception.TargetSite: Deadline.Slaves.Messaging.PluginResponseMemento d(Deadline.Net.DeadlineMessage, System.Threading.CancellationToken)

2023-10-09 21:36:06: Exception.Data: ( )

2023-10-09 21:36:06: Exception.Source: deadline

2023-10-09 21:36:06: Exception.HResult: -2146233088

2023-10-09 21:36:06: Exception.StackTrace:

2023-10-09 21:36:06: at Deadline.Plugins.SandboxedPlugin.d(DeadlineMessage bgq, CancellationToken bgr)

2023-10-09 21:36:06: at Deadline.Plugins.SandboxedPlugin.Initialize(Job job, CancellationToken cancellationToken)

2023-10-09 21:36:06: at Deadline.Slaves.SlaveRenderThread.e(String ajx, Job ajy, CancellationToken ajz)

2023-10-09 21:36:06: at Deadline.Slaves.SlaveRenderThread.b(TaskLogWriter ajt, CancellationToken aju)

2023-10-09 21:36:06: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

By the look of it you’ve got a 10.2 Blender.py running on a 10.3 Worker. If you’re running the steps and files you downloaded from Karpreet’s post here, grab it again. 3 days ago he fixed it up to be 10.3 compatible, so you may just have an out of date file.

And be sure to either restart the Worker or submit a new job after getting the files in place, or else the old application plugin files will get used, and you’ll get the same error.

To be sure you’ve got files in the right spot, once you’re done there should be a DeadlineRepository10\custom\plugins\Blender\Blender.py that looks like this:

Did you have any joy with Mac OS / GPU on Deadline?

is there a way to hard code this path so we don’t have to fill it in every time? Can’t seem to find the line to add it in the script.

You can add it into the line like below, this way it’ll auto fill

    scriptDialog.AddControlToGrid( "AdditionalArgumentsBox", "TextControl", "-P Z:\BlenderForceGPUScript.py", 7, 1, colSpan=2 )

I’m just revisiting this as I’m looking into it for a client. Seems to throw errors and fail this way

"C:\Program Files\Blender Foundation\Blender 4.2\blender.exe"  -b "Z:\tests\blender\simple_3.blend" -t 0 -x 1 -o "Z:\tests\blender\####.png" -s 14 -e 14 -a -P Z:\BlenderForceGPUScript.py

If I move the additional args I still get the errors but the render goes through

"C:\Program Files\Blender Foundation\Blender 4.2\blender.exe"   -P Z:\BlenderForceGPUScript.py -b "Z:\tests\blender\simple_3.blend" -t 0 -x 1 -o "Z:\tests\blender\####.png" -s 14 -e 14 -a

not sure if this is a 4.2 thing, I find I’m having to manually install the submitter now too

so adding the line before the others in Blender.py (Around line 80) throws an error but forces renders on the GPU

        renderArgument += StringUtils.BlankIfEitherIsBlank( " -x 1 -o \"", StringUtils.BlankIfEitherIsBlank( outputFile, "\"" ) )
        renderArgument += self.GetPluginInfoEntryWithDefault("AdditionalArguments", " -P Z:\BlenderForceGPUScript.py")
        renderArgument += " -s " + str(self.GetStartFrame()) + " -e " + str(self.GetEndFrame()) + " -a "

Since blender 3 the tiling functions are deprecated so errors will pop.
I fixed our side in 3 parts:

  1. Blender.py under def InitializeProcess(self). This will enable use of gpu pinning for deadline workers.
def InitializeProcess(self):
...
    gpu_ids = self.GpuAffinity()
    if gpu_ids:
        gpu_string = ",".join(map(str, gpu_ids))
        self.SetProcessEnvironmentVariable("BLENDER_GPUDEVICES", gpu_string)
        self.LogInfo(f"Set BLENDER_GPUDEVICES to {gpu_string}")
    else:
        self.LogInfo("No GPU affinity set — BLENDER_GPUDEVICES not defined")
  1. In Blender.py under def RenderArgument(self), this will call the gpu script and fix single frame or multi frame selection flags to not get into render loops.
renderArgument += StringUtils.BlankIfEitherIsBlank( " -x 1 -o \"", StringUtils.BlankIfEitherIsBlank( outputFile, "\"" ) )
...
gpuscriptpath = self.GetPluginInfoEntryWithDefault("AdditionalArguments", " -P pathto BlenderForceGPUScript.py")
        gpuscriptpath = RepositoryUtils.CheckPathMapping( gpuscriptpath )
        renderArgument += " -P \"" + gpuscriptpath + "\""
        if self.GetStartFrame() != self.GetEndFrame():
          renderArgument += " -a "
        else:
          renderArgument += " -f " + str(self.GetStartFrame())
  1. GPU render script. Checked gpu model to set correct cycles beckend and gpu pinning if set.
import os
import bpy

# Check for GPU pinning from Deadline or custom env var
gpu_env = os.environ.get("BLENDER_GPUDEVICES")

if gpu_env:
    pinned_ids = [int(i) for i in gpu_env.split(",") if i.strip().isdigit()]
    print(f"GPU pinning detected: enabling GPU(s) {pinned_ids}")
else:
    pinned_ids = None
    print("No GPU pinning detected — enabling all available GPUs")

# Configure Cycles preferences
prefs = bpy.context.preferences.addons["cycles"].preferences
prefs.get_devices()

# Inspect devices for vendor and capabilities
device_names = [d.name.lower() for d in prefs.devices]
print(f"Available GPU devices: {device_names}")
# Detect GPU type and choose best backend
if any("amd" in name or "radeon" in name for name in device_names):
    prefs.compute_device_type = "HIP"
    print("Detected AMD GPU — using HIP backend")
elif any("rtx" in name or "optix" in name for name in device_names):
    prefs.compute_device_type = "OPTIX"
    print("Detected NVIDIA RTX GPU — using OptiX backend")
elif any("nvidia" in name or "geforce" in name for name in device_names):
    prefs.compute_device_type = "CUDA"
    print("Detected NVIDIA GPU — using CUDA backend")
else:
    # Fallback
    prefs.compute_device_type = "CUDA"
    print("No specific GPU detected — defaulting to CUDA")

# Enable GPUs based on pinning, or fallback to all
for i, device in enumerate(prefs.devices):
    device.use = (pinned_ids is None or i in pinned_ids)

# Use GPU for rendering
scene = bpy.context.scene
scene.cycles.device = "GPU"

Just a quick update, if you have 2 or more pinned rtx gpus cycles will find double the amount. 2 will be for cuda beckend and another 2 of the same gpus but for optix. If CPU is used intead og gpu for renders then use cuda for the rtx gpus as well. Basically if the gpu amount is doubled and the deadline pinning is only for 2 gpus for in my example, the optix devices will never get used as they would have ids 3 and 4 which will be ignored.

1 Like