0x01 写在前面

现在很多项目都是基于 Linux 开发的,但是平常使用还是 Windows 香。(主要是我物理机是 Windows 我又不想装成 Linux

而有时候 Windows 真的非常不利于开发者,他的各自环境太难配置了,这时候是 Linux 香。

但是 WSL 才是真的香,启动快,共享空间,现在还能共享 GPU 了。。。。。

而我本次鉴于某些原因,失去了千辛万苦配置好 Windows 上能跑的 pycuda 的环境,重配又没有成功。好契机。

不说这么多,我先冲了。希望本教程能帮到你。


0x02 确保 WSL2

在此之前,先确保已经有 WSL/WSL2 ,若无,则可参考另一篇博文

检查现有的WSL版本

以管理员身份运行 cmd ,并输入下面的命令,检查准备安装 CUDALinux发行版本的 WSL 版本。

1
wsl --list -v

检查WSL版本

如上图,笔者的两个都是 WSL1 ,居然都是 VERSION = 1

幸好笔者在搭建的时候遇到两次没有放弃。重新查阅了别人的博客,这才检查了自己的 WSL 的版本,才发现居然都是版本1,尽管在搭建之前已经执行了命令 wsl --set-default-version 2 设置默认版本为 WSL2 。但是居然安装的还是1,或许是笔者没有在应用商店安装而是使用了,lxrunoffline 工具。(参阅上一篇博客)。导致后续验证 CUDA 是否安装成功时,一直报错运行的 CUDA 版本与显卡驱动不匹配,笔者就轻信了,认为是 CUDA11 的锅,删除了 WSL 重装了一次,从 CUDA11 降到了 CUDA10.2 ,然而还是一样的错误。

不过幸好这里找到了是这个原因,在转化升级 WSLWSL2 之后,这个问题就不存在了。安装就一瞬完成了。


升级现有的 WSL 到 WSL2

首先使用下面的命令,查看查看有哪些 WSL 。在 cmd 中键入下面的命令。

1
wsl -l

然后将想要升级的名字记住,设置其版本为 WSL2 ,在 cmd 中键入下面的命令。

1
2
# wsl --set-version <WSL名称> 2 
wsl --set-version Ubuntu18CUDA 2

升级WSL

这个过程取决于设备,可能时间比较久(笔者花了7分钟左右。)

待其完成后,就好啦。

转换完毕

再查看,转换的版本就对了

再次查看


0x03 安装 cuda

换源

由于总所周知的原因,官方源往往很慢,于是推荐换个源先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 下面所有都是非 root 自己添加 sudo
# 首先备份源列表
cp /etc/apt/sources.list /etc/apt/sources.list_backup

# 打开sources.list文件
vim /etc/apt/sources.list

# 在最前面添加阿里源
deb https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

最好注释掉其他的,默认的,后面的源,不然会多一些不可达的不必要的error。

换源

然后刷新一下源,一定要刷新一下源。

1
2
3
apt-get update
apt-get upgrade
apt-get install build-essential

耗时有点久。。。。。


安装驱动

这一部分的官方教程在这里:cuda for wsl

在 Windows 上进行显卡驱动的安装。

下载对应的显卡型号的驱动:地址

下载驱动

需要先注册一下 然后才能进行下载。

然后双击运行。默认目录就好。

安装驱动-1

安装驱动-2

安装驱动-3

安装驱动-5

安装驱动-6


安装 cuda toolkit

安装

输入以下命令进行,以安装 cuda toolkit。

1
2
3
4
5
apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub

sh -c 'echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/cuda.list'

apt-get update

命令截图1

命令截图2


然后是 install CUDA,笔者这里是选择的 10.2 版本。

CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 35 -> CUDA driver version is insufficient for CUDA runtime version Result = FAIL

援引官方的话,读者也可以自己选择自己想要的版本。

Do not choose the cuda, cuda-11-0, or cuda-drivers meta-packages under WSL 2 since these packages will result in an attempt to install the Linux NVIDIA driver under WSL 2.

意思是,不要在命令中直接选择 cudacuda-11-0 这种名字,在 WSL 中,必须要用 cuda-toolkit-10-2 这种格式的名字。

下面命令2选1。

1
2
3
4
5
# 笔者安装 10.2
apt-get install -y cuda-toolkit-10-2

# 官方叫安装 11
apt-get install -y cuda-toolkit-11-0

这里还错怪了一波 11 版本,读者大可以选择 11。

时间有点久 请耐心等待,要是没换源估计更慢了,现在切回去换源还来得及。

debug

完事之后,你有可能可能会看到这个 error

error-1

apt-get 已经用过了,那就加上 --fix-missing 吧。但是笔者这边实测只是跳过了, error 并没解决。

1
apt-get install -y cuda-toolkit-10-2 --fix-missing

然后发现,这个多半是源更换了,没有刷新的缘故。回到换源的地方,刷新一下源再执行下面的命令就可以了。

1
apt-get install -y cuda-toolkit-10-2

安装完成

安装完成

按照官方的说法似乎就可以了?

Running CUDA Applications
Just run your CUDA app as you would run it under Linux! Once the driver is installed there is nothing more to do to run existing CUDA applications that were built on Linux.

A snippet of running the BlackScholes Linux application from the CUDA samples is shown below.

Build the CUDA samples available under /usr/local/cuda/samples from your installation of the CUDA Toolkit in the previous section. The BlackScholes application is located under /usr/local/cuda/samples/4_Finance/BlackScholes. Alternatively, you can transfer a binary built on Linux to WSL 2!


检查安装

/usr/local 下可以看到刚刚的安装。而且 CUDA 的版本是 10.2 ,所以 cuDNN 也下载 CUDA10.2 对应的版本。

查看cuda

然后我们依然安装 cudnn,官方教程

Windows 查看 WSL 的文件

由于 WSL 和 Windows 的文件系统是通用的,因此,我们可以通过 Windows 下载了拷贝进去。

Windows 直接在文件夹左侧就能看到对应的 Ubuntu WSL

查看WSL

WSL 查看 Windows 文件

WSL 看 Windows 的子系统则可以在文件系统中的 /mnt 下面。c、d、e就是对应的盘。

查看Windows的系统盘

0x04 安装 cuDNN

下载 cuDNN

下载 cuDNN:地址

选择 Linux 的对应版本的 tar.gz,笔者这里是 10.2 。

下载对应的cuDNN


移动文件

下载完毕后,就是通过文件的本质共享,将其移动到子系统的某个位置去。

笔者下载下来是这个名字 cudnn-10.2-linux-x64-v8.0.5.39.solitairetheme8 笔者重命名了 cudnn-10.2-linux-x64-v8.0.5.39.tar.gz

然后运行下面的命令进行拷贝和解压。

1
2
3
4
5
# 新建目录
mkdir /usr/local/temp

# 拷贝文件
cp cudnn-10.2-linux-x64-v8.0.5.39.tar.gz /usr/local/temp

然后在temp文件夹对其进行解压,注意更换对应的文件名哈。

1
tar -xzvf cudnn-10.2-linux-x64-v8.0.5.39.tar.gz

解压完毕后。

解压完毕


移动到 CUDA 目录

执行下面的三个命令:

1
2
3
cp cuda/include/cudnn*.h /usr/local/cuda/include
cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

拷贝cuDNN

由于文件有点多,第二个复制耗时有点长。然后 temp 文件夹也可以删除了。

于是就安装完成了。


0x05 测试安装

设置环境变量

设置一个环境变量,

1
2
3
export CUDA_HOME=/usr/local/cuda
export PATH=$PATH:$CUDA_HOME/bin
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} # 前两个必须要修改什么,第三个则需要根据版本的不同,修改路径中的10.2


编译 demo

移步到 demo 中

1
cd /usr/local/cuda/samples/1_Utilities/deviceQuery 

makefile ,我们直接 make 编译一下

1
make

编译测试文件


运行 demo

然后运行

1
./deviceQuery

正常情况下,会看到下面的样子。

deviceQuery-1

deviceQuery-2


debug

有可能会遇到下面的错误,错版本和驱动不兼容。。。。

CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 35 -> CUDA driver version is insufficient for CUDA runtime version Result = FAIL

但是在解决了 WSLWSL2 的问题后就一瞬成功了。可能就是因为笔者使用的工具,所以默认的 WSL2 的选项没有生效,于是安装的都是 WSL1 的发行版,于是一直不成功。升级到 WSL2 后,再运行就一瞬成功了。

如果读者也遇到了此问题,不妨返回开头检查自己是否是 WSL2


0x06 安装 conda

安装 conda

安装一个 mini conda。

首先下载文件

1
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 

然后运行进行安装,按照提示输入两个 yes 安装就好,主要是第二个,是否需要自动运行 conda init 如果选择默认的 no 则需要自己设定环境变量,否则系统不认识 conda 因此,推荐输入 yes

1
bash Miniconda3-latest-Linux-x86_64.sh 

安装完毕后需要将此终端关闭,然后新开一个进入才会生效。

安装 conda


新建虚拟环境

虚拟环境有诸多好处,以下是笔者觉得的好处:

1、各个项目的需求和依赖有所不同,不同的项目可能对环境有冲突,虚拟环境就可以各自独立,互不影响。

2、各个项目独立,使得各自的项目环境独立,在到处依赖的时候不会导出更多的无关的依赖。

3、万一搞废了,重新整一个也不至于全部都废弃了。

等等。

创建一个虚拟环境,这里我们选择 3.6。(就是随便选了一个,貌似 Linux 默认的 python 就是3.6

1
conda create --name py36CUDA python=3.6

建立完毕后,我们如何使用,这里也说的很清楚了。

使用虚拟环境

1
2
3
4
5
# 进入虚拟环境
conda activate py36CUDA # 虚拟环境的名字

# 退出虚拟环境
conda deactivate


conda 换源

和前面一样的原因,我们还是换个源。输入下面的命令打开文件

1
vim ~/.condarc

输入下面的内容:

1
2
3
4
5
6
channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
ssl_verify: true

安装 pyCUDA

尝试安装

然后我们安装 pycuda

1
pip3 install pycuda

然后还是报错了。。。。。报错信息是 g++ 怎么怎么,这里不想列举了,太多了。

apt 安装

在上述失败后,查阅到另一种方法,试试吧。

1
apt-get install python3-pycuda

装了好多好大的文件。提示成功了。

但是在终端中(非虚拟环境) 输入 python3 还是无法 import pycuda

虚拟环境中也是一样。

返璞归真

然后又在虚拟环境中,尝试安装

1
pip3 install pycuda

这次没有报错,但是直接报错找不到这个 pycuda

查阅了资料,或许是应该笔者安装的 CUDA10.2 所以最新的 pycuda2020 不兼容。

于是,更换了安装命令,就安装成功了。

1
pip3 install pycuda==2019.1.2

安装 pycuda2019


测试 pycuda

导入 autoinit 测试

然后我们进入虚拟环境中进行 python 测试一波。

1
2
3
4
# conda activate py36CUDA 
# python

>>> from pycuda import autoinit

但是报错无 six

test-pycuda1

那就装一个 six

1
pip3 install six

完事之后就成了。

image-20201229174430625

初战告捷,准备开冲。

实战测试

新建一个 a+b copy 进去,计算加法。

建立源码

建立 a+b.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule

# 读取文件
with open('a+b.cu', 'r', encoding = 'utf-8') as f:
cuf = f.read()
mod = SourceModule(cuf)

# 获取kernal函数
add_func = mod.get_function('add')

# 导入 numpy
import numpy as np

# 初始化 a, b, c
a = np.array([1,2,3,4,5,6,7,8,9,10], dtype = np.int32)
b = np.array([2,3,5,6,7,1,2,5,1,32], dtype = np.int32)
c = np.full((10, ), 0).astype(np.int32)
n = np.int32(10)

# c = a+b
add_func(drv.In(a), drv.In(b), drv.InOut(c), drv.In(n), block=(32,1,1), grid=(1,1))

# print
print(c)

建立 a+b.cu

1
2
3
4
5
6
7
8
__global__ void add(int *a, int *b, int *c, int *n){

int tid = threadIdx.x;

if(tid < (*n)){
c[tid] = a[tid] + b[tid];
}
}

copy 到 WSL 中

笔者这里建立了一个 test 目录。

1
cp a+b.* /home/test/

copy文件

查看copy

运行

完事之后,直接开冲。

1
python3 a+b.py 

运行结果

1
2
3
4
5
a = np.array([1,2,3,4,5,6,7,8,9,10], dtype = np.int32)
b = np.array([2,3,5,6,7,1,2,5,1,32], dtype = np.int32)

(c = a + b)
c == [ 3 5 8 10 12 7 9 13 10 42]

显然是对了的。

0x07 总结

本次安装历时两天,因为某些必要的原因恢复了物理机的系统,导致机器的环境都无了。

当再次在 Windows 物理机上配置 pycuda 的环境时,按照以前的教程,花费了一天却一直没有成功,查查查就放弃了。

偶然发现了 WSL 还有了 2,并且还支持 CUDA 了,那这必然也能支持 pycuda 了。于是我又花了另外一天来搭建这个环境。

对了,还有5天就期末考试的第一门了,我还没复习。GG。

0x08 参考

wsl + cuda: https://blog.csdn.net/Raink_LH/article/details/107220941

wsl+cuda 官方教程: https://docs.nvidia.com/cuda/wsl-user-guide/index.html#installing-nvidia-drivers

wsl+cuda+(anaconde)python 官方教程: https://docs.microsoft.com/en-us/windows/win32/direct3d12/gpu-tensorflow-wsl

cuda demo测试: https://segmentfault.com/a/1190000022422496