14 November 2020

Install Nvidia Drivers & CUDA in Ubuntu 20.04 (in UEFI mode with Secure Boot Enabled)

In the previous article, we have dealt with Installation of Ubuntu in Dual Boot Mode using UEFI. Now lets look at the installation of Nvidia Drivers for the GPU.

Basic Verification's:

First let us find out the graphics card that is presently used by the system. Click on Settings->About. Presently we have "NV138 / Mesa Intel® UHD Graphics 620 (KBL GT2)" installed.

 
Next let us find information about the GPU. Do we really have an Nvidia Graphics Card? Open the terminal and type in:

$ sudo lshw -C display
  *-display                 
       description: VGA compatible controller
       product: UHD Graphics 620
       vendor: Intel Corporation
       physical id: 2
       bus info: pci@0000:00:02.0
       version: 07
       width: 64 bits
       clock: 33MHz
       capabilities: pciexpress msi pm vga_controller bus_master cap_list rom
       configuration: driver=i915 latency=0
       resources: irq:129 memory:ed000000-edffffff memory:c0000000-cfffffff ioport:f000(size=64) memory:c0000-dffff
  *-display
       description: 3D controller
       product: GP108M [GeForce MX150]
       vendor: NVIDIA Corporation
       physical id: 0
       bus info: pci@0000:01:00.0
       version: a1
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress bus_master cap_list rom
       configuration: driver=nouveau latency=0
       resources: irq:128 memory:ee000000-eeffffff memory:d0000000-dfffffff memory:e0000000-e1ffffff ioport:e000(size=128) memory:ef000000-ef07ffff

It is evident that we have Nvidia GeForce MX150 graphics card, besides an Intel UHD Graphics 620. The later is the default graphics card and our goal is to change the default to Nvidia GeForce MX150. This is a prerequisite for the installation of CUDA, which is necessary for running the machine learning algorithms.

Most importantly, let us find out if we are in the UEFI mode. Open the terminal and type in the following command:

$ sudo [ -d /sys/firmware/efi ] && echo "Installed in UEFI mode" || echo "Installed in Legacy mode"

Identify the Drivers to Install:

There are two ways to do it. One is to get the info from Ubuntu itself and the other is to get the info from Nvidia. I am not sure which is the best method, so generally go with the recommendation of Ubuntu. But before I install that, I also cross verify that with Nvidia.
$ sudo ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:1c.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001D10sv00001043sd0000163Ebc03sc02i00
vendor   : NVIDIA Corporation
model    : GP108M [GeForce MX150]
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-440-server - distro non-free
driver   : nvidia-driver-450 - distro non-free recommended
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-435 - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

The recommended driver is nvidia-driver-450 .

If we want to get the  same details in a graphical  manner, we can click on Show Applications->Additional Drivers


Now let us get to the Nvidia website and check if this is indeed a recommended driver for installation with GeForce MX150 for Linux. 

 




So driver version 455.38 is the latest, but 450.80 is the latest in the 450 version. So let us install 450 as it is recommended by Ubuntu.

Installation of Driver:

Lets go to the CLI and type in:

$ sudo apt install nvidia-driver-450

Lets now reboot the system.

Verify Installation: 

Click on Settings->About. Presently we have  "NVIDIA Corporation GP108M [GeForce MX150] / GeForce MX150/PCIe/SSE2" installed.
Go to the terminal and type in: 
$ nvidia-smi
 
 This will give the GPU info and process that are using Nvidia GPU:
 

Configure the Graphics Diver :

The nvidia-settings command start a GUI tool for configuring the NVIDIA graphics driver. This is useful to see all GPU info or configure multiple external screen/monitors connected to your system. Open the terminal and type the following command:

$ sudo nvidia-settings


 

Un-Install Nvidia Drivers:

Lets say, for some reason you want to install the Nvidia drivers just installed. Or lets say that the installation did not go through properly, for whatever reasons. Then the right thing to do would be to uninstall the nvidia-driver-450 that we had installed a while back. Follow it with the un-installation / Disable/blacklist Nouveau nvidia driver. Then only attempt a re-installation.
 

Install CUDA toolkit:

There are different methods for the installation of CUDA toolkit. The easiest method is to install CUDA from Ubuntu repository. However it needs to be noted that it might not come with the latest toolkit.

1
2
$ sudo apt update
$ sudo apt install nvidia-cuda-toolkit

That is a download of 3.86 GB. So we need to check if the installation has been completed successfully.

$ nvcc --version

 Verify Sample file of CUDA toolkit:

Since we have installed the version 10.1.243, let us also install the sample file appropriate to this. Check the details from CUDA Toolkit Documentation v10.1.243

The samples are available at Nvidia CUDA samples at GitHub .What we need is "CUDA Samples v10.1 update 2".

 I have run into problems, a quicker work around seems to be to pick up a sample program from An Easy Introduction to CUDA C and C++ .

#include <stdio.h>

__global__
void saxpy(int n, float a, float *x, float *y)
{
  int i = blockIdx.x*blockDim.x + threadIdx.x;
  if (i < n) y[i] = a*x[i] + y[i];
}

int main(void)
{
  int N = 1<<20;
  float *x, *y, *d_x, *d_y;
  x = (float*)malloc(N*sizeof(float));
  y = (float*)malloc(N*sizeof(float));

  cudaMalloc(&d_x, N*sizeof(float)); 
  cudaMalloc(&d_y, N*sizeof(float));

  for (int i = 0; i < N; i++) {
    x[i] = 1.0f;
    y[i] = 2.0f;
  }

  cudaMemcpy(d_x, x, N*sizeof(float), cudaMemcpyHostToDevice);
  cudaMemcpy(d_y, y, N*sizeof(float), cudaMemcpyHostToDevice);

  // Perform SAXPY on 1M elements
  saxpy<<<(N+255)/256, 256>>>(N, 2.0f, d_x, d_y);

  cudaMemcpy(y, d_y, N*sizeof(float), cudaMemcpyDeviceToHost);

  float maxError = 0.0f;
  for (int i = 0; i < N; i++)
    maxError = max(maxError, abs(y[i]-4.0f));
  printf("Max error: %f\n", maxError);

  cudaFree(d_x);
  cudaFree(d_y);
  free(x);
  free(y);
}

Save the code in a file with a .cu extension, say saxpy.cu. We can then compile it with nvcc  

nvcc -o saxpy saxpy.cu

We can then run the code: 

./saxpy

This is the output we get:



No comments:

Post a Comment