Friday, September 12, 2014

3D Rendering using Blender and CUDA on HPC Clusters

Blender is a popular Open Source 3D modeling system.  Recently the question was asked can one use the Flux cluster for 3D rendering. We were curious about this, and we wanted to support our students. Clusters like Flux though are normally built with scientific use in mind and we didn't know if what we had would support Blender. Turns out this was all easier than we thought.

blender-batch.sh
#run blender in batch, take all settings from those saved in the .blend file
#http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Command_Line
blender -b blender.blend -o //imagename -F PNG -x 1 -f 1

GPU Rendering with CYCLES and CUDA

What we found though is we wanted to use the CYCLES render, and not only that we wanted to run it on the FluxG GPU service.  Why GPUs?  Lets us use the current standard CYCLES benchmark file and compare GPU to CPU performance.

Blender Rendering Benchmark (mpan)


HardwareTile Settings (XxY)TimeSpeedup
1 CPU E5-267016x1610m:17s1x
4 CPU E5-267016x162m:48s3.7x
16 CPU E5-267016x1646S13.4x
1 K20X GPU256x25640S15.4x
2 K20X GPU256x25624S25.7
4 K20X GPU256x25618S34.3x

Running Blender Better

So we know GPUs are much faster, but Blender when ran in the normal batch mode above ignores any settings you pass in a python input. We want to be able to control all GPU/CPU settings on the cluster and not open the GUI each time.  The trick, is to read your blend file from the Blender Python API and then change settings.  Look at the tooltips in blender this API is powerful, everything can be controlled from Python.


#brockp@umich.edu
#blender 2.71
# BMW1M-MikePan.blend
# http://blenderartists.org/forum/showthread.php?239480-2-6x-Cycles-render-benchmark
# run with: blender -b --python bmw.py
import bpy
#read our input blend
bpy.ops.wm.open_mainfile(filepath="BMW1M-MikePan.blend")
#Switch Engine to Cycles
bpy.context.scene.render.engine = 'CYCLES'
#tell blender to use CUDA / GPU devices
bpy.context.user_preferences.system.compute_device_type = 'CUDA'
#set CYCLES render system GPU or CPU
# GPU, CPU
bpy.data.scenes["Scene"].cycles.device='GPU'
#### THIS IS IMPORTANT FOR PERFORMANCE, see link
#for GPU rendering set the tile size large
# http://adaptivesamples.com/2013/11/05/auto-tile-size-addon-updated-again/
# GPU = 256x256
# CPU = 16x16
bpy.context.scene.render.tile_x = 256
bpy.context.scene.render.tile_y = 256
#set the format we want our image saved as, and file name/location
bpy.context.scene.render.image_settings.file_format = 'PNG'
bpy.data.scenes['Scene'].render.filepath = './bmw'
#pull the trigger
bpy.ops.render.render(write_still=True)
view raw bmw.py hosted with ❤ by GitHub