Tag: Object Oriented Programming

Tutorial OOP(IV) : Operator and Assignment Overloading

In the previous tutorial, we created a constructor and destructor for our TTimer class.  Next, we extend our class with overloaded operators. Depending on the type of object your class represents, you may want to define an addition/subtraction/multiplication/… operator. In addition, the assignment operator deserves some extra attention as you may want to have a clear control over this operation  (e.g.deep copy vs shallow copy). The full source of this tutorial and the previous, can be downloaded from my github-page.

Let us start with the latter: the assignment operator. As with all other operators, it is possible to overload the assignment operator in modern fortran.

1. Assignment (=) operator overloading

When dealing with objects and classes—or extended data-structures in general—, their properties often are (implicit) pointers to the actual data-structure. This brings an interesting source of possible bugs due to shallow copies being made while deep copies are expected (although the problem may be less pronounced in Fortran than it is in Python).

In a fortran object, the assignment of a pointer component (i.e., an explicit pointer variable, or a component which is an object itself) happens via a shallow copy (or pointer assignment). In contrast, for an allocatable component, the assignment operation performs by default a deep copy (i.e., space is allocated, and values are copied). Shallow copies are very useful with regard to quickly creating new handles to the same data-structure. However, if you want to make a true copy, which you can modify without changing the original, then a deep copy is what you want. By implementing assignment overloading for your own classes, you have more control over the actual copying process, and you can make sure you are creating deep copies if those are preferred.

The implementation of overloading for the assignment operator is not too complicated. It requires two lines in your class definition:

type, public :: TTimer
        private
        ...
    contains
        private
        procedure, pass(this) :: Copy                   !< Make a copy of a timer object
        generic, public       :: assignment(=) => Copy  !< This is how copy is used.
        ...
end type TTimer

First, you need to define a class method which performs a copy-operation—which in a fit or original though we decided to call “copy” ;-).  As you can see this function is private, so it will not be accessible to the user of your class via a call like :

call MyTimer%Copy()

Secondly, you link this class method via the “=>” to the assignment-operator.  It is a generic interface, which means the assignment operator could be linked to different functions, of which the relevant one will be determined and used during run-time. This generic is also public  (otherwise you would not be able to use it).

The implementation of the class method follows the standard rules of any class method and could look like

pure subroutine Copy(this,from)
        class(TTimer), intent(inout) :: this
        class(TTimer), intent(in) :: from

    this%firstProperty = from%firstProperty
    ...
    !make explicit copies of all properties and components
    ...

end subroutine Copy

The “this” object which we passed to our class method is the object on the left side of the assignment operator, while the “from” object is the one on the right side. Note that both objects are defined as “class” and not as “type”. Within the body of this method you are in charge of copying the data from the “from”-object to the “this”-object, giving you control over deep/shallow copying.

In practice the overloaded operator is used as:

type(TTimer):: TimerThis, TimerFrom

TimerFrom = TTimer() ! initialization of the timers
TimerThis = TTimer() ! (cf., previous tutorial on constructors and destructors)
... 
! do stuff with TimerFrom
...
TimerThis = TimerFrom ! although you type "=", the overloading causes this to be implemented as-if you wrote
                      ! call TimerThis%copy(TimerFrom)

2. Operator (+,-,*,/,…) overloading

Just as you can overload the assignment operator above, you can also overload all other fortran operators. However, be careful to keep things intuitive.  For example, an addition operation on our TTimer class is strange. What would it mean to add one timer to another? How would you subtract one chronometer from another? In contrast, inside our TTimer class we have a list of TTime objects which can be used to represent a date and time, as-well-as a time interval.[1]  For the remainder of this tutorial, we will assume the TTime class only represents time-intervals. For such a class, it makes sense to be able to add and subtract time intervals.

Let us start with the basic definition of our TTime-class:

type, public :: TTime
  private
   ...
   ! the properties of the TTime class
   ...
contains
  private
   ...
   ! the methods of the TTime class
   ... 
   procedure, pass(this)        :: copy          ! Copy content from other TTime instance,  
                                                 ! private, accessed via the assignment statement
   procedure, pass(this)        :: add           ! Add two TTime instances.
   procedure, pass(this)        :: subtract      ! subtract two TTime instances.
   generic, public :: assignment(=) => copy      ! This is how copy is used.
   generic, public :: operator(+)   => add       ! This is how add is used.
   generic, public :: operator(-)   => subtract  ! This is how subtract is used.
   final :: destructor
end type TTime

interface TTime
   module procedure constructor
end interface TTime

The TTime class has a constructor and destructor, implemented as we discussed before. The assignment operator is over-loaded as well. The overloading of the “+” and “” operator follows the same setup as for the assignment operator. First, you define a class method where you will implement the addition or subtraction. Second, you link this class method to the operator as a generic. The main difference with overloading the assignment operator is that you need to use the keyword operator instead of assignment, during the second step. The class methods are private, while the generic link is public. The only thing left to do is to implement the class methods. In case of operator overloading, the class methods are functions.

pure function add(this,that) Result(Total)
     class(TTime), intent(in) :: this, that
     Type(TTime) :: total

total = TTime()
...
! implementation of the addition of the properties of 
! this to the properties of that, and storing them in 
! Total
! e.g.: Total%seconds = this%seconds + that%seconds        
...
end function add

The returned object need to be defined as a type, and the further implementation of the function follows the standard fortran rules. It is important to note that for a function-header like this one, the object to the left of the operator will be the one calling the overloaded operator function, so:

Total = this + that

and not

Total = that + this

This may not seem this important, as we are adding two objects of the same class, but that is not necessarily always the case. Imagine that you want to overload the multiplication operator, such that you could multiply your time-interval with any possible real value. On paper

Δt * 3.5 = 3.5 * Δt

but for the compiler in the left product “this” would be a TTime object and “that” would be a real, while in the right product “this” is the real, and “that” is the TTime object. To deal with such a situation, you need to implement two class methods, which in practice only differ in their header:

pure function MultLeft(this,that) Result(Total) 
    class(TTime), intent(in) :: this
    real, intent(in) :: that 
    Type(TTime) :: total

and

pure function MultRight(that, this) Result(Total) 
    class(TTime), intent(in) :: this
    real, intent(in) :: that 
    Type(TTime) :: total

In the class definition both functions are linked to the operator as

procedure, pass(this) ::  MultLeft
procedure, pass(this) ::  MultRight
generic, public :: operator(*) => MultLeft, MultRight

With this in mind, we could also expand our implementation of the “+” and “” operator, by adding functionality that allows for the addition and subtraction of reals representing time-intervals. Also here, the left and right versions would need to be implemented.

As you can see, modern object oriented fortran provides you all the tools you need to create powerful classes capable of operator overloading using simple and straightforward implementations.

In our next Tutorial, we’ll look into data-hiding and private/public options in fortran classes.

 

 

[1] You could argue that this is not an ideal choice and that it would be better to keep these two concepts ( absolute and relative time) separate through the use of different classes. 

Tutorial OOP(III): Constructors and Destructors

In this tutorial on Object Oriented Programming in Fortran 2003, we are going to discuss how to create constructors and destructors for a Fortran class. During this tutorial, I assume that you know how to create a new project and what a class looks like in Fortran 2003.  This tutorial is build around a TimerClass, which I wrote as an upgrade for my initial timing module in HIVE-tools. The full source of this TimerClass can be found and downloaded from github.

Where the former two tutorials were aimed at translating a scientific model into classes within the confines of the Fortran programming language, this tutorial is aimed at consolidating a class using good practices: The creation a constructor and destructor. As the destructor in Fortran classes is most straight forward of the two, we’ll start with it.

1. The destructor.

A destructor is a method (i.e., a class subroutine) which is automatically invoked when the object is destroyed (e.g., by going out of scope).  In case of a Fortran class, this task is performed by the class-method(s) indicated as  final procedure. Hence such methods are also sometimes referred to as finalizers. Although in some languages destructors and finalizers are two distinctly different features (finalizers are then often linked to garbage collecting), within the Fortran context I consider them the same.

Within the definition of our TTimerClass the destructor is implemented as:

  1. module TimerClass
  2. implicit none
  3.  
  4.     type, public :: TTimer
  5.       private
  6.       ! here come the properties
  7.     contains
  8.       private
  9.       ! here come the methods
  10.       final :: destructor
  11.     end type TTimer
  12.    
  13. contains
  14.  
  15.     subroutine destructor(this)
  16.     Type(TTimer) :: this
  17.     ! Do whatever needs doing in the destructor
  18.     end subroutine destructor
  19.    
  20. end module TimerClass

In contrast to a normal class-method, the destructor is called using the final keyword, instead of the usual procedure keyword. This method is private, as it is not intended to be used by the user anyway, only by the compiler upon cleanup of the instance of the class (i.e., the object). Furthermore, although defined as part of the class, a final subroutine is not type-bound, and can thus not be accessed through the type.

The destructor subroutine itself is a normal Fortran subroutine. There is, however, one small difference with a usual class-method, the parameter referring to the object (c.q. “this“) is indicated as a TYPE and not as a CLASS. This is because the destructor is only applicable to properties belonging to this “class” (Note that final subroutines are not inherited by the child-class). For a child-class (also called a derived class), the destructor of the child-class should deal with all the additional properties of the child-class, while the destructor of the parent-class is called to deal with its respective properties. In practice, the destructor of the child-class is called first, after which the destructor of the parent class is called (and recursively further along the class its family tree.)

So what do you put in such a destructor? Anything that needs to be done to allow the object to be gracefully terminated. Most obviously: deallocation of allocatable arrays, pointer components, closing file handles,…

2. The constructor.

Where other programming  languages may provide an initialization section or access to a key-worded constructor. Although Fortran allows for variables to be initialized upon definition, there is no constructor keyword available to be used in its classes. Of course, this does not prevent you from adding an “init()” subroutine which the user should call once the new object is allocated. You could even use a private Boolean property (initialized old style)  to keep track of the fact that an object was initialized when entering any of its methods, and if not, call the init() function there and then. There are many ways to deal with the initialization of a new object.  Furthermore, different approaches also put the burden of doing things right either with the programmer developing the class, or the user, applying the class and creating objects.

Here, I want to present an approach which allows you to present a clear set-up of your class and which resembles the instance creation approach also seen in other languages (and which implicitly shows the “pointer”-nature of objects ):

NewObject = TClass()

In case of our TTimer class this will look like:

Type(TTimer) :: MyTimer

MyTimer = TTimer()

This means we need to have a function with the exact same name as our class (cf., above), which is achieved through the use of an interface to a module procedure.  Just giving this name to the constructor function itself will cause your compiler to complain (“Name ttimer at (1)  is already defined as a generic interface“).  By using a different name for the  function, and wrapping it in an interface, this issue is avoided.

  1. module Timerclass
  2.     implicit none
  3.  
  4.  
  5.     type, public :: TTimer
  6.         private
  7.     ...
  8.     contains
  9.         private
  10.         ...
  11.     end type TTimer
  12.    
  13.     interface TTimer
  14.         module procedure Constructor
  15.     end interface TTimer
  16.  
  17. contains
  18. function Constructor() Result(Timer)
  19.     type(TTimer) :: Timer
  20.    
  21.     !initialize variables directly
  22.     Timer%x=...
  23.     ! or through method calls
  24.     call Timer%setTime(now)
  25.     ...
  26.  
  27. end function Constructor
  28.  
  29. end module TimerClass

Note that the constructor function is not part of the class definition, and as such the object is not passed to the constructor function. In addition, the Timer object being created is defined as a Type(TTimer) not Class(TTimer), also because this function is not part of the class definition.

That is all there is to it. Simple and elegant.

In our next Tutorial, we’ll have a look at operator and assignment overloading. Combined with a constructor and destructor as presented here, you are able to create powerful and intuitive classes (even in Fortran).

Fortran dll’s and libraries: a Progress bar

In the previous fortran tutorials, we learned the initial aspects of object oriented programming (OOP) in fortran 2003. And even though our agent-based opinion-dynamics-code is rather simple, it can quickly take several minutes for a single run of the program to finish. Two tools which quickly become of interest for codes that need more than a few minutes to run are: (1) a progress bar, to track the advance of the “slow” part of the code and prevent you from killing the program 5 seconds before it is to finish, and (2) a timer, allowing you to calculate the time needed to complete certain sections of code, and possibly make predictions of the expected total time of execution.

In this tutorial, we will focus on the progress bar. Since our (hypothetical) code is intended to run on High-Performance Computing (HPC) systems and is written in the fortran language, there generally is no (or no easy) access to GUI’s. So we need our progress bar class to run in a command line user interface. Furthermore, because it is such a widely useful tool we want to build it into a (shared) library (or dll in windows).progress_1pct

The progress bar class

What do we want out of our progress bar? It needs to be easy to use, flexible and smart enough to work nicely even for a lazy user. The output it should provide is formatted as follows: <string> <% progress> <text progress bar>, where the string is a custom character string provided by the user, while ‘%progress’ and ‘text progress bar’ both show the progress. The first shows the progress as an updating number (fine grained), while the second shows it visually as a growing bar (coarse grained).

  1. type, public :: TProgressBar
  2. private
  3. logical :: init
  4. logical :: running
  5. logical :: done
  6. character(len=255) :: message
  7. character(len=30) :: progressString
  8. character(len=20) :: bar
  9. real :: progress
  10. contains
  11. private
  12. procedure,pass(this),public :: initialize
  13. procedure,pass(this),public :: reset
  14. procedure,pass(this),public :: run
  15. procedure,pass(this),private:: printbar
  16. procedure,pass(this),private:: updateBar
  17. end type TProgressBar

All properties of the class are private (data hiding), and only 3 procedures are available to the user: initialize, run and reset. The procedures, printbar and updatebar are private, because we intend the class to be smart enough to decide if a new print and/or update is required. The reset procedure is intended to reset all properties of the class. Although one might consider to make this procedure private as well, it may be useful to allow the user to reset a progress bar in mid progress.(The same goes for the initialize procedure.)

  1. subroutine run(this,pct,Ix,msg)
  2. class(TProgressBar) :: this
  3. real::pct
  4. integer, intent(in), optional :: Ix
  5. character(len=*),intent(in),optional :: msg
  6.  
  7. if (.not. this%init) call this%initialize(msg)
  8. if (.not. this%done) then
  9. this%running=.true.
  10. this%progress=pct
  11. call this%updateBar(Ix)
  12. call this%printbar()
  13. if (abs(pct-100.0)<1.0E-6) then
  14. this%done=.true.
  15. write(*,'(A6)') "] done"
  16. end if
  17. end if
  18.  
  19. end subroutine run

In practice, the run procedure is the heart of the class, and the only procedure needed in most applications. It takes 3 parameters: The progress (pct), the number of digits to print of pct (Ix),and the <string> message (msg). The later two parameters are even optional, since msg may already have been provided if the initialize procedure was called by the user. If the class was not yet initialized it will be done at the start of the procedure. And while the progress bar has not yet reached 100% (within 1 millionth of a %) updates and prints of the bar are performed. Using a set of Boolean properties (init, running, done), the class keeps track of its status. The update and print procedures just do this: update the progress bar data and print the progress bar. To print the progress bar time and time again on the same line, we need to make use of the carriage return character (character 13 of the ASCII table):

write(*,trim(fm), advance='NO') achar(13), trim(this%message),trim(adjustl(this%progressString)),'%','[',trim(adjustl(this%bar))

The advance=’NO‘ option prevents the write statement to move to the next line. This can sometimes have the unwanted side-effect that the write statement above does not appear on the screen. To force this, we can use the fortran 2003 statement flush(OUTPUT_UNIT), where “OUTPUT_UNIT” is a constant defined in the intrinsic fortran 2003 module iso_fortran_env. For older versions of fortran, several compilers provided a (non standard) flush subroutine that could be called to perform the same action. As such, we now have our class ready to be used. The only thing left to do is to turn it into a dll or shared library.progress_25pct

How to create a library and use it

There are two types of libraries: static and dynamic.

Static libraries are used to provide access to functions/subroutines at compile time to the library user. These functions/subroutines are then included in the executable that is being build. In linux environments these will have the extension “.a”, with the .a referring to archive. In a windows environment the extension is “.lib”, for library.

Dynamic libraries are used to provide access to functions/subroutines at run time. In contrast to static libraries, the functions are not included in the executable, making it smaller in size. In linux environments these will have the extension “.so”, with the .so referring to shared object. In a windows environment the extension is “.dll”, for dynamically linked library.

In contrast to C/C++, there is relatively little information to be found on the implementation and use of libraries in fortran. This may be the reason why many available fortran-“libraries” are not really libraries, in the sense meant here. Instead they are just one or more files of fortran code shared by their author(s), and there is nothing wrong with that. These files can then be compiled and used as any other module file.

So how do we create a library from our Progressbar class? Standard examples start from a set of procedures one wants to put in a library. These procedures are put into a .f or .f90 file. Although they are not put into a module (probably due to the idea of having compatibility with fortran 77) which is required for our class, this is not really an issue. The same goes for the .f03 or .f2003 extension for our file containing a fortran 2003 class. To have access to our class and its procedures in our test program, we just need to add the use progressbarsmodule clause. This is because our procedures and class are incorporated in a module (in contrast to the standard examples). Some of the examples I found online also include compiler dependent pragmas to export and import procedures from a dll. Since I am using gfortran+CB for development, and ifort for creating production code, I prefer to avoid such approaches since it hampers workflow and introduces another possible source of bugs.

The compiler setups I present below should not be considered perfect, exhaustive or fool-proof, they are just the ones that work fine for me. I am, however, always very interested in hearing other approaches and fixes in the comments.progress_52pct

Windows

The windows approach is very easy. We let Code::Blocks do all the hard work.

shared library: PBar.dll

Creating the dll : Start a new project, and select the option “Fortran DLL“. Follow the instructions, which are similar to the setup of a standard fortran executable. Modify/replace/add the fortran source you wish to include into your library and build your code (you can not run it since it is a library).

Creating a user program : The program in which you will be using the dll is setup in the usual way. And to get the compilation running smoothly the following steps are required:

  • Add the use myspecificdllmodule clause where needed, with myspecificdllmodule the name of the module included in the dll you wish to use at that specific point.
  • If there are modules included in the dll, the *.mod files need to be present for the compiler to access upon compilation of the user program. (Which results in a limitation with regard to distribution of the dll.)
  • Add the library to the linker settings of the program (project>build options>linker settings), and then add the .dll file.
  • Upon running the program you only need the program executable and the dll.

static library

The entire setup is the same as for the shared library. This time, however, choose the “Fortran Library” option instead of Fortran dll. As the static library is included in the executable, there is no need to ship it with the executable, as is the case for the dll.

Unix

For the unix approach we will be working on the command line, using the intel compiler, since this compiler is often installed at HPC infrastructures.

static library: PBar.a

After having created the appropriate fortran files you wish to include in your library (in our example this is always a single file: PBar.f03, but for multiple files you just need to replace PBar.f03 with the list of files of interest.)

  1. Create the object files:
    ifort -fpic -c -free -Tf Pbar.f03

    Where -fpic tells the compiler to generate position independent code, typical for use in a shared object/library, while -c tells the compiler to create an object file. The -free and -Tf compiler options are there to convince the compiler that the f03 file is actual fortran code to compile and that it is free format.

  2. Use the GNU ar tool to combine the object files into a library:
    ar rc PBarlib.a PBar.o
  3. Compile the program with the library
    ifort TestProgram.f90 PBarlib.a -o TestProgram.exe

    Note that also here the .mod file of our Progressbarsmodule needs to be present for the compilation to be successful.

shared library: PBar.so

For the shared library the approach does not differ that much.

  1. Create the object files:
    ifort -fpic -c -free -Tf Pbar.f03

    In this case the fpic option is not optional in contrast to the static library above. The other options are the same as above.

  2. Compile the object files into a shared library:
    ifort -shared PBar.o -o libPBar.so

    The compiler option -shared creates a shared library, while the -o option allows us to set the name of the library.

  3. Compile the program with the library
    ifort TestProgram.f90 libPBar.so -o TestProgram.exe

    Note that also here the .mod file of our Progressbarsmodule needs to be present for the compilation to be successful. To run the program you also need to add the location of the library file libPBar.so to the environment variable LD_LIBRARY_PATH

One small pickle

HPC systems may perform extensive buffering of data before output, to increase the efficiency of the machine (disk-writes are the slowest memory access option)…and as a result this can sometimes overrule our flush command. The progressbar in turn will not show much progress until it is actually finished, at which point the entire bar will be shown at once. There are options to force the infrastructure not to use this buffering (and the system administrators in general will not appreciate this), for example by setting the compiler flag -assume nobuffered_stdout. So the best solution for HPC applications will be the construction of a slightly modified progress bar, where the carriage return is not used.

progress_100pct

 

Special thanks also to the people of stack-exchange for clarifying some of the issues with the modules.

Source files for the class and test-program can be downloaded here.

 

Tutorial OOP(II): One problem, different possible classes

additional resources
agent paper: Sobkowicz
source-code: AgentTutorials
Arxiv: Full Tutorial

In the previous tutorial, we saw how to tackle an opinion dynamics problem using agents as a class in an Object Oriented Programming (OOP) approach. In many topics of interest in (socio-)physics and chemistry, we deal with a large number of particles, be it electrons, atoms, agents, stars, … These are contained in a superstructure (electrons⇒atom, atoms⇒molecule/solid, agents⇒population, stars⇒galaxy,…) which is generally represented in the code as an array. As we noted in the previous tutorial, there were several variables which were global to the agents, but we implemented them as properties of the agents anyhow. As a result, a significant amount of additional memory needed to be allocated for storing in essence the same data. This was done to prevent the need of having to provide this information at every function call.

Returning to our problem of interest, we now consider two object classes: The TAgent-class and the TPopulation-class. This leads to several possible ways this problem can be implemented.

  1. Array of TAgents: As was done in the previous tutorial, we only make a class of the agents, and put them in an array.
  2. TPopulation of TAgents: In this case we construct a class called TPopulation of which one property is the set of TAgents. The TPopulation-class also contains some of the global variables as properties, and operations on this set are methods of the TPopulation-class.
  3. TPopulation-class without TAgent-class: In this last case, the agents are dissolved, and their properties are stored in array-properties of the TPopulation-class. The methods of the TAgent-class now become methods of the TPopulation-class. And the global variables become additional properties of the TPopulation-class.

Although the true OOP-programmer may only consider the  second option the way to go, we will consider the third option in this tutorial.

Continue reading

Tutorial OOP(I): Objects in Fortran 2003

After having set up our new project in the first session of this tutorial, we now come to an important second step: choosing and creating our Objects. In OOP, the central focus is not a (primitive) variable or a function, but “an object”. In Object Oriented Programming (OOP) most if not all variables and functions are incorporated in one or more (types of) objects. An object, is just like a real-life object; It has properties and can do things. For example: a car. It has properties (color, automatic or stick, weight, number of seats,…) and can do things (drive, break down, accelerate,…). In OOP, the variables containing the values that give the color, weight, stick or not,… of the car are called the properties of the car-object. The functions that perform the necessary calculations/modifications of the variables to perform the actions of driving, breaking down,… are called the methods.

Since we are still focusing on the opinion dynamics paper of Sobkowicz, let us use the objects of that paper to continue our tutorial. A simplified version of the research question in the paper could be as follows:

How does the (average) opinion of a population of agents evolve over time?

For our object-based approach, this already contains much of the information we need. It tells us what our “objects” could be: agents. It gives us properties for these objects: opinion. And it also tells us something of the methods that will be involved: opinion…evolve over time.

Let us now put this into Fortran code. A class definition in Fortran uses the TYPE keyword, just like complex data types.

  1. Type, public :: TAgentClass
  2. private
  3. real :: oi !< opinion
  4. contains
  5. private
  6. procedure, pass(this), public :: getOpinion
  7. procedure, pass(this), public :: setOpinion
  8. procedure, pass(this), public :: updateOpinion
  9. end type TAgentClass

Continue reading

Tutorial: Starting a new Object Oriented Fortran-project in Code::Blocks

Because Fortran has been around since the time of the dinosaurs, or so it seems, one persistent myth is that modern constructs and techniques are not supported. One very important modern programming approach is Object Oriented Programming (OOP). Where procedural programming focuses on splitting the program in smaller functional units (functions and procedures), OOP is centered on “Objects and Classes”. These objects, just like real life objects, have properties (eg. name, color, position, …) and contain methods (i.e. procedures representing their functionality). This sounds more complex than it actually is. In a very simplistic sense, objects and classes are created by extending complex data types in procedural programming languages with internally contained functions/procedures, referred to as methods. In the table below, you see a limited comparison between the two. The first three languages are procedural oriented languages, while the last two allow for OOP.

C Pascal F95 C++ OOP F2003 OOP
data type keyword struct record type class type
containing variables field field field property property
containing functions / / / method method
inheritance no no no yes yes

In this tutorial series, I want to show how you can use OOP in Fortran in scientific codes. As a first example, I will show you how to create an agent based opinion dynamics code implementing the model presented by Sobkowicz in a publication I recently had  to review.

I choose this as our tutorial example (over for example geometric shapes) because it is a real-life scientific example which is simple enough to allow for several aspects in scientific and OO-programming to be shown. In addition, from the physicists point of view: particle or agent, it is all the same to us when we are implementing their behavior into a program.(You could even start thinking in terms of NPC’s for a game, although game-dynamics in general require quite a bit more implementation)

So let us get started. First, you might wish to grab a copy of the paper by Sobkowicz (it’s freely accessible), just to be able to more easily track the notation I will be using in the code. After having installed code::blocks it is rather straight-forward to create a new Fortran program.

  1. Open code::blocks, and start a new project (File > New > Project) by selecting “Fortran application”newProject
  2. Provide a “Project title” and a location to store the files of the new project.setupProject1
  3. Choose your compiler (GNU Fortran Compiler, make sure this is the one selected) and Finish.setupProject2
  4. Now Code::Blocks will present you a new project, with already one file present: main.f90 HelloWorld
  5. First we are going to rename this main file, e.g. to main.f95, to indicate that we will be  using Fortran 95 code in this file. By right-clicking on the file name (indicated with the red arrow) you see a list of possible op w this option while the file is open in the right-hand pane. Close the file there, and now you can rename main.f95.
  6. Although we will be following the OOP paradigm for the main internal workings of our program, a procedural setup will be used to set up the global lines of the program. I split the code in three levels: The top-level being the main program loop which is limited to the code below, the middle level which contains what you may normally consider the program layout (which you can easily merge with the top level) and the bottom level which contains the OO innards of our program. All subroutines/functions belonging to the middle level will be placed in one external module (Tutorial1) which is linked to the main program through the use-statement at line 2 and the single subroutine call (RunTutorial1).
  1. program AgentTutorials
  2. use Tutorial1;
  3. implicit none
  4.  
  5. write(*,'(A)') "Welcome to the Agents OOP-Fortran Tutorial"
  6. call RunTutorial1()
  7. write(*,'(A)') "-- Goodbye"
  8. end program AgentTutorials
  1. Next step, we need a place for the RunTutorial1 subroutine, and all other subroutines/functions that will provide the global layout of our agents-program. Make a new file in Code::Blocks as followsNewFile
  2. and select a Fortran source file and finish by placing it in a directory of your choice and click OK.NewFile2
  3. In this empty file, a module is setup in the following fashion:
  1. module Tutorial1
  2. implicit none
  3. private
  4.  
  5. public :: RunTutorial1
  6.  
  7. contains
  8. !+++++++++++++++++++++++++++++++++++++
  9. !>\brief Main program routine for the first agents tutorial
  10. !!
  11. !! This is the only function accessable outside this module.
  12. !<------------------------------------
  13. subroutine RunTutorial1()
  14. write(*,'(A)') "----Starting Turorial 1 subprogram.----"
  15. write(*,'(A)') "-------End Turorial 1 subprogram.------"
  16. end subroutine RunTutorial1
  17.  
  18. end module Tutorial1
  1. implicit none : Makes sure that you have to define all variables.
  2. private : The private statement on line 3 makes sure that everything inside the module remains hidden for the outside world, unless you explicitly make it visible. In addition to data/information-hiding this also helps you keep your namespace in check.
  3. public :: Runtutorial1 : Only the function Runtutorial1 is available outside this module.(Because we want to use it in program  AgentTutorials.)
  4. contains : Below this  keyword all functions and subroutines of the module will be placed.
  5. “!” : The exclamation marks indicate a comment block. In this case it is formatted to be parsed by doxygen.
  6. subroutine XXX  / end subroutine XXX : The subroutine we will be implementing/using as the main loop of our agents program. Note that in recent incarnations of fortran the name of the subroutine/function/module/… is repeated at their end statement. For small functions this may look ridiculous, but for larger subroutines it improves readability.

At this point or program doesn’t do that much, we have only set up the framework in which we will be working. Compiling and running the program (F9 or Build > Build and run) should show you:

AgentsRun1 In the next session of this tutorial we will use OO-Fortran 2003 to create the agent-class and create a first small simulation.

 

 

CA: Coders Anonymous

It has been 2 weeks since I last wrote some code, today I started again.

Two weeks ago  I started the, for me, daunting task of upgrading my IDE and compiler to their most recent version. The upgrade itself went smoothly, since it basically consisted of uninstalling the old versions and installing the new ones. The the big finale, recompiling my fortran codebase, went just a little bit less smoothly. It crashed straight into a compiler-bug, nicely introduced in version 4.9 of the gcc fortran compiler, and carefully nurtured up to version 4.10 I had just installed. The bug sounds as follows:

error: internal compiler error: in gfc_conv_descriptor_data_get, at fortran/trans-array.c:145
end module TPeriodicTableModule

Clear sounding as it is, it required some further investigation to find out what was actually the problem and if and how it can be resolved. The problem appeared to be a rather simple one; The compiler seems to be unable to generate the finalization code for some object based constructions involving both fixed size and allocatable arrays, the strong suite of the fortran language.  A minimal example allowing you to bump into this compiler bug goes as follows:

 

Bug 59765   
  1. module bug59765
  2. type TSubObject
  3. integer, dimension(:), allocatable :: c
  4. end type TSubObject
  5. type TObject
  6. type(TSubObject), dimension(1) :: u
  7. end type TObject
  8. contains
  9.  
  10. subroutine add(s)
  11. class(TObject), intent(inout) :: s
  12. end subroutine add
  13.  
  14. end module bug59765

 

The issue arises when the compiler tries to setup the deallocation of the allocatable array of the TSubObject elements of the array u. Apparently the combination of the static array u and allocatable arrays c in the elements of u result in confusion. It was suggested that the compiler wants to perform the deallocation procedure as an array operation (one of the neat tricks fortran has up its sleeves):

deallocate(s%u(:)%c)

instead it should just use a normal do-loop and run over all elements of u.

One of the main ironies of this story is that this bug is strongly connected to object oriented programming, a rather new concept in the world of fortran. Although introduced in fortran 2003, more than 10 year ago, compiler support for these features have only reached basic maturity in recent years. The problem we are facing is one in the destructor of an object: the smart compiler wants to make our life easy, and implicitly create a good destructor for us. As with most smart solutions of modern day life, such things have a tendency to fail when you least expect it.

However, this bug (and the fact that it persists in more recent versions of the compiler) forces us to employ good coding practices: write a destructor yourself. Where C++ has implemented keywords for both constructor and destructor, the fortran programmer, as yet, only has a keyword for a destructor: final. This finalization concept was introduced in the fortran 2003 standard as part of the introduction of the Object Oriented Programming paradigm. A final procedure/function also works slightly different than what you may be used to in for example C++, namely, it is not directly callable by the programmer as an object-function/procedure. A final procedure/function is only called upon in an automatic way when an object is destroyed. So for those of us who also implement  ‘free()‘ procedures to clean-up objects at runtime, this means some extra work may be needed (I haven’t checked this in detail).

So how is our example-problem healed from bug 59765? Through the introduction of our own destructor.

  1. module fixbug59765
  2. type TSubObject
  3. integer, dimension(:), allocatable :: c
  4. contains
  5. final :: destroy_TSubObject
  6. end type TSubObject
  7. type TObject
  8. type(TSubObject), dimension(1) :: u
  9. end type TObject
  10. contains
  11.  
  12. subroutine add(s)
  13. class(TObject), intent(inout) :: s
  14. end subroutine add
  15.  
  16. subroutine destroy_TSubObject(this)
  17. type(TSubObject) :: this !note: this needs to be a type not a class
  18.  
  19. if (allocated(this%c)) deallocate(this%c)
  20. end subroutine destroy_TSubObject
  21.  
  22. end module fixbug59765

In my own code, both the TSubObject and TObject classes got their own final procedure, due to the slightly higher complexity of the objects involved. The resulting code compiled without further complaints, and what is more, it also still compiled with the recent intel ifort compiler. Unfortunately, final procedures are only included in the gcc compiler since version 4.9, making code containing them incompatible with the gcc version 4.8 and earlier.