我的环境:
win10 我自己的电脑,用来连远程服务器

  • vscode

ubuntu16.04 远程服务器

  • docker
  • 没有amd的显卡

一、前言

由于gem5的gcn3是基于amd显卡的,而我这里的服务器没有amd显卡,所以直接搭建环境很麻烦,如果有amd显卡,估计常规方法也能用,不过使用docker确实很方便。

二、 基于docker镜像搭建环境(成功)

先列举一下步骤:
1、获取或构建gem5-gcn的镜像
----[可选] docker pull, 用docker拉一下gem5-gcn的镜像(能访问外网的话可以采取该方法)
----[可选] docker build, 使用gem5提供的Dockfile构建镜像(网络能访问github就可以)
ps: 根据第一步的步骤不同,镜像的名字也不同。即pull下来的名字是gcr.io/gem5-test/gcn-gpu:v21-2,而自己根据dockerfile搭建的名字就是自己定了,文档里是以gcr.io/gem5-test/gcn-gpu:v21-2为例。
2、clone一下gem5的代码
3、在gem5-gcn容器内编译gem5的代码
4、在gem5-gcn容器内运行demo
5、(可选)在gem5-gcn的基础上建一个自己的镜像层
6、(可选)使用vscode连接到容器内部,编译调试

2.1 在docker容器内安装gem5

2.1.1 获取docker镜像

方法一:直接pull(如果可以访问墙外)

如果电脑上的docker可以访问墙外,可以直接拉镜像(当前最新的稳定版本为v21-2)

docker pull gcr.io/gem5-test/gcn-gpu:v21-2

我在Ubuntu上挂vpn,然后设置dockerd(不是docker)的代理倒是可以成功拉取。
但是Win 10上面的docker代理没搞成功,拉取不成功,不晓得哪里设置有问题。

方法二:使用Dockerfile文件(不需要访问墙外)

写在前面: 官方提供的dockerfile有一些bug,需要稍微修改一下修复bug的patch地址讨论的邮件地址
官方提供了dockerfile文件,路径为gem5/util/dockerfiles/gcn-gpu/Dockerfile,也有简单的文档说明gem5/util/dockerfiles/gcn-gpu/README.md
运行命令(镜像名字自己定义,整个过程需要挺久时间,我这里网络不好,如果不出错的话大概1个多小时)

docker build -t <image_name> .

构建过程一般不会有什么问题。由于我这里的校园网太辣鸡,连github的仓库都无法成功访问,因此需要把github仓库地址给改成其它地址。
我想到的有两种办法

第一种方法:将github的仓库转到gitee

(1) 把github仓库克隆到gitee仓库(或者找gitee上面开源的仓库,虽然gitee上开源的仓库并不是最新的,但是gem5-gcn使用的也不是最新版本,它会git checkout到旧版本),
(2) 修改dockerfile里的仓库地址(注意如果是gitee的私人仓库,可以在仓库url前面的一部分加上用户名和密码,如https://username:passwd@gitee.com/....
(3) 特别地,里面有一个rocBLAS的项目,它在安装的时候,又会去访问github,因此我在dockerfile中,加了一条命令,通过sed修改了里面的地址

# 重定向github
RUN sed -i 's/github.com\/${tensile_fork}/username:passwd@gitee.com\/username/' CMakeLists.txt
第二种方法:先离线下载,然后使用dockerfile的ADD指令添加到容器中

简单示例
先离线下载rocm-cmake-master.zip,然后放到dockerfile的目录下

文件:
ADD rocm-cmake-master.zip /
即将主机的./rocm-cmake-master.zip放到容器的/目录下

文件夹(需要在后面加上文件夹名)
ADD dirname /dirname
即将主机的./dirname 文件夹移动到容器的/dirname 目录

方法三:离线pull(不能直接访问墙外)

方法优点是:导出一个离线镜像后,就可以保存下来,导入到哪里都可以,不会出错。
缺点是:离线的完整镜像有点大,15G左右。而且一开始还是需要搞一个能访问外网的服务器。

电脑无法访问外网,可以采用离线的方式。
当时我使用的方法是:

补充:谷歌有一个免费的服务,叫CloudShell,也很好用,可以用来做测试,也可以用来打包docker镜像,缺点就是你需要能在本地访问谷歌才行

1、在华为云上面租了一台香港的服务器,ubuntu 20.04(按需计费,网络的话按流量计费,用完就释放掉资源),注意:20G的空间不够用,镜像本身大概就需要15G。
2、在香港的服务器上面安装docker,并拉取镜像

# 先修改镜像源
# 安装docker
$ sudo apt install docker.io
# 下载镜像
$ docker pull gcr.io/gem5-test/gcn-gpu:v21-2

3、导出镜像

$ docker save gcr.io/gem5-test/gcn-gpu:v21-2 -o gcn-gpu.tar

4、将镜像从服务器下载到本地
建议使用rsync,因为支持断点续传。而scp断了就要重新下载。

rsync -avz -e "ssh -p 22" user@remotehost:/SRC/ DEST/ 

5、再将镜像传到我们要跑gem5的服务器上面
6、导入镜像

docker load -i gcn-gpu.tar

但是这种方法好像会导致locale命令有问题,猜测是因为香港服务器的字符集和我本地的不一样,在后续编译benchmark的时候,会报警告,然后在gem5运行的时候,它就卡住了
检查是否有这种问题,就是运行local命令,看是否有如下报错

$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

如果报错了,可以运行一下locale -a命令

$ locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
C.UTF-8
POSIX

可以发现我们这里没有en_US.UTF-8这个字符集。方法就是安装一下字符集

$ apt-get install -y locales
$ locale-gen "en_US.UTF-8"
# 重新测试
$ locale -a
C
C.UTF-8
en_US.utf8
POSIX

2.1.2 在容器内编译gem5

# 假设当前目录为gem5的上一层目录
$ cd gem5
$ docker run -u $UID:$GUID --volume $(pwd):$(pwd) -w $(pwd) gcr.io/gem5-test/gcn-gpu:v21-2 scons build/GCN3_X86/gem5.opt -j 16

2.1.3 在容器内运行gem5

注意修改square的路径

docker run -u $UID:$GUID --volume $(pwd):$(pwd) -w $(pwd) gcr.io/gem5-test/gcn-gpu:v21-2 gem5/build/GCN3_X86/gem5.opt gem5/configs/example/apu_se.py -n 3 -c bin/square

至此,gem5的运行环境已经搭建好了

注意:上面的-n 后面的参数要改成3。如果改成1的话会报错/HIP/rocclr/hip_global.cpp:69: guarantee(false && "Cannot find Symbol"),改成2的话,会陷入循环,无法正常工作(如下面邮件里的描述)。
gem5-users有别人的邮件存档讲了这个问题,原话是ROCm 4.0 requires 3 CPUs to run now. I thought we had updated the README.md and website before gem5 21.1 release to reflect this but looks like they are not up to date.

附上邮件链接

2.2 在容器内编译gpu程序

以gem5-resource里的square为例,运行命令如下

$ git clone https://github.com/gem5/gem5-resources.git
$ cd gem5-resourcessrc/gpu/square
$ docker run --rm -v ${PWD}:${PWD} -w ${PWD} -u $UID:$GID gcr.io/gem5-test/gcn-gpu:v21-2 make

2.3 使用vscode的remote-container开发代码

使用docker的命令行当然也可以完成开发,但是肯定是效率越高越好。

我的环境:
win10 我自己的电脑,用来连远程服务器

  • vscode

ubuntu16.04 远程服务器

  • docker
  • 没有amd的显卡

基本流程就是,在我的win10电脑上利用remote-ssh插件远程连接ubuntu16.04服务器,然后再使用remote-container连接到container内部。
这里主要记录一下remote-container的用法,另外它好像有很多种方法,这里只记录我用的:先运行gem5容器,然后再用插件attach容器。

1. 运行容器

sudo docker run --name gem5-gcn-test --privileged -it --volume $(pwd):$(pwd) -w $(pwd) gcr.io/gem5-test/gcn-gpu:v21-2

注意不要加-u $UID:$GID ,不然会vscode没权限安装vscode-server,会报错remote-container mkdir: cannot create directory '/root': Permission denied

--name testname来取名字,此处名字为"gem5-gcn-test"

注意:如果要使用vscode的gdb功能,--privileged是需要加的,不然docker的ptrace系统调用权限有问题。会报错docker sysctl: setting key "kernel.yama.ptrace_scope", ignoring: Read-only file system

--volume $(pwd):$(pwd),是将host的路径映射到guest的对应路径
-w $(pwd) 是设置workdir

2. 用vscode来查看并attach运行中的容器

方法一:使用remote-container插件

在这里插入图片描述
如图(Other Containers菜单中),点那个连接按钮,vscode就会去打开容器
在这里插入图片描述

方法二:使用docker插件

在这里插入图片描述

在这里插入图片描述

如果此处有报错(error connect eacces /var/run/docker.sock),可以运行命令把当前用户加到docker用户组里

sudo groupadd docker
sudo usermod -aG docker $USER
# 重启生效
reboot

不想重启的话可以尝试别人博客的方法:https://blog.csdn.net/point0mine/article/details/79448402
在这里插入图片描述

右键对应的容器,选择Attach VScode这个选项,就会让你在vscode中打开容器
在这里插入图片描述

3. 打开终端

第一次连接比较慢,要安装些东西,等到终端进入正常的bash界面,说明环境就装好了,之后的开发就和普通的remote-ssh一样了,打开文件夹即可
在这里插入图片描述

4. 自定义dockerfile

上面是直接用的gcn-gpu镜像,其实也可以换成自己的镜像(基于gcn-gpu)
最简单的Dockfile如下:

FROM gcr.io/gem5-test/gcn-gpu:latest
RUN echo 'Hello, mytest!'

接下来,构建容器,运行容器就好了。

2.4 使用vscode调试代码

在前面我们已经在vscode中进入容器内部了,接下来简单配置一下就可以使用vscode调试代码了。虽然命令行的gdb也可以用,但是简单的调试我还是习惯图形化界面。
基本步骤为:

  1. 首先确保连到容器内部了(可以看窗口上面的标题或者左下角状态栏等)
    在这里插入图片描述
    在这里插入图片描述
  2. 在容器内安装gdb(gem5的docker镜像默认没有安装gdb)
$ sudo apt install gdb
# 测试
$ gdb --version
  1. 安装c/c++插件
    在这里插入图片描述
  2. 编写.vscode/launch.json文件
    比如,我是直接写的,文件内容为
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/GCN3_X86/gem5.opt",
            "args": ["configs/example/apu_se.py", "-n", "3", "-c", "mytest/square"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
  1. 设置断点,启动vscode的gdb运行即可
    在这里插入图片描述

附:常规环境安装(失败)

我一开始是按平常的安装方法(安装记录):

3.1 方法1

1、安装gem5的依赖
2、clone gem5的代码
3、编译gem5(python3 $(which scons) ./build/GCN3_X86/gem5.opt -j9
4、下载官方提供的编译好的示例square.owget https://dist.gem5.org/dist/v21-1/test-progs/square/square.o
5、运行square.o,报错,提示有系统调用没有实现

build/GCN3_X86/sim/syscall_emul.cc:66: fatal: syscall sched_get_priority_max (#146) unimplemented.

我实现不了这个系统调用,而且这个简单的程序都跑不了,复杂的程序估计需要的系统调用更多。

3.2 方法2

不使用官方提供的预编译的示例,自己手动编译square.o,假设有amd显卡
1、…,编译完gem5
2、如果有amd的显卡,那么按照gem5写的,根据amd官方提供的教程安装好rocm套件、hip、Radeon Open Compute runtime (ROCr)、Radeon Open Compute thunk (ROCt)、HIP
3、编译示例代码
4、运行gem5(gem5/build/GCN3_X86/gem5.opt gem5/configs/example/apu_se.py -n 3 -c bin/square
理论上这种方法肯定是可行的,但是我没有amd显卡,所以不能尝试。

3.3 方法3

用英伟达的显卡,在服务器上安装rocm交叉编译器,编译示例代码,然后运行
我尝试后,依然有报错,而且我觉得就算解决了可能也会回到方法1,不太清楚怎么解决。

3.4 方法4(照抄dockerfile内容)

没尝试过,但是既然照着dockerfile生成的容器可以正常运行gem5-gcn3,那么我们阅读dockerfile内容,然后照着搭一个环境应该也是可以的。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐