Monday, March 18, 2019

AMD GPU on Ubuntu

Summary: I upgraded my Ubuntu desktop to an AMD graphics card; here's my notes on the (very simple) process. You don't need AMDs closed drivers and you don't need any external repositories — everything you need for both graphics and OpenCL is already included in Ubuntu itself.


I built my own desktop in early 2016. Not a high-end system, but pretty fast, with plenty of memory and with great cost-performance. Overall, it's aging remarkably well and will be fine for at least another three years, possibly longer. The exception is the graphics card. The Nvidia 750ti I had was a midrange card when it launched in late 2013, and already a generation behind when I bought it(1).  It has served me well, but by now it's really starting to show its age. Some of my current games only run at the lowest possible graphical settings.


Do people still use desktops? Yes, many do. Do people bring their desktops — and monitor, and keyboard, and mouse — with them when they travel? No, normal people don't. Somebody must have forgotten to tell this guy. Supercomputing 17, Denver.

Worse, the Nvidia Linux drivers — not open source so they must be installed separately — have increasingly been causing problems. I've had screen tearing and other glitches for the past year. The driver now often fails to restart properly after waking the machine so I can no longer put it to sleep. Botched driver upgrades have left me without a usable desktop a couple of times. I don't know if my card is too old to be supported properly, or if the quality of the Nvidia drivers are declining.


AMD is Nvidia's main competitor, and the underdog in the GPU market. They provide full open source Linux drivers for their GPUs. For a few years now, any AMD card should theoretically work out of the box; in practice you always seemed to have to tweak your graphics settings, add unstable or unfinished external components or upgrade your kernel. But for the past year or so, people have increasingly insisted that yes, nowadays it really is as simple as just switching cards, with no messing about with your system.


I didn't think to take a picture of the card until I had already installed it. Besides, for all that I like computers in principle, seeing modern hardware if often as exciting as watching paint dry. Instead, here's a Cray 1 supercomputer on display at the Supercomputing conference in Dallas last year.

So I took the plunge. I got an AMD RX570 with 8GB of memory — a two-year old mid-range card from their previous generation. Not hugely fast, but inexpensive and great performance for the money. The hardware installation is straightforward: unplug and open your computer, pull out the old card then slot in new one. Remember to connect the PCIe power cord to the card, then close the case and restart.

My machine came back up with no issues. The desktop and 3D rendering all worked out of the box. I have no more tearing, and the system definitely feels more responsive. One game was confused by the Nvidia drivers still on the system so I removed them (you can do this from the software center, but it's faster on the command line):

  $ sudo apt purge nvidia*
  $ sudo apt autoremove


Vulkan


While OpenGL support is included out of the box in Ubuntu, the newer, faster Vulkan support is not (these are both standard libraries for rendering 3D graphics). You can install the Vulkan libraries with the following line:

  $ sudo apt install mesa-vulkan-drivers vulkan-utils mesa-vulkan-drivers:i386 libvulkan-dev dkms

What difference does Vulkan make? "The Talos Principle" is a fully immersive 3D puzzle game with a cool storyline that aims for a photorealistic graphical style. It can use either OpenGL or Vulkan. Here's a set of benchmarks with my old 750ti card and my new RX570, with OpenGL or Vulkan, at three different levels of graphical detail:


Dotted lines are OpenGL, solid lines are Vulkan. The blue pair is my old card, the red pair is the new one. The red, horizontal line marks 60 frames/s; you ideally want the graphics to be faster than this at all times.


Take-away: Vulcan is around 25% faster than OpenGL in this game, both for the old card and for the new one. That's a major speed difference just for changing a rendering library. Also, my new card is ~120% faster than my old one. Sounds reasonable for the same class of card about three years apart.

OpenCL


At this point I had a fully feature-complete, well-working graphics system. But GPUs are used for more than graphics these days. You can use GPUs as general accelerators for certain kinds of computations, deep learning and certain kinds of molecular dynamics in particular. We have several dozen compute nodes with very high-end GPUs at work for this purpose (and no, they don't do graphics at all, just computation).

Nvidia is completely dominant today with their CUDA library and compilers, but it's not the only alternative. If you want to do do real compute on an AMD card you should install ROCm, and I intend to do that in the near future. Meanwhile, you can install basic OpenCL 1.1 support using only the open tools in Ubuntu.

OpenCL is an open standard for programming GPUs, and you can use it on AMD GPUs, on Intel GPUs and on smartphones (yes, they have GPUs and yes, they can be useful for this in some cases) and it works on Nvidia GPUs as well. It's not as efficient as CUDA, and it's not as popular, but it still gets the job done, especially if you're just looking to learn.

Today, getting basic OpenCL support for AMD on Ubuntu is easy. Ubuntu already carries all packages you need. Install them with:

sudo apt install clinfo mesa-opencl-icd opencl-headers

"clinfo" is a utility that reports what kind of OpenCL support you have, if any. Run "clinfo" on the command line to see what your particular hardware supports.

"mesa-opencl-icd" (and the packages it pulls in) is the actual OpenCL 1.1 libraries, compiler and other stuff. The "opencl-headers" gives you a set of standard headers for your own code.

There is one single hack you do need to get OpenCL working completely transparently. For some reason, the OpenCL library doesn't get a symbolic link "libOpenCL.so", and this is needed to be able to link with the library without giving the linker the exact file. You can add the link yourself like this:

$ cd /usr/lib/x86_64-linux-gnu/
$ sudo ln libOpenCL.so.1 libOpenCL.so
$ cd


Now you can take any OpenCL program, compile it and run on the GPU. For instance, download this vector addition example: vecAdd.c (from this short tutorial). Compile the program, then run it:

$ gcc vec_add.c -o vec_add  -lOpenCL -lm
$ ./vec_add
final result: 1.000000


There you have it. Full 3D graphics capability using OpenGL and Vulkan (and with working Proton support on Steam); and OpenCL 1.1 support both for running and developing code. All using open source and without enabling a single PPA or going outside the Ubuntu repos. Not bad, not bad at all.


1) Buying the newest, greatest high-end GPUs rarely makes sense. You pay a huge extra cost — in money and in power — for a bit of extra performance and perhaps some new functionality. But games are made to run well on mid-range cards or lower (for as many potential buyers as possible), so that extra cost is largely wasted. They also tend to be physically large and won't fit a small case; and they use a lot of power so you may need to upgrade your power supply and add fans. And as they're new, the drivers won't be as stable or polished. 

You'll spend a lot of money for a computer that's noisy, big, uses lots of power, with frequent graphical glitches and crashes. For all that, you get some nice, cool in-game graphical effects that you notice once then ignore, because you're too busy playing the actual game to notice.