當前位置:成語大全網 - 書法字典 - fortran mpi如何定義mpi數據類型

fortran mpi如何定義mpi數據類型

MPI只定義Fortran中內置的標準數據類型,如整數、實數、字符、雙精度等。,但不提供Fortran90提供的派生數據類型(即type命令定義的結構化數據類型)。這種派生的數據類型屬於不連續數據,往往包含很多標準的數據類型和數組。

在MPI中,通常有兩種方法發送和接收這種派生的數據類型。壹種方式是利用MPI提供的創建派生數據類型的命令,創建壹個與Fortran90程序中已經定義的派生數據類型相同的新數據結構,然後生成壹個MPI的派生數據類型,最後傳遞這個MPI的派生數據類型;另壹種方法是以數據包的形式發送數據,然後在接收端將其解包。最近在研究前壹種方法,這裏簡單介紹壹下我的經驗。

例如,在Fortran90程序中定義了以下派生數據類型:

type type_global!INT(5+5),character(2*10),real(3),real*8(2)

整數npoin、nelem、ngroup、nmat、nblks

真實的x,y,z

真實*8 x8,y8

整數icmatrix(5)

character*20 outplot,type_abc

結束類型type_global

這個派生數據類型有四種標準數據類型,分別是integer (10,包括5個標量和5個元素的1數組)、real類型(3)、雙精度real類型(3)和string類型(2,各20個字符)。為了傳遞這個派生類型的數據,首先要將其數據結構定義為壹個MPI派生類型,要使用兩個MPI命令,分別是MPI_TYPE_STRUCT和MPI_TYPE_COMMIT。前者用於定義派生的數據結構,後者用於提交確認。MPI_TYPE_STRUCT的調用格式如下:

調用MPI_TYPE_STRUCT(ndatatype,blocklens_global,offsets_global,oldtypes_global,& amp

type_global_MPI,ierr)

解釋如下:

Ndatatype為整型變量,其值為派生數據類型中包含的標準類型的個數(本例中合並了相同的標準類型數據),本例中的值為4,即整型、字符串型、實型和雙精度實型;

Blockens _ global (0: 3)是壹個有n個數據類型的整數數組,每個元素的值就是這個派生類型中對應的標準數據類型的個數。如果順序為整數、字符串、實數、雙精度實數,則該數組的值為;

Offsets_global(0:3)是壹個帶有ndatatype元素的整數數組,每個元素的值都是該派生類型中對應標準數據類型的位移偏移量。這需要知道派生類型數據結構的類型表。簡單來說,在這個派生類型中,第1個標準類型(整型)的位移偏移量是0,第二個標準類型(字符串型)的位移偏移量應該是前壹個標準類型(第1個標準類型)的個數乘以該標準類型在內存中占用的字節數(4字節*10 =40),第壹個標準類型應該是0。本例中,值為,在Fortran90中,默認整數點為4字節,實型為4字節,雙精度實型為8字節,字符串按其長度計算,壹個字符占壹個字節。

Oldtypes_global(0:3)是壹個有n個數據類型的整數數組,每個元素的值都是這個派生類型中對應標準數據類型的MPI類型。按照上面的順序,它的值應該是[MPI _ integer,MPI _ character,MPI _ real,MPI _ double _ precedent]。

Blocklines _ global、Offsets _ global和oldtypes _ global應該有相同的標準數據類型順序,哪個在前哪個在後並不重要,但是三個數據的順序必須相同。

Type_global_MPI是壹個整型變量,定義後成為MPI可以使用的派生數據類型名,可以像MPI_INTEGER、MPI_REAL等壹樣使用。

Ierr是壹個整型變量,妳應該對它了如指掌。

最後,可以使用Call MPI _ Type _ Commit(Type _ global _ MPI,IERR)提交確認,然後使用MPI_SEND和MPI_RECV作為派生數據類型進行傳遞。

下面給出壹個完整的用MPI傳輸Fortran90的派生數據類型的代碼,主要是用MPI傳輸壹個派生結構數據,然後在每個進程中修改數據,然後打印出每個進程修改的數據,看看是否成功。

!==============================================================

程序MPI_TypeData_SendRecv

使用mpi

character *(MPI _ MAX _ PROCESSOR _ NAME)PC NAME,text*20

整數,參數::ndatatype=4

整數myid,npc,namelen,re,ierr,ver,subver,m,n,status(MPI_STATUS_SIZE),ipc

整數type_block_MPI,type_global_MPI,& amp

block lens _ global(0:ndatatype-1),offsets _ global(0:ndatatype-1),& amp

old types _ global(0:ndatatype-1),& amp

blocklens_block(0:2),offsets_block(0:2),oldtypes_block(0:2)

整數(8)::範圍

type type_global!INT(5+5),character(2*10),real(3),real*8(2)

整數npoin、nelem、ngroup、nmat、nblks

真實的x,y,z

真實*8 x8,y8

整數icmatrix(5)

character*20 outplot,type_abc

結束類型type_global

類型類型_塊

integer,allocatable::appear_process(:,:),matno_process(:,:)

結束類型type_block

類型(類型_全球)GHM _全球,GHM _全球1

類型(類型塊)GHM塊

調用MPI_INIT(ierr)

調用MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)

調用MPI_COMM_SIZE(MPI_COMM_WORLD,npc,ierr)

btime=MPI_WTIME()

調用MPI_GET_PROCESSOR_NAME(pcname,namelen,ierr)

調用MPI_GET_VERSION(ver,subver,ieer)

寫(*,1000)myid,npc,trim(pcname),ver,subver

if(myid==0)then!處理器0中的初始類型數組

GHM _全球% npoin = 10;GHM _全球% n組=5

GHM _全球%nblks=2

do ipc=1,size(GHM _全球%icmatrix)

GHM _全球%icmatrix(ipc)=ipc-1

恩多

GHM _全球% y = 0.4GHM _全球%y8=0.8

GHM _全球%輸出計劃= ' GIDGHM _全球%type_ABC='VIE '

n group = GHM _全球%ngroup

nblks = GHM _全球%nblks

allocate(GHM塊百分比出現進程(n組,nblks),& amp

GHM _ Blocks % matno _ process(n group,nblks))

GHM _街區%出現_進程= 0;GHM_Blocks%matno_process=0

endif

blocklens_global(0)=10!10整數

offsets_global(0) =0

oldtypes_global(0) =MPI_INTEGER

調用MPI_TYPE_EXTENT(MPI_INTEGER,EXTENT,ierr)

blocklens_global(1)=40!40個字符

offsets _ global(www.cshangzj.com 1)= offsets _ global(0)+block lens _ global(0)*範圍

oldtypes _ global(1)= MPI _ CHARACTER

調用MPI_TYPE_EXTENT(MPI_CHARACTER,EXTENT,ierr)

blocklens_global(2)=3!3實數

offsets _ global(2)= offsets _ global(1)+block lens _ global(1)*範圍

oldtypes_global(2) =MPI_REAL

調用MPI_TYPE_EXTENT(MPI_REAL,EXTENT,ierr)

blocklens_global(3)=2!2實數*8

offsets _ global(3)= offsets _ global(2)+block lens _ global(2)*範圍

oldtypes _ global(3)= MPI _ DOUBLE _ PRECISION

調用MPI_TYPE_EXTENT(MPI_INTEGER,EXTENT,ierr)

write(*,'(a,10i4)')'myid_int = ',myid,extent

調用MPI_TYPE_EXTENT(MPI_REAL,EXTENT,ierr)

write(*,'(a,10i4)')'myid_real= ',myid,extent

調用MPI _ TYPE _ EXTENT(MPI _ DOUBLE _ PRECISION,EXTENT,ierr)

write(*,'(a,10i4)')'myid_doub= ',myid,extent

調用MPI_TYPE_EXTENT(MPI_CHARACTER,EXTENT,ierr)

write(*,'(a,10i4)')'myid_char= ',myid,extent,offsets_global

調用MPI_TYPE_STRUCT(ndatatype,blocklens_global,offsets_global,oldtypes_global,& amp

type_global_MPI,ierr)

調用MPI _ TYPE _ COMMIT(TYPE _ global _ MPI,ierr)

if(myid==0)then!將GHM _全局從0處理器發送到其他處理器

do ipc=1,npc-1

調用MPI _ SEND(GHM _全球,1,類型_全球_MPI,ipc,9,MPI _通訊_世界,ierr)

恩多

其他

調用MPI _ RECV(GHM _全球1,1,類型_全球_MP