<[email protected]> François Colonna² ¹ Labratoire de Chimie et Physique Quantiques IRSAMC (Toulouse) ² Laboratoire de Chimie Théorique (Paris) 26/10/2014
Fortran is a low level language -> difficult to maintain • High-level features of Fortran 95 kill the efficiency (pointers, array syntax, etc) -> not a good solution • Less effort in program development and good efficiency with Python/Numpy or Python/F2Py • Other option : use Python to write low level Fortran code 1 / 22 http://irpf90.ups-tlse.fr
of its input data: output = program (input) A program can be represented as a production tree where • The nodes are the variables • The vertices represent the relation needs/needed by Example: u(x,y) = x + y + 1 v(x,y) = x + y + 2 w(x) = x + 3 t(x,y) = x + y + 4 What is the production tree of t( u(d1,d2), v( u(d3,d4), w(d5) ) )? 2 / 22 http://irpf90.ups-tlse.fr
order: • The programmers needs have the knowledge of the production tree • Production trees are usually too complex to be handled by humans • Collaborative work is difficult : any user can alter the production tree • Programmers may not be sure that their modification did not break some other part 5 / 22 http://irpf90.ups-tlse.fr
to build a value : by calling its provider • Provider : • If the value is already built : return the previous value (memo function) • Otherwise : call the providers of the needed entities and then build the value Advantages: • The provider guarantees that the value is valid • Only a local knowledge of the production tree : the needed entities • This is equivalent to calling t( u(d1,d2), v( u(d3,d4), w(d5) ) ). As there is only one set of possible parameters for each function (the needed entities are always the same), the parameters can be embedded inside the functions. IRP : functions with Implicit Reference to Parameters 6 / 22 http://irpf90.ups-tlse.fr
represented inside a common class. This function generates the provider of an entity. f is the function that builds the entity. """ # Switch the current environment to the class containing the # IRP entities locals = sys._getframe(1).f_locals # Name of the memo value : _f cache = "_"+f.__name__ # Generic provider 7 / 22 http://irpf90.ups-tlse.fr
getattr(self,cache) print " -- Already built "+f.__name__ except AttributeError: # If self._f doesn't exist, build it print " -> Building "+f.__name__ result = f(self) setattr(self,cache,result) print " <- Done building "+f.__name__ # Return self._f return result # Return a class property to call the provider return property(fget=provider) 8 / 22 http://irpf90.ups-tlse.fr
\ -> Building d # u1 v <- Done building d # / | | \ -- Already built d # d1 d2 u2 w <- Done building u1 # / \ \ 4 # d3 d4 d5 t : -> Building t -- Already built u1 -> Building v -> Building u2 -- Already built d -- Already built d <- Done building u2 -> Building w 11 / 22 http://irpf90.ups-tlse.fr
introspection, properties, etc. Solution IRPF90: • Add a few keywords to Fortran • Use Python to read the code • Python builds the dependence tree • Python writes the missing Fortran source lines to handle the tree Example with IRPF90 BEGIN_PROVIDER [ integer, t ] t = u1+v+4 END_PROVIDER BEGIN_PROVIDER [integer,w] w = d5+3 13 / 22 http://irpf90.ups-tlse.fr
... END_PROVIDER • Allocation of IRP arrays done automatically • Dimensioning variables can be IRP entities, provided before the memory allocation 16 / 22 http://irpf90.ups-tlse.fr
of tags to navigate in the code • Variables can be declared anywhere • Dependencies are known by IRPF90 -> Makefiles are built automatically • No problem using external libraries (MKL, MPI, etc) • Compatible with OpenMP • Support for Coarray Fortran (distributed parallelism) • Codelet generation for code optimization • Generation of Intel Fortran compiler directives to align arrays • Generated code is very efficient (960 Tflops/s on Curie in 2011 with QMC=Chem) • etc... 21 / 22 http://irpf90.ups-tlse.fr