Running GPU accelerated WebGL Application on headless chrome on EC2
Tags: webgl, gpu, ec2, chrome
Published: 2021-12-18 07:46:57

I make a performance-critical WebGL library that loads and simulates some heavy 3D models. Detecting any compromise on performances on every code changes are crucial. So I made a benchmarking system and integrated it into CI/CD. It starts an EC2 instance, retrieves the latest version of our library and runs the benchmarking in the headless, gpu-accelerated chrome. Getting chrome the gpu-acceleration in EC2 environment was very tricky. I'm going to share how I did it in this article.

## EC2 instance type

There were two requirement for the environment.

- To have a GPU
- To represent user environment well. Neither too good nor too bad.

[G4 instances](https://aws.amazon.com/ec2/instance-types/g4/) family seemed all good for me so I picked *g4ad.xlarge* (or *g4dn.xlarge*, if you prefer to use NVIDIA)because it was the cheapest one.

## AMI

I had two options.

- Basic AMI(e.g. Amazon Linux 2) and install the driver manually 
- Commercial AMI that is pre-shipped with the gpu driver. 

I tried the former and even with a [well-written instructions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-nvidia-driver.html) it was a hassle for several reasons.
- It took a long time to download and install the driver. (about 10m)
- Initializer shell script got very complicated
    - Installing the dependencies
    - Rebooting the system

So I chose the latter. I used [Amazon Linux 2 AMI with AMD Radeon Pro Driver](https://aws.amazon.com/marketplace/pp/prodview-h2zpfhnkvdiko) when I was using *g4ad* and `Deep Learning AMI (Amazon Linux 2) - ami-08dbdbed58c271fec` when *g4dn*. I recommend you to do the same because it's cheap, ready to go, and saves you from all the mundane system configuration.

## Chrome version

I installed Chrome using yum
```bash
# Enable EPEL repository so yum can find chromium
sudo amazon-linux-extras install epel -y
sudo yum install chromium -y
```
I tried some other options like using direct chrome installer and Puppeteer but for some reason they failed to recognize gpu driver. I didn't bother to inspect the reason since the first one worked well.

## Headless Chrome and EGL

Here's little background knowledge about EGL. In order to use OpenGL you need to create an OpenGL Context. On Linux it's been usually done by GLX which requires windows system(e.g. X11), which requires display device (e.g. monitor, VNC). The problem was that this whole dependency chain kept people from using OpenGL on display-less devices like server or Arduino. So EGL emerged. EGL is a protocol that enables OpenGL Context creation without windows system. It made everything so easier and is now regarded as the future of OpenGL Context Interface. Now major graphics drivers are shipped with their own EGL implementation library.

Headless Chrome is one of the perfect example in which EGL is desired. Headless Chrome by definition lacks display therefore you need EGL to run OpenGL.

## Run GPU-Accelerated Headless Chrome

All I had to do was to give the right arguments

```
sudo chromium-browser --no-sandbox --headless --use-gl=egl 'https://benchmarking.system'
```

- sudo - I don't exactly know why but unprivileged users didn't get gpu acceleration.
- chromium-browser - Default executable name of chromium installed by yum.
- --no-sandbox - Required for root user
- --headless - Required for EGL
- --use-gl=egl - Enables EGL

## Debugging

Chrome has `chrome://gpu` dashboard page that displays every gpu-related stuff. All I had to was to export it into pdf.

```
sudo chromium-browser --no-sandbox --headless --use-gl=egl --print-to-pdf=out.pdf 'chrome://gpu'
```

.. and bring it into my local computer using `scp` like this

```
scp -i certificate.pem ec2-user@<ec2 ip address>:<path to out.pdf> ./ 
```

When everything is ok it should look like this.

![sample graphics feature status](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbaify7mwfapsuq3pzen.png)

and the correct driver information should be shown.

![sample driver information](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1u21hdz7zs59cbnwzku.png)