Using Modules for Data and Procedure Sharing in Fortran - Prof. Rodman, Study notes of Computer Science

A demonstration of how to use modules in fortran for sharing data and procedures among program units. It includes examples of creating a module, using it in a program, and adding subroutines and functions to the module. It also discusses the benefits of using modules, such as explicit interfacing and the ability to use the same data and procedures in multiple program units.

Typology: Study notes

Pre 2010

Uploaded on 03/24/2009

kmcrippe
kmcrippe 🇺🇸

9 documents

1 / 15

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
(All DEMOs work 3/24/2009)
Lab 8: Modules
1. Sharing Data
Remember when you were little and your mother encouraged you
to “share your toys.” Sharing, we learn at a young age, is
important. Your mother was right!
Fortran is very much about sharing. You share the compiler and
you share the library of intrinsic functions. If you need the cosine
of some angle you don’t have to write a Taylor series subroutine to
compute it. You take advantage of the fact that someone once did,
and you get to use it.
This sharing is public. Everyone has access to it. But sharing can
be private, too, and in the most extreme case, private to one person,
you, the programmer.
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Partial preview of the text

Download Using Modules for Data and Procedure Sharing in Fortran - Prof. Rodman and more Study notes Computer Science in PDF only on Docsity!

(All DEMOs work 3/24/2009) Lab 8: Modules

1. Sharing Data Remember when you were little and your mother encouraged you to “share your toys.” Sharing, we learn at a young age, is important. Your mother was right! Fortran is very much about sharing. You share the compiler and you share the library of intrinsic functions. If you need the cosine of some angle you don’t have to write a Taylor series subroutine to compute it. You take advantage of the fact that someone once did, and you get to use it. This sharing is public. Everyone has access to it. But sharing can be private, too, and in the most extreme case, private to one person, you, the programmer.

Suppose you have private data, perhaps a cryptographic key, and you have lots of programs that require access to that data. You can create a personal library that contains that data, and make that library available to every one of your programs. Such a collection of data is “shelved” in a MODULE. Suppose your secret 8-digit key is 0-1-1-2-3-5-8-13, and you don’t want it showing up in every program that uses it. You put it in a module: MODULE key IMPLICIT NONE SAVE INTEGER, DIMENSION(8)::mykey=(/0,1,1,2,3,5,8,13/) END MODULE key We can compile this as it stands: Suppose it is stored in Mod.f95. Then: f95 –c Mod.f This produces Mod.o DEMO IN CLASS

Let’s add a subroutine and a function to the driver program and show how the data can be shared among all these program units: FUNCTION add_up( ) USE key IMPLICIT NONE INTEGER:: add_up, i add_up= DO i=1, add_up=add_up + mykey(i) END DO END FUNCTION add_up And we add this to our program with one additional WRITE stmt. PROGRAM test_module USE key IMPLICIT NONE INTEGER:: i, add_up WRITE(,10) (mykey(i), i=1,8) WRITE(,) 'Sum = ', add_up() 10 FORMAT(10x, 8I3) END PROGRAM test_module !************************ FUNCTION add_up( ) USE key IMPLICIT NONE INTEGER:: add_up, i*

add_up= DO i=1, add_up=add_up + mykey(i) END DO END FUNCTION add_up And we compile this whole thing: f95 ModDriverFunc.f95 –o ModDriverFunc.exe ModTest.o DEMO

And put this all together, with a call to the subroutine: PROGRAM test_module USE key IMPLICIT NONE INTEGER::i, add_up WRITE(,10) (mykey(i), i=1,8) WRITE(,) 'Sum = ', add_up() CALL reverse( ) 10 FORMAT(10x, 8I3) END PROGRAM test_module !!!!!!!!!!!!!!!!!!! FUNCTION add_up() USE key IMPLICIT NONE INTEGER:: add_up, i add_up= DO i=1, add_up=add_up + mykey(i) END DO END FUNCTION add_up !!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE reverse ( ) USE key IMPLICIT NONE INTEGER, DIMENSION(8) :: r_key INTEGER i DO i=1, r_key(9-i)=mykey(i) END DO WRITE(,11) (r_key(i), i=1,8) 11 FORMAT(10x, 8I3) END SUBROUTINE reverse**

We compile and run this: f95 ModDriverFuncSubr.f95 –o ModDriverFuncSubr.exe Mod.o

2. Module Procedures In addition to data, modules may also contain complete subroutines and functions known as module procedures. These procedures are compiled as part of the module and made available to a program unit by including the USE statement containing the module name. Module procedures must come after all data declarations in the module and must be proceeded by a CONTAINS statement. As used above, function add_up and subroutine reverse are themselves external procedures. External procedures do not provide the compiler with an explicit interface , additional information that the compiler can use to cross check how the variables in the calling sequences are used. To achieve explicit interfacing, we can (and should!) place subroutines in a module, compile the module, and USE it in the main program.

The Driver is now simpler, but does the same thing: PROGRAM test_module USE keyplus IMPLICIT NONE INTEGER::i! , add_up not needed; produces dup declar error WRITE(,10) (mykey(i), i=1,8) WRITE(,) 'Sum = ', add_up( ) CALL reverse( ) 10 FORMAT(10x, 8I3) END PROGRAM test_module f95 ModDriverplus.f95 –o ModDriverplus.exe Modplus.o* At this point any program could use the data, the subroutine and the function just as in the program. Are there ever situations where you cannot use external procedures, and must use a module? Consider the following:

Ordinarily we can place our functions and subroutines in a module, compile the module, and USE it. This provides an explicit interface. We can also just include them as external procedures , which how we first used subroutines and functions. FUNCTION x(a, b, n) IMPLICIT NONE INTEGER:: n REAL:: x(n, n), a(n, n),b(n, n) x = a + b END FUNCTION x This is a matrix function that computes the sum of two matrices.

But when I put the function in a module, everything is cool. MODULE hold_function IMPLICIT NONE CONTAINS FUNCTION x(a, b, n) IMPLICIT NONE INTEGER:: n REAL:: x(n, n), a(n, n),b(n, n) x = a + b END FUNCTION END MODULE hold_function F95 –c IBfuncInModule.f produces IBfuncInModule.o DEMO Add the USE statement:

PROGRAM test USE hold_function IMPLICIT NONE INTEGER:: i REAL,ALLOCATABLE:: array(:,:) REAL,ALLOCATABLE:: array1(:,:) REAL,ALLOCATABLE:: array2(:,:) i = 5 ALLOCATE(array(i,i)) ALLOCATE(array1(i,i)) ALLOCATE(array2(i,i)) CALL RANDOM_NUMBER(array1) CALL RANDOM_NUMBER(array2) array = x(array1,array2,i) END PROGRAM f95 IBdrivefuncInModule.f95 IBfuncInModule.o DEMO Now it compiles!

With allocatable arrays it’s necessary to have the

explicit interface provided by the modules.

And now we can complicate things a little to get output: