1. 程式人生 > >作業2-1:矩陣協方差

作業2-1:矩陣協方差

備註:待親手實驗

講評:

(1)編譯器引數:

  改makefile

  1.降精度 -O3:精度誤差累加可能會出錯

  2.xHost:intel編譯優化,告訴編譯器生成編譯主機處理器上可用的最高指令集的指令。無腦加就行。

  3.開向量模組(intel編譯器)

修改過的makefile

FC=ifort
LD= ifort
FFLAGS= -qopenmp -mcmodel=large -O3 -xHost //增加 -O3 -xHost

main.b: main.o Covariance1.o Covariance.o check.o
    ${FC} ${FFLAGS} main.o Covariance1.o Covariance.o check.o 
-o main.b main.o: main.f90 ${FC} ${FFLAGS} -c main.f90 Covariance1.o: Covariance1.f90 ${FC} ${FFLAGS} -c Covariance1.f90 Covariance.o: Covariance.f90 ${FC} ${FFLAGS} -c Covariance.f90 check.o: check.f90 ${FC} ${FFLAGS} -c check.f90 clean: rm -rf *.o *.i main

 

(2)改程式碼

  1.函式inline可以跨檔案,直接拷過來

  2.fortran:列優先,若程式碼為行邏輯則考慮先矩陣轉置(可並行可分塊,按cache層);

       fortran語言:先宣告,後申請空間(陣列),然後才是語句

修改後converiance程式碼SUBROUTINE FindCOV(NVAR, NROW, NV, M1Type, COV)


        IMPLICIT NONE

        INTEGER, INTENT(IN)    :: NVAR              !Number of variables
        INTEGER, INTENT(IN)    :: NROW              
!Number of rows in MType INTEGER, INTENT(IN) :: NV !Number of cals in MType REAL*8, INTENT(IN) :: M1Type(NVAR, NROW) !Data used to calculate covariance REAL*8, INTENT(INOUT) :: COV(NVAR, NV) !Covariance matrix, output INTEGER :: IVar1 INTEGER :: IVar2 INTEGER :: I2 REAL*8, ALLOCATABLE::MType(:, :)//陣列宣告 REAL*8,EXTERNAL :: Covariance ALLOCATE(MType(NROW, NVAR))//陣列申空間 !$OMP PARALLEL DO private(IVar1,IVar2) shared(M1Type, MType) schedule(guided) //並行,每個並行塊都要寫 DO IVar1 = 1, NVAR//陣列轉置 DO IVar2 = 1, NROW MType(IVar1, IVar2) = M1Type(IVar2, IVar1) ENDDO ENDDO !$OMP END PARALLEL DO !$OMP PARALLEL DO private(IVar1,IVar2,I2) shared(NVAR,COV,MType) schedule(guided) //並行 加排程引數 DO IVar1 = 1, NVAR DO IVar2 = 1, NV I2 = mod(IVar1 + IVar2 - 1, NVAR) + 1 COV(IVar1, IVar2) = Covariance(NROW, MType(:,IVar1), MType(:,I2))//正確遍歷:列優先
//fortran冒號:隱含遍歷
   ENDDO ENDDO !$OMP END PARALLEL DO RETURN END SUBROUTINE FindCOV !DEC$ ATTRIBUTES FORCEINLINE :: Covariance REAL*8 FUNCTION Covariance(NObs, X1, X2) IMPLICIT NONE INTEGER, INTENT(IN) :: NObs REAL*8, INTENT(IN) :: X1(NObs) REAL*8, INTENT(IN) :: X2(NObs) INTEGER :: IObs, NumMissing REAL*8 :: MeanX1, MeanX2 LOGICAL :: IsMissingPheno//將外面的函式拷進來,刪掉external,一開始把external的函式忽略了。。 NumMissing=0 MeanX1=0.0 MeanX2=0.0 Covariance=0.0 !!$OMP PARALLEL DO private(Iobs) shared(Covariance, X1, X2, NObs) schedule(guided) DO IObs=1, NObs IF(ISNAN(X1(IObs)) .OR. & //IsMissngPheno的展開 ISNAN(X2(IObs)) .OR. & ABS(X1(IObs)-65.0) .LE. 1.e-03 .OR. ABS(X2(IObs)-65.0) .LE. 1.e-03) THEN NumMissing=NumMissing+1 ELSE MeanX1=MeanX1+X1(IObs) MeanX2=MeanX2+X2(IObs) Covariance=Covariance+X1(IObs)*X2(IObs) ENDIF ENDDO !!$OMP END PARALLEL DO MeanX1=MeanX1/(NObs-NumMissing) MeanX2=MeanX2/(NObs-NumMissing) IF(NObs-NumMissing .LE. 0) THEN Covariance=0.0 ELSE Covariance=Covariance/(NObs-NumMissing)-MeanX1*MeanX2 ENDIF RETURN END FUNCTION Covariance

 

 

經過:

(1)將本地檔案傳到伺服器:使用pscp顯示unreachable。下載xshell 使用rz傳:

https://blog.csdn.net/weixin_37909391/article/details/80530575

下載完xshell覺得很好看,我要捨棄putty了。

(2)解壓zip:unzip+名字

https://www.cnblogs.com/zdz8207/p/3765604.html

(3)執行,需要編譯。f90是fortran,需要ifort編譯。

  按ifort:伺服器上有

  使用命令: module load intel/2017.6.064 (module:環境模組 http://blog.sciencenet.cn/blog-468005-920774.html)

  如何編譯:http://blog.sciencenet.cn/blog-1982759-890635.html :

1.直接生成可執行檔案

假如我們手頭上有一個intel的fortran編譯器進行編譯,就要採用如下命令:

ifort global.f90 main.f90 function1.f90 subrouine1.f90

這樣會自動生成檔案a.out,這是一個可執行檔案。


 如果想讓生成的可執行程式有一個名字,將命令改成

 ifort -o execname global.f90 main.f90 function1.f90 subrouine1.f90

即可。

輸入命令

 ./execname

即可執行該程式。

  這個題的readme寫了直接make就行。一開始make報錯是因為沒有load ifort,load完直接make就可以了。執行要等好久,我還以為卡了。。

(4)安裝VTune:

教程:https://blog.csdn.net/WY_stutdy/article/details/79106501

註冊試用版最多需要兩天,還要等。