MPI + FORTRAN 的子例行子程序测试

本文介绍使用MPI进行简单数据发送与接收的方法,并通过示例演示如何避免常见错误,如忘记包含必要的头文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


用MPI实现一个简单的标准发送接收操作,如下,0进程将一个数据发送给1号进程,1号进程接收从0进程发送的数据。

 

result:

 

 

现在,我把发送和接收操作分别放到子例行子程序里,如下

 

于是,出错了。。。

 

 

 

感谢hahe  的指正,终于找到了错误原因:

子例行子程序中,也要加头文件包含

#include 'mpif.h'

 

附一个修改后类似的代码,将i,j作为参数传递给子程序,执行发送接收操作。

 

 

result:

 

并且可以将子例行程序单独放进一个文件,然后分开编译:

 

此文档描述了Fortranmpi使用Fortran語言 1 MPI 平行計算程式設計 1 第一章 前言 5 1.1 MPI 平行計算軟體 6 1.2 國家高速網路與計算中心的平行計算環境 7 1.3 在IBM 電腦系統上如何使用MPI 8 1.3.1 IBM 電腦系統的MPI Fortran程式編譯指令 8 1.3.2 IBM 電腦系統的 Job command file 8 1.3.3 IBM 電腦系統的平行程式的執行指令 11 1.4 在PC Cluster上如何使用MPI 13 1.4.1 PC Cluster上的MPI Fortran程式編譯指令 13 1.4.2 PC Cluster 上的 Job command file 14 1.4.3 PC Cluster 上的平行程式執行指令 15 第二章 無邊界資料交換的平行程式 16 2.1 MPI 基本指令 17 2.1.1 mpif.h include file 17 2.1.2 MPI_INIT, MPI_FINALIZE 17 2.1.3 MPI_COMM_SIZE, MPI_COMM_RANK 18 2.1.4 MPI_SEND, MPI_RECV 19 2.2 無邊界資料交換的循序程式 T2SEQ 21 2.3 資料不切割的平行程式 T2CP 23 2.4 MPI_SCATTER,MPI_GATHER,MPI_REDUCE 28 2.4.1 MPI_SCATTER,MPI_GATHER 28 2.4.2 MPI_REDUCE, MPI_ALLREDUCE 30 2.5 資料切割的平行程式 T2DCP 32 第三章 需要邊界資料交換的平行程式 36 3.1 MPI_SENDRECV, MPI_BCAST 37 3.1.1 MPI_SENDRECV 37 3.1.2 MPI_BCAST 37 3.2 邊界資料交換的循序程式 T3SEQ 39 3.3 資料不切割的邊界資料交換平行程式 T3CP 40 3.4 資料切割的邊界資料交換平行程式(一) T3DCP_1 47 3.5 資料切割的邊界資料交換平行程式 (二) T3DCP_2 52 第四章 格點數不能整除的平行程式 57 4.1 格點數不能整除的循序程式 T4SEQ 58 4.2. MPI_SCATTERV、MPI_GATHERV 60 4.3 MPI_PACK、UNPACK、BARRIER、WTIME 62 4.3.1 MPI_PACK、MPI_UNPACK 62 4.3.2 MPI_BARRIER、MPI_WTIME 65 4.4 資料切割的平行程式 T4DCP 67 第五章 多維陣列的平行程式 72 5.1 多維陣列的循序程式 T5SEQ 73 5.2 多維陣列資料不切割的平行程式 T5CP 76 5.3 多維陣列末維資料切割的平行程式 T5DCP 85 5.4 與二維切割有關的 MPI 副程式 92 5.4.1 垂直座標圖示法則 (Cartesian Topology) 92 5.4.2 界定二維切割的 MPI 副程式MPI_CART_CREATE、 93 MPI_CART_COORDS、MPI_CART_SHIFT 93 5.4.3 定義固定間隔資料的 MPI 副程式 96 MPI_TYPE_VECTOR、MPI_TYPE_COMMIT 96 5.5 多維陣列末二維切割的平行程式 T5_2D 98 第六章 MPI程式的效率提昇 112 6.1 Nonblocking資料傳送 113 6.2 資料傳送的合併 122 6.3 以邊界資料計算取代邊界資料交換 126 6.4 輸出入資料的安排 128 6.4.1 事先切割輸入資料 128 6.4.2 事後收集切割過的輸出資料 131 第七章 導出的資料類別 133 7.1 導出的資料類別 134 7.2 陣列的轉換 139 7.3 兩方迴歸與管線法 149 第八章 多方依賴及SOR解法 155 8.1 四方依賴及SOR解法 156 8.2 黑白點間隔 SOR 解法 159 8.3 斑馬線 SOR 解法 168 8.4 八方依賴與四色點間隔SOR解法 175 第九章 有限元素法程式 183 9.1 有限元素法的循序程式 184 9.2 有限元素法的平行程式 187 附錄一 撰寫C語言的MPI程式 197 參考書目 200 Parallel Processing without Partition of 1-D Arrays 201 Parallel Processing with Partition of 1-D Arrays 202 Parallel on the 2nd Dimension of 2-D Arrays without Partition 203 Parallel on the 2nd Dimension of 2-D Arrays with Partition 204 Partition on the 3rd dimension of 3-D Arrays 205
<think>好的,我需要帮助用户解析包含MPI_Init、MPI_Send和MPI_Recv的Fortran代码。首先,我得回忆一下MPI的基本知识,MPI是消息传递接口,用于并行计算中的进程间通信。用户提供的引用中有关于MPI函数的信息,比如MPI_Init、MPI_Comm_size,以及MPI_Sendrecv的参数说明,这些都可能对解析代码有帮助。 首先,用户提到的代码包含MPI_Init,这是初始化MPI环境的函数,必须在其他MPI函数之前调用。然后MPI_Comm_size用来获取通信域中的进程总数,MPI_Comm_rank获取当前进程的编号(rank)。接下来是MPI_Send和MPI_Recv,这两个函数分别用于发送和接收消息。用户提供的引用[3]和[4]中有关于MPI_Gather和MPI_Sendrecv的参数说明,虽然不完全相同,但参数结构类似,可能可以参考。 我需要按照用户的要求,用中文分步骤解释代码的工作原理。首先,代码的结构应该是初始化MPI,获取进程数和rank,然后主进程(rank 0)发送消息,其他进程接收。需要详细说明每个函数的参数和作用,比如发送缓冲区、数据数量、数据类型、目标进程、标签、通信域等。同时,要注意Fortran中的参数传递方式,比如可能使用整数类型和地址传递。 还要考虑用户可能的疑问点,比如阻塞通信和非阻塞通信的区别,但用户的问题集中在Send和Recv上,所以先专注于这两个函数。此外,用户提供的引用中有关于编译时找不到MPI函数的问题(引用[2]),可能在解析代码时需要提醒用户正确链接MPI库。 最后,根据用户的要求生成相关问题,这些问题应该与MPI的工作原理、函数使用和调试相关。需要确保问题覆盖代码解析中提到的关键点,比如参数含义、通信机制、调试技巧等。 总结步骤: 1. 初始化MPI环境。 2. 获取进程数和rank。 3. 主进程发送消息。 4. 其他进程接收消息。 5. 结束MPI环境。 6. 解释每个函数参数。 7. 强调阻塞通信的特点。 8. 提及编译注意事项。</think>以下是对包含MPI基础通信函数的Fortran代码解析,以分步骤说明其工作原理: ### 1. MPI环境初始化 ```fortran call MPI_Init(ierr) ``` - 所有MPI程序必须首先调用$MPI\_Init$,用于初始化并行环境并建立进程间通信基础[^1] - 参数$ierr$返回错误代码,Fortran中通常以最后一个参数作为状态返回 ### 2. 进程信息获取 ```fortran call MPI_Comm_size(MPI_COMM_WORLD, numprocs, ierr) call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) ``` - $MPI\_Comm\_size$获取通信域$MPI\_COMM\_WORLD$中的进程总数$numprocs$[^3] - $MPI\_Comm\_rank$获取当前进程编号$rank$(从0开始编号) ### 3. 消息传递流程 #### 主进程发送数据 ```fortran if (rank == 0) then data = 100 call MPI_Send(data, 1, MPI_INTEGER, 1, 0, MPI_COMM_WORLD, ierr) endif ``` - 参数解析: - $data$:发送缓冲区地址 - $1$:发送数据个数 - $MPI\_INTEGER$:数据类型标记 - $1$:目标进程rank - $0$:消息标签(用于区分不同消息) - $MPI\_COMM\_WORLD$:通信域 #### 工作进程接收数据 ```fortran if (rank == 1) then call MPI_Recv(data, 1, MPI_INTEGER, 0, 0, MPI_COMM_WORLD, status, ierr) print *, "Received:", data endif ``` - 参数解析: - $data$:接收缓冲区地址 - $1$:最大接收数据量 - $MPI\_INTEGER$:数据类型 - $0$:源进程rank - $0$:匹配发送端的消息标签 - $status$:返回状态信息(包含实际接收数量等) ### 4. 环境终止 ```fortran call MPI_Finalize(ierr) ``` - 必须调用$MPI\_Finalize$释放MPI资源 ### 关键特性说明 1. **阻塞通信**:$MPI\_Send$和$MPI\_Recv$都是阻塞操作,发送方会等待缓冲区可重用,接收方会等待消息到达[^4] 2. **通信域**:$MPI\_COMM\_WORLD$包含所有进程 3. **数据类型匹配**:必须保证发送/接收端使用相同数据类型标识 4. **标签匹配**:接收操作通过标签+源进程rank来筛选消息 编译提示:需使用mpifort编译器并正确链接MPI库,避免出现未定义引用错误[^2] ```fortran ! 完整代码示例 program main use mpi implicit none integer :: ierr, numprocs, rank, data integer :: status(MPI_STATUS_SIZE) call MPI_Init(ierr) call MPI_Comm_size(MPI_COMM_WORLD, numprocs, ierr) call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) if (rank == 0) then data = 100 call MPI_Send(data, 1, MPI_INTEGER, 1, 0, MPI_COMM_WORLD, ierr) else if (rank == 1) then call MPI_Recv(data, 1, MPI_INTEGER, 0, 0, MPI_COMM_WORLD, status, ierr) print *, "Rank", rank, "received:", data endif call MPI_Finalize(ierr) end program ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值