编写健壮的“现代”Fortran代码

时间:2010-05-03 14:13:26

标签: oop fortran assertions scientific-computing fortran90

在某些科学环境中,你经常离不开FORTRAN,因为大多数开发人员只知道这个习语,并且有很多遗留代码和相关经验。 坦率地说,高性能编程没有很多其他跨平台选项(C ++可以完成任务,但语法,零启动数组和指针与某些人不兼容)。< / p>

所以,让我们假设一个新项目必须使用Fortran 90,但我想用它构建最现代的软件架构,同时兼容最新的编译器(Intel ifort,但也包括Sun / HP / IBM编译器)

所以我想要强加一些广为人知的东西,但在我的环境中还不是标准:

  • 全局变量禁止,没有getos,没有跳转标签,implicit none
  • “面向对象编程”(具有数据类型和相关子例程的模块)
  • 模块化/可重用的功能,文档齐全,可重用的库
  • 断言/前提条件/不变量(使用预处理程序语句实现)
  • 所有(大多数)子程序和“对象”的单元测试
  • 强烈的“调试模式”(#ifdef DEBUG),包含更多检查和所有可能的英特尔编译器检查(数组边界,子程序接口等)
  • 使用代码处理工具帮助程序统一和强制清晰的编码风格。

所有这一切的目标是拥有值得信赖,可维护和模块化的代码。然而,在许多遗留代码中,可重用性并不是一个重要的目标。

我搜索了有关面向对象的Fortran,按合同编程(断言/前提条件等)的引用,并且发现只有那些没有大规模项目参与的人所做的丑陋且过时的文档,语法和文章,和死的项目。

有关此主题的任何好的网址,建议,参考文件/书籍?

7 个答案:

答案 0 :(得分:45)

我建议OP放弃这样的态度,即Fortran在高性能科学计算中是令人讨厌的,并且热情地潜入其中。如果OP保留了那种相当不屑一顾的心态,那么他/她的整个Fortran编码生涯将是一场斗争。实际上,你无法使用Fortran做任何你无法用C ++做的事情,所以如果你真的不想要这么麻烦呢?

在OP的子弹列表中没有任何内容,我们很多在过去30年里一直在使用Fortran的人都没有这样做(因为Fortran 90编译器的普及,但之前也有一些)。是的,有计算科学家和科学软件工程师,他们了解指针,知道很多(被误导的)人开始计数为0,而全局变量是不好的。

与@MSB一样,我推荐Metcalf 的书作为现代Fortran功能和特性的信息来源。而且,就像@MSB一样,我对使用C或C ++来封装库的想法表示赞赏,这些库完全是Fortran等价物或更好的方法。 2003标准与C功能的互操作性(在英特尔Fortran中实现)使得直接调用C库变得前所未有的简单。

我对OP有疑问,拥有模块化代码本身就是一个目标。我建议,这些目标是正确的,可验证的,可验证的,健壮的,可靠的代码。模块化是支持实现这些目标的一种方式,但这是一种策略,而不是终点。如果我认为我们可以编写好(在上述意义上)包含10 ^ 6行代码而没有模块化的程序,我就不会费心去模块化了。

好的,现在有一些具体的提示可以添加OP已经打算做或已被告知:

  • 在变量声明上使用KIND来强制执行所需的精度;不要将此留给编译器选项或猜测这个编译器可能在该处理器上做什么;
  • 尽可能使用数组操作而不是显式循环;这有助于使代码更安全 - 有时以牺牲性能为代价,但您需要根据具体情况进行检查;
  • 写PURE函数;
  • 不依赖于预处理器或其他非Fortran方法来编码正确性(等),在Fortran中编写断言和前置条件(等);只要编写得好的Fortran程序,预处理器(等)就无法生存,并且将成为现在和将来可移植性的主要障碍;
  • 如果您有权访问英特尔Fortran,可以访问英特尔MKL(和IPP)并使用这些库而不是编写自己的代码;
  • 计划解决OpenMP和MPI的并行化问题,它们都非常适合Fortran;哦,并计划尽快并行,它比串行编程更有趣;
  • 这组Fortran Coding Standards是一个好的开始,但可能只是那个;第一版代码完成有很多关于Fortran(77)编程的内容,而不是当前版本,但它的大部分建议都适用于您编写的任何语言。

最后,最后,我认为Fortran程序和程序员更好地了解函数式编程的想法,而不是面向对象编程的想法。

答案 1 :(得分:39)

我5美分。

Fortran Wiki是一个很好的起点。它有关于使用现代Fortran进行编程的不同方面的文章。单元测试,调试,通用编程等。还可以获得有关Fortran 2003标准的编译器支持的非常有趣的table。 (正如Blklight已经提到的,编译器中没有一些2003功能。它是比较不同编译器的好地方。)

  

我是C ++人,但我坚持使用一些F90项目。

我建议您阅读本课程:Introduction to Modern Fortran。 M. S. B.提到了着名的“Fortran 95/2003 Explained”,但是这本书足够大并且充满了细节。相反,上述课程是一个很好的起点。另请参阅利物浦大学的An Interactive Fortran 90 Programming Course

Mistakes in Fortran 90 Programs That Might Surprise You。这个页面标题说明了一切。 =)

嗯......我的书签中也有一些链接PSTI RESEARCH LECTURE SERIES "SCIENTIFIC COMPUTING WITH FORTRAN 95"。试一试。

J.F。塞巴斯蒂安提到了F2Py并提出了教授Python的建议。我赞同他的意见。 Python不是我最喜欢的语言。但它足以教导它。对于已经提到过的预处理器(其中许多是用Python编写的)和F2Py不会传递SCons - 现代软件构建工具。

P.S。上周我在lulu.com买了一本电子书。 Drew McCormack Scientific Software Development in Fortran。我希望这是好读,但突然间没有时间。作者是Forpedo(Fortran Wiki中提到的F​​ortran特定预处理器之一)的开发人员,也是许多关于Objective-C和Python编程的书籍和教程的作者。

答案 2 :(得分:13)

Fortran 90/95/2003的设计使得人们可以通过添加模块,私有/公共,用户定义类型等来编写模块化代码.Fortran 2003引入了更多面向对象的功能。当Fortran 90“分配”以更安全的方式直接动态分配Fortran数组时,连接到C以添加malloc是没有意义的。将过程(函数和子例程)放在模块中然后“使用”模块将导致检查接口。可以使用编译器的许多调试/检查选项,例如下标边界检查。

了解这些和其他功能的优秀书籍:Metcalf,Reid和Cohen撰写的“Fortran 95/2003解释”。学习现代Fortran的最佳功能绝对是一个好主意,而不是继续编写FORTRAN 77 - 如果有必要,编写编码标准/指南。

答案 3 :(得分:6)

在过去的几年里,我和一位同事在现代Fortran中开发了一个相当大的计算库,它提供了许多你提到的功能 - 面向对象,模块化/可重用,一致的代码风格等等(我们没有但是,在单元测试方面做得很好 - 需要了解它,然后将所有这些包装起来以提供与C ++,Python等的接口。这里的其他人指出了我推荐的所有书籍和链接(以及更多),所以我不再重复。我发布的原因只是说可以用Fortran做这些事情并创造出很棒的东西,所以坚持下去。

我还要指出,在所有主要编译器中实现了大量的Fortran 2003标准之后,您是多么幸运。您会发现很多这些功能(例如程序指针)非常有用。

答案 4 :(得分:4)

我很匆忙,如果我以检查点的形式而不是合理的句子来回答,请原谅我。

  • 尝试遵守标准(Fortran是一种标准化语言,并且通过遵循标准语言功能,并避免供应商特定扩展,您将拥有一个可移植的平台程序,您可以为此确保编译器没有问题)。我不知道我在哪里下载了我的副本,但我很确定你可以下载最新的草稿(注意; fortran 2008或2003的许多功能仍然没有在当前的编译器中实现,尽管很多都是现在差不多 ......来自J3's page
  • 的Cray
  • 对于有关上述问题的所有问题,我衷心推荐 comp.lang.fortran usenet组 - 不仅在那里有一些知识渊博的人(例如,Richard Maine先生......将会可能愿意回答你可能会提出的任何标准合规性问题,如果问得很多,如果得到很好的解答......对于许多其他问题也是如此)但是它也有那些曾经从事过大规模问题的人,他们会知道并愿意就主题
  • 提供建议
  • 书籍 - 除了已经提到的所有内容(Metcalf,Reid和Cohen的书也有我的推荐,还有缅因州和其他人的“Fortran 2003手册”),试着找一个Stephen J. Chapman的副本"Fortran 95/2003 for scientists and engineers" ...对某些主题采取了一点过于自信的立场,但总的来说,这本书非常好,并提到了许多“良好的编程习惯”)
  • 另外,不知道你是否已经在这个"Object oriented programming via Fortran 90/95"
  • 中痴迷

对您的文字的一些评论:

(这似乎都是“明显的”现代编程假设,但在传统的fortran世界中,大多数都是典型程序员工作流程中的重大变化)

即使在现代的fortran世界中,其中一些假设也值得怀疑......记住,fortran程序员不是程序员(我是以浓缩形式重复这个;我已经在这个论坛上写了很多次)但是工程师,科学家等。对他们(我们?)代码不是一个目标,而只是一个工具......对于专业程序员而言,代码就是一切;他们没有“超越它”......因此,他们非常珍惜它。对于我们的工程师来说,它只是获得我们想要的结果的一种手段......考虑到这一点,尽管良好的编程实践稍后付出,但没有必要坚持他们没有明显需要它们。

所有目标都是拥有值得信赖,可维护和模块化的代码。然而,在典型的fortran中,模块化通常不是主要目标,只有当原始开发人员非常聪明并且代码从那时起没有改变时,代码才是值得信赖的! (我在这里有点开玩笑,但并不多)

有人说过,你不会相信它是多么真实:
“没有什么比临时修复更永久了。”

有关此主题的任何好的网址,建议,参考文件/书籍?

鉴于以上几点。

另外,在写这个答案时,我看到High Perf。马克发布了一个非常好的答案,我大多同意这个答案......它更详细地说明了标准的坚持。

另外,我的建议是肯定也会在comp.lang.fortran上发布这个问题...我知道你可以在那里获得更多质量的答案,然后在这里(我相信不会超过20左右)整个stackoverflow的fortran程序员。)

一些欧洲联盟委员会自由发布了一套代码编写指南;作为这个答案的一部分,它们会非常有用,但不幸的是,我在我的快速谷歌搜索中找不到它们,并且没有时间进行广泛的查看。尝试搜索主题...也许你会有更好的运气。

答案 5 :(得分:3)

我刚刚在F2003上发现了这个由两部分组成的面向对象编程系列。这里有很多很棒的东西:

第1部分:http://www.pgroup.com/lit/articles/insider/v3n1a3.htm

第2部分:http://www.pgroup.com/lit/articles/insider/v3n2a2.htm

它有很好的例子,并且非常清楚地解释了一切。

答案 6 :(得分:1)

如果您想在OO中查看大型Fortran程序,请访问www.mohid.com。这是GPL。 我同意编写现代Fortran OO是不够的,必须包含功能编程概念。我正在对此进行一些研究,我相信主要的缺失功能是lambda(匿名)函数。 另一方面,我认为要进行并行化最好是采用MPI路由,而不是OpenMP。