Fortran结合MPI并行
该Bolg整理在Fortran用MPI编写并行程序,用在科学计算中速度提升肉眼可见,{:.info} 代码解析先给一个完整的代码,是用来计算自旋极化率的,实际上在Fortran结合MPI并行计算自旋极化率中已经出现过了,这里就是解读一下其中的并行部分是如何用MPI写的。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242module param implicit none integer kn,hn parameter(kn = 64,hn = 4) real,parameter::pi = 3.1415926535897 real,parameter::omega = 0.00 complex,parameter::im = (0.,1.) !Imagine unit complex Ham(hn,hn),Umat(hn,hn),ones(hn,hn)...
Fortran结合MPI并行计算自旋极化率
在之前的博客Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)利用Julia计算了一个模型的极化率,但是在撒点数量增加的时候计算速度还是堪忧。这里就返祖利用Fortran语言再结合MPI并行来重写code。根据测试发现计算速度显著提升。{:.info} 前言虽然使用Julia在计算的时候速度已经相当快了,但是如果涉及到计算极化率这种需要在布里渊区撒点很多才能精确计算的量,Julia在计算的时候需要的时间还是有点久。况且想要速度更快,就需要仔细的去对代码进行优化,想想还是挺复杂的。最后考虑直接返祖,就用Fortran(公式翻译器)来计算极化率。 关于公式具体的内容可以参考Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)这篇Blog,或者去查看原文Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure,下面直接上代码。 代码这里在写的时候偷懒了,将哈密顿量设置为全局变量了,而且对角化厄米矩阵的函数并没有进行封装,调用之后就是直接对角化哈密顿量。实际上正确且安全的写法就是通过子过程返回哈密顿量,并将其传递给对角化函数计算本征值和本征矢量,这样才能让程序具有通用性。不过事情我是知道的,但这个程序很简单,就先不做这样做了,后续写大程序的时候就会规范了。 计算耗时这里撒点数量为 256 * 256,调用了64个核,计算时间如下123======== Job starts at 2024-04-15 15:25:16 on n26 ======== Start Fortran code======== Job ends at 2024-04-15 15:25:37 on n26 ========...
使用Latex进行文档对比并自动标记修改的内容
这里整理一下如何使用Latex自动整理出文档改动内容并进行标记,这个功能在我们给审稿人回复意见的时候非常有用。{:.info} 前言通常在文章审稿的过程中,都需要根据审稿人的要求和问题对文章内容进行修改,常用的方法就是将修改的部分用颜色标记出来,但是这样就将原来的内容删除掉了,审稿人再次看到的时候只能看到我们修改文章的结果,但具体修改了什么,修改到了什么程度就不是很显而易见了。当然,如果有精力也可以用下划线以及删除线等标记自己手动将原本的内容与修改之后的内容分别进行标记,但这种手动的方式操作起来还是挺累的,毕竟Latex本身虽然排本能力很强,但是在写的时候可读性就不是很好了,内容多了就会眼花缭乱。 解决方法实际上在安装了TexLive之后,本身就会自带一个文档比对的功能,与Linux系统里面的diff的功能是相似的,使用1latexdiff file-1.tex file-2.tex > diff.tex这个命令之后,就可以自动生成一个对比之后的文件diff.tex,当然,这里的名字都是自己起的。在产生的diff.tex文件中就会将两个文件的比对结果存储,删除以及修改的内容都会用各种标记方式给出。再对diff.tex文件编译之后就可以得到一个内容修改对比的结果了,示例如下 原版(file-1.tex) 修改版(file-2.tex) 对比版(diff.tex) 这样就可以让审稿人一目了然的看清楚我们对正文的修改以及修改程度,对文章审稿意见的仔细回复也能体现出对审稿人的尊重{:.info} 上面给出的只是latexdiff的默认参数选择,更加丰富的选项可以移步官网查看,但是以我现在的需要,看起来默认的选项就已经足够了。 提示前面只是给出了一个很简单的示例,实际上文档中包含的并不仅仅是文字,还会有公式和图片,这些都是可以识别修改前后的差别。 但有一点很重要,在修改之后的file-2.tex中,尽量要保证它与file-1.tex的结构是一致的。比如说你有一张图片本来在Latex中在Section I里面的,但是在修改过程中将这个图片的插入移动到了Section...
Julia中MPI,@distributed,@threads三种并行方法的比较
最近折腾了一下Julia的并行操作,目前我了解到的有三种:MPI并行、@distributed、@threads,这里就用极化率的计算来对比一下三者的速度。{:.info}这里先单独列举一下三种并行方式在语法上的不同 MPI123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657using LinearAlgebra,DelimitedFiles,Printf,MPI,Dates#-------------------------------------------------------------------------------function main1(nk::Int64) # nk::Int64 = 200 klist = range(0,pi,length = nk) qxlist = zeros(Float64,nk^2) qylist = zeros(Float64,nk^2) chilist = zeros(Float64,nk^2,2) #************************************************* # Parameter for MPI MPI.Init() comm = MPI.COMM_WORLD root = 0 numcore = MPI.Comm_size(comm) # 申请的核心数量 indcore = MPI.Comm_rank(comm) # 核心的id标号 #************************************************* #************************************************* # 循环区间分配 nki = floor(indcore * nk/numcore) + 1 nkf = floor((indcore + 1) * nk/numcore) if (MPI.Comm_rank(comm) == root) ...
Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)
这里将Julia的并行实操了一下,并行计算了自旋极化率,在通常的计算中这部分的计算量是非常大的,而使用Julia的宏@distributed我目前无法实现跨节点计算,这里就尝试用MPI并行实现跨节点计算.{:.info} 介绍这里就不具体介绍自旋极化率是如何计算的了,直接上公式 \chi^{st}=-\frac{1}{2N}\sum_{\mathbf{k},mn}\frac{f(\epsilon^n(\mathbf{k}))-f(\epsilon^m(\mathbf{k}+\mathbf{q}))}{i\omega_n+\epsilon^n(\mathbf{k})-\epsilon^m(\mathbf{k}+\mathbf{q})}\langle m\rvert\mathbf{k}+\mathbf{q},t\rangle\langle \mathbf{k}+\mathbf{q},s\rvert m\rangle\langle s\rvert\mathbf{k},s\rangle\langle\mathbf{k},t\rvert n\rangle具体的内容可以参考Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure这篇原文。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146# 已经通过BBH模型检测using...
Julia的MPI并行
在之前搞计算的时候,虽然也用到了Julia的并行计算,但实现方法上并没有利用MPI,单速度上勉强也是够用的.最近遇到了计算量比较大的情形,此时如果可以在集群上多使用几个节点,多点CPU的话计算速度就可以显著提高.这里就整理一下如何结合MPI实现对Julia的并行。{:.info} 并行循环基本操作首先要使用Julia的MPI包,但是目前给出的文档在实用性方面比较差,如果本来已经熟悉MPI的话也勉强能看,连蒙带猜的可以用一下这些函数,我就是这么做的。 首先是进行环境初始化123456using MPIMPI.Init()comm = MPI.COMM_WORLDroot = 0numcore = MPI.Comm_size(comm)indcore = MPI.Comm_rank(comm)这里的MPI.Comm_size(comm)用来获取计算时能够使用的总CPU数量,MPI.Comm_rank(comm)则是对每个CPU一个编号,方便后续的管理以及CPU之间的通信。一般习惯上会将MPI.Comm_rank(comm)=0的核心称为root,因为最后的数据收集以及保存等操作会在这个CPU上进行。得到了这些信息之后,接下来的目的就是将一个循环分成不同的区间,然后每个CPU计算不同的部分。加入我先在想实现一个求和功能12345678function test(x1,x2) te1 = x1:x2 re::Float64 = 0.0 for i0 in eachindex(te1) re += te1[i0] end return reend将函数放到MPI并行中首先要进行环境的初始化,然后将函数要想实现的功能分配到不同的CPU上面进行计算123456numcore = MPI.Comm_size(comm) # 获取总的CPU数量indcore = MPI.Comm_rank(comm) # 每个CPU的索引numk::Int64 = 1000000nki = floor(indcore * numk/numcore)nkf = nki + floor(numk/numcore)temp = test(nki +...