fortran并行程序入门(1)

文章介绍了Fortran中使用MPI进行并行编程的基本概念,包括MPI_INIT初始化并行环境,MPI_COMM_RANK获取进程ID,MPI_COMM_SIZE获取进程数量,以及MPI_SEND和MPI_RECV实现线程间的通信。示例代码展示了如何在Linux集群中编译和运行并行程序,以及线程间数据的发送和接收过程。

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


前言

今天,迫不得已还是要学fortran了,不然工作进行不下去。

一、简单并行程序?

本处先加载前人所写的部分代码。

program main
    use mpi
    implicit none
    integer*4::ierr,my_id,num_procs
    call MPI_INIT ( ierr )
  ! find out my process ID, and how many processes were started.
    call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
    call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr) !num_procs--number of process
    write(*,'(1x,i2,a,i2)')my_id,'/',num_procs

    call MPI_FINALIZE ( ierr )
end program
————————————————
版权声明:本文为CSDN博主「xhh22900」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xhh22900/article/details/117305417

其中种种代码究竟是,干什么用的呢?
use mpi 是导入mpi包,有了这行代码,下面的MPI_INIT之类的函数才能使用。
然后就是MPI_INIT,这是个初始化MPI的代码,初始化调用 MPI 进程的执行环境以执行单线程执行,里面需要包含一个变量,我看大多数人都用ierr。
MPI_COMM_RANK用来标识各个MPI进程,给出调用该函数的进程号,其中的my_id可以作为进程的唯一标识符。
MPI_COMM_SIZE 用来返回通信子进程的进程数
MPI_FINALIZE 用来终结进程

上述代码再linux集群中编译时需要用到mpif90命令,这也是Mpi执行f90文件的命令

mpif90 example.f90 -o example

然后用如下命令执行程序

mpirun -np 8 ./example

这样设置的线程总数为8,也就是用8个线程来执行这个程序,最后输出结果为

  1/ 8
  3/ 8
  4/ 8
  5/ 8
  6/ 8
  7/ 8
  0/ 8
  2/ 8

可以看到,左边为执行程序的线程my_id,斜杠右边为总线程数

二、Fortran并行的一些注解

1.线程通信的一些代码注解

代码如下,这里同样引用了前人所写的代码:

program main
    use mpi
    implicit none
    integer*4::ierr,my_id,num_procs,i,tempa,status(mpi_status_size),tt,j
    call MPI_INIT ( ierr )
  ! find out my process ID, and how many processes were started.
    call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
    call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr) !num_procs--number of process
    
    tempa=my_id
    if(my_id==0)then
        write(*,'(1x,i2,a,3i2)')my_id,'/',num_procs,mod(my_id+1,num_procs),mod(my_id-1+num_procs,num_procs)
        call mpi_send(tempa,1,mpi_integer,mod(my_id+1,num_procs),99,mpi_comm_world,ierr)
    else
        call mpi_recv(tempa,1,mpi_integer,mod(my_id-1+num_procs,num_procs),99,mpi_comm_world,status,ierr)
        write(*,'(1x,i2,a,3i2)')my_id,'/',num_procs,mod(my_id+1,num_procs),mod(my_id-1+num_procs,num_procs)
    endif
    if(my_id<num_procs-1)call mpi_send(tempa,1,mpi_integer,mod(my_id+1,num_procs),99,mpi_comm_world,ierr)

    call MPI_FINALIZE ( ierr )
end program
————————————————
版权声明:本文为CSDN博主「xhh22900」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xhh22900/article/details/117305417

这里新增了两个关键的线程通信的代码
MPI_SEND这个代码从英语意思看就是发送,在本代码中的第一个if里,只有my_id=0的线程才仅仅发送,后面都是既接收又发送。
其中,
MPI_SEND(DATA,ICOUNT,DATA_TYPE,IDEST,ITAG,MPI_COMM_WORLD,IERR)
里参数的主要意义为

DATA:要送出资料的起点
ICOUNT:要送出资料的数量,当ICOUNT的值大于1时,DATA必须是阵列类型数据
DATA_TYPE:要送出去的资料类别
IDEST:是收受资料的CPUid
ITAG:是要送出的资料标签

从上解释可以看出,MPI_SEND只管发送,所以它作为先头的第一次进程命令

MPI_RECV 是同时接受发送的命令

CALL MPI_RECV(DATA,ICOUNT,DATA_TYPE,ISRC,ITAG,MPI_COMM_WORLD,ISTATUS,IERR)

以上命令的主要参数意义为

DATA:是要收受资料的起点
ICOUNT:是要收受资料的数量
DATA_TYPE:是要收受资料的类别
ISRC:是送出资料的CPU id
ITAG:是要收受资料的标签
ISTATUS:是执行MPI_RECV副程式之后的状况

其中主要的参数和MPI_SEND差不多,比较易于理解

总结

下班了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值