Fortran90 - Grupo de Paralelismo

Transcripción

Fortran90 - Grupo de Paralelismo
Introducción a las Herramientas
Informáticas Unix para el
Desarrollo de la Investigación
Fortran90
24−25 de junio de 2002
Francisco de Sande
[email protected]
Dpto. de Estadística, I.O. y
Computación
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Presentación
Nombre
Campo de trabajo
Experiencia en informática
Módulos del curso que ha realizado
Motivación que le ha llevado a matricularse
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
1
Introducción
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Introducción
Índice
1.1 Historia
1.2 Objetivos
1.3 Principales características
1.4 Otras características
1.5 Disponibilidad de compiladores
1.6 Referencias
1.7 Lista de recursos
1.8 Convenios de codificación
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Historia
FORmula TRANslation
1954 Fortran I
1958 Fortran II
1958 Fortran IV
1966 Fortran 66 standard
1978 Fortran 77 standard
1991 Fortran 90 standard
La próxima revisión se espera que ocurra
dentro de unos 10 años
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Objetivos de Fortran 90
Evolucionar el lenguaje
Características obsoletas
Estandarizar las extensiones de las diferentes
compañías
Portabilidad
Modernizar el lenguaje
Facilitando su utilización a través de nuevas
características como los tipos derivados o el
formato libre
Introducción de gestión de memoria dinámica
Modularización a través de la definición de los
módulos
Portabilidad numérica a través de la selección
de precisión
Sentencias case, exit, cycle
Sobrecarga de operadores
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Objetivos del lenguaje
Proporcionar capacidad de paralelismo de
datos
Operaciones paralelas sobre vectores para una
mejor utilización de procesadores vectoriales y
máquinas paralelas
Compatibilidad con Fortran77
Fortran77 es un subconjunto de Fortran90
Mejorar la seguridad
Reduciendo el riesgo de errores en códigos
estándar
Concordancia con el estándar
Los compiladores han de notificar códigos no
estándar y características anticuadas
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Principales Características
Proceso de vectores
Memoria dinámica
Módulos
Procedimientos:
Parámetros opcionales y parámetros con
nombre
Procedimientos internos
Procedimientos recursivos
Punteros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Otras Características
Formato del código fuente
Especificaciones / implicit none
Tipos de datos parametrizados (kind)
Tipos derivados y sobrecarga de operadores
Estructuras de control
Nuevas funciones intrínsecas
Nuevas características de entrada/salida
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Características obsoletas
Fortran90 sigue manteniendo algunas
características que califica de obsoletas.
Pueden ser eliminadas en la siguiente revisión
del lenguaje:
http://www.ccti.ull.es/cpu/f90/f90_reference_manual_a.txt
if aritmético
Variables real y double en bucles do y
expresiones de control
Terminación del do con sentencias distintas de
continue o end do
Sentencias assign y goto asignadas
Especificadores asignados en sentencias
format
Saltos a un end if desde dentro de un bloque if
return alternado
Sentencia pause
Descriptor H edit
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Disponibilidad
Compiladores de Fortran90
Where can I get a f95 compiler?
http://www.physics.ohio−state.edu/~wilkins/computing/f95.html
http://www.fortran.com/fortran/metcalf.htm
Cray CF90 − YMP vectorización. Mensajes
limitados y algunas funciones intrínsecas no están
bien ajustadas
DEC Fortran90 − DEC OSF/1. Incluye extensiones
HPF
http://www.ccti.ull.es/cpu/f90/f90.htm
EPC Fortran90 − SPARC Solaris, IBM RS/6000,
Intel 3/486, Motorola 88000
IBM XLF V3 − RISC System 6000
Lahey − Fujitsu LF90 − Para DOS y Windows
http://www.lahey.com/
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Disponibilidad
Microway − DOS, OS/2, Unix
NA Software F90+ − 386/486, Sparc, T800, T9000
Portland Group
http://www.pgroup.com/
NAG f90 − Diversas plataformas Unix y VAX/VMS.
Utiliza C como lenguaje intermedio
http://www.nag.com/nagware.asp
Pacific Sierra VAST−90 − Utiliza Fortran77 como
lenguaje intermedio
Parasoft − F77 como lenguaje intermedio
Absoft
http://www.cs−software.com/software/fortran/absoft/absoft.html
Salford FTN90 − Implementación para PC s del
NAG f90. Genera código directamente
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Referencias
Bibliografía y Referencias
Adams, J. C. et. al. (1992) Fortran 90
Handbook. McGraw−Hill.
ISBN 0−07−000406−4
Brainerd, W. S. et. al., (1994) Programmer’s
Guide to Fortran 90. 2nd edition , Unicomp.
ISBN 0−07−000248−7
Counihan, M. (1991) Fortran 90. Pitman. ISBN
0−273−03073−6
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Referencias
Bibliografía y Referencias
Hahn, B. D. (1994) Fortran 90 for Scientists
and Engineers. Edward Arnold. ISBN: 0−340−
60034−9
Kerrigan, J. (1993) Migrating to Fortran 90.
O’Reilly and Associates. ISBN 1−56592−049−
X
Metcalf, M. & Reid, J. (1992) Fortran 90
Explained. Oxford University Press. ISBN: 0−
19−850558−2
Morgan, J. S. & Schonfelder, J. L. (1993)
Programming in Fortran 90. Alfred Waller Ltd.
ISBN 1−872474−06−3
Smith, I M. Programming in Fortran 90. Wiley.
0471−94185−9
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Referencias
Bibliografía y Referencias
Este Curso
http://webpages.ull.es/~fsande/doctorado/curso_doc.html
Recursos sobre Fortran:
http://webpages.ull.es/~fsande/doctorado/curso_doc.html
http://www.csi.ull.es/~sande/compi2/recursos.html
Pueden encontrar:
FAQ
Cursos y tutoriales
Grupos de discusión
Repositorios de software
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Convenios de codificación
Reservar las mayúsculas solo para
constantes. Utilizaremos minúsculas para las
palabras reservadas.
Indentar 2 columnas en el cuerpo de las
unidades de programa, bloques interface,
bucles do, bloques if, bloques case, etc.
Incluir siempre el nombre del programa,
subrutina o función en su sentencia end
En las sentencias use utilizar la cláusula only
para documentar explícitamente todos los
elementos que son accedidos desde ese
módulo
En sentencias call y referencias a funciones
utilizar parámetros con nombre para los
parámetros opcionales
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Conexión al sistema
telnet teide.ccti.ull.es
login: ic2aluXX
passwd: ihiu2001
/usr/local/bin/tcsh
home> mkdir f90
home> cd f90
home/f90> cp /tmp/inicio.tar
.
home/f90> tar xvf inicio.tar
home/f90> cd inicio
home/f90> f90 hola.f90
home/f90> ls −l
home/f90> ./a.out
home/f90> man f90
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
2
Código Fuente,
Tipos y
Estructuras
de Control
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de
control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Código Fuente, Tipos y
Estructuras de Control
Índice
2.1 Formato del código fuente
2.2 Especificaciones
2.3 implicit none
2.4 Valores de clase (Kind)
2.5 Tipos derivados
2.6 Sentencias de control
2.7 Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Código Fuente
Las líneas pueden tener hasta 132 caracteres
Se permiten letras minúsculas
Identificadores hasta 31 caracteres (incluyendo
el subrayado, underscore) (El primer carácter
ha de ser una letra). Usar identificadores
significativos!!
Se usa punto y coma (;) para separar
diferentes sentencias en la misma línea
Los comentarios pueden comenzar con
exclamación (!)
El Ampersand (&) se usa como signo de
continuación
El juego de caracteres incluye
+<>;!?%−“ &
Nuevos operadores relacionales:
< <=
==
/=
>=
>
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Código Fuente
Ejemplo:
program programa_en_formato_libre
!nombres largos con subrayado
! No hay columnas especiales
implicit none
!Mayúsculas y minúsculas
real :: tx, ty, tz !Comentario final
!Varias sentencias por línea
tx = 1.0; ty = 2.0; tz = tx * ty;
!Las líneas se pueden partir
print *, &
tx, ty, tz
end program programa_en_formato_libre
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
Una especificación es una forma (extendida) de
declaración donde se colocan juntas todas las
características de una entidad
tipo [ [, atributo ] ... :: ] lista
El tipo puede ser integer, real, complex, logical o
character con un valor de clase opcional:
integer [([kind=]kind−value)]
character [(actual−parameter−list)]
type (type−name)
El atributo puede ser
parameter
private
target
dimension(extent−list)
optional
external
public
pointer
allocatable
intent(inout)
save
intrinsic
Se pueden inicializar variables en las
especificaciones
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
Ejemplos
real :: a = 2.61828, b = 3.14159
! Dos variables reales declaradas e
! inicializadas
integer, parameter :: N = 100, M = 1000
! Declaración e inicialización de dos
! constantes enteras
character (len = 8) :: ch
! Declaración de una cadena de caracteres
! de longitud 8
integer, dimension(−3:5, 7) :: ia
! Declaración de un vector de enteros con
! límite inferior negativo
integer, dimension(−3:5,7) :: ia, ib, ic(5,5)
! Vectores de 9x7 componentes
! Los índices de ic varían en [1,5] [1, 5]
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
implicit none
En Fortran77 los tipos implícitos permiten la
utilización de variables no declaradas. Esto ha
sido la causa de muchos errores de
programación
implicit none obliga a declarar todas las
variables que se utilizan en un programa
implicit none puede ir precedida en una
unidad de programa solamente por sentencias
use y format
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
Hay 5 tipos intrínsecos: real, integer, complex,
character y logical
Cada tipo puede tener asociado un valor
entero no negativo llamado el parámetro de
clase de tipo (Kind). El parámetro de clase es
un entero no negativo.
Se trata de una característica útil para escribir
código portable que requiera una precisión
numérica determinada
Los valores de clase dependen de la máquina
en cuestión, pero todo procesador ha de
soportar al menos 2 clases para real y complex
y 1 para integer, logical y character
Hay diversas funciones intrínsecas para
obtener y establecer los parámetros de clase
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
real
real (kind=wp)::ra
real(wp)::ra
! o bien:
Declara una variable, ra, cuya precisión está
determinada por el parámetro de clase wp
Los valores de clase son dependientes del
sistema
Una variable real de 8 bytes (64 bits)
habitualmente tiene un valor de clase 8 ó 2
Una variable real de 4 bytes (32 bits)
habitualmente tiene un valor de clase de 4 ó 1
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
La función intrínseca kind, que tiene un
parámetro de cualquier tipo intrínseco
devuelve la clase de tipo de su parámetro. Por
ejemplo:
real(kind = 2) :: x
! x declarada de clase de tipo 2
real :: y
! y declarada de clase de tipo
! por defecto
integer :: i,j
i = kind(x)
! i=2
j = kind(y)
! j tiene el valor por
! defecto de los reales
! El valor de j depende
! del sistema
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
real
La función intrínseca selected_real_kind tiene
dos parámetros enteros opcionales, p y r
El
valor p especifica el número de dígitos
decimales y r especifica el mínimo rango de
exponente que se desea
La función selected_real_kind (p, r) devuelve el
valor de clase que se ajusta o que excede los
requisitos dados por p y r. Si más de un valor
de clase satisface los requisitos el valor que se
devuelve es el que tenga la mínima precisión
decimal. Si la precisión no está disponible se
retorna −1. Si el rango no está disponible, −2
http://www.ccti.ull.es/cpu/f90/f90_reference_manual_9.txt
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
real
El uso de kind con esta función da una gran
portabilidad:
integer, parameter ::idp=kind(1.0D)
real(kind=idp) ::ra
La variable ra se declara de doble precisión.
Nótese que el valor de clase depende del
sistema
integer, parameter :: IDP = kind(1.0D)
complex (kind=IDP) :: raiz1, raiz2
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
integer
Los enteros habitualmente tienen 16, 32 ó 64
bits
Para declarar un entero de forma que dependa
del sistema, indique el valor de clase asociado
con el rango de enteros que se desea:
integer, parameter :: &
I8=selected_INT_kind(8)
integer(kind=I8) :: ia, ib, ic
Las variables ia, ib, ic tomarán valores en el
rango de al menos [−108, 108] si lo permite el
procesador
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Valores de clase
program mayores
implicit none
integer, parameter :: &
I8 = selected_INT_kind(8)
integer(kind=I8) :: ia
print *, huge(ia), kind(ia)
end program mayores
Este código imprime el mayor entero
disponible para este tipo de enteros, y su valor
de clase
integer, parameter :: &
I10 = selected_real_kind(10, 200)
real(kind=I10) :: a
print *, range(a), precision(a), kind(a)
Imprime el rango del exponente, los dígitos de
precisión y el valor de clase de la variable a
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Tipos derivados
Son definidos por el usuario
Pueden contener diferentes tipos intrínsecos
(básicos) y otros tipos derivados
Las componentes se acceden usando el
símbolo (%)
El único operador predefinido para tipos
derivados es el de asignación (=)
Se pueden (re)definir operadores (los
estudiaremos con la sobrecarga de
operadores)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Tipos derivados
Ejemplos:
Definición de la forma del tipo derivado:
type matricula
character (len=2) :: letra
integer :: numero
character (len=2) :: prov
end type matricula
Declaración de variables de ese tipo:
type(matricula) :: coche1, coche2
matricula :: coche1
!Incorrecto!
Asignar un valor constante a coche1:
coche1 = matricula( AG’, 2227, TF’)
Uso de % para asignar una componente de
coche2:
coche2%letra = BZ’
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Tipos derivados
Ejemplos:
Definir un vector de un tipo derivado:
type (matricula), dimension(n) :: coches
Definir un tipo derivado conteniendo otro:
type household
character (len=1) :: name
character (len=50) :: address
type(matricula) :: car
end type household
Declarar una estructura de tipo household:
type(household) :: myhouse
Utilizar % para referenciar una componente letra:
myhouse%car%letra = BZ
Una constante de un tipo derivado:
type puntos::origin=puntos(0.0, 0.0, 0.0)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Fortran 90 posee tres constructores de bloque:
if
do
case
Todos ellos pueden ser anidados y puede
dárseles nombres para incrementar la
legibilidad y fiabilidad
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
if
La Forma general de un if es:
[name:] if (logical expression) then
block
else if (logical expression) then [name]
block]...
[else [name]
block]
end if [name]
Ejemplo:
seleccion: if (i < 0) then
call negativo
else if (i==0) then seleccion
call cero
else select
call positivo
end if seleccion
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Bucles do
Forma general:
[name:] do [control clause]
block
end do [name]
La cláusula de control puede ser:
Una cláusula de control de iteración
count = inicial, final [, incr]
una cláusula de control while
while (expr. logica)
ninguna
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Bucles do
Clausula de control de iteración:
fils: do i = 1, n
cols:
do j = 1, m
a(1, j) = i + j
end do cols
end do fils
Cláusula de control while:
cierto: do while (i <= 100)
...
Body of loop
...
end do true
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Bucles do
Uso de exit y cycle:
Se sale de un bucle con exit
cycle transfiere control al end do
exit y cycle, por defecto se refieren al bucle más
interno pero pueden referirse a un bucle con
nombre
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Bucles do
Uso de exit y cycle:
exter: do i = 1,n
interm: do j = 1,m
intern:
do k = 1,l
...
if (a(i,j,k)<0) exit exter
if (j==5) cycle interm
! Salta fuera
! Omite j==5 y
! hace j=6
if (i==5) cycle
! Salta el resto
! Del bucle interno
! Y pasa a su
! Siguiente iteración
...
end do intern
end do interm
end do exter
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
Bucles do
Sin cláusula de control:
do
read(*, *) x
if (x < 0) exit
y = sqrt(x)
...
end do
Nótese que esta forma puede tener el mismo efecto
que un bucle do−while
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
case
Es una forma estructurada de seleccionar
diferentes opciones, dependiendo del valor de
una única expresión
Sirve para reemplazar a:
Un goto calculado (Fortran77)
Repetidos if ... then ... else
Forma General:
[name:] select case (expression)
[case (selector)[name]
block]
.
.
.
end select [name]
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
case
La expresión ha de ser de tipo character, logical
o integer
El selector ha de ser default o bien uno ó más
valores del mismo tipo que la expresión:
Un único valor
Un rango de valores separados por : (solamente
integer o character)
Una lista de valores o rangos. El valor mayor o
menor del rango puede omitirse
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructuras de Control
case
Ejemplo:
colour: select case (ch)
case ( C , D , G : M )
colour = red
case ( X :)
colour = green
case default
colour = blue
end select colour
Por compatibilidad con Fortran77, la sentencia
goto sigue estando disponible, pero es preferible
usar if, do, case, exit y cycle en su lugar
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
3
Procedimientos
y
Módulos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos y Módulos
Índice
3.1 Unidades de programa
3.2 Procedimientos
3.3 bloques interface
3.4 Procedimientos internos
3.5 Argumentos procedurales
3.6 Cláusula result para funciones
3.7 Funciones que devuelven vectores
3.8 Procedimientos recursivos
3.9 Procedimientos genéricos
3.10 Módulos
3.11 Sobrecarga de operadores
3.12 Definición de operadores
3.13 Sobrecarga del operador de asignación
3.14 Ámbito
3.15 Estructura de los programas
3.16 Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Unidades de Programa
Programa
Principal
Módulo
Procedimiento
Externo
Procedimientos
de módulo
Procedimientos
Internos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Unidades de programa
Un programa sólo puede tener un único
programa principal y todas las unidades de
programa que se desee (módulos o
procedimientos externos)
Un módulo se utiliza para que diferentes
programas compartan código (datos y
subrutinas)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Programa Principal
Forma:
program nombre_de_programa
[sentencias_de_especificación]
[sentencias_ejecutables]
...
end [program [nombre_de_programa]]
Ejemplo:
program prueba
...
...
!
end
!
end program
end program prueba
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos
Llamamos procedimientos de forma genérica a
Funciones y Subrutinas
Una función devuelve un único resultado y no
suele modificar los valores de sus parámetros.
Las subrutinas realizan tareas generalmente
más complejas y retornan valores a través de
sus parámetros
Estructuralmente los procedimientos pueden
ser:
Externos (autocontenidos, no necesariamente
Fortran)
Internos (dentro de una unidad de programa)
de Módulo (miembros de un módulo)
Fortran 77 sólo tiene procedimientos externos
Un bloque interface se utiliza para definir los
detalles de los parámetros de un
procedimiento. Es obligatorio para los
procedimientos externos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Externos
Forma:
subroutine nombre(parámetros_formales)
[sentencias_de_especificación]
[sentencias_ejecutables]
...
end [subroutine [nombre]]
O bien:
function nombre(dummy−argument−list)
[sentecias_de_especificación]
[sentecias_ejecutables]
...
end [function [nombre]]
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Internos
Cualquier unidad de programa (un programa
principal, un módulo o un procedimiento externo)
puede contener procedimientos internos
Los procedimientos internos se colocan todos
juntos al final de una unidad de programa y
precedidos por la sentencia contains
Tienen la misma forma que los procedimientos
externos excepto en que la palabra
subroutine/function ha de aparecer en la
sentencia end
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Internos
Las variables definidas en la unidad de
programa permanecen accesibles (definidas) en
los procedimientos internos, a menos que se
redefinan allí
Es una buena práctica declarar todas las
variables que se utilicen en un subprograma
(parámetros y variables locales)
No se permite anidar procedimientos internos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Internos
Ejemplo:
program principal
implicit none
real :: a, b, c
real :: suma_ppal
...
suma_ppal = suma()
...
contains
Tiene efecto sobre
todos los proc. internos
que contenga
function suma()
real :: suma
! a, b y c ya
definidas
suma = a + b + c
end function suma
...
end program principal
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos internos
implicit none en una unidad de programa
también tiene efecto sobre todos los
procedimientos internos que contenga.
No
obstante, se recomienda volver a usarlo, tanto
por claridad como para evitar errores:
subroutine aritmetica(n,x,y,z)
implicit none
integer :: n
real, dimension(100) :: x, y, z
...
contains
function suma(a, b, c) result(sum)
implicit none
real, intent(in) :: a, b, c
real :: sum
sum = a + b + c
end function suma
end subroutine aritmetica
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Bloques interface
Si se suministra explícitamente una interface
para un procedimiento, el compilador puede
comprobar inconsistencias en los parámetros
En el caso de los subprogramas intrínsecos,
los subprogramas internos y los módulos, el
compilador conoce siempre esta información y
se dice que es explícita
Cuando se invoca un subprograma externo,
esta información no está disponible y se dice
que es implícita
Fortran90 utiliza los bloques interface para
especificar una interface explícita para los
procedimientos externos
Hay que utilizar siempre bloques interface en
las unidades de programa que invoquen
procedimientos externos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Bloques interface
Forma general:
interface
cuerpo_de_la_interface
...
end interface
!Ojo: no se pone nombre
Donde cuerpo_de_la_interface es una copia exacta
de la especificación del subprograma, su
especificación de argumentos y su sentencia end
Ejemplo:
interface
real function func(x)
real, intent(in) :: x
end function func
end interface
!Lo veremos
El bloque interface se coloca en la unidad de
programa que realiza la llamada
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos − Intent
Sirve para especificar si un parámetro de un
procedimiento es para:
Entrada (in) (No puede ser modificado)
Salida (out)
o ambos (inout)
Ejemplos
integer, intent(in) :: x
real, intent(out) :: y
real, intent(inout) :: Z
subroutine interc_real(a, b)
implicit none
real, intent(inout) :: a, b
real :: temp
temp = a
a = b
b = temp
end subroutine interc_real
! llamada: call interc_real(x, y)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Parámetros con nombre
Se utiliza para evitar confusión cuando un
procedimiento tiene varios parámetros. Evita el
tener que recordar el orden de los parámetros.
Ejemplo: Si se tiene la función
real function area(inicio, fin, error)
implicit none
real, intent(in) :: inicio, fin,
error
...
end function area
La llamada podría hacerse:
a = area(0.0, 100.0, 0.01)
b = area(inicio=0.0, error=0.01, fin=100.0)
c = area(0.0, error=0.01, fin=100.0)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Parámetros con nombre
Una vez que se usa un nombre para uno de los
parámetros, el resto de parámetros han de
usarlo también.
Así no es posible:
c=area(0.0, error=0.01, 100.0)
!prohibido
Aquí no se necesita una interface porque area
es una función interna. Sí haría falta si se tratara
de un procedimiento externo con parámetros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos opcionales
En ciertas ocasiones, no todos los parámetros
necesitan estar presentes en una llamada. Un
parámetro se puede declarar como opcional:
real function area(inicio, fin, error)
implicit none
real, intent(in), optional :: inicio, &
fin, error
...
end function area
La llamada podría realizarse:
a=area(0.0, 100.0, 0.010)
b=area(inicio=0.0, fin=100.0, error=0.01)
c=area(0.0)
d=area(0.0, error=0.01)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Parámetros opcionales
La función lógica (intrínseca) present se utiliza
para comprobar la presencia de un parámetro
opcional:
real function area(inicio, fin, error)
implicit none
real,intent(in),optional ::inicio, &
fin, error
real ttol
...
if (present(error)) then
ttol = error
else
ttol = 0.01
end if
end function area
No se podría modificar error, porque es
intent(in). Por ello se usa una variable local, ttol
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Parámetros opcionales
Si el procedimiento es externo y tiene parámetros
opcionales, se ha de suministrar una interface. Si la
función del ejemplo anterior fuera externa sería
necesario el siguiente bloque interface:
interface
real function area(inicio, fin, error)
real, intent(in),optional :: inicio,&
fin, error
end function area
end interface
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Tipos derivados como
Argumentos
Los parámetros de un procedimiento pueden
ser de un tipo derivado si:
1.− El procedimiento es interno a la unidad de
programa en la que se define el tipo derivado
2.− el tipo derivado se define en un módulo que
es accesible desde el procedimiento
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Parámetros procedurales
En Fortran77 un parámetro procedural se ha de
declarar como external
En Fortran90 un procedimiento que es pasado
como parámetro debe ser un procedimiento
externo o un procedimiento de módulo
No se permite pasar como parámetro un
procedimiento interno
Para procedimientos externos se recomienda
suministrar un bloque interface en la unidad de
programa que realiza la llamada
Un procedimiento de módulo tiene una interface
explícita por defecto
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos procedurales
Ejemplo:
La unidad de programa que realiza la llamada:
...
interface
real function func(x, y)
real, intent(in) :: x, y
end function func
end interface
...
call area(func, inicio, fin, error)
La función externa:
real function func(x, y)
implicit none
real, intent(in) :: x, y
...
end function func
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Cláusula result para funciones
Las funciones pueden tener una variable
resultado.
El identificador de resultado que se utilice dentro
de la función ha de ser especificado entre
paréntesis al final de la sentencia function.
Ejemplo:
function suma(a, b, c)
result(sum_abc)
implicit none
real, intent(in) :: a, b, c
real :: sum_abc
sum_abc = a + b + c
end function suma
Las funciones directamente recursivas (la
recursividad se estudia más adelante) han de
tener una variable result
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones que devuelven
vectores
El resultado de una función no tiene porqué ser
un escalar.
El tipo de una función que devuelve un vector no
se especifica en la sentencia function inicial sino
en una declaración de tipo en el cuerpo de la
función, en la que hay que especificar las
dimensiones del vector:
function suma_vec (a,
implicit none
real, dimension (n)
integer, intent(in)
real,dimension (n),
b
b, n)
:: suma_vec
:: n
intent(in) :: a,
do i = 1, n
suma_vec(i) = a(i) + b(i)
end do
end function suma_vec
Si la función fuera externa, habría que especificar
una interface en el programa llamador
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Recursivos
Los procedimientos se pueden invocar
recursivamente:
P1 invoca a P2 y P2 invoca a P1 o bien
P1 invoca directamente a P1 (se requiere result)
Los procedimientos recursivos han de declararse
como tales:
recursive function fact(n) result (res)
implicit none
integer intent(in) :: n
integer :: res
if (n == 1) then
res=1
else
res=n * fact(n − 1)
endif
end function fact
¡La recursividad es Ineficiente!
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Genéricos
Cuando se utilizan proc. genéricos, se usa un
mismo identificador para el procedimiento y el
código que se ejecuta depende del tipo de los
parámetros (como en C++)
Un procedimiento genérico se define utilizando
un bloque interface y usando un identificador
genérico para todos los procedimientos definidos
dentro de ese bloque interface
La forma general es:
interface generic_name
cuerpo_especifico_de_la_interface
cuerpo_especifico_de_la_interface
...
end interface
Todos los procedimientos de un bloque interface
genérico han de diferenciarse de forma no
ambigua y por lo tanto todos han de ser
subrutinas o todos funciones
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Genéricos
Ejemplo:
subroutine interc_real
implicit none
real, intent(inout) :: a, b
real :: temp
temp = a
a = b
b = temp
end subroutine interc_real
subroutine interc_int
implicit none
integer, intent(inout) :: a, b
integer :: temp
temp = a
a = b
b = temp
end subroutine interc_int
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos Genéricos
Interface genérica:
interface intercambia
subroutine interc_real (a, b)
real, intent(inout) :: a, b
end subroutine interc_real
subroutine interc_int (a, b)
integer, intent(inout) :: a, b
end subroutine interc_int
end interface
Llamada:
call intercambia(x, y)
Vea un ejemplo en
ej2_modules/ejemplos/
generic_intercambia.f90
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos
Se trata de una característica del lenguaje que
incide (positivamente) sobre la estructura de
los programas
Constituyen una forma de compartir datos y/o
procedimientos entre diferentes unidades de
programa
Los módulos juegan un papel importante en la
definición de tipos y operadores asociados
La forma general es:
module nombre
[sentecias_de_especificación]
[sentecias_ejecutables]
[contains
procedimientos_de_módulo]
end [module [nombre]]
Al módulo se accede a través de la sentencia
use
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Datos globales
En Fortran las variables son habitualmente
entidades locales. Utilizando módulos es posible
hacer accesibles un conjunto de datos a
diferentes unidades de programa:
module globales
real, save :: a, b, c
integer, save :: i, j, k
end module globales
El atributo save permite declarar datos como
globales (es un sustituto del COMMON de
Fortran77)
Los datos se utilizan en otras unidades de
programa a través de la sentencia use:
use globales
La sentencia use no es ejecutable y debe
aparecer al principio de la unidad de programa
antes que cualquier otra sentencia y después de
program, function o subroutine
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Datos globales
Una unidad de programa puede invocar código
de diferentes módulos utilizando una serie de
sentencias use.
Nótese que un módulo puede usar a su vez otros
módulos, pero un módulo no puede usarse a sí
mismo (ni directa ni indirectamente)
Ejemplos de uso de la sentencia use:
use globales
! Permite acceder a todas las variables
! del módulo
use globales, only : a, c
! Permite acceder sólo a las variables
a
! y c
use globales, r=>a, s=>b
! Permite acceder a las variables a y b
! a través de los identificadores r y s
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Procedimientos de módulo
Los procedimientos que se especifican dentro de
un módulo se llaman procedimientos de módulo
Son procedimientos que pueden ser accedidos
(utilizados) por otras unidades de programa
Puede haber varios procedimientos de módulo
contenidos en el mismo módulo
Han de estar codificados en Fortran (los
externos pueden estar en otro lenguaje)
Tienen la misma forma que los procedimientos
externos salvo que:
Los procedimientos de un módulo deben
aparecer después de una sentencia contains
La sentencia end ha de tener especificada una
subroutine o function
Se invocan mediante la sentencia call o
referencia a la función, pero sólo desde una
unidad de programa que haya declarado con
una sentencia use la utilización del módulo en
cuestión
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Procedimientos de módulo
Los procedimientos de módulo son
especialmente útiles para un conjunto de tipos
derivados y sus correspondientes operaciones
module modulo_puntos
type puntos
real :: x, y
end type puntos
contains
function suma_puntos(p, q)
type (puntos), intent(in) :: p, q
type (puntos) :: suma_puntos
suma_puntos%x = p%x + q%x
suma_puntos%y = p%y + q%y
end function suma_puntos
end module modulo_puntos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Procedimientos de módulo
El programa principal podría declarar:
use modulo_puntos
type (puntos) :: px, py, pz
...
pz = suma_puntos(px, py)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Procedimientos genéricos
La utilización de módulos permite parámetros
de tipos derivados y por tanto procedimientos
genéricos con tipos derivados
Veamos como ejemplo, una extensión del
procedimiento intercambia genérico que
hemos desarrollado, para intercambiar
puntos:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos
module intercambio_generico
implicit none
type puntos
real :: x, y
end type puntos
interface intercambia
module procedure interc_real, &
interc_int, interc_log, interc_puntos
end interface
contains
subroutine interc_puntos (a,b)
implicit none
type (puntos), intent(inout) :: a, b
type (puntos) :: temp
temp = a
a = b
b = temp
end subroutine interc_puntos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos
subroutine interc_real
implicit none
real, intent(inout) :: a,b
real :: temp
temp = a
a = b
b = temp
end subroutine interc_real
! Rutinas similares para intercambiar
! otros tipos de datos
...
end module intercambio_generico
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos:
Private y Public
Por defecto, todas las entidades de un módulo
son accesibles a las unidades de programa que
utilicen la sentencia use
A veces interesa prohibir el uso de ciertas
entidades al programa llamador para forzar al
usuario a utilizar las rutinas del módulo en lugar
de las suyas propias o también para permitir
flexibilidad a la hora de realizar cambios internos
sin necesidad de informar a los usuarios del
módulo o cambiar la documentación
Esto se consigue a través de la sentencia private:
private :: sub1, sub2
o el atributo private:
integer, private, save :: fil, col
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sobrecarga de operadores
En Fortran90 se puede extender el significado
de un operador intrínseco para que actúe sobre
tipos de datos adicionales: a ello se le llama
sobrecarga de operadores. Para conseguirlo se
necesita un bloque interface de la forma:
interface operator (op_intrinseco)
cuerpo_de_la_interface
end interface
Por ejemplo, el operador + podría extenderse a
variables de tipo carácter para concatenar dos
cadenas de caracteres ignorando los espacios
sobrantes, y el código podría colocarse en un
módulo:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sobrecarga de operadores
Ahora la expresión cha + chb tiene
significado en cualquier programa que use
este módulo
Obsérvese en el ejemplo el bloque interface.
La función que define el operador está en un
módulo y no es necesario tener interfaces
explícitas para procedimientos de módulo que
están dentro del mismo módulo
Cuando se da un nombre genérico o un
operador para un conjunto de procedimientos,
se necesita un bloque de interface. El bloque
interface tiene la forma:
interface ...
lista_de_procedimientos_de_modulo
end interface
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Definición de operadores
Se pueden definir nuevos operadores
Resulta especialmente útil para tipos definidos
por el usuario
Los operadores definidos han de tener . (punto)
al principio y al final. Por ejemplo, en el ejemplo
anterior podríamos haber definido .mas. en lugar
de sobrecargar +
La operación se ha de definir a través de una
función que tenga uno o dos parámetros no
opcionales con atributo intent(in) (que sean de
entrada)
Veamos un Ejemplo: calcular la distancia
euclídea entre dos elementos del tipo derivado
punto:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Definición de operadores:
distancia_principal.f90
program principal
implicit none
use distancia_mod
type(puntos) :: px, py
...
distancia = px .dist. py
...
end program principal
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Definición de
operadores: distancia_mod.f90
module distancia_mod
implicit none
...
type puntos
real :: x, y
end type puntos
...
interface operator (.dist.)
module procedure calcdist
end interface
...
contains
...
function calcdist (px, py)
implicit none
real :: calcdist
type (puntos), intent(in) :: px, py
calcdist = &
sqrt ((px%x−py%x)**2 +(px%y−py%y)**2 )
end function calcdist
...
end module distancia_mod
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos mon_mod.f90
Veamos otro ejemplo que define en un módulo
un tipo derivado y todas las operaciones
asociadas:
module dineros
implicit none
type pasta
integer :: euros, cents
end type pasta
interface operator (+)
module procedure sumar_pasta
end interface
interface operator (−)
module procedure negar_pasta,
resta_pasta
end interface
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos mon_mod.f90
contains
function sumar_pasta(a, b)
implicit none
type (pasta) :: sumar_pasta
type (pasta), intent(in) :: a ,b
integer :: acarreo, tmp_cents
tmp_cents = a%cents + b%cents
acarreo = 0
if (tmp_cents > 100) then
tmp_cents = tmp_cents − 100
acarreo = 1
end if
sumar_pasta%euros=a%euros + &
b%euros+acarreo
sumar_pasta%cents = tmp_cents
end function sumar_pasta
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos mon_mod.f90
function negar_pasta(a)
implicit none
type (pasta) :: negar_pasta
type (pasta), intent(in) :: a
negar_pasta%euros = −a%euros
negar_pasta%cents = −a%cents
end function negar_pasta
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Módulos mon_mod.f90
function resta_pasta(a, b)
implicit none
type (pasta) :: resta_pasta
type (pasta), intent(in) :: a, b
integer :: tmp_euros, tmp_cents, acarreo
tmp_cents = a%cents − b%cents
tmp_euros = a%euros − b%euros
! Para incorporar acarreos necesarios
if ((tmp_cents < 0).and.(tmp_euros > 0)) then
tmp_cents = 100 + tmp_cents
tmp_euros = tmp_euros − 1
else if ((tmp_cents>0).and.(tmp_euros<0)) then
tmp_cents = tmp_cents − 100
tmp_euros = tmp_euros + 1
end if
resta_pasta%cents = tmp_cents
resta_pasta%euros = tmp_euros
end function resta_pasta
end module dineros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sobrecarga del operador de
asignación
Al usar tipos derivados puede ser necesario
extender el significado del operador de asignación
(=)
real :: ax
type (puntos) :: px
...
ax = px
! Se asigna un punto a un real
...
! No es válido si no se define
Siguiendo con el ejemplo, supongamos que
queremos que ax tome el valor máximo de las
componentes de px. Esta asignación se ha de
hacer a través de una subrutina con 2 parámetros
no opcionales, el primero de ellos intent(out) o
intent(inout) y el segundo intent(in).
Debe crearse un bloque interface de asignación:
interface assignment (=)
cuerpo_de_la_subrutina_interface
end interface
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sobrecarga del operador de
asignación
La definición de la asignación se podría colocar en
un módulo como:
module mod_sobrecarga_assign
implicit none
type puntos
real :: x, y
end type puntos
...
interface assignment (=)
module procedure assign_puntos
end interface
contains
subroutine assign_puntos (ax, px)
real, intent(out) :: ax
type (puntos), intent(in) :: px
ax = max(px%x, px%y)
end subroutine assign_puntos
...
end module mod_sobrecarga_assign
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sobrecarga del operador de
asignación
El programa principal necesita invocar a este
módulo con una sentencia use:
use mod_sobrecarga_assign
real :: ax
type (puntos) :: px
...
ax = px
! Correcto
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
El ámbito de un identificador (de variable,
función, subrutina) o etiqueta es el conjunto de
entidades no−solapadas donde el identificador
o etiqueta puede utilizarse sin ambigüedad
Estas entidades (unidades de ámbito) son:
Una definición de tipo (derivado)
Un cuerpo de interface de procedimiento,
excluyendo las definiciones de tipos y cuerpos
de interface definidos dentro de él
Una unidad de programa o procedimiento
interno, excluyendo las definiciones de tipos,
cuerpos de interfaces y subprogramas
contenidos en él
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
Etiquetas
Cada subprograma, interno o externo tiene su
propio conjunto de etiquetas. La misma etiqueta
puede usarse en un programa principal y sus
procedimientos internos sin ambigüedad. Por lo
tanto el ámbito de una etiqueta es un programa
principal o un procedimiento excluyendo cualquier
procedimiento interno que pueda contener
Identificadores
El ámbito de un identificador declarado en una
unidad de programa se extiende desde desde su
cabecera hasta su sentencia end
El ámbito de un identificador declarado en un
programa principal o subprograma externo se
extiende a todos los subprogramas que contenga a
menos que el mismo identificador se redefina en
ellos
El ámbito de un identificador declarado en un
subprograma interno es sólo el propio subprograma
y no otros subprogramas internos.
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
Identificadores
El ámbito del identificador de un subprograma
interno, y del número y tipo de sus parámetros
se extiende a través de la unidad de programa
en que está contenido y por lo tanto a todos los
otros subprogramas internos
El ámbito de un identificador declarado en un
módulo se extiende a todas las unidades de
programa que use(n) ese módulo, a menos que
el identificador tenga atributo private o que sea
renombrado en el programa que usa el módulo
o que la sentencia use tenga una cláusula use
only
El ámbito de un identificador declarado en un
módulo se extiende a todos los subprogramas
internos excepto aquellos en los que el
identificador sea redefinido
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
Consideremos las unidades de ámbito señaladas
anteriormente
Entidades declaradas en diferentes unidades de
ámbito son siempre diferentes, aunque tengan los
mismos identificadores y propiedades
Dentro de una unidad de ámbito, cada entidad con
nombre ha de tener un identificador diferente, con
la excepción de los procedimientos genéricos
Los identificadores de unidades de programa son
globales, de modo que han de ser diferentes entre
sí y diferentes de cualquier entidad local a las
unidades de programa
El ámbito de un identificador de un procedimiento
interno se extiende sólo a toda la unidad de
programa que lo contiene
El ámbito de un identificador declarado en un
procedimiento interno es ese procedimiento interno
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
Se dice que los identificadores son accesibles
por asociación de anfitrión o por asociación de
uso:
Asociación de anfitrión: el ámbito de un
identificador declarado en una unidad de
programa se extiende desde la cabecera de la
unidad de programa hasta su sentencia end
Asociación por uso: el ámbito de un
identificador declarado en un módulo, cuando
no tiene el atributo private, se extiende a
cualquier unidad de programa que use el
módulo
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ámbito
Ejemplo
module ambito1
...
contains
subroutine ambito2
type ambito3
...
end type
interface
100
...
end interface
real x, y
...
contains
function ambito5(...)
real y
y = x + 1.0
100
...
end function ambito5
end subroutine
ambito2
end module
ambito1
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
ambito
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
1
1
1
2
3
3
3
3
4
3
2
2
2
5
5
5
5
5
2
1
Estructura de los programas
Orden de las sentencias
Sentencias PROGRAM , FUNCTI ON, SUBROUTI NE
o MODULE
Sentencias USE
Sentencia I MPLI CI T NONE
Sentencias
Sentencias
PARAMETER
I MPLI CI T
Definiciones de tipos
Sentencias derivados,
Sentencias PARAMETER Bloques interface,
FORMAT
y
Sentencias de declaración
de tipos, y
DATA
Sentencias de
especificación
Sentencias ejecutables
Sentencia CONTAI NS
Subprogramas internos o
Subprogramas del módulo
Sentencia END
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructura de los programas
Cuando utilizar bloques interface
Cuando un módulo o procedimiento externo es
invocado:
Si el módulo define o sobrecarga un operador o
sobrecarga la asignación
Si el módulo utiliza un identificador genérico
Se utiliza un bloque interface cuando un
procedimiento externo:
Es invocado con un argumento con nombre y/o
opcional
es una función que devuelve un vector o un puntero
o bien una función de caracteres que no es ni
constante ni de longitud conocida
Tiene un parámetro que es un vector de forma
asumida o un puntero
Es argumento de otro subprograma (en este caso no
es obligatorio, pero se recomienda)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructura de los programas
Resumen
Estilo Fortran77:
Programa principal con procedimientos externos,
posiblemente en una librería
No hay interfaces explícitas de modo que el
compilador no comprueba inconsistencias en los
parámetros de las llamadas a subprograma
Fortran90 simple:
Programa principal con procedimientos internos
Las interfaces son explícitas, de modo que el
compilador detecta posibles inconsistencias
Fortran90 con módulos:
Programa principal y módulo(s) conteniendo
interfaces y posiblemente especificaciones y la
posibilidad de procedimientos externos (y de
librerías precompiladas)
Una versión F90 del estilo F77 con interfaces
para permitir al compilador la comprobación de
inconsistencias en los parámetros
Programa principal y módulo(s) conteniendo
especificaciones, interfaces y procedimientos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estructura de los programas
Resumen
Fortran90 con módulos:
Un programa F90 estructurado consiste en un
programa principal y módulos que contienen
especificaciones, interfaces y procedimientos.
Los procedimientos externos dejan de ser
necesarios
La introducción de nuevas características en el
lenguaje tales como tipos derivados, sobrecarga,
subprogramas internos y módulos hacen posible
el desarrollo de código F90 sofisticado
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
4
Proceso de
vectores
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Proceso de vectores
Índice
4.1 Terminología
4.2 Especificaciones
4.3 Operaciones sobre vectores
4.4 Sentencia y constructor where
4.5 Procedimientos intrínsecos simples
4.6 Secciones de vectores
4.7 Posición del elemento versus indexación
4.8 Vectores de tamaño cero
4.9 Constructores de vectores
4.10 Vectores dinámicos
4.11 Vectores automáticos
4.12 Vectores con forma asumida
4.13 Funciones intrínsecas para operar con
vectores
4.14 Ejemplo
4.15 Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Terminología
Hablaremos en general de vectores (arrays) para
referirnos a vectores multidimensionales
(matrices)
Fortran90 permite vectores de hasta 7
dimensiones
real, dimension(50) :: w
real, dimension(5:54) :: x
real y(50)
real z(11:60)
!w, x, y, z vectores de 50 elementos
Rango de un vector: número de dimensiones
Extensión: número de elementos en una
dimensión
Forma: vector de extensiones. El vector contiene
la extensión de cada dimensión
Tamaño: Número de elementos. Es el producto
de extensiones
2 vectores son compatibles si tienen la misma
forma. Cualquier vector es compatible con un
escalar
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Terminología
Ejemplo
real, dimension :: a(−3:4,7)
real, dimension :: b(8,2:8)
real, dimension :: d(8,1:8)
integer :: c
El vector a tiene:
Rango: 2
Extensiones: 8 y 7
Forma: (/8, 7/)
Tamaño: 56
El vector a es compatible con b y c, pero no
con d (d tiene forma (/8, 9/)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
tipo [[,dimension (lista_de_extensiones)]
[,atributo]... ::] identificadores
tipo: tipo básico o derivado
dimension es opcional, pero necesario para definir
dimensiones por defecto
La lista de extensiones da las dimensiones del
vector. Puede ser:
Una constante entera
Una expresión entera usando parámetros formales
: para mostrar que el vector es dinámico o de forma
asumida
Los atributos pueden ser los que ya hemos
estudiado: (parameter, public, private, pointer,
target, allocatable, dimension(extent−list),
intent(inout), optional, save, external, intrinsic)
identificadores: Una lista de identificadores de
vector que opcionalmente pueden tener
dimensiones y valores iniciales
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
Inicialización de vectores de 1 dimensión
conteniendo 3 elementos:
integer, dimension(3) :: &
ia=(/1, 2, 3/), ib=(/(i, i=1, 3)/)
Declaración de un vector automático lb. la es un
vector de argumentos dummy y size una función
intrínseca que da el tamaño del vector la
logical, dimension(size(la)) :: lb
Declaración de 2 vectores bidimensionales
dinámicos a y b. La forma (nº de elementos en
cada dimensión) se definiría con una sentencia
allocate posterior:
real, dimension (:,:), allocatable :: a,b
Declaración de 2 vectores tridimentionales de
forma asumida. La forma se tomaría de los
parámetros actuales de la rutina llamadora:
real, dimension(:,:,:) :: a,b
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Operaciones sobre vectores
En Fortran90 es posible realizar operaciones
sobre todos los elementos de un vector sin
necesidad de usar bucles
Para ello, los vectores implicados deben ser
compatibles
Las operaciones entre dos vectores
compatibles se realizan elemento a elemento
y todos los operadores intrínsecos están
definidos para vectores compatibles. P. ej.:
3 4 8
5 6 6
*
5 2 1
3 3 1
=
15 8 8
15 18 6
Si uno de los operandos es un escalar, éste
se expande para ser compatible con el otro
operando. Esta expansión de escalares es útil
a la hora de inicializar o escalar vectores
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Operaciones sobre vectores
Un concepto fundamental con respecto a las
asignaciones en operaciones sobre vectores
es que la evaluación de la expresión del lado
derecho de la asignación se realiza antes de
que ocurra cualquier asignación.
Esto es importante cuando aparecen vectores
en ambos lados de la asignación: si no fuera
así los elementos de los vectores de la parte
derecha se podrían ver afectados antes de
que la operación se completara.
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Operaciones sobre vectores
Consideremos tres vectores del mismo tamaño.
Asignemos 0 a todos los elementos y luego
hagamos a(i) = a(i)/3.1 + b(i)*sqrt(c(i)) para
todo i
Solución en Fortran 77:
real a(20), b(20), c(20)
...
do 10 i=1, 20
a(i)=0
10
continue
...
do 20 i=1, 20
a(i)=a(i)/3.1 + b(i)*sqrt(c(i))
20
20 continue
Solución en Fortran 90:
real, dimension(20) :: a, b, c
...
a = 0
...
a = a / 3.1 + b * sqrt(c) !sqrt Para cada
!elemento
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Operaciones sobre vectores
Consideremos tres matrices bidimensionales de la
misma forma. Multiplicar dos de las matrices
elemento a elemento asignando el resultado a la
tercera matriz
Fortran 77
10
20
real a(5, 5), b(5, 5), c(5, 5)
...
do 20 i = 1, 5
do 10 j = 1, 5
c(j, i) = a(j, i) * b(j, i)
continue
continue
Fortran 90
real, dimension (5, 5) :: a, b, c
...
c = a * b
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Operaciones sobre vectores
Consideremos una matriz tridimensional. Hallar el
máximo valor menor que 1000 en la matriz. En
Fortran90 el código es:
real, dimension(10, 10, 10) :: a
amax = maxval(a, mask = (a <1000))
mask es una función que devuelve un vector lógico:
sólo los elementos de a que se corresponden con
elementos de mask participan en la llamada a
maxval
Hallar el valor medio de los valores mayores que
3000 en un vector
av = sum(a, mask=(a > 3000)) / &
count(mask=(a > 3000))
Funciones intrínsecas sobre vectores:
maxval − retorna el valor máximo de los elementos
de un vector
sum − la suma de los elementos del vector
count − El número de elementos TRUE
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
elementales
Fortran90 permite procedimientos intrínsecos
sobre vectores. El procedimiento se aplica a
cada elemento del vector (matriz). De nuevo,
los operandos deben ser compatibles. Veamos
ejemplos:
1.− Hallar la raiz cuadrada de todos los
elementos de una matriz:
b = sqrt(a)
2.− Hallar la longitud de una cadena dada por
un vector de caracteres ch, ignorando los
espacios en blanco:
length = len_trim(ch)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sentencia where
Se usa para realizar asignaciones sólo si se cumple
una condición lógica, y es útil para para realizar
operaciones sobre ciertos elementos de un vector.
Un ejemplo simple es evitar una división por cero:
real, dimension(5, 5) : ra, rb
...
where(rb > 0.0) ra = ra / rb
Forma general:
where(logical−array−expression) &
array−variable = array−expression
Se evalúa la expresión lógica y todos los elementos
de la array−expression que tienen un valor true se
evalúan y asignan. Los elementos que resultan
false no se cambian. La expresión lógica ha de
tener la misma forma que el vector
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Sentencia where
También es posible controlar asignaciones sobre
un vector a través de un vector lógico. En este
caso la forma del constructo where es:
where (logical−array−expression)
array−assignment−statements
end where
o bien
where (logical−array−expression)
array−assignment−statements
elsewhere
array−assignment−statements
end where
Ejemplo:
real, dimension(5, 5) :: ra, rb
...
where(rb > 0.0)
ra = ra / rb
elsewhere
ra = 0.0
end where
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Secciones de vectores
Una parte de un vector (lo que se llama una
sección) puede referenciarse especificando un
rango de subíndices mediante:
Un subíndice simple:
0
0

0

0
 0
0
X
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0 
0  = ra (2, 2)

0
0 
Una tripleta de subíndices:
[lim_inf]:[lim_sup][:stride]
1
Por defecto se toman los límites declarados y
stride=1
Los siguientes ejemplos muestran secciones de
vectores utilizando tripletas de subíndices:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Secciones de vectores
0
0

0

0
 0
0
X
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

0

0
 0
0
0
0
0
0
0
X
0
0
0
X
0
0
0
0
0
0 
0  = ra (2 : 2, 2 : 2)

0
Un elemento. Forma: (/1/)
0 
0
0 
X  = ra (3, 3 : 5)

0
Una Subcolumna. Forma: (/3/)
0 
0
0

0

0
 0
0
0
0
0
0
X
X
X
X
X
0
0
0
0
0
0
0 
0  = ra (:, 3)

0
Una columna. Forma: (/5/)
0 
0
0

0

0
 0
X
0
X
0
X
0
X
0
X
0
X
0
X
X
X
0
0 
0  = ra (1 :: 2, 2 : 4)

0
Stride 2 en filas. Forma: (/3, 3/)
0 
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Secciones de vectores
Un vector de subíndices. Es una expresión entera de
rango 1 (vector de enteros). Cada elemento de la
expresión ha de definirse con valores en el rango de
los límites del vector padre . Los elementos del
vector de subíndices pueden estar en cualquier orden
Un ejemplo de expresión entera de rango 1 es:
(/3, 2, 12, 2, 1/)
Veamos ejemplos de uso:
real, dimension :: ra(6), rb(3)
integer, dimension (3) :: iv
iv = (/ 1, 3, 5 /) !expr. entera de rango 1
ra = (/ 1.2, 3.4, 3.0, 11.2, 1.0, 3.7 /)
rb = ra(iv) !iv es el vector de subíndices
! = (/ ra(1), ra(3), ra(5) /)
! = (/ 1.2, 3.0, 1.0 /)
ra(iv) = (/1.2, 3.4, 5.6/)
!= ra((/1, 3, 5/)) = (/1.2, 3.4, 5.6/)
!= ra(1:5:2) = (/1.2, 3.4, 5.6/)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Secciones de vectores
Se permite utilizar varias veces el mismo
vector de subíndices. No se pueden repetir
elementos en la parte izquierda (muchos a
uno), pero sí en la parte derecha (uno a
muchos):
real, dimension :: ra(6), rb(3)
integer, dimension (3) :: iv
iv = (/1, 3, 1/)
ra(iv) = (/1.2, 3.4, 5.6/) !
Prohibido
! = ra(/1, 3, 1/) = (/1.2, 3.4,
5.6/)
rb = ra(iv)
!
Permitido
! = ra(/1, 3, 1/) = (/1.2, 3.4,
1.2/)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Asignaciones con vectores
Tanto vectores completos como secciones de
vectores se pueden usar como operandos en
asignaciones con vectores, siempre que sean
compatibles. Por ejemplo:
real, dimension(5, 5) :: ra, rb, rc
integer :: i
...
! Forma (/5, 5/) y escalar
ra = rb + rc * i
! Forma (/3, 2/)
ra(3:5,3:4) = rb(1::2, 3:5:2) + rc(1:3,
:2)
! Forma (/5/)
ra(:,1) = rb(:,1) + rb(:,2) + rc(:,3)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Recursividad
Es importante saber cómo obtener
recursividad en Fortran90. Por ejemplo el
código:
do i = 2, n
x(i) = x(i) + x(i−1)
end do
No produce el mismo resultado que:
x(2:n)= x(2:n) + x(1:n−1)
En el primer caso, la asignación es:
x(i) = x(i) + x(i−1) + x(i−2) + ... + x(1)
Mientras que en el segundo:
x(i) = x(i) + x(i−1)
!Comprobarlo!
En Fortran90 se puede obtener el efecto
recursivo del bucle do utilizando la función
intrínseca sum, que devuelve la suma de
todos los elementos del vector parámetro:
x(2:n) = (/(sum(x(1:i)), i= 2,n)/)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Posición del elemento versus
indexación
Las funciones intrínsecas maxloc y minloc
devuelven la posición de los valores máximo y
mínimo del vector pasado como parámetro. Si el
límite inferior no es 1 hay que tener en cuenta que
estas funciones devuelven la posición y no el
subíndice:
real, dimension (1:8) :: ra
real, dimension (−3:4) :: rb
integer, dimension (1) :: locmax1, locmax2
real :: max1, max2
ra=(/1.2, 3.4, 5.4, 11.2, 1.0, 3.7,
1.0,1.0/)
rb = ra
!Para hallar el valor máximo:
locmax1 = maxloc(ra)
! = (/ 4 /)
locmax2 = maxloc(rb)
! = (/ 4 /)
max1 = ra(locmax(1))
! OK porque el límite inferior de ra es 1
max2 = rb(lbound(rb) + locmax2(1) − 1)
! Se necesita esto si el límite inferior
! no es 1
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores de tamaño cero
Si el límite inferior de un vector es mayor que el
superior, el vector tiene tamaño cero. Estos
vectores siguen las reglas normales
Son útiles para operaciones de contorno (no se
necesita código especial para tratar los límites de
un modo especial):
do i=1, n
x(i) = b(i) / a(i, i)
b(i+1:n) = b(i+1:n) − a(i+1:n, i) * x(i)
! Tamaño cero cuando i=n
end do
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Constructores de vectores
Un constructor de vectores crea un vector de rango
1 conteniendo valores especificados. Los valores
se pueden dar listándolos o bien usando un bucle
implícito o una combinación de ambos
Forma general:
(/ array−constructor−value−list /)
Ejemplo:
real, dimension(6) :: a
a=(/array−constructor−value−list/)
Donde array−constructer−value−list puede ser:
(/(i, i = 1,6)/)
! = (/1,2,3,4,5,6/)
(/7, (i, i=1,4), 9/)! = (/7,1,2,3,4,9/)
(/1.0/real(i), i = 1,6)/)
!=(/1.0/1.0,1.0/2.0,1.0/3.0,1.0/4.0,1.0/5.0,
1.0/6.0/)
(/((i+j, i=1,3), j=1,2)/)
! = (/((1+j,2+j,3+j),j=1,2)/)
! = (/2,3,4,3,4,5/)
(/a(i,2:4),a(1:5:2,i+3)/)
!=(/a(i,2),a(i,3),a(i,4),a(1,i+3),a(3,i+3),
a(5,i+3)/)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Constructores de vectores
Es posible transferir los valores de un vector de
rango 1 a un vector de diferente forma utilizando la
función reshape, que tiene la forma:
reshape(fuente,shape,[,pad][,order])
Donde el parámetro fuente puede ser un array de
cualquier clase, y sus elementos se distribuyen
para formar un nuevo vector (reshape) con forma
shape, (que es devuelto por la función)
Si fuente tiene más elementos que el vector al que
se asigna, entonces los elementos no deseados se
ignoran
Si reshape tiene más elementos que fuente,
entonces pad ha de estar presente. pad es un
vector del mismo tipo que fuente que se usa
(quizás repetidamente) para rellenar
order permite que los elementos de reshape se
coloquen en órdenes diferentes al del vector. Ha de
tener el mismo tamaño y forma que shape y
contiene las dimensiones de reshape en el orden
en que deben recorrerse
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Constructores de vectores
Ejemplo
real, dimension(3, 2) :: ra
ra=reshape((/((i + j, i= 1,3), j= 1,2)/),&
shape=(/3, 2/))
!Crea el vector:
 2 3
ra =  3 4
 4 5
ra=reshape((/((i+j,i=1,3),j=1,2)/),shape= &
(/3,2/),order(2,1))
! El resultado sería:
 2 3
ra =  4 3
 4 5
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores dinámicos
En Fortran77 todo el manejo de memoria era
estático
Fortran90
Permite obtener y liberar memoria dinámica
a través de los vectores dinámicos
Permite a los vectores locales a un
procedimiento tener tamaños y formas
diferentes en cada llamada a través de los
vectores automáticos
Reduce los recursos globales necesarios
para almacenamiento en memoria
Simplifica los parámetros de las subrutinas
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores dinámicos
Un vector dinámico se declara en una sentencia de
declaración de tipo con el atributo allocatable
El rango del vector debe especificarse en la
declaración incluyendo el número adecuado de :
en el atributo dimension
Un vector bidimensional se podría declarar:
real, dimension(:,:), allocatable :: a
La declaración no reserva memoria para el vector
allocate (a(0:n, m))
allocate (a(0:n+1, m))
deallocate (a)
La forma general de estas sentencias:
allocate(allocate−object−list &
[,STAT=checkstat])
deallocate(allocate−object−list &
[,STAT=checkstat])
Si STAT está presente, toma el valor 0 si la
operación se realizó correctamente o un valor
positivo si hubo un error
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores dinámicos
Ejemplo
integer n
real, dimension(:,:), allocatable :: ra
integer :: checkstat
...
read(*, *) nsize1, nsize2
ALLLOCATE(ra(nsize1, nsize2),
STAT=checkstat)
if (checkstat > 0) then
! ... Hubo un error ...
end if
...
deallocate (ra)
Se pueden alojar/desalojar varios vectores en la
misma sentencia
if (allocated(a)) deallocate(a)
or
if (.not. allocated(a)) allocate(a(5,
20))
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores dinámicos
Si un vector dinámico se declara con el atributo
save:
real, dimension(:), allocatable, save :: a
el vector estará disponible incluso a la salida del
procedimiento en que fue alojado
Los vectores dinámicos:
han de ser creados y liberados dentro de la
misma unidad de programa
El resultado de una función no puede ser un
vector dinámico
No se puede usar vectores dinámicos en una
definición de tipo derivado
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
Llamaremos vector automático a un vector que
tiene forma explícita dentro de un procedimiento y
cuyos límites se dan cuando el procedimiento es
invocado
a través de los parámetros formales
a través de variables definidas por asociación por
uso o asociación por hospedaje
Asociación por uso es cuando las variables
declaradas en el cuerpo de un módulo se hacen
disponibles a un programa a través de una
sentencia use. Asociación por hospedaje es
cuando las variables declaradas en una unidad de
programa se hacen disponibles a sus
procedimientos internos
Los vectores automáticos se crean al entrar al
procedimiento y se liberan al salir del mismo
No existe un mecanismo para comprobar si hay
suficiente memoria para un vector automático
Es frecuente usar la función intrínseca size al
declarar vectores automáticos:
size(ARRAY [,DIM])
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
Ejemplos
subroutine sub(n, a)
implicit none
integer :: n
real, dimension(n, n), intent(inout) ::
a
real, dimension(n, n) :: work1
real, dimension(size(a, 1)) :: work2
...
end subroutine sub
Los vectores work1 y work2 toman su tamaño de los
parámetros formales n y a
El siguiente ejemplo muestra los límites de un
vector automático dependiendo de una
variable global definida en un módulo.
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
module auto_mod
implicit none
integer :: n=1
!Por defecto n=1
contains
subroutine sub
implicit none
real, dimension(n) :: w
write (*, *) Límites−tamaño de w: &
,lbound(w), ubound(w), size(w)
end subroutine sub
end module auto_mod
program auto_arrays
use auto_mod
implicit none
n = 10
call sub
end program auto_arrays
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
Supongamos que el programa principal
declara un vector de tamaño NxN pero a una
subrutina ha de pasar como parámetro una
sección de tamaño N1xN1 (N1 < N). Para
conseguir esto en Fortran77 hemos de pasar
como parámetros tanto N como N1, mientras
que en Fortran90 se puede simplificar el
código:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
program array
! Fortran77
integer n,n1
parameter (n=10)
real a(n,n),work(n,n)
real res
...
read(*,*) n1
if (n1 .LE. n) then
call sub(a,n,n1,res,work)
else
c
... Hubo un error ...
end if
...
end program array
subroutine sub(a, n, n1, res, work)
integer n, n1
real a(n, n)
real work(n1, n1)
real res
...
res=a(...)
...
end subroutine sub
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
PPROGRAM array
!Fortran90
implicit none
real, allocatable, dimension(:,:) :: a
real :: res
integer :: n1, alloc_stat
...
read(*,*) n1
allocate(a(n1, n1), STAT=alloc_stat)
if (alloc_stat /= 0) then
! ... Hubo un error ...
end if
call sub(a, n1, res)
deallocate(a, STAT=alloc_stat)
if (alloc_stat /= 0) then
! ... Hubo un error ...
end if
...
contains
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores Automáticos
contains
subroutine sub(a, n1,
implicit none
integer, intent(in)
real, intent(inout)
real, dimension(n1,
real, dimension(n1,
...
res=a(...)
...
end subroutine sub
end program array
res)
:: n1
:: res
n1), intent(in) :: a
n1):: work
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores con forma asumida
Un vector de forma asumida es un vector cuya
forma no es conocida sino que toma cualquier
forma dependiendo de un parámetro actual
Cuando se declara un vector de forma asumida
cada dimensión se especifica como:
[lower_bound]:
donde el límite inferior se toma como 1 si se omite
Los vectores de forma asumida hacen posible el
paso de vectores entre unidades de programa sin
necesidad de pasar las dimensiones como
parámetros. Si un procedimiento externo tiene un
vector de forma asumida como parámetro formal ha
de darse un bloque de interface en la unidad de
programadora que invoque al procedimiento
Consideremos el siguiente subprograma externo
con vectores de forma asumida ra, rb y rc
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores con forma asumida
subroutine sub(ra, rb, rc)
implicit none
real, dimension(:,:), intent(in) :: ra
! Forma (10, 10)
real, dimension(:,:), intent(in) :: rb
! Forma (5, 5)
! = real, dimension(1:5,1:5) :: rb
real, dimension(0:,2:), intent(out) :: rc
! Forma (5, 5)
! = real, dimension (0:4,2:6) :: rc
...
end subroutine sub
! El prog. Ppal. Debería tener una interface:
real, dimension (0:9,10) :: ra
! Shape (10, 10)
interface
subroutine sub(ra, rb, rc)
real, dimension(:,:),intent(in):: ra,rb
real, dimension(0:,2:),intent(out):: rc
end subroutine sub
end interface
...
call sub (ra, ra(0:4,2:6), ra(0:4,2:6))
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ejemplo
program array
implicit none
real, allocatable, dimension(:,:) :: a
real :: res
integer :: n1
interface
subroutine sub(a,res)
real,dimension(:,:), intent(in)::a
real,dimension(size(a,1),size(a, 2)) :: work
end subroutine sub
end interface
...
read (*, *) n1
allocate (a(n1, n1))! Vector dinámico
call sub(a, res)
...
contains
subroutine sub(a,res)
implicit none
real, intent(out) :: res
real, dimension(:, :), intent(in) :: a
! Vector de forma asumida
real,dimension (size(a,1),size(a,2)) :: work
! Vector automático
...
res = a(...)
Introducción
... a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
end subroutine sub
end program array
Funciones intrínsecas para
vectores
Reducciones
ALL(MASK[, DIM])
True si todos los elementos son true
ANY(MASK[, DIM])
True si algún elemento es True
COUNT(MASK[, DIM])
Número de elementos true
maxval(ARRAY[, DIM][, MASK])
Máximo del vector
MINVAL(ARRAY[, DIM][, MASK])
Mínimo del vector
PRODUCT(ARRAY[, DIM][, MASK])
Producto de todos los elementos
SUM(ARRAY[, DIM][, MASK])
Suma de todos los elementos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones intrínsecas para
vectores
Consulta
allocated(ARRAY)
True si el vector ha sido creado
lbound(ARRAY[, DIM])
Límites inferiores del vector
shape(fuente)
Forma del vector (o escalar)
size(ARRAY[, DIM])
Tamaño del vector
ubound(ARRAY[, DIM])
Límite superior del vector
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones intrínsecas para
vectores
Construcción
MERGE(TSOURCE, FSOURCE, MASK)
Mezcla dos vectores en términos de la
máscara
pack(ARRAY, MASK[, VECTOR])
Empaqueta elementos en el vector en
términos de la máscara
SPREAD(fuente, DIM, ncopias)
Construye un vector duplicando una
sección de otro
UNPACK(VECTOR, MASK, FIELD)
Desempaqueta elementos de un vector
en términos de la máscara
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones intrínsecas para
vectores
Reshape
reshape(fuente, shape[, pad][,
order])
Cambia la forma de un vector
Posición en el vector
MAXLOC(ARRAY[, MASK])
Posición del máximo
MINLOC(ARRAY[, MASK])
Posición del mínimo
Manipulación de vectores
CSHIFT(ARRAY, SHIFT[, DIM])
Realiza una rotación circular
EOSHIFT(ARRAY, SHIFT[, BOUNDARY][,
DIM])
Rotación “ nd−off”
TRANSPOSE(MATRIX)
Traspone una matriz
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones intrínsecas para
vectores
Aritmética vectorial y matricial
DOT_PRODUCT(VECTOR_A, VECTOR_B)
Producto escalar
MATMUL(MATRIX_A, MATRIX_B)
Producto de matrices
Ejemplos
Los siguientes ejemplos ilustran el uso de
algunas de estas funciones intrínsecas. Tres
estudiantes realizan 4 exámenes. Las
calificaciones (sobre 100 puntos) se
almacenan en un vector de enteros:
85 76 90 60 
score(1 : 3, 1 : 4) =  71 45 50 80 
66 45 21 55 
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones vectoriales
intrínsecas: Ejemplos
85 76 90 60 
score(1 : 3, 1 : 4) =  71 45 50 80 
66 45 21 55 
Máxima nota:
maxval (score)
! = 90
Máxima nota para cada estudiante:
maxval (score, DIM = 2)
! = (/90, 80, 66/)
Alumno con la nota máxima:
maxloc (maxval (SCORE, DIM = 2))
! = maxloc ((/90, 80, 66 /)) = (/ 1 /)
Nota media:
average = sum(score)/size(score)!=62
! average es una variable entera
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones vectoriales
intrínsecas: Ejemplos
85 76 90 60 
score(1 : 3, 1 : 4) =  71 45 50 80 
66 45 21 55 
Número de calificaciones por encima de la media:
above = score > average
! above(3, 4) es un vector lógico
T
! above = T
T
T
F
F
T
F
F
F
T 
F 
n_gt_average = count (above)
! n_gt_average es un entero
! = 6
Empaquetar todas las notas por encima de la
media:
...
integer, allocatable, dimension (:) :: &
score_gt_average
...
allocate (score_gt_average(n_gt_average)
scores_gt_average = pack (score, above)
! = (/ 85, 71, 66, 76, 90, 80 /)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones vectoriales
intrínsecas: Ejemplos
85 76 90 60 
score(1 : 3, 1 : 4) =  71 45 50 80 
66 45 21 55 
¿Algún alumno puntuó siempre por encima de la
media?:
ANY (ALL (above, DIM = 2))
! = .FALSE.
¿Todos los alumnos puntuaron por encima de la
media en cualquiera de los exámenes?
ANY (ALL (above, DIM = 1))
! = .TRUE.
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ejemplo: Conjugado del
gradiente
program conjugate_gradients
implicit none
integer :: iters, its, n
logical :: converged
real :: error, up, alpha, beta
real, allocatable :: &
a(:,:), b(:), x(:), r(:), &
u(:), p(:), xnew(:)
read (*,*) n, error, its
allocate &
(a(n,n),b(n),x(n),r(n),u(n),p(n),xnew(n))
open (10, file=’data’)
read (10,*) a
read (10,*) b
x = 1.0
r = b − MATMUL(a, x)
p = r
iters = 0
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Ejemplo: Conjugado del
gradiente
do
iters = iters + 1
u = MATMUL(a, p)
up = DOT_PRODUCT(r, r)
alpha = up / DOT_PRODUCT(p, u)
xnew = x + p * alpha
r = r − u * alpha
beta = DOT_PRODUCT(r, r) / up
p = r + p * beta
converged = ( maxval(ABS(xnew−x)) / &
maxval(ABS(x)) < error )
x = xnew
if (converged .OR. iters == its) exit
end do
write (*,*) iters
write (*,*) x
end program conjugate_gradients
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
5
Punteros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros
Índice
5.1 − Significado de un puntero
5.2 − Especificaciones
5.3 − Asignaciones de punteros
5.4 − Estado de una asociación de punteros
5.5 − Memoria dinámica
5.6 − Argumentos puntero
5.7 − Funciones que devuelven punteros
5.8 − Vectores de punteros
5.9 − Listas enlazadas
5.10 − Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Significado de un puntero
Una variable de tipo puntero (o simplemente un
puntero) tiene el atributo pointer y puede apuntar a
otra variable de un tipo adecuado, que tendrá el
atributo target o bien a un área de memoria alojada
dinámicamente
Los punteros en F90 son diferentes a los de C o
Pascal: no contienen un dato en sí mismos y no
deberían interpretarse como una dirección. Más
bien deberían verse como variables que se asocian
dinámicamente (en tiempo de ejecución) con otros
datos que sí tienen asignado un espacio de
memoria física ( target )
Los beneficios más interesantes de la introducción
de punteros son:
Una alternativa más flexible a los arrays dinámicos
Una herramienta para crear y manipular listas
enlazadas y otras estructuras de datos dinámicas
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
La forma general de declarar una variable puntero y
un destino (target) son:
type [[,attribute]...] pointer :: list of
pointer variables
type [[,attribute]...] target :: list of
target variables
Donde
El tipo especifica el tipo de variables que pueden
ser apuntadas por el puntero (incluyendo tipos
derivados)
La lista de atributos da el resto de atributos del tipo
de datos (si tiene alguno/s)
Una variable puntero ha de tener el mismo tipo,
parámetros y rango que su variable destino
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Especificaciones
La declaración de un puntero a vectores especifica
el tipo y rango de los vectores a los que puede
apuntar (sólo el rango, no los límites del vector)
El atributo dimensión de un puntero a vectores no
puede especificar una forma explícita o una forma
asumida sino que debe tomar la forma de un
vector de forma diferida de modo similar a como se
hace con los vectores dinámicos. Así por ejemplo la
declaración:
real, dimension(:), pointer :: p
Declara un puntero p, que puede apuntar a
vectores de reales de rango 1. La declaración:
real, dimension(20), pointer :: p
Es errónea y no es admitida por el compilador F90
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Asignaciones de punteros
Un puntero puede convertirse en un alias de una
variable destino (target) a través de una sentencia
de asignación de punteros, que es ejecutable y
tiene la forma:
pointer => target
Donde pointer es una variable con atributo pointer y
target es una variable con atributo target o bien
atributo pointer
Una vez que un puntero se convierte en alias de un
destino, se puede utilizar en cualquier punto en
lugar de la variable destino
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Asignaciones de punteros
Ejemplos:
real,
real,
p1 =>
print
p2 =>
print
pointer :: p1, p2
target :: t1 = 3.4, t2 = 4.5
t1
! p1 apunta a t1
*, t1, p1
! ambos valen 3.4
t2
! p2 apunta a t2
*, t2, p2
! ambos valen 4.5
t1
p1
3.4
t2
p2
4.5
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Asignaciones de punteros
t1
p1
3.4
t2
p2
4.5
p2 => p1
! p2 apunta al destino de p1
print *, t1, p1, p2
!Todos valen 3.4
t1
p1
p2
3.4
t1 = 5.2
print *, t1, p1, p2
t2
4.5
!Todos valen 5.2
Téngase en cuenta que la asignación:
p2 => p1 + 4.3
!Error
No está permitida porque no se puede asociar un
puntero con una expresión aritmética
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Asignación de punteros /
asignaciones normales
Comparemos lo anterior con el siguiente código,
en el que sólo la última línea es diferente:
real, pointer :: p1, p2
real, target :: t1 = 3.4, t2 = 4.5
p1 => t1
! p1 apunta a t1
p2 => t2
! p2 apunta a t2
p2 = p1
! Asignación normal,
! equivalente a t2 = t1
t1
p1
3.4
t2
p2
4.5
Después de que la última asignación se ejecuta, la
situación es:
t1
p1
3.4
t2
p2
3.4
La sentencia tiene el mismo efecto que t2=t1
puesto que p1 es un alias de t1 y p2 lo es de t2
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros a vectores
El destino de un puntero puede ser también un
vector. Veamos ejemplos de su uso:
real, dimension (:), pointer :: pv1
real, dimension (:, :), pointer :: pv2
real, dimension (−3:5), target :: tv1
real, dimension (5, 10), target :: tv2
integer, dimension(3) :: v = (/4, 1,−3/)
pv1 => tv1
! pv1 es un alias de tv1
pv1 => tv1(:)
! pv1 apunta a tv1 con
! Subíndices de sección
pv1 => tv2(4, :)
! pv1 apunta a la 4ª
fila
! de tv2
pv2 => tv2(2:4, 4:8)
! pv2 apunta a una
! sección de tv2
pv1 => tv1(1:5:2)
! pv1 apunta a una
! Sección de tv1
pv1 => tv1(v)
! Error
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros a vectores
real, dimension (:), pointer :: pv1
real, dimension (−3:5), target :: tv1
pv1 => tv1
! pv1 es un alias de tv1
tv1(−3:5)
pv1(−3:5)
pv1 => tv1(:)
! pv1 apunta a tv1 con
! Subíndices de sección
tv1(−3:5)
pv1(1:9)
pv1 => tv1(1:5:2)
! Sección de tv1
! pv1 apunta a una
tv1(1:5:2)
pv1(1:3)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros a vectores
real, dimension (:), pointer :: pv1
real, dimension (:, :), pointer :: pv2
real, dimension (5, 10), target :: tv2
pv1 => tv(4, :)
! pv1 apunta a la 4ª
fila
! de tv2
tv2(4, :)
pv1(1:10)
pv2 => tv2(2:4, 4:8)
! sección de tv2
! pv2 apunta a una
tv2(2:4, 4:8)
pv2(1:3, 1:5)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros a vectores
Hay varios aspectos a tener en cuenta:
El puntero pv1 se asocia en diferentes momentos
con vectores (secciones de vector) de diferentes
extensiones. Esto se permite porque lo que cuenta
es el rango, no la extensión
Si un puntero a vector se hace alias de un vector,
sus extensiones son las mismas que las del vector
al que apunta. Así con la asignación pv1 => tv1,
pv1 tiene los mismos límites que tv1, es decir
−
3:5. Si un puntero a vector apunta a una sección de
vector, su límite inferior en cada dimensión se
renumera siempre a 1.
Así con pv1 => tv1(:), donde se use el subíndice
de la sección de vector los límites de pv1 son 1:9
en lugar de −3:5; de modo que pv1(1) se interpreta
como tv1(−3), pv1(2) es tv1(−2), y así
sucesivamente. Esta renumeración también ocurre
cuando tv2 se interpreta como la sección tv2(2:4,
4:8)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Punteros a vectores
Es lícito asociar un puntero a vector con una
sección de vector definida por una tripleta de
subíndices, pero no se permite asociarlo con una
sección definida por subíndices. Así
pv1 => tv1(1:5:2)
es correcto con pv1(1) siendo un alias de tv1(1),
pv1(2) de tv1(3), y pv1(3) de tv1(5), pero la
asignación de punteros:
pv1 => tv1(v)
! Error
no es admitida por el compilador
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estado de una asociación de
punteros
Todo puntero tiene uno de los siguientes estados
de asociación:
1.− Indefinido − cuando es inicialmente especificado en
una sentencia de declaración
2.− Null (disociado) − cuando se hace nulo con una
sentencia NULLIFY
3.− Asociado − cuando apunta a un destino
Un puntero puede disociarse explícitamente de su
destino (target) usando una sentencia NULLIFY:
NULLIFY(list of pointers)
La función intrínseca associated puede usarse para
comprobar el estado de asociación de un puntero
usando 1 ó 2 parámetros:
associated(p, [,t])
Si el 2º parámetro no aparece, retorna .TRUE. si el
puntero p está asociado con agún destino y
.FALSE. en caso contrario. El 2º parámetro puede
ser un puntero en cuyo caso retorna .TRUE. si
ambos punteros están asociados al mismo destino
o disociados y .FALSE. en caso contario
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Estado de una asociación de
punteros
Una restricción de associated es que no se le
pueden pasar punteros indefinidos. Por ello se
recomienda asociar un puntero después de su
declaración o disociarlo explícitamente con
NULLIFY
Ejemplos:
real, pointer :: p, q
! Indefinidos
real, target :: t = 3.4
p => t
! p apunta a t
q => t
! q también apunta a t
print *, associated(p)=",associated(p) !.T.
print *,"associated(p,q)=",associated(p,q)!.T.
NULLIFY(p)
print *,"associated(p)= ", associated(p) !.F.
print *,"associated(p,q)=",associated(p,
q)!.F.
...
p => t
! p apunta a t
NULLIFY(p, q)
Nótese que la disociación de p no afectó a q a
pesar de que ambos apuntaban al mismo objeto.
Después de anular un puntero, puede asociársele
de nuevo con el mismo u otro objeto
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Memoria dinámica
También un puntero puede asociarse con un área
de memoria alojada dinámicamente a través de la
sentencia allocate. Esta sentencia crea (sin
nombre) un área de memoria del tamaño, tipo y
rango especificados y con un atributo target:
real, pointer :: p
real, dimension (:, :), pointer :: pv
integer :: m, n
...
allocate (p, pv(m, n))
Aquí el puntero p apunta a un área de memoria
dinámica con capacidad para almacenar un real.
El puntero pv apunta a un vector (matriz) de tamaño
mxn
La memoria dinámica puede liberarse:
deallocate(pv)
haciendo que el estado de pv pase a ser NULL
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Memoria dinámica
La forma general de estas sentencias es:
allocate(pointer[(dim. specification)]...
[,STAT = status])
deallocate(pointer... [,STAT = status]
Donde pointer es una variable puntero y la
especificación de dimensión especifica la extensión
de cada dimensión si el puntero tiene los atributos
pointer y dimension (es un puntero a un vector).
status es un entero que tomará el valor 0 si la
demanda/liberación de memoria ocurrió
correctamente. Ambas sentencias pueden
solicitar/liberar memoria para varios punteros
La programación con punteros entraña algunos
peligros si no se diseña con precaución:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Memoria dinámica
Referencias suspendidas:
...
real, pointer :: p1, p2
allocate (p1)
p1 = 3.4
p2 => p1
...
deallocate (p1) ! Las referencias a p2
...
! ahora serán errores
! y los resultados son
! impredecibles...
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Memoria dinámica
Memoria inaccesible:
...
real, dimension(:), pointer :: p
allocate (p(1000))
...
Si el puntero p es anulado (NULLIFY), se hace
apuntar a otra zona de memoria o este código está
en un subprograma y el subprograma es
abandonado (p no tiene atributo save) sin liberar la
memoria, no habrá forma de referenciar ese bloque
de memoria y por tanto no podrá ser liberado
Solución: liberar cualquier bloque de memoria
antes de modificar un puntero que apunte a ella
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos puntero
Los punteros, asociados o no, se pueden
pasar como parámetros a los subprogramas
pero sólo si se dan las siguientes condiciones:
Si un procedimiento tiene un puntero o
destino como parámetro formal, la interface
al procedimiento ha de ser explícita
Si un parámetro formal es un puntero, el
parámetro actual ha de ser un puntero con
el mismo tipo, parámetros de tipo y rango
Un parámetro formal de tipo puntero no
puede tener atributo intent
Si el parámetro actual es un puntero pero el
formal no lo es, el parámetro formal se asocia
con el destino del puntero
Consideremos el siguiente código:
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos puntero
...! Unidad de prog. Que invoca a sub1 y
sub2
interface
! interface para sub2
subroutine sub2(b)
real, dimension(:, :), pointer :: b
end subroutine sub2
end interface
real, dimension(:, :), pointer :: p
...
allocate (p(50, 50))
call sub1(p)
call sub2(p)
...
subroutine sub1(a) !a no es un puntero sino
real, dimension(:, :) :: a ! un vector de
...
! forma asumida
end subroutine sub1
subroutine sub2(b)
! b es un puntero
real, dimension(:, :), pointer :: b
...
deallocate(b)
...
end subroutine sub2
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Argumentos puntero
Los aspectos a tener en cuenta aquí son:
Tanto sub1 como sub2 son procedimientos
externos. Puesto que sub2 tiene un parámetro
formal puntero, se necesita un bloque interface
en la unidad llamadora (no es necesario para
sub1). Una alternativa hubiera sido usar un
módulo o un procedimiento interno para
suministrar una interface explícita por defecto
La unidad de programa llamadora hace que el
puntero p sea un alias de un vector de 50x50
reales e invoca a sub2. Esto asocia el
parámetro formal puntero b con el parámetro
actual puntero p. Cuando sub2 libera b se
libera también p en el programa llamador y
hace que p pase a ser NULL
Los vectores dinámicos no pueden usarse como
parámetros formales y deben ser alojados y
liberados en la misma unidad de programa. Se
permite pasar como parámetros actuales vectores
dinámicos con memoria asignada, pero no sin que
les haya sido asignada memoria
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones que devuelven
punteros
El resultado de una función puede tener el atributo
pointer, lo cual es útil si el tamaño del resultado
depende de cálculos realizados en la función.
Veamos un ejemplo: Una función que devuelve
todos los valores >0 de un vector:
...
integer, dimension(100) :: x
integer, dimension(:), pointer :: p
...
p => gtzero(x)
...
contains
function gtzero(a)
integer, dimension(:), pointer :: gtzero
integer, dimension(:) :: a
integer :: n
...
!n = nº de valores> 0
if (n == 0)
NULLIFY(gtzero)
else
allocate (gtzero(n))
endif
...
! Poner los valores en gtzero
end function gtzero
...
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones que devuelven
punteros
Consideraciones:
La función gtzero se ha codificado como un
procedimiento interno porque la interface a una
función que devuelve un puntero ha de ser
explícita
El resultado de la función puede utilizarse como
una expresión en una sentencia de asignación
de punteros (pero ha de asociarse antes con un
destino −target− definido). Como resultado el
puntero p apunta a un vector dinámico de
enteros del tamaño correcto que contiene todos
los valores positivos del vector x
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores de punteros
Un vector de punteros no se puede declarar
directamente:
real, dimension(20), pointer :: p
!Error
No puede hacerse porque pointer es un atributo y
no un tipo de datos. Un puntero puede ser una
componente de un tipo derivado. Un vector de
punteros se declara a través de un tipo derivado:
type real_pointer
real, dimension(:), pointer :: p
end type real_pointer
Ahora se puede definir un vector de variables de
este tipo:
type(real_pointer), dimension(100) :: a
Y se puede hacer referencia al i−ésimo puntero:
a(i)%p
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Vectores de punteros
Un ejemplo en el que cada columna de una matriz
triangular inferior se representa mediante un vector
dinámico de tamaño creciente:
integer, parameter :: n = 10
type(real_pointer), dimension(n) :: a
integer :: i
do i = 1, n
allocate (a(i)%p(i))
end do
! Referencia al
i−ésimo puntero
Nótese que a(i)%p apunta a un vector dinámico
de reales de tamaño i y por lo tanto esta
representación utiliza sólo la mitad de la memoria
que se necesitaría con un vector bidimensional
convencional
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Listas enlazadas
Una componente de tipo puntero de un tipo
derivado puede apuntar a un objeto del mismo tipo,
lo cual permite crear listas enlazadas y otras
estructuras de datos dinámicas:
type node
integer :: value
Datos
type (node), pointer :: next
end type node
!
! Puntero
En una estructura de este tipo los nodos
− No tienen porqué almacenarse de forma contigua en
memoria
− Pueden crearse dinámicamente (en tiempo de
ejecución)
− Pueden insertarse en cualquier posición de la lista
− Pueden eliminarse dinámicamente
Por todo ello, el tamaño de estas estructuras puede
crecer, casi arbitrariamente, conforme se ejecuta el
programa
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Listas enlazadas
Una lista enlazada consiste habitualmente en
elementos de un tipo derivado que contiene
uno o varios campos de datos más un campo
que es un puntero al siguiente elemento del
mismo tipo en la lista
cabecera
Campos de datos
Puntero
cola
Campos de datos
Puntero
...
Campos de datos
Puntero
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Listas enlazadas
program simple_linked_list
implicit none
type node
integer :: value
! Campo de datos
type (node), pointer :: next ! Campo puntero
end type node
integer :: num, status
type (node), pointer :: list, current
! build up the list
NULLIFY(list)
!Inicialmente, vaciar la lista
do
read *, num
!Leer num del teclado
if (num == 0) exit
!Hasta que se lea un 0
allocate(current, STAT = status) !Crear nodo if
(status > 0) stop ’Fallo al crear nodo’
current%value = num
current%next => list
!Apuntar al anterior
list => current
!Actualizar head
end do
! Recorrer la lista imprimiendo los valores
current => list ! Current es un alias de list
do
if (.not. associated(current)) exit
print *, current%value
current => current%next
end do
end program simple_linked_list
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Listas enlazadas
!Recorrer la lista eliminando nodos:
current => list
do
if (.not. associated(current)) exit
list => current%next
deallocate(current)
current => list
end do
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
6
Nuevas
características
de entrada/salida
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Entrada/Salida
Índice
6.1 − Introducción
6.2 − Entrada/Salida (E/S) sin avance
6.3 − Consultar lista de E/S (INQUIRE)
6.4 − NAMELIST
6.5 − Nuevos descriptores de edición
6.6 − Nuevos especificadores de sentencias
6.7 − Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Introducción
Las sentencias de entrada/salida (E/S) en
Fortran90 son respectivamente read y write
Cada una de ellas puede adoptar 3 formas
diferentes:
read <ch_var>, <lista_de_entrada>
read <etiqueta>, <lista_de_entrada>
read *, <lista_de_entrada>
print <ch_var>, <lista_de_entrada>
print <etiqueta>, <lista_de_entrada>
print *, <lista_de_entrada>
<ch_var> es una constante de caracteres, una
variable de tipo character o un vector de
caracteres
<etiqueta> es la etiqueta de una sentencia en
el código
Las listas corresponden a las variables que se
desea leer o escribir
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Introducción
La primera forma de sentencia de E/S se
denomina de formato empotrado porque el
formato en sí mismo forma parte de la
sentencia:
print (<lista_de_descriptores>) ,
<lista_salida>
En la segunda variante, la etiqueta
corresponderá con una sentencia format, que
contiene el formato que se desea en la
operación de E/S
La tercera forma es la que se conoce como
E/S dirigida por lista. Se trata de la forma más
simple y la que más hemos utilizado a lo largo
del curso.
En esta forma el asterisco indica que se desea un
formato de entada o salida acorde con el tipo
de los valores a leer/escribir
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Formateadores de E/S
Iw
Fw .d
Ew .d
Aw
A
Lw
nX
Tc
TLn
TRn
"c 1c2 ...cn "
’c1 c2 ...cn ’
Escribe un entero en los siguientes w
caracter es
I m pr im e un núm ero r eal en los
siguientes w car acter es utilizando d
posiciones decim ales
I m pr im e un núm ero r eal en los
siguientes w car acter es utilizando un
form ato de exponente con d posiciones
decim ales y 4 dígitos par a el exponente
Escribe una cadena de car acter es en los
siguientes w car acter es
Escribe una cadena de car acter es
com enzando en la siguiente posición
I m pr im e L−1 espacios en blanco seguidos
por T o F par a indicar un v alor lógico
I gnora las siguientes n posiciones
I m pr im e el siguiente elem ento
com enzando en el car ácter c
I m pr im e el siguiente elem ento
com enzando n posiciones antes ( TL)
O después ( TR) de la posición actual
I m pr im e la cadena de caracter es c 1 c2 ...cn
com enzando en la siguiente posición
I m pr im e la cadena de caracter es c 1 c2 ...cn
com enzando en la siguiente posición
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
E/S sin avance
En Fortran 77, cualquier sentencia read o write
involucra a registros completos. Hay ocasiones en
que resulta conveniente leer/escribir sólo parte de
un registro, y leer/escribir el resto más tarde. En
F90 esta capacidad la proporciona la E/S sin
avance
La E/S sin avance elimina la necesidad de que los
registros sean leídos como un todo y de que la
longitud de los registros sea conocida de
antemano. Se especifica mediante
advance=’NO
En la sentencia read o write e inhibe el avance
automático hasta el siguiente registro al ejecutar la
sentencia. Si se especifica
advance=’YES’
O no se ha especificado nada, entonces se utiliza
la forma normal (con avance) de E/S
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
E/S sin avance
Se puede especificar E/S con y sin avance en el
mismo registro o fichero. Una aplicación común de
esta posibilidad es escribir una pregunta en
pantalla sin usar avance, y leer la siguiente
posición en la pantalla. Por ejemplo:
write(*, ’("Tamaño? ")’, advance=’NO’)
read(*, ’(I5)’) size
A veces es útil determinar cuantos caracteres han
sido leídos en una entrada sin avance. Esto se
puede conseguir utilizando el especificador size (en
la sentencia read), que tiene la forma:
size=character_count
Al finalizar la lectura sin avance, a la variable
entera character_count se le asigna el número
de caracteres leídos, excluyendo caracteres de
relleno
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
E/S sin avance
Se puede detectar si una lectura sin avance lee
más allá del final de un registro utilizando el
especificador IOSTAT, que tiene la forma:
IOSTAT=io_status
Al finalizar una sentencia read, a io_status se le
asigna un valor que indica si se ha alcanzado un fin
de fichero o fin de registro.
Es necesario estudiar la documentación del
compilador que se utilice para comprobar el valor
de IOSTAT devuelto en estas situaciones
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Consulta de
la lista de E/S
Se utiliza para determinar la longitud de una lista de
elementos de salida sin formato. La forma es:
INQUIRE(IOLENGTH=length) output−list
La longitud puede usarse como valor para el
especificador RECL en una operación open
subsiguiente. Por ejemplo:
integer :: rec_len
...
INQUIRE(IOLENGTH=rec_len) name, title, &
age, address, tel
...
open(unit=1,file=’TEST’,RECL=rec_len, &
FORM=’UNFORMATTED’)
...
write(1) name, title, age, address, tel
...
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
NAMELIST
NAMELIST da la capacidad de agrupar juntas
un conjunto de variables para simplificar la E/S.
NAMELIST es una sentencia de especificación
y ha de aparecer antes que las sentencias
ejecutables. La forma general es:
NAMELIST/namelist−group−name/variable−
list
Se trata de de una característica del lenguaje
que debería evitarse siempre que sea posible
En sentencias read o write el nombre de lista
debe especificarse con el especificador NML o
puede sustituir al especificador de formato. No
se necesitan listas de E/S.
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
NAMELIST
Un registro de E/S para un grupo NAMELIST tiene
un formato específico:
&namelist−group−name var1=x, var2=y, var3=z
Es posible omitir elementos cuando se está
introduciendo datos y esos elementos no cambian.
Tampoco hay que introducir los elementos en el
orden especificado por la sentencia NAMELIST
El siguiente ejemplo muestra el grupo llamado
clothes:
integer :: size=2
character (len=4) :: colour(3) = &
(/’ red’,’pink’,’blue’/)
NAMELIST /clothes/ size, colour
write(*, NML = clothes)
La salida sería:
&CLOTHES size = 2, COLOUR =
redpinkblue/
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Descriptores de edición
Los descriptores de edición especifican
exactamente cómo se convertirán en cadenas
de caracteres los valores en un dispositivo de
salida o fichero interno o cómo se convierten
en cadenas de caracteres en un dispositivo de
entrada o fichero interno
Fortran90 posee los siguientes descriptores de
edición nuevos con respecto a F77:
EN (Engineering − ingeniería). Análogo a E
pero
con exponentes divisibles por 3
ES (Scientific). Análogo a E pero con el valor
antes del punto decimal en [1, 10]
B
Binario
O
Octal
Z
Hexadecimal
G
Descriptor Generalizado aplicable
a todos
los tipos intrínsecos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Descriptores de edición
El siguiente ejemplo muestra la diferencia entre los
descriptores de edición E, EN, ES y G
program e_en_es_g_compare
implicit none
real, dimension(4) :: &
x=(/1.234, −0.5, 0.00678, 98765.4/)
print ’(4E14.3/4EN14.3/4ES14.3/4G14.3)’,&
x, x, x, x
end program e_en_es_g_compare
La salida sería:
0.123E+01 −0.500E+00 0.678E−02 0.988E+05
1.234E+00 −500.000E−03 6.780E−03
98.765E+03
1.234E+00 −5.000E−01 6.780E−03 9.877E+04
1.23 −0.500 0.678E−02 0.988E+05
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Nuevos especificadores de
sentencias
Las sentencias INQUIRE, open, read y write no son
nuevas, pero se han añadido unos cuantos
especificadores nuevos:
INQUIRE
POSITION=ASIS, REWIND, APPEND o UNDEFINED
Indica la posición en el fichero tal como
se especificó en la sentencia open
ACTION=read, write, READWRITE o UNDEFINED
DELIM=APOSTROPHE, QUOTE, NONE o UNDEFINED
Indica el carácter utilizado para
delimitar constantes de caracteres con
E/S dirigida por listas o por NAMELIST.
Por defecto es NONE (ninguna)
PAD=YES o NO
‘ ES’ signfica que el registro de entrada
ha de rellenarse con blancos. El
defecto es PAD=‘ ES’
READWRITE=YES, NO o UNKNOWN
Indica si para un fichero está permitido
o no leer y escribir o no está
determinado
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Nuevos especificadores de
sentencias
INQUIRE
read=YES, NO o UNKNOWN
Indica si para un fichero está permitido
o no leer o no está determinado
write=YES, NO o UNKNOWN
Indica si para un fichero está permitido
o no escribir o no está determinado
open
Los especificadores POSITION, ACTION,
DELIM y PAD tienen los mismos valores y
significados que con INQUIRE. Hay un
valor adicional:
STATUS=REPLACE
Si el fichero a abrir no existe, se crea,
y si existe se borra y se crea uno
nuevo
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Nuevos especificadores de
sentencias
read/write
NML=namelist_name
Se utiliza en lugar del especificador de
formato cuando se usa un grupo NAMELIST
advance=YES o NO
read
EOR=label
Transfiere el control a la sentencia
etiquetada cuando ocurre una condición
de fin de registro
size=character_count
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
7
Procedimientos
intrínsecos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
Índice
7.1 − Procedimientos elementales
7.2 − Funciones de consulta
7.3 − Funciones de transformación
7.4 − Subrutinas intrínsecas no elementales
7.5 − Procedimientos intrínsecos para vectores
7.6 − Ejercicios
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Se especifican para parámetros escalares,
pero también son aplicables a parámetros
vectoriales compatibles aplicando el
procedimiento elemento a elemento
Funciones elementales
Funciones Numéricas:
ceiling(A)
El menor entero mayor que A
floor(A)
El mayor entero que no exceda A
modulo(A, P)
Resto de A/P (ambos reales o enteros)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Funciones de caracteres:
achar(I)
El carácter en la posición I de la
secuencia
adjustl(string)
Ajusta a la izquierda cambiando blancos
adjustr(string)
Ajusta a la derecha cambiando blancos
iachar(C)
Posición del carácter C en la secuencia
index(string, substring [,back])
Posición de comienzo de substring dentro
de string. Si hay más de una subcadena
se retorna la posición de la primera (o
de la última si back es true)
len_trim(string)
Longitud de la cadena eliminando blancos
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Funciones de caracteres:
scan(string, SET [,back])
Índice del carácter más a la izquierda
(más a la derecha si back es true) de
la cadena que pertenece a SET. Cero si
ninguno pertenece
verify(string, SET [,back])
La posición del carácter más a la
izquierda (más a la derecha si back es
true) de la cadena que no está en SET.
Cero si todos están en SET
Funciones de manipulación de bits
BTEST(I, POS)
True si el bit POS del entero I es 1
IAND(I, J)
Y lógico de los bits de I y J
IBCLR(I, POS)
Pone a 0 el bit POS de I
IBITS(I, POS, len)
Extrae una secuencia de len bits de I
comenzando en el bit POS
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Funciones de manipulación de bits
IBSET(I,POS)
Pone a 1 el bit POS de I
IEOR(I,J)
O−Exclusiva lógica de los bits de I, J
IOR(I,J)
O−Inclusiva lógica de los bits de I, J
ISHFT(I,SHIFT)
Valor de I con sus bits rotados SHIFT
posiciones a la izquierda (derecha si
es negativo) y con ceros por el extremo
opuesto
ISHFTC(I,SHIFT[,size])
Valor de I con una rotación circular de
sus size bits más a la derecha rotados
SHIFT posiciones a la izquierda
(derecha si es negativo)
NOT(I)
Complemento lógito de todos los bits de I
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Funciones de valores de clase
selected_int_kind(R)
Clase del parámetro de tipo para el rango
de exponente dado. Se retorna −1 si no
está disponbile esa clase
selected_real_kind(P,R)
Clase del parámetro de tipo para la
precisión y rango de exponente dados.
Se retorna −1 si la precisión no está
disponble, −2 si no lo está el rango y −
3 si no lo está ninguno de los dos
Funciones de manejo de Punto flotante
exponent(X)
Exponente de X
fraction(X)
Parte fraccional de X
nearest(X, S)
El siguiente número diferente (en la
máquina en cuestión) en la dirección
dada por el signo de S
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos elementales
Funciones de manejo de Punto flotante
RRSPACING(X)
El recíproco del espaciado relativo de
los números más próximos a X
SCALE(X I)
Convierte X a I (real a entero)
SET_exponent(X, I)
Real cuyo signo y parte fraccional son
los de X y cuya parte de exponente es I
SPACING(X)
Espaciado absoluto de los números
cercanos a X
Funciones lógicas
logical(L [,kind])
Convierte entre clases de números lógicos
Subrutina elemental
call MVBITS(FROM, FROMPOS, len, TO,TOPOS)
Copia len bits de FROM comenzando en la
posición FROMPOS hasta la posición TO,
comenzando en la posición TOPOS
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones de consulta
associated(pointer[,target])
True si el puntero está asociado con el
destino. Si target aparece, sólo es
true si está asociado con el destino
especificado
bit_size(I)
Número máximo de bits que pueden
almacenarse en un entero
kind(X)
Valor de clase de tipo para X
present(A)
True si el parámetro opcional A ha sido
pasado a la subrutina
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones de consulta
Funciones de consulta numéricas
digits(X)
Número de dígitos significativos en la
representación de X
epsilon(X)
Número que es casi despreciable comparado
con 1 en la representación interna de
números del tipo de X
huge(X)
El mayor número en la representación de
números del tipo de X
maxexponent(X)
Máximo exponente en la representación de
números del tipo de X
minexponent(X)
Mínimo exponente en la representación de
números del tipo de X
precision(X)
Precisión decimal en la representación de
X
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones de consulta
Funciones de consulta numéricas
radix(X)
Base de la representación de números del
tipo de X
range(X)
Rango del exponente decimal en la
representación que incluye X de tipo
entero, real y complejo
tiny(X)
El menor número positivo en la
representación de números del tipo de X
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Funciones de Transformación
repeat(string, ncopias)
Concatena ncopias de string
transfer(fuente, MOLD [,size])
La misma representación física que fuente
pero de tipo MOLD
trim(string)
Elimina los espacios en blanco sobrantes
de string
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Subrutinas intrínsecas no
elementales
call
date_and_time([DATE][,TIME][,ZONE][VALUES])
Leer la fecha y la hora del reloj interno
random_number(HARVEST)
Devuelve un número pseudoaleatorio en el
rango [0, 1)
random_seed([size][,PUT][,GET])
Inicializa o reinicializa el generador de
números pseudoaleatorios
system_clock([count][,count_RATE][count_max])
Devuelve un entero del reloj interno
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
para vectores
Reducciones
ALL(MASK[, DIM])
True si todos los elementos son true
ANY(MASK[, DIM])
True si algún elemento es true
COUNT(MASK [,DIM])
Número de elementos true
MAXVAL(ARRAY [,DIM] [,MASK])
Valor del mayor elemento
MINVAL(ARRAY [,DIM] [,MASK])
Valor del menor elemento
PRODUCT(ARRAY [,DIM] [,MASK])
Producto de los elementos del vector
SUM(ARRAY [,DIM] [,MASK])
Suma de los elementos del vector
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
para vectores
Consulta
allocated(ARRAY)
true si el vector ha sido alojado
lbound(ARRAY[,DIM])
Límites inferiores del vector
shape(fuente)
Forma del vector (o escalar)
size(ARRAY[,DIM])
Tamaño del vector
ubound(ARRAY[,DIM])
Límites superiores del vector
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
para vectores
Construcción
MERGE(TSOURCE,FSOURCE,MASK)
Mezcla vectores de acuerdo a MASK
pack(ARRAY,MASK[,VECTOR])
Empaqueta elementos en VECTOR de acuerdo
a MASK
SPREAD(fuente,DIM,ncopias)
Construye un vector duplicando una
sección de otro
UNPACK(VECTOR,MASK,FIELD)
Desempaqueta elementos de vector de
acuerdo a MASK
Cambio de forma
reshape(fuente,shape[,PAD][,ORDER])
Cambia la forma de un vector
Posición en un vector
MAXLOC(ARRAY[,MASK])
Posición del elemento máximo
MINLOC(ARRAY[,MASK])
Posición del elemento mínimo
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos intrínsecos
para vectores
Manipulación de vectores
CSHIFT(ARRAY,SHIFT[,DIM])
Realiza una rotación circular
EOSHIFT(ARRAY,SHIFT[,BOUNDARY][,DIM])
Realiza una rotación sin fin
TRANSPOSE(MATRIX)
Traspone la matriz
Aritmética vectorial y matricial
DOT_PRODUCT(VECTOR_A,VECTOR_B)
Producto escalar
MATMUL(MATRIX_A, MATRIX_B)
Producto de matrices
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
8
Características
redundantes con
respecto a
Fortran77
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Características redundantes
Índice
8.1 − Forma del código fuente
8.2 − Datos
8.3 − Control
8.4 − Procedimientos
8.5 − Entrada/Salida
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Características Redundantes
Fortran90 incluye características redundantes
(deprecated) que se pueden seguir usando
puesto que no está previsto que desaparezcan
en la siguiente revisión, pero se desaconseja
su utilización en programas nuevos puesto que
en el futuro sí es posible que desaparezcan
Estas características redundantes se clasifican
dentro de 5 categorías: forma del código
fuente, datos, control, procedimientos y E/S
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Forma del código fuente
El formato fijo, que estaba basado en el
aspecto de una tarjeta perforada ha sido
sustituido por el formato libre y éste debería
usarse en los programas nuevos. Es posible
hacer modificaciones sencillas al formato fijo
para producir código que es legal tanto en
formato libre como fijo
Se recomienda la utilización de módulos en
lugar de usar líneas INCLUDE. Esta directiva
se utilizaba para incluir ficheros texto en un
lugar específico
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Datos
Fortran 77 tiene dos formas de variables y
constantes reales: real y double precision. Han sido
sustituidas por el concepto de tipos de datos
parametrizados que dan mayor portabilidad
numérica. No debería usarse double precision en
programas nuevos
El peligroso concepto de tipo implícito y la
sentencia IMPLICIT no deberían usarse. Se
aconseja el uso de implicit none
Se recomienda el uso de la nueva forma de
declarar variables usando dos puntos (::) entre el
tipo y la lista de variables. Asimismo se recomienda
usar los atributos parameter, dimension, etc. en la
declaración más que en forma de sentencias
Generalmente no se necesita la sentencia DATA
puesto que las variables pueden ser inicializadas
en una sentencia de declaración
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Datos
Los bloques COMMON y BLOCK DATA no
deberían usarse puesto que el uso de módulos
elimina la necesidad de su utilización. De forma
análoga, la sentencia EQUIVALENCE ha dejado de
ser necesaria por la introducción de los módulos,
manejo dinámico de memoria, punteros y la función
intrínseca transfer
Se recomienda no utilizar nunca el atributo
SEQUENCE
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Control
Características obsoletas de F77 son:
Sentencia if aritmética
Terminación compartida de un do. Terminación de
un do en una sentencia diferente de continue o end
do
Variables do y de control de expresiones de tipo real
o double precision
Sentencias assign y GO TO asignados
Saltos hacia un end if desde fuera de un bloque if
return alternado
Sentencia pause
Estas características no deberían usarse en
códigos nuevos o revisados. Pueden reemplazarse
por sentencias if, do, case, exit y cycle
Con la introducción de modernas estructuras de
control y de especificaciones de cadenas de
caracteres la necesidad de etiquetas es redundante
El constructo do y las sentencias exit y cycle
sustituyen el uso de la sentencia continue al final
de un bucle do
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Control
Las sentencias GO TO y GO TO calculados
deberían sustituirse por los constructos if, do y
case y las sentencias exit y cycle
Se puede utilizar el bucle do combinado con la
sentencia exit como forma equivalente a los bucles
do while
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Procedimientos
Las funciones intrínsecas con nombres
específicos para diferentes tipos de datos se
han sustituido por versiones genéricas. Aún se
necesitan nombres específicos cuando una
función intrínseca se utiliza como parámetro
actual en una llamada
La sentencia ENTRY permite que un
procedimiento tenga más de un punto de
entrada. En F90 es innecesaria puesto que en
un módulo cada punto de entrada se convierte
en un procedimiento de módulo
La utilización de procedimientos de módulo y
procedimientos internos hacen innecesarios
los procedimientos externos. Los
procedimientos externos y la sentencia
external son redundantes en F90
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Entrada / Salida
Los especificadores de formato asignados
deberían sustituirse por especificaciones de
cadenas de caracteres
Los especificadores end, EOR y ERR se
utilizan cuando ocurren condiciones anómalas
en entrada/salida. Se recomienda el uso de
IOSTAT en lugar de éstos
La entrada/salida usando Namelist es una
característica mal diseñada y se desaconseja
su utilización
Se desaconseja la utilización de 6 descriptores
de edición: D, BN, BZ, P, G y X
El descriptor de edición D se sustituye por el E
y los BN y BZ por el especificador BLANK
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Entrada / Salida
El descriptor de edición P permite que los
datos numéricos se escalen tanto al hacer
entrada o salida. Esto podría conducir a
confusión y por tanto se desaconseja
El descriptor de edición G es un descriptor
generalizado que se puede utilizar al leer o
escribir valores de cualquier tipo intrínseco. Se
aconseja la utilización de los descritptores I, E,
EN, F, L o A puesto que a través de éstos se
comprueba que los tipos de datos son los
correctos
El descritptor de edición X tiene el mismo
efecto que el TR y se recomienda el uso de
este último
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
9
Desarrollos
futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Contenidos del Curso
1.− Introducción
2.− Código fuente, tipos y estructuras de control
3.− Procedimientos y Módulos
4.− Proceso de vectores
5.− Punteros
6.− Nuevas características de entrada/salida
7.− Procedimientos intrínsecos
8.− Características redundantes
9.− Desarrollos futuros
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Desarrollos Futuros
Índice
9.1 − Fortran95
9.2 − Arquitecturas paralelas
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Fortran95
Fortran95 se esperaba que hubiera sido
simplemente una actualización de F90 consistente
fundamentalmente en clarificaciones y correcciones
de aquél.
El mayor cambio significativo se espera que sea
Fortran2000
Sin embargo Fortran95 debería suministrar algunas
características nuevas:
Sentencia y constructo FORALL
FORALL permite asignaciones vectoriales más
simples:
FORALL (i=1:n) a(i,i)=i
FORALL (i=1:n,j=1:n,y(i,j)/=0 .and. &
i/=j) x(i,j)=1.0/y(i,j)
FORALL (i=1:n)
a(i,i)=i
b(i)=i*i
end
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Fortran95
El atributo PURE
que permite una utilización segura de procedimientos
en las sentencias FORALL
Funciones intrínsecas para la consulta del tiempo
de CPU:
call CPU_TIME(t1)
Parámetros dinámicos en los subprogramas
where anidados:
where (mask1)
...
where (mask2)
...
elsewhere
...
end where
elsewhere
...
end where
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Fortran95
Inicialización de entidades
Estado inicial para punteros y tipos:
real, pointer :: P(:)=>NULL()
type string
character, pointer :: ch(:)=>NULL()
ENDTYPE
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Arquitecturas paralelas
Es muy importante en la actualidad que un nuevo
estándar como lenguaje de programación permita
una compilación y ejecución eficiente tanto en
supercomputadores como en arquitecturas
convencionales.
F90 se dice que es eficiente en arquitecturas
convencionales y vectoriales, pero es menos
eficiente en arquitecturas paralelas. Sin embargo
las tendencias arquitectónicas se han desplazado
desde las máquinas vectoriales a los computadores
masivamente paralelos. Este interés en
arquitecturas paralelas ha conducido al desarrollo
de tres estándares de facto:
High Performance Fortran (HPF)
OpenMP
Message Passing Interface (MPI)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
HPF
El objetivo de High Performance Fortran (HPF) es
suministrar una serie de extensiones a Fortran90
para soportar:
Expresión de paralelismo de datos
Máxima eficiencia sobre máquinas MIMD y SIMD
con acceso no uniforme a memoria
Sintonización de código para diferentes
arquitecturas
Desviación mínima de otros estándares de
programación
Definir interfaces abiertas a otros lenguajes
Potenciar la incorporación de conocimientos de
la comunidad científica de computación de altas
prestaciones
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
HPF
Fotran 90 soporta paralelismo de datos a través de
las operaciones sobre vectores y funciones
intrínsecas sobre vectores. HPF extiende este
soporte con:
Directivas de compilación para alineamiento y
distribución de datos
Características de ejecucón concurrente
utilizando la sentencia FORALL
La directiva INDEPENDENT que permite al
programador informar al compilador del
comportamiento de un bucle do o de una
sentencia FORALL
Funciones intrínsecas para consultar detalles
específicos de la arquitectura
Una librería de rutinas para soportar
operaciones globales
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
OpenMP
La API de OpenMP da soporte para programación
en paralelo en diversas plataformas de memoria
compartida tanto en Fortran como en C/C++
Definida de forma conjunta por un grupo de
fabricantes de software y hardware, OpenMP es un
modelo portable y escalable que suministra a los
programadores en paralelo una interface simple y
flexible para el desarrollo de aplicaciones paralelas.
http://www.openmp.org/h
ttp://www.compunity.org/
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Un ejemplo en OpenMP
* Copy new solution into old
!$omp parallel
!$omp do
do j=1,m
do i=1,n
uold(i,j) = u(i,j)
enddo
enddo
* Compute stencil, residual, & update
!$omp do private(resid) reduction(+:error)
do j = 2,m−1
do i = 2,n−1
* Evaluate residual
resid = (ax*(uold(i−1,j) + uold(i+1,j))
&
+ ay*(uold(i,j−1) + uold(i,j+1))
&
+ b * uold(i,j) − f(i,j))/b
* Update solution
u(i,j) = uold(i,j) − omega * resid
* Accumulate residual error
error = error + resid*resid
end do
enddo
!$omp enddo nowait
!$omp end parallel
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
MPI
MPI (Message Passing Interface) es un estándar
propuesto para:
Paso de mensajes explícito
Programas de aplicaciones
Arquitecturas MIMD de memoria distribuida
Redes de estaciones de trabajo
Se necesita un estándar de este tipo por diferentes
motivos:
Portabilidad y facilidad de uso
Es el momento adecuado para definir un
estándar en este campo
Construcción de librerías de programas
Es un prerequisito para el desarrollo de la
industria del software concurrente
Suministra a los vendedores de hardware con un
conjunto bien definido de rutinas que han de
implementar eficientemente
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
MPI
MPI contiene:
Paso de mensajes punto a punto
Rutinas de comunicación colectiva
Para movimiento de datos (versiones uno a todos
y todos a todos de las rutinas de broadcast,
scatter y gather)
Cómputos globales (rutinas reduce y scan)
Soporte para grupos de procesadores y para
contextos de comunicaciones
Las comunicaciones combinan contextos y
grupos para la seguridad de mensajes y de
threads de ejecución
Soporte para topologías de aplicación (mallas y
grafos)
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002
Referencias
Máquina de cálculo científico de la ULL:
http://www.ccti.ull.es/cpu/
Fortran 77
http://www.ccti.ull.es/cpu/f77/f77.htm
Fortran 90
http://www.ccti.ull.es/cpu/f90/f90.htm
Procedimientos intrínsecos en Fortran 90
http://www.ccti.ull.es/cpu/f90/f90_refer
ence_manual_9.txt
HPF
http://www.ccti.ull.es/cpu/hpf/hpf.htm
MPI
http://www−unix.mcs.anl.gov/mpi/index.html
Introducción a las Herramientas Informáticas Unix para el Desarrollo de la Investigación.
2002

Documentos relacionados