정보
-
업무명 : 포트란을 활용한 인터페이스 : 개요, 외부 프로시저, 내부 프로시저, INTENT, 모듈
-
작성자 : 이상호
-
작성일 : 2020-12-03
-
설 명 :
-
수정이력 :
내용
[개요]
-
안녕하세요? 웹 개발 및 연구 개발을 담당하고 있는 해솔입니다.
-
Fortran (포트란)은 수식 (Formular) 변환기 (Translator)의 약자로 과학 계산용으로 주고 사용되는 언어입니다.
-
복잡한 계산 수행 성능이 뛰어나 공학과 자연과학 등 특정분야에 주로 사용되며 기상 데이터 처리를 위해 널리 사용되고 있습니다.
-
오늘 포스팅은 포트란을 활용한 인터페이스를 소개합니다.
[특징]
-
기상 데이터 처리를 위해서 포트란 (Fortran)기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 기술서
[기능]
-
개 요
-
외부 프로시저
-
내부 프로시저
-
INTENT
-
모듈
[활용 자료]
-
없음
[자료 처리 방안 및 활용 분석 기법]
-
없음
[사용법]
-
없음
[사용 OS]
-
Linux (CentOS v7.8)
[사용 언어]
-
gfortran v4.8.5
세부 내용
개요
-
서브루틴과 함수를 말하는 프로시저는 메인 프로그램에 포함돼 있는 내부 프로시저와 메인 프로그램이나 모듈에 포함되지 않고 독립적으로 존재하는 외부프로시저 그리고 모듈 프로시저가 있습니다.
-
메인 프로그램과 외부 프로시저는 서로 분리된 독립적인 프로그램 단위입니다.
-
메인 프로그램과 프로시저는 다른 프로시저에서 지역적으로 선언된 변수들에 접근 할 수 없으며 마찬가지로 외부 프로시저는 메인 프로그램에 선언된 변수에 접근 할 수 없습니다.
-
한 프로그램 단위에서 다른 단위로 정보를 전하기 위해서 함수에 인수를 전달하여야만 가능합니다.
-
내부 프로시저는 하나의 프로그램 단위에 포함돼 있으므로 프로시저에 대한 참조에 대해서 인수의 개수와 타입 등의 속성들과 함수의 리턴 값 등이 바르게 사용 되었는지를 컴파일러가 점검할 수 있습니다.
-
비슷하게 모듈에 포함되는 모듈 프로시저 역시 모듈내의 문장으로 참조되거나 모듈에 대한 USE문을 사용함으로써 컴파일러가 인수와 결과 등이 올바른지 점검할 수 있도록 할 수 있습니다.
-
이와 같이 모듈 또는 내부 프로시저는 기본적으로 명시적 인터페이스 (explicit interface)를 가져 인수의 사용과 리턴 값 등에 대해 컴파일러가 오류를 점검할 수 있습니다.
-
반면 외부 프로시저는 메인 프로그램이나 다른 프로그램 단위와 분리되어 독립적으로 존재하므로 컴파일러가 프로시저에 대한 참조의 오류 여부를 점검할 수 없습니다.
-
외부 프로시저는 기본적으로 암시적 인터페이스 (implicit interface)를 가집니다.
외부 프로시저
-
포트란에서는 인터페이스 블록(interface block)을 이용하여 외부 프로시저에 대해 명시적 인터페이스를 제공합니다.
-
인터페이스 블록은 컴파일러에게 프로시저 인수의 모양, 형태 등의 속성을 알려 주어 프로시저에 대한 참조의 오류 여부를 점검할 수 있도록 해줍니다.
-
인터페이스 블록의 일반적인 형태는 다음과 같습니다.
PROGRAM exercise
INTERFACE
SUBROUTINE squrt(a,n)
REAL :: a(n)
END SUBROUTINE
END INTERFACE
INTEGER, PARAMETER :: m = 100
REAL :: q(m) q=71
CALL squrt(q,m)
END PROGRAM exercise
-
이렇게 인터페이스 블록을 사용하여 외부프로시저에 대한 명시적 인터페이스를 정의해주면 다음과 같은 예제처럼 컴파일 단계에서 에러가 발생해 의도치 않은 코딩 실수를 줄일 수 있습니다.
PROGRAM inter
INTERFACE
REAL FUNCTION ratio(x, y)
REAL::x, y
END FUNCTION ratio
END INTERFACE
INTEGER :: i=3, j=25
PRINT *,'The ratio is ',ratio(i,j)
END PROGRAM inter
REAL FUNCTION ratio(x, y)
REAL:: x, y
ratio=x/y
END FUNCTION ratio
-
위 예제는 메인프로그램과 외부 프로시저의 인수타입이 일치 하지 않아 컴파일 단계에서 다음과 같은 에러가 발생합니다.
"test.f", line 9.34: 1513-061 (S) Actual argument attributes do not match those specified by
an accessible explicit interface.
** inter === End of Compilation 1 ===
** ratio === End of Compilation 2 ===
1501-511 Compilation failed for file test.f
내부 프로시저
-
프로그램 단위 내에 함수나 서브루틴 같은 프로시저가 올 수 있으며 이를 내부 프로시저라 합니다.
-
모든 내부 프로시저는 그것을 포함하는 프로그램 단위의 맨 마지막 부분에서 CONTAINS문 다음에 위치해야 합니다.
-
외부 프로시저와 그 형태는 동일하나 단지 END문 다음에 FUNCTION 또는 SUBROUTINE을 반드시 붙여 주어야 한다는 점이 다릅니다.
-
내부 프로시저를 포함하는 프로그램 단위에서 선언된 변수는 내부 프로시저에서 접근할 수 있으며 내부 프로시저에서 다시 정의할 수도 있습니다.
-
다음은 외부 프로시저에서 작성된 예제에서 인터페이스블록을 사용하지 않고 내부 프로시저를 이용하도록 수정 한 것입니다.
PROGRAM explicit
INTEGER :: i=3, j=25
PRINT *,'The ratio is ',ratio(i,j)
CONTAINS
REAL FUNCTION ratio(x, y)
REAL:: x, y
ratio=x/y
END FUNCTION ratio
END PROGRAM explicit
-
내부 프로시저는 명시적 인터페이스가 기본이므로 위 예제는 다음과 같이 컴파일러에 의해 오류가 발견됩니다.
"inter.f", line 3.31: 1513-061 (S) Actual argument attributes do not match those specified by
an accessible explicit interface.
** inter === End of Compilation 1 ===
1501-511 Compilation failed for file inter.f.
INTENT
-
포트란에서는 보다 효율적인 컴파일 성능향상을 위해 INTENT 속성(attribute)을 이용해 프로시저내의 더미 인수들에 대한 계획된 이용(in, out, 또는 inout)을 컴파일러에게 알려 줄 수 있습니다.
-
INTENT(in) : 프로시저에 들어와서 나갈 때까지 값이 변함없는 인수
-
INTENT(out) : 프로시저 내에서 값을 할당 받을 때까지 사용되지 않는 인수
-
INTENT(inout) : 프로시저에 들어와 사용되고 값을 새로이 할당 받아 그 결과를 호출한 프로그램에되돌려 주는 인수
-
SUBROUTINE meron(a, b, c, m, n)
REAL, DIMENSION(n, n), INTENT(IN) :: a
REAL, DIMENSION(m, m) :: b, c
INTENT(out) :: b
INTENT(inout) :: c
c = SQRT(c)
b = c + SUM(a)
END
! 인수 a는 프로시저 내에서 값이 변하지 않는다.
! 인수 b의 값은 프로시저 내에서 값을 할당 받을 때까지 사용되지 않는다.
! 인수 c는 프로시저 내에서 사용되고 값이 새로 할당된다.
-
포트란 프로그램에서 INTENT 속성을 반드시 사용해야 하는 것은 아닙니다.
-
그러나 INTENT 속성을 사용함으로써 컴파일러는 코딩 오류 점검이 빨라지고 프로그램의 안정성을 높일 수 있습니다.
-
만약 INTENT(in) 속성의 인수가 값을 할당 받거나 INTENT(out) 속성의 인수가 새로운 값을 할당 받지 않는다면 컴파일 단계에서 에러가 발생하게 될 것입니다.
-
다음 예제처럼 INTENT 속성을 잘못 지정해 준 경우 컴파일 단계에서 에러가 발생 할 것 입니다.
PROGRAM intent_err
REAL :: x, y
y = 5.
CALL mistaken(x, y)
PRINT *, x
CONTAINS
SUBROUTINE miserr(a, b)
IMPLICIT NONE
REAL, INTENT(in) :: a
REAL, INTENT(out) :: b
a = 2*b
END SUBROUTINE miserr
END PROGRAM intent_err
모듈
-
모듈은 타입선언, 서브프로그램, 새로운 데이터 타입선언 등을 하나로 묶어 정의 할 수 있는 프로그램 단위로서 Fortran90에 새롭게 추가된 기능입니다.
-
사용자는 모듈을 사용해서 보다 신뢰성 있고, 재사용이 쉬우며 작성하기도 쉬운 객체 기반의 코드를 작성할 수 있습니다.
-
모든 프로그램 단위는 USE문을 이용해 모듈을 첨부할 수 있고 그렇게 해서 그 모듈이 제공하는 기능을이용할 수 있습니다.
-
Global Object Declaration
-
모듈은 Fortran77의 COMMON과 INCLUDE문을 대신해 사용됩니다. 글로벌 데이터 설정이 필요한 경우 하나의 모듈에 그 데이터를 정의해 둡니다.
-
이렇게 모듈에 정의된 데이터는 그 모듈을 첨부하는 어떤 프로그램 단위에서도 사용될 수 있으며 그 값은 각각의 모듈 첨부에 대해 일정하게 유지됩니다.
-
-
Interface Declaration
-
인터페이스에 대한 정의도 모듈에 해두고 명시적 인터페이스가 필요할 때마다 모듈을 첨부해 사용할 수 있습니다.
-
-
Procedure Declaration
-
프로시저를 모듈에 정의해서 그 모듈을 첨부한 어떤 프로그램 단위에서도 사용할 수 있도록 합니다.
-
-
Controlled Object Declaration
-
접근 구문을 이용해 모듈에서 선언된 변수, 프로시저, 연산자 등의 노출 정도 (visibility)를 제어할 수 있습니다.
-
-
Packaged of Whole Sets of Facilities
-
사용자 정의 타입, 프로시저, 연산자, generic 인터페이스 등을 정의하고 하나로 묶을 수 있어 간단한 객체 지향성을 제공합니다.
-
-
모듈 프로그램 단위의 기본 모양은 다음과 같습니다.
MODULE <module name>
<declarations and specifications statements>
[CONTAINS
<definitions of module procedures>]
END [MODULE [<module name>]]
<module name>은 USE문에 사용되는 이름이고 파일명과 같을 필요는 없습니다.
-
Global data
-
글로벌 변수를 모듈에 정의해 두면 이를 필요로 하는 프로그램은 USE문을 이용해 모듈을 첨부하여 글로벌 변수에 접근할 수 있습니다.
-
MODULE global
REAL :: a, b, c
INTEGER :: i, j, k
END MODULE global
-
위와 같이 정의된 모듈 globals를 첨부시키기 위해 프로그램 단위는 다음과 같이 USE문을 사용할 수 있다.
-
단, USE문은 프로그램 단위에서 제일 위에 위치해야 합니다.
USE globals ! 모든 변수 접근 가능
USE globals, ONLY: a, c ! a,c 특정 변수만 사용 가능
USE globals, r => a, s => b ! 지역변수 r,s를 이용하여 a,b 변수 접근 가능
-
Procedure
-
모듈은 다른 프로그램 단위가 접근할 수 있는 프로시저를 포함할 수 있습니다.
-
모듈 내에 위치하는 모듈 프로시저도 내부 프로시저와 같이 다음과 같은 점을 제외하고는 외부 프로시저와 동일한 모양을 가집니다.
-
CONTAINS 문 다음에 위치 해야 합니다.
-
END 문 다음에 FUNCTION 또는 SUBROUTINE이 있어야 합니다.
-
-
MODULE module_pro
TYPE point
REAL :: x, y
END TYPE point
CONTAINS
FUNCTION addpoints (p, q)
TYPE (point), INTENT(IN) :: p, q
TYPE (point) :: addpoints
addpoints%x = p%x + q%x
addpoints%y = p%y + q%y
END FUNCTION addpoints
END MODULE module_pro
PROGRAM sum_p
USE module_pro
TYPE (point) :: px, py, pz
px = point(1., 2.)
py = point(2., 5.)
pz = addpoints(px, py)
PRINT*, ' pz =', pz
END
참고 문헌
[논문]
- 없음
[보고서]
- 없음
[URL]
- Fortran을 활용한 분석, 날씨마루 (기상기후 빅데이터 분석 플랫폼), bd.kma.go.kr/kma2020/dta/edu/KBP57200_Fortran.do?pageNum=5&menuCd=F040304000.
문의사항
[기상학/프로그래밍 언어]
- sangho.lee.1990@gmail.com
[해양학/천문학/빅데이터]
- saimang0804@gmail.com
'프로그래밍 언어 > Fortran' 카테고리의 다른 글
[Fortran] 인텔 (intel) 포트란 도움말 정보 (ifort --help) (0) | 2021.02.24 |
---|---|
[Fortran] 포트란을 활용한 배열 : 개요, 정합성 요구, 배열 작성자 (constructor), 마스크된 배열 할당 (where문), 동적배열, 배열함수 (0) | 2020.11.26 |
[Fortran] 포트란 기초 및 활용 문서 (4) | 2020.11.17 |
[Fortran] 포트란을 활용한 에러 : 개요, NaN and Inf3, 예외 처리 (Exception), 에러 종류와 예시 (0) | 2020.11.11 |
[Fortran] 포트란을 활용한 기초 2 : 상수,키워드, 기본 제어입출력, 연산자 (논리, 관계, IF, CASE, DO, CYCLE) (0) | 2020.11.10 |
최근댓글