Colección de citas famosas - Slogan de motivación - Cómo Fortran mpi define el tipo de datos mpi

Cómo Fortran mpi define el tipo de datos mpi

MPI solo define tipos de datos estándar integrados en Fortran, como enteros, números reales, caracteres, dobles, etc. , pero no proporciona los tipos de datos derivados proporcionados por Fortran90 (es decir, los tipos de datos estructurados definidos por el comando type). Este tipo de datos derivados son datos discontinuos y, a menudo, contienen muchos tipos de datos y matrices estándar.

En MPI, generalmente hay dos formas de enviar y recibir este tipo de datos derivados. Una forma es usar el comando para crear un tipo de datos derivados proporcionado por MPI para crear una nueva estructura de datos que sea la misma que el tipo de datos derivados ya definido en el programa Fortran90, luego generar un tipo de datos derivados de MPI y finalmente pasar el Tipo de datos derivado de MPI. Otro enfoque es enviar los datos en paquetes y luego descomprimirlos en el extremo receptor. Recientemente he estado investigando el método anterior y aquí hay una breve introducción a mi experiencia.

Por ejemplo, los siguientes tipos de datos derivados se definen en un programa Fortran90:

type type_global! INT(5 5), carácter(2*10), real(3), real*8(2)

Entero npoin, nelem, ngroup, nmat, nblks

Real x , y, z

Real*8 x8,y8

Entero icmatrix(5)

carácter*20 diagrama de salida, type_abc

Fin type type_global

Este tipo de datos derivados tiene cuatro tipos de datos estándar, a saber, entero (10, incluidos 5 escalares y 1 matriz de 5 elementos), tipo real (3), tipo real de doble precisión (3) y cadena. tipo (2, 20 caracteres cada uno). Para transferir datos de este tipo derivado, primero defina su estructura de datos como un tipo derivado de MPI y utilice dos comandos MPI, a saber, MPI_TYPE_STRUCT y MPI_TYPE_COMMIT. El primero se utiliza para definir estructuras de datos derivadas y el segundo se utiliza para confirmar la confirmación. El formato de llamada de MPI_TYPE_STRUCT es el siguiente:

Llamar a MPI_TYPE_STRUCT(ndatatype, blocklens_global, offsets_global, oldtypes_global, amp

type_global_MPI, ierr)

La explicación es la siguiente siguiente:

Ndatatype es una variable entera, su valor es el número de tipos estándar incluidos en el tipo de datos derivado (en este ejemplo, se fusionan los mismos datos de tipo estándar), el valor en este ejemplo es 4 , Es decir, tipo entero, tipo cadena, tipo real y tipo real de doble precisión;

Blockens _ global (0: 3) es una matriz de enteros con n tipos de datos El valor de cada elemento es el estándar correspondiente. datos en este tipo derivado. El número de tipos. Si el orden es entero, cadena, número real, número real de doble precisión, el valor de la matriz es;

Offsets_global(0:3) es una matriz de enteros con elementos de tipo ndata y el valor de cada elemento is Es el desplazamiento de desplazamiento del tipo de datos estándar correspondiente en este tipo derivado. Esto requiere conocimiento de la tabla de tipos de la estructura de datos de tipo derivado. En pocas palabras, en este tipo derivado, el desplazamiento del primer tipo estándar (entero) es 0, y el desplazamiento del segundo tipo estándar (tipo cadena) debe ser el tipo estándar anterior (ésimo tipo estándar) multiplicado por el número de bytes ocupados por el tipo estándar en la memoria (4 bytes * 10 = 40), el primer tipo estándar debe ser 0. En este ejemplo, el valor es, en Fortran90, el punto entero predeterminado es 4 bytes, el tipo real es 4 bytes, el tipo real de doble precisión es 8 bytes, la cadena se calcula según su longitud, un carácter ocupa un byte.

Oldtypes_global(0:3) es una matriz de números enteros con n tipos de datos. El valor de cada elemento es el tipo MPI del tipo de datos estándar correspondiente en este tipo derivado. Según el orden anterior, su valor debe ser [MPI_integer, MPI_character, MPI_real, MPI_double_precedent].

Blocklines_global, Offsets_global y oldtypes_global deben tener el mismo orden de tipos de datos estándar. No importa cuál aparece primero, pero el orden de los tres datos debe ser el mismo.

Type_global_MPI es una variable entera después de la definición, se convierte en un nombre de tipo de datos derivado que puede ser utilizado por MPI. Puede usarse como MPI_INTEGER, MPI_REAL, etc.

Ierr es una variable entera, debes conocerla bien.

Finalmente, se puede confirmar una confirmación usando Call MPI_Type_Commit(Type_global_MPI, IERR) y luego pasar usando MPI_SEND y MPI_RECV como tipos de datos derivados.

El siguiente es un código completo para transmitir tipos de datos derivados de Fortran90 usando MPI. Utiliza principalmente MPI para transmitir datos de una estructura derivada, luego modifica los datos en cada proceso y luego imprime las modificaciones de cada proceso. .datos para ver si tiene éxito.

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

Programa MPI_TypeData_SendRecv

Usa mpi

carácter *(MPI_MAX_PROCESSOR_NAME)NOMBRE DE PC, texto*20

Entero, parámetro: ndatatype=4

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

Entero type_block_MPI, type_global_MPI, amp

bloque lens_global(0:ndatatype-1), offsets_global(0:ndatatype-1), amp

antiguo tipos_global(0:ndatatype-1) , amp

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

entero (8):: Rango

escriba tipo_global! INT(5 5), carácter(2*10), real(3), real*8(2)

Entero npoin, nelem, ngroup, nmat, nblks

Real x , y, z

Real*8 x8,y8

Entero icmatrix(5)

carácter*20 diagrama de salida, type_abc

Fin tipo type_global

Tipo type_block

entero, asignable::appear_process(:,:), matno_process(:,:)

Tipo final type_block

Tipo(type_global)GHM_global,GHM_global1

Tipo(type_block)GHM_Block

Llamar a MPI_INIT(ierr)

Llamar a MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)

Llamando a MPI_COMM_SIZE(MPI_COMM_WORLD, npc, ierr)

btime=MPI_WTIME()

Llamando a MPI_GET_PROCESSOR_NAME( pcname, namelen, ierr)

Llame a MPI_GET_VERSION(ver, subver, ieer)

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

if(myid==0)entonces ! Matriz de tipo inicial en el procesador 0

GHM_globalnpoin=10; GHM_globalnpoin=5

GHM_globalnblks=2

do ipc=1,size(GHM_globalicmatrix)

GHM_globalicmatrix(ipc)=ipc-1

endo

GHM_globaly= 0.4GHM _Global y8=0.8

GHM _Global Output Plan=

' GIDGHM _global type_ABC='VIE '

n grupo = GHM _global ngroup

nblks = GHM _global nblks

allocate(el porcentaje de bloque de GHM aparece en el proceso (n grupo , nblks), amp

GHM_Blocks matno_process(n grupo,nblks))

GHM_blocksmatno_process=0;GHM_Blocksmatno_process=0

endif

blocklens_global(0)=10! 10 entero

offsets_global(0) =0

oldtypes_global(0) =MPI_INTEGER

Llamar a MPI_TYPE_EXTENT(MPI_INTEGER, EXTENT, ierr )

blocklens_global(1)=40! 40 caracteres

compensaciones _ global(www.cshangzj.com 1)= compensaciones _ global(0) lente de bloque _ global(0)* alcance

oldtypes _ global(1)= MPI _ CHARACTER

Llamar a MPI_TYPE_EXTENT(MPI_CHARACTER, EXTENT, ierr)

blocklens_global(2)=3!3 real número

compensaciones _ global(2)= compensaciones _ global(1) lente de bloque _ global(1)*rango

oldtypes_global (2) =MPI_REAL

Llame a MPI_TYPE_EXTENT(MPI_REAL, EXTENT, ierr)

blocklens_global(3)=2!2 número real*8

compensaciones _ global( 3)= compensaciones _ global(2) lente de bloque _ global(2)*range

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

Llamar a MPI_TYPE_EXTENT(MPI_INTEGER, EXTENT , ierr)

escribir (*, '(a, 10i4)') 'myid_int = ', myid, extensión

Llamar a MPI_TYPE_EXTENT(MPI_REAL, EXTENT, ierr)

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

Llamar a MPI_TYPE_EXTENT(MPI_DOUBLE_PRECISION,EXTENT,ierr)

write(*, '(a, 10i4)') 'myid_doub= ', myid, extensión

Llamar a MPI_TYPE_EXTENT(MPI_CHARACTER, EXTENT, ierr)

write(* ,'(a,10i4)')'myid_char= ', myid, extensión, offsets_global

Llamar a MPI_TYPE

_STRUCT(ndatatype, blocklens_global, offsets_global, oldtypes_global, amp

type_global_MPI, ierr)

Llamar a MPI_TYPE_COMMIT(TYPE_global_MPI,ierr)

if(myid==0) ¡entonces! Enviar GHM_global desde el procesador 0 a otros procesadores

hacer ipc=1,npc-1

Llamar a MPI_SEND(GHM_GLOBAL, 1, TYPE_GLOBAL_ MPI, ipc, 9, MPI_COMMUNICATION_WORLD, ierr)

ENDOR

Otro

CALL MPI_RECV(GHM_GLOBAL1,1, Type_global_MP