JdeRobot / RoboticsAcademy

Learn Robotics with JdeRobot
https://jderobot.github.io/RoboticsAcademy
GNU General Public License v3.0
314 stars 224 forks source link

Add scripts for GPU selection and benchmarking #2754

Open dpascualhe opened 1 day ago

dpascualhe commented 1 day ago

This PR includes scripts related with GPU managing in the RoboticsBackend. ONLY TESTED IN LINUX.

set_dri_name.sh

This script sets the DRI_NAME environment variable depending on the available GPUs, which could reduce the docker run command complexity by freeing users from having to check which devices are available and manually setting their paths (it is meant to be called within entrypoint.sh). The only extra dependency is pciutils.

It yields traces about whether or not a GPU has been selected and its vendor. By default, the script prioritizes Nvidia, then Intel, then anything else. This default behavior can be overriden by passing the preferred vender as argument (e.g. source set_dri_name.sh amd)

Real example in a laptop with dual GPU configuration:

$ source set_dri_name.sh 
Vendor: nvidia
DRI_NAME: card1
$ source set_dri_name.sh intel
Vendor: intel
DRI_NAME: card0
$ source set_dri_name.sh asdga
Error: No GPU found for the vendor 'asdga'.

check_gpu.sh

This script benchmarks all available GPUs using glmark2. First, it installs missing dependencies (pciutils and glmark2), and then proceeds to run said benchmark for each found device. It is helpful in two scenarios:

  1. Debugging: it is a real scenario in which vglrun is used and will complain if there's anything wrong with any of the available GPUs.
  2. Measuring perfomance: it can help us compare different devices / set-ups.

For running this script, which is meant to be a tool for developers, the docker run command must be adapted: $ xhost +local: && docker run --rm -e DISPLAY=$DISPLAY --gpus all --device /dev/dri --net host -it --entrypoint /bin/bash jderobot/robotics-backend Once inside the docker, you can launch the benchmarking tool by running: source check_gpu.sh

An example of running such benchmark can be seen in the following video: https://youtu.be/ZBXO3J_wgcg

Full output:

Running glmark2 on GPU: /dev/dri/card0 (PCI: 00:02.0, Name: Intel Corporation HD Graphics 630 (rev 04))
libEGL warning: egl: failed to create dri2 screen
libEGL warning: egl: failed to create dri2 screen
=======================================================
    glmark2 2021.02
=======================================================
    OpenGL Information
    GL_VENDOR:     Intel
    GL_RENDERER:   Mesa Intel(R) HD Graphics 630 (KBL GT2)
    GL_VERSION:    4.6 (Compatibility Profile) Mesa 23.2.1-1ubuntu3.1~22.04.2
=======================================================
[build] use-vbo=false: FPS: 84 FrameTime: 11.905 ms
[build] use-vbo=true: FPS: 80 FrameTime: 12.500 ms
[texture] texture-filter=nearest: FPS: 86 FrameTime: 11.628 ms
[texture] texture-filter=linear: FPS: 79 FrameTime: 12.658 ms
[texture] texture-filter=mipmap: FPS: 93 FrameTime: 10.753 ms
[shading] shading=gouraud: FPS: 86 FrameTime: 11.628 ms
[shading] shading=blinn-phong-inf: FPS: 88 FrameTime: 11.364 ms
[shading] shading=phong: FPS: 83 FrameTime: 12.048 ms
[shading] shading=cel: FPS: 89 FrameTime: 11.236 ms
[bump] bump-render=high-poly: FPS: 78 FrameTime: 12.821 ms
[bump] bump-render=normals: FPS: 81 FrameTime: 12.346 ms
[bump] bump-render=height: FPS: 82 FrameTime: 12.195 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 88 FrameTime: 11.364 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 77 FrameTime: 12.987 ms
[pulsar] light=false:quads=5:texture=false: FPS: 94 FrameTime: 10.638 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 47 FrameTime: 21.277 ms
[desktop] effect=shadow:windows=4: FPS: 31 FrameTime: 32.258 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 55 FrameTime: 18.182 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 66 FrameTime: 15.152 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 60 FrameTime: 16.667 ms
[ideas] speed=duration: FPS: 77 FrameTime: 12.987 ms
[jellyfish] <default>: FPS: 81 FrameTime: 12.346 ms
[terrain] <default>: FPS: 45 FrameTime: 22.222 ms
[shadow] <default>: FPS: 64 FrameTime: 15.625 ms
[refract] <default>: FPS: 60 FrameTime: 16.667 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 83 FrameTime: 12.048 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 85 FrameTime: 11.765 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 90 FrameTime: 11.111 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 92 FrameTime: 10.870 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 90 FrameTime: 11.111 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 87 FrameTime: 11.494 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 86 FrameTime: 11.628 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 93 FrameTime: 10.753 ms
=======================================================
                                  glmark2 Score: 77 
=======================================================

Running glmark2 on GPU: /dev/dri/card1 (PCI: 01:00.0, Name: NVIDIA Corporation GP107M [GeForce GTX 1050 Mobile] (rev a1))
=======================================================
    glmark2 2021.02
=======================================================
    OpenGL Information
    GL_VENDOR:     NVIDIA Corporation
    GL_RENDERER:   NVIDIA GeForce GTX 1050/PCIe/SSE2
    GL_VERSION:    4.6.0 NVIDIA 550.54.15
=======================================================
[build] use-vbo=false: FPS: 124 FrameTime: 8.065 ms
[build] use-vbo=true: FPS: 141 FrameTime: 7.092 ms
[texture] texture-filter=nearest: FPS: 128 FrameTime: 7.812 ms
[texture] texture-filter=linear: FPS: 142 FrameTime: 7.042 ms
[texture] texture-filter=mipmap: FPS: 135 FrameTime: 7.407 ms
[shading] shading=gouraud: FPS: 141 FrameTime: 7.092 ms
[shading] shading=blinn-phong-inf: FPS: 137 FrameTime: 7.299 ms
[shading] shading=phong: FPS: 122 FrameTime: 8.197 ms
[shading] shading=cel: FPS: 141 FrameTime: 7.092 ms
[bump] bump-render=high-poly: FPS: 140 FrameTime: 7.143 ms
[bump] bump-render=normals: FPS: 136 FrameTime: 7.353 ms
[bump] bump-render=height: FPS: 137 FrameTime: 7.299 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 118 FrameTime: 8.475 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 142 FrameTime: 7.042 ms
[pulsar] light=false:quads=5:texture=false: FPS: 136 FrameTime: 7.353 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 44 FrameTime: 22.727 ms
[desktop] effect=shadow:windows=4: FPS: 37 FrameTime: 27.027 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 77 FrameTime: 12.987 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 75 FrameTime: 13.333 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 93 FrameTime: 10.753 ms
[ideas] speed=duration: FPS: 132 FrameTime: 7.576 ms
[jellyfish] <default>: FPS: 135 FrameTime: 7.407 ms
[terrain] <default>: FPS: 52 FrameTime: 19.231 ms
[shadow] <default>: FPS: 98 FrameTime: 10.204 ms
[refract] <default>: FPS: 79 FrameTime: 12.658 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 140 FrameTime: 7.143 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 129 FrameTime: 7.752 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 136 FrameTime: 7.353 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 145 FrameTime: 6.897 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 141 FrameTime: 7.092 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 142 FrameTime: 7.042 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 126 FrameTime: 7.937 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 136 FrameTime: 7.353 ms
=======================================================
                                  glmark2 Score: 119 
=======================================================
dpascualhe commented 4 hours ago

Right now the set_dri_name.sh does not make much sense, because for it to work properly you need to specify if you want to launch the docker without gpu, with Intel or with Nvidia.

Unless there is an advanced user who wants to choose a specific architecture, if the script is launched with no arguments it prioritizes Nvidia, then Intel, then any other GPU, and if none are found then the DRI_NAME variable is left empty and no acceleration will be performed.

Also executing gives the next error if the docker is launched with no gpu or only Intel:

source set_dri_name.sh 
bash: lspci: command not found
Warning: nvidia-smi not available or failed, skipping NVIDIA GPU.
Error: No GPU found for the vendor ''.

It's yielding that error because it can't run lspci. I added pcituils as a dependency in the dockerfiles here in RoboticsAcademy (please let me know if that is the right place). Could you install pciutils and then run the script? It should be working then.

In any case, I'll update the script to improve the error management.

And also I'm not able of executing the check_gpu.sh :

Running glmark2 on GPU: /dev/dri/card1 (PCI: 00:02.0, Name: Intel Corporation Device a788 (rev 04))
Error: main: Could not initialize canvas

Running glmark2 on GPU: /dev/dri/card0 (PCI: 01:00.0, Name: NVIDIA Corporation Device 28e0 (rev a1))
Error: main: Could not initialize canvas

Which docker command are you using to run the container?

Thanks so much for taking the time of reviewing the PR! :hugs:

javizqh commented 44 minutes ago

Using the command:

sudo apt-get install pciutils

Seems to solve the ./set_dri_name script and now it works properly.

For the second part, I am launching the docker container with the develop_academy.sh script found in RoboticsAcademy that uses docker compose with the files found in here.