stfc / PSyclone

Domain-specific compiler and code transformation system for Finite Difference/Volume/Element Earth-system models in Fortran
BSD 3-Clause "New" or "Revised" License
103 stars 25 forks source link

Translating LFRic kernel code into PSyIR #336

Open rupertford opened 5 years ago

rupertford commented 5 years ago

Having run Sergi's kernel to PSyIR translation on the latest LFRic master using the following PSyclone script ...

'''PSyclone transformation script which outputs the PSyIR
representation of any kernels called from the algorithm layer

'''
def trans(psy):
    ''' Output LFRic kernel PSyIR '''
    for invoke in psy.invokes.invoke_list:
        #print invoke.name
        for kernel in invoke.schedule.kern_calls():
            #print "  "+kernel.name
            try:
                kernel_schedule = kernel.get_kernel_schedule()
                kernel_schedule.view()
            except NotImplementedError as excinfo:
                print str(excinfo)

and a simple script over all algorithm files ...

#!/bin/bash
for filename in gungho/source/algorithm/*.x90; do
    psyclone $filename -d gungho/source/kernel -api dynamo0.3 -oalg alg.f90 -opsy psy.f90 -s ./script.py
done

I get two types of error (which are repeated in the different kernels).

Could not process DIMENSION(ndf1). Only integer literals are supported for explicit shape array declarations.

Could not process (Intrinsic_Type_Spec('REAL', Kind_Selector('(', Name('r_def'), ')')), Attr_Spec('INTENT(OUT)'), Entity_Decl(Name('a0'), Explicit_Shape_Spec(None, Name('undf_w3')), None, None)). Array specifications after the variable name are not supported.

Andy says the first is because in

real ..., dimension(XXX) :: ...

currently XXX must be a literal and we have variable names

and the second is because array declarations of the form ...

real ... :: a(XXX)

are not yet supported.

rupertford commented 5 years ago

We also need to support multiple dimensions ...

Could not process DIMENSION(3, ndf, nqp_h, nqp_v). Only integer literals are supported for explicit shape array declarations.
sergisiso commented 5 years ago

We also need to support multiple dimensions ...

Multiple dimensions are supported, but your example has integer variables (not literals), which is the same as 'Case 1'.

The seconds case real ... :: a(XXX) is also quite trivial, but it will fail again by having integer variables as the size.

To solve this the main change we need to make is allowing the Symbol shape to contain references to another Symbol of type Integer in addition to the None and Integer Literal currently supported. Note that this integer symbol should already be in the symbol table before declaring the array.

rupertford commented 5 years ago

I've just tried the new branch and most kernels now produce a schedule (whoop) however in some cases we get a related error. For example, in compute_total_aam_code we get ...

PSyclone internal error: Could not process (Intrinsic_Type_Spec('REAL', Kind_Selector('(', Name('r_def'), ')')), None, Entity_Decl_List(',', (Entity_Decl(Name('u_at_quad'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('scaled_omega_vec'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('r_vec'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('am'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('x_vec'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('u_vec'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None), Entity_Decl(Name('j_u'), Explicit_Shape_Spec(None, Int_Literal_Constant('3', None)), None, None)))). Multiple dimension specifications found.

for the following code ...

  real(kind=r_def) :: u_at_quad(3), scaled_omega_vec(3), r_vec(3), &
                      am(3), x_vec(3), u_vec(3), j_u(3)

Similarly for ...

  real(kind=r_def) :: grad_theta_v_at_quad(3), v(3)

and

  real(kind=r_def) :: jacobian(3,3,ndf,1), jacobian_inv(3,3,ndf,1), dj(ndf,1)

So I'm guessing it is to do with multiple array declarations per line.

sergisiso commented 5 years ago

OK, it seems the error 'Multiple dimension specifications found.' message I added in #338 is misleading, I will solve this in the current PR and ask you to try again :)

rupertford commented 5 years ago

I also found this (but only one file) :-) ...

Could not process (Intrinsic_Type_Spec('REAL', Kind_Selector('(', Name('r_def'), ')')), Attr_Spec('ALLOCATABLE'), Entity_Decl(Name('u_n_local'), Assumed_Shape_Spec(None, None), None, None)). Unrecognized attribute 'ALLOCATABLE'.
rupertford commented 5 years ago

And this :-) (but only one file) ...

    TypeError: Could not process DIMENSION(0 : nlayers - 1). Only scalar integer literals or symbols are allowed for explicit shape array declarations.
rupertford commented 5 years ago

And a logical (in one file) ...

Could not process (Intrinsic_Type_Spec('LOGICAL', Kind_Selector('(', Name('l_def'), ')')), None, Entity_Decl_List(',', (Entity_Decl(Name('positive'), None, None, None), Entity_Decl(Name('monotone'), None, None, None)))). Only 'real', 'integer' and 'character' intrinsic types are supported.
sergisiso commented 5 years ago

I am introducing the Logical types at #338 and fixing the multiple array in a single statement issue..

I will not add support for ALLOCATABLES or dimension ranges in that PR yet.

Also, you may want to add: kernel_schedule.symbol_table.view() in your script to check that PSyIR does not just accept the declarations, but it got them right when comparing to the original Fortran.

rupertford commented 5 years ago

PR #338 has been merged to master but I'm keeping this issue open as there are two outstanding issues from the LFRic code base as described above (allocatables and dimension ranges/offsets).

sergisiso commented 5 years ago

With the additions of Loops fparser2-to-PSyIR, there are the following things missing for fully representing LFRic kernels:

NotImplementedError:

Unrecognized nodes:

Not related to PSyclone: