Skip to content

Create meta-directive for openacc/mp #834

@sbryngelson

Description

@sbryngelson

Instead of having

!$acc parallel loop collapse(2) default(present) private(var1,var2)
!$omp target teams distribute parallel do collapse(2) private(var1,var2)

, which would duplicate a ton of code, we can just use an fypp macro. I put an example of how one would have optionals and lists and confirmed that it works in this gist: https://gist.github.com/sbryngelson/c469cfc05551cd7a1868b028c51039c7

one would then use something like this

$:parallel_loop(private="[var1,var2]", collapse="2")

instead of an openacc or openmp directive. We would then want to automatically write/create both omp and openacc directives (the compiler will decide which one to use).

NOTE: OMP does not have a default(present) option and instead uses syntax like this in a different directive to make sure the variables are relevant variables are mapped to the device and there are no unnecessary data transfers. It would look like this:

!$omp target data map(present: x, y, z)
  !$omp target teams distribute parallel do collapse(2) private(var1, var2)
    ! ... nested loops ...
  !$omp end target teams distribute parallel do
!$omp end target data

However, I don't think there is a default option here, so not sure exactly what to do (probably just not use the data map?).

The gist looks like this

#:def mymacro(arg1, arg2=None, arg3=None)
    !arg2 and arg3 are optional
    #:set arg1_items = [x.strip() for x in arg1.strip('[]').split(',')]
    print *, "arg1 = ${', '.join(arg1_items)}$"

    #:if arg2 is not None
        #:set arg2_items = [x.strip() for x in arg2.strip('[]').split(',')]
        print*, "arg2 = ${', '.join(arg2_items)}$"
    #:endif

    #:if arg3 is not None
        #:set arg3_items = [x.strip() for x in arg3.strip('[]').split(',')]
        print*, "arg3 = ${', '.join(arg3_items)}$"
    #:endif
#:enddef mymacro

program test_macro
  implicit none
  call print_macro_args()
contains
  subroutine print_macro_args()
    print*, '> test macro with list of 3'
    $:mymacro(arg1="[A,B,C]", arg2="2", arg3="1")
    print*, '> test macro with numbers'
    $:mymacro(arg1="[1,2]", arg2="2", arg3="1")
    print*, '> test macro with one entry'
    $:mymacro(arg1="[1]", arg2="2", arg3="1")
    print*, '> test macro with one entry no brackets'
    $:mymacro(arg1="1", arg2="2", arg3="1")
    print*, '> test macro with no third argument'
    $:mymacro(arg1="[1,2]", arg2="2")
    print*, '> test macro with no second argument'
    $:mymacro(arg1="[1,2]", arg3="[1,a]")
  end subroutine print_macro_args
end program test_macro

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthelp wantedExtra attention is needed

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions