简洁步骤搭建编写Fortran77程序示例环境 调用BLAS Fortran库函数

本文介绍如何在Win10环境下配置Fortran77编译环境,并通过编写和编译HelloWorld程序验证环境的正确性。此外,还详细讲解了如何下载、编译和使用BLAS库中的SDOT函数来计算两个向量的点积,同时提供了对SDOT源代码的分析及DDOT和DCOPY函数的使用示例。

本来想一口气编辑一篇长文,排版意识较弱,一段一段地来吧。

一,搭建Fortran77编译环境(前文有综述,这里给出最省时方案)

(a)Win10下载并安装MinGW

                  假设安装在了D:\MinGW\,那么检查D:\MinGW\bin中是否存在gfortran.exe  make.exe   gdb.exe  gcc.exe等。如果不存在,则从类似mingw32-make.exe 复制一份并改名为  make.exe等。

(b)将D:\MinGW\bin加入环境变量path中

                  然后打开cmd控制台,执行gfortran --version,看看有没有正常反馈,类似

                                                       GNU Fortran (MinGW.org GCC-6.3.0-1) 6.3.0
                                                       Copyright (C) ... ...

(c)类似执行 gcc --version 、gdb  --version  、make --version等等

(d)如果以上可执行文件不存在,则需要打开桌面的MinGW Intaller 选择并安装。

 

二,编写编译运行blas示例程序

(a)编辑、编译一个fortran77的helloworld程序

            新建一个空文件夹,新建一个新文件:helloWorld.f,打开文件,写入如下内容,每行开头要先tab键。

            输入如下代码:

	PROGRAM EX_SDOT
	REAL VX(1:5),VY(1:5), RESULT_dot
	INTEGER I
	
	DO 10, I=1,5,1
		VX(I)=I
		VY(I)=I*10.0
10	CONTINUE
	PRINT *, VX
	PRINT *, VY
	END

在cmd 控制台里面进行编译:

>gfortran helloWorld.f -o helloWorld

>helloWorld.exe

效果如图

(b)下载blas-3.8.0.tgz          或直接浏览页面下载:http://www.netlib.org/blas/blas-3.8.0.tgz

(c)解压到一个空闲文件夹中,在cmd进入到blas源码的目录,其中有一个makefile文件。

执行make,会生成一个blas的二进制打包文件:blas_LINUX.a

>make

blas的makefile很简洁,基本就是把每个fortran源文件编译成.o文件后,用ar工具打包起来成为blas_LINUX.a

(d)将上一步的.a文件拷贝到helloWorld.f所在的源文件夹中(可省略编译时指定库文件目录)。

并且重新编辑helloworld.f文件,加入对blas函数SDOT的调用,计算两个向量的点积:

	PROGRAM EX_SDOT
	REAL VX(1:5),VY(1:5), RESULT_dot
	INTEGER I
	
	DO 10, I=1,5,1
		VX(I)=I
		VY(I)=I*10.0
10	CONTINUE
	PRINT *, 'VX = ',VX
	PRINT *, 'VY = ',VY
	PRINT *, ''
	PRINT *, 'VX DOT VY = ', SDOT(5,VX,1,VY,1)
	END

执行效果如图:

其中,SDOT函数的定义在blas源文件 sdot.f 中,原型如下:

      REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)

其中:

N 是说明两个相乘向量的元素个数,本例中每个向量VX和VY分别是5个元素;

SX  是第一个向量的形参变量名,本例中实参为VX;

INCX  是下一个参与点积运算的元素的步长,本例中元素是一个挨着一个元素,所以INCX为1;

SY  是第二个向量的形参变量名,实参为VY;

INCY 是指SY中下一个元素的步长,这里也是1.

 

三,对SDOT源代码的分析

(a)从源文件sdot.f中,删掉关键注释信息,只保留程序代码,如下:

*  =====================================================================
      REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)

      INTEGER INCX,INCY,N

      REAL SX(*),SY(*)

      REAL STEMP
      INTEGER I,IX,IY,M,MP1

      INTRINSIC MOD
      STEMP = 0.0e0
      SDOT = 0.0e0
      IF (N.LE.0) RETURN
      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN

*        code for both increments equal to 1
*        clean-up loop
         M = MOD(N,5)
         IF (M.NE.0) THEN
            DO I = 1,M
               STEMP = STEMP + SX(I)*SY(I)
            END DO
            IF (N.LT.5) THEN
               SDOT=STEMP
            RETURN
            END IF
         END IF
         MP1 = M + 1
         DO I = MP1,N,5
          STEMP = STEMP + SX(I)*SY(I) + SX(I+1)*SY(I+1) +
     $            SX(I+2)*SY(I+2) + SX(I+3)*SY(I+3) + SX(I+4)*SY(I+4)
         END DO
      ELSE
*
*        code for unequal increments or equal increments
*          not equal to 1
*
         IX = 1
         IY = 1
         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
         DO I = 1,N
            STEMP = STEMP + SX(IX)*SY(IY)
            IX = IX + INCX
            IY = IY + INCY
         END DO
      END IF
      SDOT = STEMP
      RETURN
      END

由源代码可以看出来,在元素步长都为1的情况下,SDOT函数计算点积,是按五个五个一组进行累加乘积的。这应该是针对cpu计算能力和内存访问的的一种优化。

而对于元素步长不等于1的情况,则是逐个相乘累加的,针对cpu没办法优化。

 

四,DDOT 和 DCOPY示例

DDOT和DCOPY参数的含义,跟sdot中的参数一样,三者的源代码实现结构也基本相同,只是元素都是DOUBLE PRICISION型的。DDOT也是两个向量点积;DCOPY则是将第二个向量中的元素拷贝到第一个向量中去。

	PROGRAM EX_DDOT_DCOPY
	DOUBLE PRECISION VX(1:5),VY(1:5), COPY_FROM_VY(1:5)
	INTEGER I
	
	DO 10, I=1,5,1
		VX(I)=I
		VY(I)=I*10.0
10	CONTINUE
	PRINT *, 'VX = ',VX
	PRINT *, 'VY = ',VY
	PRINT *, ''
	PRINT *, 'VX DOT VY = ', DDOT(5,VX,1,VY,1)
	VX = 2.0*VX
	PRINT *, 'VX DOT VY = ', DDOT(5,VX,1,VY,1)
	CALL DCOPY(5,VY,1,COPY_FROM_VY,1)
	PRINT *, 'VY = ',VY
	PRINT *, 'COPY_FROM_VY = ',COPY_FROM_VY
	END

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值