Skip to content

1.0 Running freeview

Jennings Zhang edited this page Apr 9, 2021 · 3 revisions

Background

Typically, GUI apps can work in Linux containers on a Linux host by allowing the container to connect to the host's X (display) server. In the most basic cases, the container needs to have graphical libraries (like Qt) installed. freeview is more complicated because it depends on OpenGL. The steps to run an OpenGL application are different depending on your host graphics drivers.

You can figure out what drivers are being used by OpenGL by running

glxinfo | grep "OpenGL renderer"

glxinfo and glxgears are provided by the package mesa-utils on Ubuntu. They are helpful for testing whether OpenGL works.

If the command glxinfo doesn't work, stop! Fix your drivers before moving on.

If the output is something like "Mesa Intel(R) HD Graphics 630 (KBL GT2)" (integrated graphics, usually for laptops) or "llvmpipe (LLVM 10.0.0, 256 bits)" (fallback graphics, maybe remote through SSH X forwarding or VNC), you're in luck—the instructions still aren't straightforward, but at least you won't have to fight with driver problems. Mesa is an open source implementation of the OpenGL specification.

On the other hand, Nvidia drivers are proprietary software and contain binary blobs. Nvidia dGPUs have better performance, but harder to get working, neither is this (rendering OpenGL to a host X server from within a container using nvidia-container-toolkit) officially supported.

Nvidia Containers

Skip this section if you are not using an Nvidia dGPU.

Install nvidia-container-toolkit. These two commands below will help you verify that everything is working:

# You might need to 
#     docker pull nvidia/cuda:10.0-base
# if you haven't already

nvidia-container-cli info
docker run --gpus all nvidia/cuda:11.2.2-base-ubuntu20.04 nvidia-smi

# if the '--gpus all' is problematic, your docker-cli is probably outdated.
# Make sure that you have at least version 19.03:
docker --version

Using Singularity

Singularity is better suited for scientific use-cases than Docker.

Try either of these two:

# typical usage
singularity run docker://fnndsc/freesurfer:freeview
# specify filename to open
singularity exec docker://fnndsc/freesurfer:freeview freeview brain.nii.gz
# using Nvidia dGPU
singularity run --nv docker://fnndsc/freesurfer:freeview

Rest of the instructions below are from past trifles with Docker. If Singularity works for you, then all that is below is unimportant.

About pl-fshack

pl-fshack is a naive Python wrapper around the entire FreeSurfer software distribution. The container image fnndsc/pl-fshack:latest contains all of FreeSurfer's programs, including freeview.

The fnndsc/pl-fshack:latest Docker image has the relevant graphical libraries preinstalled (it is a bloated image). This page shows you how to run freeview inside the fnndsc/pl-fshack:latest container.

Using Docker

Using Mesa (Not Nvidia)

If you are using anything but Nvidia, like Intel integrated graphics, these instructions are for you.

# Edit this command before copying and pasting,
# you should always understand the command before you run it!
docker run --rm
  # connect to host computer's GUI
  -v $HOME/.Xauthority:$HOME/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY
  # run as normal user
  --env HOME --user $(id -u)
  # not strictly necessary but it'll save you from warnings
  --device /dev/dri
  # load your brain data
  -v $PWD/data.nii.gz:/data.nii.gz
  # program to run
  --entrypoint /usr/local/freesurfer/bin/freeview
  # docker image name and data filename
  fnndsc/pl-fshack:latest /data.nii.gz

# Or, more suitably for copy/paste:

docker run --rm                                    \
  -v $HOME/.Xauthority:$HOME/.Xauthority           \
  -v /tmp/.X11-unix:/tmp/.X11-unix                 \
  -e DISPLAY --env HOME --user $(id -u)            \
  --device /dev/dri                                \
  -v $(pwd):$HOME/host                             \
  --entrypoint /usr/local/freesurfer/bin/freeview  \
  fnndsc/pl-fshack:latest

Using Nvidia

Run freeview:

# Edit the command below before copying and pasting.
docker run --rm                         
  # connect to host computer's GUI      
  -v $HOME/.Xauthority:$HOME/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY
  # run as normal user
  --env HOME --user $(id -u)
  # use Nvidia dGPU with display support
  --gpus all,capabilities=display
  # load your brain data
  -v $PWD/someones_epi.nii.gz:/data.nii.gz
  # a workaround
  --entrypoint /bin/bash -i
  # container name, command to run, and arguments
  fnndsc/pl-fshack:latest <<< "freeview /data.nii.gz"

# Alternatively, since the above multiline is not copy/paste friendly, do
docker run --rm                             \
  -v $HOME/.Xauthority:$HOME/.Xauthority    \
  -v /tmp/.X11-unix:/tmp/.X11-unix          \
  -e DISPLAY                                \
  --env HOME --user $(id -u)                \
  --gpus all,capabilities=display           \
  -v $(pwd):/$HOME/host                     \
  --entrypoint /bin/bash  -i                \
  fnndsc/pl-fshack:latest <<< "freeview"

Result

You can confirm that the nvidia dGPU is in use using nvidia-smi.

Screenshot of Freeview

Race Condition Bug

Let's try calling freeview directly...

docker run --rm  \                 
  [...]          \
  --gpus all,capabilities=display \
  --entrypoint /usr/local/freesurfer/bin/freeview fnndsc/pl-fshack:nvidia

Sometimes it works, sometimes it doesn't. Seems like a race condition in MPI. This is an upstream bug.

error: No such file or directory
[0]PETSC ERROR: ------------------------------------------------------------------------
[0]PETSC ERROR: Caught signal
[0]PETSC ERROR: Try option -start_in_debugger or -on_error_attach_debugger
[0]PETSC ERROR: or see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Signal[0]PETSC ERROR: or try http://valgrind.org on linux or man libgmalloc on Apple to find memory corruption errors
[0]PETSC ERROR: configure using --with-debugging=yes, recompile, link, and run 
[0]PETSC ERROR: to get more information on the crash.
[0]PETSC ERROR: --------------------- Error Message ------------------------------------
[0]PETSC ERROR: Signal received!
[0]PETSC ERROR: ------------------------------------------------------------------------
[0]PETSC ERROR: Petsc Release Version 2.3.3, Patch 13, Thu May 15 17:29:26 CDT 2008 HG revision: 4466c6289a0922df26e20626fd4a0b4dd03c8124
[0]PETSC ERROR: See docs/changes/index.html for recent updates.
[0]PETSC ERROR: See docs/faq.html for hints about trouble shooting.
[0]PETSC ERROR: See docs/index.html for manual pages.
[0]PETSC ERROR: ------------------------------------------------------------------------
[0]PETSC ERROR: Unknown Name on a linux-gnu named 55d7ff0224c8 by Unknown Tue Jun 23 00:25:47 2020
[0]PETSC ERROR: Libraries linked from /autofs/space/lyon_006/pubsw/Linux2-2.3-x86_64/packages/petsc/2.3.3-p13/src/petsc-2.3.3-p13/lib/linux-gnu-c-opt
[0]PETSC ERROR: Configure run at Tue Aug 10 15:01:59 2010
[0]PETSC ERROR: Configure options --with-debugging=no --with-cc=gcc --with-fc=g77 --download-f-blas-lapack=0 --download-mpich=1 --with-mpi=1 --with-x=0 --with-gnu-copyright-code=0 --with-shared=0 COPTFLAGS=-O3 CXXOPTFLAGS=-O3 FOPTFLAGS=-O3
[0]PETSC ERROR: ------------------------------------------------------------------------
[0]PETSC ERROR: User provided function() line 0 in unknown directory unknown file
[unset]: aborting job:
application called MPI_Abort(MPI_COMM_WORLD, 59) - process 0

For whatever reason, the freeview command must not be present in the docker run command itself, but instead be passed via STDIN.

The following will (sometimes) not work:

docker run --rm  \
  -v $HOME/.Xauthority:$HOME/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY \
  --env HOME --user $(id -u) \
  -v $PWD/someones_epi.nii.gz:/data.nii.gz \
  --gpus all,capabilities=display \
  --entrypoint /usr/local/freesurfer/bin/freeview fnndsc/pl-fshack:nvidia /data.nii.gz
docker run --rm  \
  -v $HOME/.Xauthority:$HOME/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY \
  --env HOME --user $(id -u) \
  --gpus all,capabilities=display \
  --entrypoint /usr/local/freesurfer/bin/freeview fnndsc/pl-fshack:nvidia
docker run --rm  \
  -v $HOME/.Xauthority:$HOME/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY \
  --env HOME --user $(id -u) \
  --gpus all,capabilities=display \
  -it --entrypoint /bin/bash fnndsc/pl-fshack:nvidia -c freeview

I found that using docker run -i and a herestring instead works 100% of the time. You might find it easier to open an interactive shell instead (-it --entrypoint /bin/bash) and then type freeview.

X Troubleshooting

No protocol specified
QXcbConnection: Could not connect to display :1.0
Could not connect to any X display.

This might happen if your user account is not local (e.g. an FNNDSC network account). Before docker run, you need to do

xhost +