Running Linux GPU Applications on Windows#

Introduction top#

Some of the GPU-requiring tools commonly used with SVL Simulator, like Apollo or Autoware.Auto, might require the Linux operating system to run. If you don't have Linux available or prefer to use Windows, it's now possible to run Linux programs using Windows Subsystem for Linux (WSL).

Features available in WSL are dependent on the version of Windows 10. Windows build 21362 contains the version of WSL required to run Linux GPU applications on Windows. As an alternative, you can set up a desktop environment).

Installation top#

NOTE: At the time of writing, most of the drivers and software required to use GPU-PV in WSL are still in preview. This might require using their pre-release versions. Details can be found in the specific sub-sections.

Verify Windows 10 version top#

In the Windows command line, enter:

winver

The reported OS Build should be 21362 or higher. If the build number is lower, and your system is up to date, the required Windows version is not yet a part of public release. To use it, you will have to join Windows Insider Program on the Dev Channel. Doing so will let you use preview builds of Windows 10. If you're interested, please follow official instructions and update your Windows version.

Install WSL 2 top#

To install WSL 2, please refer to the official documentation. We recommend using Ubuntu 18.04 or Ubuntu 20.04 Linux distribution. This tutorial will assume Ubuntu 20.04 is installed.

If you have installed WSL previously, make sure you're using WSL version 2. To check for version, enter:

wsl -l -v

The distribution you're planning to use should report 2 under VERSION. If you're using WSL 1, update it to WSL 2.

Make sure your Linux kernel version is up to date. You can update it through an elevated Windows command line by entering:

wsl --update

Install NVIDIA drivers top#

As of the end of September 2021, the NVIDIA drivers for CUDA on WSL are still in public preview. Version 470.14 (with CUDA 11.3) or higher is required. You can check your current driver version through Windows command line, by entering:

nvidia-smi

If your driver version is older, you can download required version from official NVIDIA web page.

To verify that your GPU is working inside WSL, you can build and run one of default CUDA examples using WSL terminal:

cd /usr/local/cuda/samples/4_Finance/BlackScholes
make
./BlackScholes

Your console should provide you with output similar to the one shown below. This means that your GPU is accessible inside of WSL and can be used to run CUDA programs.

[./BlackScholes] - Starting...
GPU Device 0: "Pascal" with compute capability 6.1

Initializing data...
...allocating CPU memory for options.
...allocating GPU memory for options.
...generating input data in CPU mem.
...copying input data to GPU mem.
Data init done.

Executing Black-Scholes GPU kernel (512 iterations)...
Options count             : 8000000
BlackScholesGPU() time    : 0.363584 msec
Effective memory bandwidth: 220.031695 GB/s
Gigaoptions per second    : 22.003170

BlackScholes, Throughput = 22.0032 GOptions/s, Time = 0.00036 s, Size = 8000000 options, NumDevsUsed = 1, Workgroup = 128

Reading back GPU results...
Checking the results...
...running CPU calculations.

Comparing the results...
L1 norm: 1.741792E-07
Max absolute error: 1.192093E-05

Shutting down...
...releasing GPU memory.
...releasing CPU memory.
Shutdown done.

[BlackScholes] - Test Summary

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

Test passed

Install Docker Desktop for Windows top#

If you plan to use Docker inside your WSL 2 distro, we suggest to install Docker Desktop by following official documentation. Alternatively, you can decide to skip Docker Desktop and use Docker and NVIDIA Container Toolkit installed directly from your WSL 2. We recommend the first option - this tutorial will assume Docker Desktop for Windows is used. If you insist on using the second option, you can find instructions in official NVIDIA documentation.

If you're already using Docker Desktop for Windows, make sure version 3.1 or higher is installed.

After installing and launching Docker Desktop, navigate to Settings -> General and make sure that the option Use the WSL 2 based engine is enabled. After that, navigate to Settings -> Resources -> WSL integration and make sure that integration with your WSL 2 distro is enabled.

Whenever you're using Docker from WSL, the Docker Desktop application must be running on your Windows machine - otherwise WSL won't be able to recognize service docker.

To verify that Docker environment is running properly, enter your WSL terminal and launch a sample CUDA docker image from NVIDIA:

docker run --rm -it --gpus=all --env NVIDIA_DISABLE_REQUIRE=1 nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark

NOTE: Parameter --env NVIDIA_DISABLE_REQUIRE=1 disables the CUDA version check. This is required as of the end of September 2021 due to bug in NVIDIA drivers (CUDA version reported in WSL is lower than installed).

Your console should provide you with output similar to the one shown below. This means that your GPU is accessible inside of Docker containers and can be used to run CUDA programs.

Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance.
        -fullscreen       (run n-body simulation in fullscreen mode)
        -fp64             (use double precision floating point values for simulation)
        -hostmem          (stores simulation data in host memory)
        -benchmark        (run benchmark to measure performance)
        -numbodies=<N>    (number of bodies (>= 1) to run in simulation)
        -device=<d>       (where d=0,1,2.... for the CUDA device to use)
        -numdevices=<i>   (where i=(number of CUDA devices > 0) to use for simulation)
        -compare          (compares simulation results running once on the default GPU and once on the CPU)
        -cpu              (run n-body simulation on the CPU)
        -tipsy=<file.bin> (load a tipsy model file for simulation)

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation
> 1 Devices used for simulation
GPU Device 0: "Pascal" with compute capability 6.1

> Compute 6.1 CUDA device: [NVIDIA GeForce GTX 1080]
20480 bodies, total time for 10 iterations: 16.788 ms
= 249.832 billion interactions per second
= 4996.645 single-precision GFLOP/s at 20 flops per interaction

Set up desktop environment (optional) top#

If you want to run any GUI-based applications inside your WSL or Docker environment, you have configure the X Window System. By default, display options inside of WSL are not configured and no valid output device is registered. This means not only that GUI will not be displayed, but also that any program attempting to output something to screen might not work correctly or fail to launch.

If you have Windows 10 build 21362 or higher, you don't have to do anything - along your WSL instance, WSLg should have been automatically installed. WSLg pipes X11 and Wayland (used to run Linux GUI applications) directly into Windows graphical user interface. This means that any GUI application launched inside WSL will simply open on your Windows desktop. To verify that's the case, run any GUI-based application from your WSL instance. As an example, you can use one of OpenGL test applications. In your WSL terminal, enter:

glxgears

This should open new window with three spinning gears. If your Linux distro does not have this installed by default, you can get glxgears application from mesa-utils package:

sudo apt install mesa-utils

Networking considerations top#

Compared to using Docker on Linux, using it on Windows through Docker Desktop with the WSL 2 backend has some significant differences in networking. Whenever you want to use any kind of networking functionality in a container running on Docker Desktop, make sure to take the points below into account:

  • The --net=host option for docker run will not behave as expected. The Docker daemon runs inside an isolated network namespace, which, from the perspective of the Docker container, is a host network. You won't be able to access containers started with this option through the usual means.
  • Docker Desktop provides special host name (host.docker.internal) that resolves to your host machine. It always resolves to an IP reachable from the container, and resolves to 127.0.0.1 on the host. If you can't connect to your container through localhost, try using host.docker.internal instead.
  • Since you can't use the --net=host option, all of the ports that will be used to communicate with the container have to be explicitly exposed using -p flags (see official documentation for details). They will be tunneled both to the WSL 2 network namespace and the Windows host.