Fortran代码高效重用的一种方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1概述
最初的工业界计算机应用,主要在于科学计算。从20世纪50年代开始,工程师们也特别喜爱这种语法简单、查错容易、运行效率高的开发语言,他们使用For⁃tran语言开发了大量的函数库和应用程序。这些资源可靠而高效,值得直接使用。
时代在进步,今天的软件已基本转变为交互式的。如何快速开发科学计算型的程序,是软件工程师和专业技术领域工程师必须共同面对的问题:领域工程师习惯自己熟悉的Fortran语言,并且积累了大量成熟的代码,同时要对这些代码进行长期的维护;软件工程师需要面临网络计算、交互,一般会选择Java、C/C++这样的现代开发语言实现程序的框架。
利用混合编程思路,解决了企业充分利用已有代码快速开发新应用提供了一种方法。
2实现C/C++对Fortran已有代码资源的调用要实现C/C++、Fortran语言间的混合编程,需要了解两种语言间的编译约定、参数传递方法和存储原理。
2.1简单混合编程
为了兼顾Fortran语言的特点,C语言使用简单的变量类型:整数、浮点数、双精度、字符串。在这样的情况下,实现C调用Fortran函数,变得非常简单(例1)。程序员只需要关注值传递的C语言函数调用方式。
例1C/C++简单调用Fortran程序
main.c
#include
#include
#include“sub.h”int main(int argc,char**argv)
{
int number=-1234;
float decimal=12345.6789;
double decimal_l=1.e40;
char a[16];
strcpy(a,“0123456789112345”);
printf("c i%d\n",number);
printf("c f%f\n",decimal);
printf("c d%lf\n",decimal_l);
printf("c c%s\n\n",a);
fort_(&number,&decimal,&decimal_l,a); }
sub.h
void fort_(int*,float*,double*,char*); fort.f
subroutine fort(nm,rl,dbl,c) character*16c
double precision dbl
integer nm
real rl
print*,“f I”,nm
print*,“f r”,rl
print*,“f d”,dbl
print*,“f c”,c
return
end
编译命令
$gcc main.c fort.f–lgfortran
运行结果,如图1所示。
Fortran代码高效重用的一种方法
贾继军,王昌宏,刘社平
(中国石油集团东方地球物理公司物探技术研究中心,河北涿州072750)
摘要:利用已有的软件资源,在不影响可维护性的前提下,快速开发出交互程序,是一个摆在工程
师和软件人员之间的现实问题。提出了Fortran代码高效重用的方法,兼顾了现代软件开发语言和传统
代码,值得借鉴。
关键词:混合编程;格式转换
基金项目:国家重大专项《新一代地球物理油气勘探
软件系统》(编号2017ZX05018001)。
收稿日期:2018-11-10
17
2019.02
2019.02
可以看出,整数和字符串没有任何问题,但单精度浮点数和双精度浮点数,有存储误差存在。
在编写代码时,注意区分代码中函数名称的大小写;Fortran 语言不区分字母大小写,编译系统一般约定是小写字母,并且在名字后面加一个下划线“_”。2.2复杂参数传递
C/C++语言具有数据类型的可扩展性,Fortran 90之
后,也有一定的自定义数据类型,但对已有代码的利用帮助不大。
C 语言的struct 可以把一组的简单数据组合在一起,
作为一种扩展数据,传递到被调用函数中,而Fortran77不具备这种能力。C 语言的struct 数据在内存里面是连续存储的(Fortran 的数组也是一个连续内存块),C 语言还支持数据地址类型强制转换,这就为将C 语言的数据传递到Fortran 代码供了前提条件。
例2通过结构传递参数
test.c
#include
int main(int argc,char**argv){
struct {int n;float dec;double rl;char a[16];}mix;
mix.n =190;mix.dec=-12.3;mix.rl =123456.789;
strcpy(mix.a,"0123456789112345");printf("c i %d\n",mix.n);printf("c f %f\n",mix.dec);printf("c d %lf\n",mix.rl);printf("c c %s\n",mix.a);
int n =32;
fort_((float *)&mix,&n);fortd_((double *)&mix,&n);
}
sub.h
void fort_(float *,int *);void fortd_(double *,int *);void fortc_(char *,int *);fort.f
CCCC 用4字节作为单元传递数据
subroutine fort(d,n)real d(*)integer in real ff(4)
double precision df character*16cchar
equivalence(in,ff,df,cchar)call int(in,d(1))ff(1)=d(1)print *,"f i ",in print *,"f f ",d(2)ff(1)=d(3)ff(2)=d(4)
print *,"f d ",df ff(1)=d(5)ff(2)=d(6)ff(3)=d(7)ff(4)=d(8)
print *,"f c ",cchar return end
CCCCC 用8字节传递参数
subroutine fortd(d,n)double precision d(*)integer in real ff
double precision df character*16cc
equivalence(in,ff,df,cc)df =d(1)
print *,"df i ",in print *,"df f ",ff df =d(2)
print *,"df d ",df df =d(3)
print *,"df c ",cc
return
图1
18