本文将介绍 Windows 下,使用 CLion 和 WSL 配置 MPI 运行及调试环境的方法。

0. 前提

阅读本文前,请确保:

  • Windows 下已启用 WSL2,并安装了任一 Linux 发行版

1. WSL环境配置

(1) 配置编译环境

sudo apt-get update
sudo apt-get install build-essential cmake gdb

(2) 配置MPI

MPI 环境可选择通过包管理器配置,也可自行编译源码配置。简便起见,本文采用包管理器进行配置,选用的 MPI 实现为 MPICH,安装命令为:

# Debian、Ubuntu等发行版使用如下命令安装:
sudo apt-get install mpich

如果安装成功,运行命令 mpichversion,将输出:

之后,尝试运行测试程序,将以下代码保存到文件 mpi_hello.c 中:

/* File:
* mpi_hello.c
*
* Purpose:
* A "hello,world" program that uses MPI
*
* Compile:
* mpicc -g -Wall -std=C99 -o mpi_hello mpi_hello.c
* Usage:
* mpiexec -n<number of processes> ./mpi_hello
*
* Input:
* None
* Output:
* A greeting from each process
*
* Algorithm:
* Each process sends a message to process 0, which prints
* the messages it has received, as well as its own message.
*
* IPP: Section 3.1 (pp. 84 and ff.)
*/
#include <stdio.h>
#include <string.h> /* For strlen */
#include <mpi.h> /* For MPI functions, etc */ const int MAX_STRING = 100; int main(void) {
char greeting[MAX_STRING]; /* String storing message */
int comm_sz; /* Number of processes */
int my_rank; /* My process rank */ /* Start up MPI */
MPI_Init(NULL, NULL); /* Get the number of processes */
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); /* Get my rank among all the processes */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank != 0) {
/* Create message */
sprintf(greeting, "Greetings from process %d of %d!",
my_rank, comm_sz);
/* Send message to process 0 */
MPI_Send(greeting, strlen(greeting)+1, MPI_CHAR, 0, 0,
MPI_COMM_WORLD);
} else {
/* Print my message */
printf("Greetings from process %d of %d!\n", my_rank, comm_sz);
for (int q = 1; q < comm_sz; q++) {
/* Receive message from process q */
MPI_Recv(greeting, MAX_STRING, MPI_CHAR, q,
0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Print message from process q */
printf("%s\n", greeting);
}
} /* Shut down MPI */
MPI_Finalize(); return 0;
} /* main */

编译并执行:

# 编译
mpicc -g -Wall -std=C99 -o mpi_hello mpi_hello.c # 运行,4表示进程数
mpiexec -n 4 ./mpi_hello

输出应为:

Greetings from process 0 of 4!
Greetings from process 1 of 4!
Greetings from process 2 of 4!
Greetings from process 3 of 4!

2. CLion运行环境配置

(1) 新建项目

CLion 新建一个项目 mpi,将 main.c 或 main.cpp 内容修改为:

/* File:
* mpi_hello.c
*
* Purpose:
* A "hello,world" program that uses MPI
*
* Compile:
* mpicc -g -Wall -std=C99 -o mpi_hello mpi_hello.c
* Usage:
* mpiexec -n<number of processes> ./mpi_hello
*
* Input:
* None
* Output:
* A greeting from each process
*
* Algorithm:
* Each process sends a message to process 0, which prints
* the messages it has received, as well as its own message.
*
* IPP: Section 3.1 (pp. 84 and ff.)
*/
#include <stdio.h>
#include <string.h> /* For strlen */
#include <mpi.h> /* For MPI functions, etc */ const int MAX_STRING = 100; int main(void) {
char greeting[MAX_STRING]; /* String storing message */
int comm_sz; /* Number of processes */
int my_rank; /* My process rank */ /* Start up MPI */
MPI_Init(NULL, NULL); /* Get the number of processes */
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); /* Get my rank among all the processes */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank != 0) {
/* Create message */
sprintf(greeting, "Greetings from process %d of %d!",
my_rank, comm_sz);
/* Send message to process 0 */
MPI_Send(greeting, strlen(greeting)+1, MPI_CHAR, 0, 0,
MPI_COMM_WORLD);
} else {
/* Print my message */
printf("Greetings from process %d of %d!\n", my_rank, comm_sz);
for (int q = 1; q < comm_sz; q++) {
/* Receive message from process q */
MPI_Recv(greeting, MAX_STRING, MPI_CHAR, q,
0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Print message from process q */
printf("%s\n", greeting);
}
} /* Shut down MPI */
MPI_Finalize(); return 0;
} /* main */

(2) 添加工具链

在设置 => 构建、运行、部署 => 工具链中添加一个工具链,类型选 WSL。

CLion 会自动检测填写,但 C 编译器和 C++ 编译器路径需要手动指定,相应路径使用 which 命令获取:

# 获取 C 编译器路径
which mpicc # 获取 C++ 编译器路径
which mpicxx

(3) 指定项目所用工具链

添加工具链后,必须手动设置项目使用新添加的工具链,在设置 => 构建、运行、部署 => CMake 中进行设置:

(4) 修改项目终端(可选)

在设置 => 工具 => 终端中,将 Shell 路径修改为所用的发行版路径,该路径一般为:

# C:\Users\<你的电脑用户名>\AppData\Local\Microsoft\WindowsApps\<发行版名称>.exe,如:
C:\Users\username\AppData\Local\Microsoft\WindowsApps\ubuntu.exe

(5) 修改CMake配置文件

修改项目根目录下的 CMake 配置文件 CMakeLists.txt:

  • 在 add_executable 所在行之前添加:find_package(MPI REQUIRED)
  • 在 add_executable 所在行之后添加:
    • 如果为 C 项目:target_link_libraries(<your_project_name> PRIVATE MPI::MPI_C)
    • 如果为 C++ 项目:target_link_libraries(<your_project_name> PRIVATE MPI::MPI_CXX)
  • 可能需要修改 cmake_minimum_required 中的版本号,使其不高于 WSL 中安装的 CMake 版本

示例:

cmake_minimum_required(VERSION 3.22)
project(mpi) set(CMAKE_C_STANDARD 11) find_package(MPI REQUIRED)
add_executable(mpi main.c)
target_link_libraries(mpi PRIVATE MPI::MPI_C)

之后,重新加载 CMake 配置:

尝试构建项目:

(6) 修改运行配置

为了可以一键运行,需要修改运行配置:

需要将可执行文件修改为 mpiexec 的路径(WSL 内通过 which 命令获取),并将程序实参填写为:-n 4 "$CMakeCurrentProductFile$",其中表示运行时使用 4 个进程,可根据需要修改

之后,点击运行,程序输出如图:

3. CLion调试MPI程序

CLion 调试 MPI 程序需要通过使用 GDB 的附加到进程功能间接实现。

(1) 添加断点

在需要打断点的位置打上断点,并在所有断点位置上方添加如下代码:

int i = 0;
while (!i)
sleep(5); // 需要包含unistd.h头文件

之后在 sleep(5) 一行添加断点。

(2) 运行程序

点击运行按钮,运行程序。

(3) GDB附加到进程功能

点击工具 => 附加到进程:

在 SSH/WSL 中搜索当前可执行文件:

选取想要调试的进程(在实例中,因为 0 号进程中未添加断点,故不应选取进程号小的进程138113),点击使用WSL GDB附加,进入调试模式。

为了程序可以向下运行,需要将 i 的值设置成 1。

之后正常调试即可。

4. 后记

  • 使用 CLion 只能通过 GDB 一个进程一个进程地调试,未找到方法调用 TotalView 同时跟踪和调试多个进程
  • 运行配置中的程序实参可以填写为:-n $Prompt$ "$CMakeCurrentProductFile$",实现每次运行前弹窗填写需要运行的进程数

参考资料:

  1. How to work with OpenMPI projects in CLion | CLion Documentation
  2. Clion 可以编译调用 MPI 并行库的项目么? - 知乎

CLion和WSL配置MPI运行及调试环境的更多相关文章

  1. vs Code配置C++运行和调试环境以及相关问题

    vs Code配置C++运行和调试环境以及相关问题 第一步:下载c++插件 第二步:安装编译.调试环境 如果没有Dev-C++下载MinGW 下载地址:https://sourceforge.net/ ...

  2. 在Mac系统上配置Android真机调试环境

    在Mac系统上配置Android真机调试环境 mac上配置安卓环境还说挺方便的,真机调试也比win上要好一些.win上被各种软件强行安装了xxx助手. 在mac上就了一个干净的感觉. 下载Androi ...

  3. [SoapUI]怎样配置SoapUI运行的不同环境,并在Jenkins上面通过命令调用不用的环境

    配置SoapUI运行的不同环境 Groovy 脚本来控制environment 在Jenkins上面通过命令调用不用的环境 http://www.soapui.org/Test-Automation/ ...

  4. Eclipse IDE配置PHP开发、调试环境

    前言 使用java语言开发的朋友想必对Eclipse开发工具已经不陌生了,那么Eclipse作为java主流的开发工具,是否能够开发PHP项目呢?答案如你所想,肯定是可以的!以下就是该IDE下如何配置 ...

  5. 配置移动前端开发调试环境(nodejs+npm+weiner的安装和配置使用)

    这段时间发现做移动端的开发调试是一大难题,网上逛了逛发现有一些工具可用,如chrome的远程调试,实际测试过程中我始终调试不成功,听说被墙后是不行的,所以最终找了如下的方法. 因为基于nodeJS环境 ...

  6. 笔记:MAC OS X下配置PHP开发、调试环境

    操作系统:MAC OS X 工具:MAMP.PhpStorm.xdebug.chrome 1.下载MAMP 2.安装比较简单,安装完成后,应用程序中会增加如下4个应用 MacGDBp是PHP调试器,使 ...

  7. 怎么用notepad配置来运行C语音环境

    想要运行C语言,我们可以用notepad软件来进行编辑,那么怎么用notepad 配置运行c语言开发环境呢? Notepad++是一款很好的编辑器,可以用来开发很多的工具,具体大家请看下文给大家详细讲 ...

  8. 配置QtCreator+CDB远程调试环境(要设置_NT_SYMBOL_PATH和QT_PLUGIN_PATH和Path)

    相关环境信息:开发机Win7 x64.远程机器WinXP.调试器是CDB.Qt版本5.2.1 一.部署远程机器环境 我这里用的是虚拟机(Windows XP),根据你要调试的程序选择安装不同架构的Wi ...

  9. MAC OS X下配置PHP开发、调试环境

    操作系统:MAC OS X 工具:MAMP.PhpStorm.xdebug.chrome 1.下载MAMP 2.安装比较简单,安装完成后,应用程序中会增加如下4个应用 MacGDBp是PHP调试器,使 ...

  10. 配置QtCreator+CDB远程调试环境(用到了符号表) good

    相关环境信息:开发机Win7 x64.远程机器WinXP.调试器是CDB.Qt版本5.2.1 一.部署远程机器环境 我这里用的是虚拟机(Windows XP),根据你要调试的程序选择安装不同架构的Wi ...

随机推荐

  1. NVME(学习笔记八)—Asymmetric Namespace Report

    8.20 非对称namespace访问报告 8.20.1 非对称namespace访问报告概况 非对称Namespace访问(ANA)在如下场景下产生,基于访问这个namespace的controll ...

  2. SATA 学习笔记——Frame/Primitive解析

    一.故事前传 我们之前说到Link layer的结构,link layer的作用大致可以包括以下几点: Frame flow control CRC的生成与检测(已解析,详细见历史文章) 对数据与控制 ...

  3. python中矩阵切片维数微秒变化

    1 前言 使用切片访问矩阵的部分数据(特别是一行或一列数据)时,通常会出现切片维数怎么在瞎变化,以致于不得不用reshape()强制改变维数.在深度学习中,网络对矩阵维数的要求是非常严格的,往往就是这 ...

  4. Java容器及其常用方法汇总

    1 概述 Java Collections 框架中包含了大量的接口及其实现类和操作它们的算法,主要包括列表(List).集合(Set).映射(Map),如下: 接口 实现类 数据结构 初始容量 加载因 ...

  5. 超详细的 springboot & mybatis 程序入门

    ps:网上有很多类似的入门案例,我也是看了被人的之后自己写的一个 估计有哥们懒 我把数据表格拿上来,数据自己填吧 CREATE TABLE `tb_user` ( `id` int(10) DEFAU ...

  6. 《深入理解Java虚拟机》(三)类加载机制

    @ 目录 1.什么是类的加载 2.类加载的过程 加载 连接 验证 文件格式验证 元数据验证 字节码验证 符号引用验证 准备 解析: 类或接口的解析 字段解析 类方法解析 接口方法解析 初始化 结束生命 ...

  7. StretchDIBits在一些图像尺寸下失败

    StretchDIBits用来打印图像,但是由于某种未知的原因,当图像达到特定尺寸时,它会失败. 图像数据从其他一些图像源以24位BGR格式加载到无符号int数组中.它可以在某些大小下工作,但根本无法 ...

  8. Redis原理学习:Redis主体流程分析

    转自:七把刀 https://www.jianshu.com/p/427cf97d7951 网上分析Redis源码的文章挺多,如黄健宏的<Redis设计与实现>就很详尽的分析了redis源 ...

  9. Notepad++找回自动保存缓存内容的文件

    在目录C:\Users\Administrator\AppData\Roaming\Notepad++\backup中找到自动保存的缓存文件. 参考Notepad++找回自动保存缓存内容的文件

  10. 双层循环练习,pass_break_continue,和for循环---day06

    1.双层循环练习 2.pass_break_continue pass:在代码块中无代码可写时,可用pass占位 break:终止当前循环,只能应用在循环里 continue:跳过当前循环,从下一次开 ...