#36 Merged at 76bd89a
Repository
plasma_jakub_sistek
Branch
fortran
Repository
plasma
Branch
default

Fortran interface revisited

Author
  1. Jakub Sistek
Reviewers
Description

The interface is now generated in a completely automated way using the fortran_gen.py script, which creates only a single file plasma_mod.f90 in the include/ directory. Precompiling this file creates the module file include/plasma.mod While reducing the chance to introduce some errors, it can also introduce some. Only a subset of functions is actually tested at the moment.

Comments (4)

  1. Mark Gates

    One minor quibble: capitalization and indentation is inconsistent. E.g., test_zgetrs.f90 uses consistent 4-space indent and lowercase for program, use, implicit (below). I think I prefer this style, as it is more consistent with the C code in PLASMA.

    program test_zgetrs
        use, intrinsic :: iso_fortran_env
    
        use plasma
        implicit none
        ....
        if (num_panel_threads_check /= num_panel_threads) then
            write(*,'(a, i2, a, i2)') &
                "Something is wrong - number of threads for panel factorization " &
                //"is not set correctly:", &
                num_panel_threads_check, " not the same as ", num_panel_threads
        end if
    

    While test_zpotrf.f90 uses a mixture of 6-space and 2-space indent, and uppercase for PROGRAM, USE, IMPLICIT:

          PROGRAM TEST_ZPOTRF
    
          USE, INTRINSIC :: ISO_FORTRAN_ENV
          USE OMP_LIB
          USE PLASMA
    
          IMPLICIT NONE
          ...
          do i = 1, n
            A(i,i) = A(i,i) + n
          end do
    
  2. Mark Gates

    The Fortran module defines, say, plasma_dgetrf_c as the C routine in PLASMA, and plasma_dgetrf as a wrapper that calls it. The only difference I see is that the plasma_dgetrf wrapper has info instead of a return value. Can we just define plasma_dgetrf as the C routine, so Fortran directly calls that routine, have it return the error, and forgo having a separate wrapper?

    (Incidentally, BLAS G2 is proposing that BLAS routines return error values this way.)

    At first I thought there could be a name collision in the object file, as there is a C routine plasma_dgetrf and now a Fortran wrapper named the same, plasma_dgetrf. While gfortran appends an _ underscore, not all compilers do. Directly calling the C routine would avoid any potential name collision. But it appears that the name gets suitable mangled in the .o file:

    plasma> nm include/plasma_mod.o | grep -i dgetrf
    0000000000004b50 T ___plasma_MOD_plasma_dgetrf
    0000000000003bf0 T ___plasma_MOD_plasma_omp_dgetrf
    00000000000098e0 T ___plasma_MOD_plasma_pdgetrf
                     U _plasma_dgetrf
                     U _plasma_omp_dgetrf
                     U _plasma_pdgetrf
    

    I guess all compilers must do some form of mangling so that two modules can define the same name. Something to check, e.g., with PGI and IBM compilers. MAGMA uses magmaf_dgetrf (note extra "f") to avoid the name collision, but it doesn't use modules this way.

  3. Jakub Sistek author

    Good point with the mangling. I think that this could be a problem for the bare symbols like subroutines outside modules. But I am almost sure the module name is always mangled into the symbol name of routines and functions defined in modules. Most likely by all compilers. In our case, this should avoid the clash with the C symbols.

    Regarding the need for wrapper functions, we have thought quite a lot about not having them. However, the nice thing about having them is that we can isolate some of the passing by value/address business like c_loc(A) from the user. e.g. in info = plasma_zgetrf_c(m, n, c_loc(pA), lda, c_loc(ipiv)) One could probably improve the interface of the functions as well, but I do not see how we would deal with the recently added handling of ** pointers as in the wrapper subroutine plasma_sequence_create() This wrapper even has some code apart of simply calling the C function.

    Plus it seems Fortran programmers are much more used to the "call " subroutine syntax than to using functions in Fortran. I have never seen many functions used in Fortran codes so it is also about making the interface look familiar to the users :-) We were thinking at some point of having all functions void on the C side, but decided to stick to return values. So it seems that the wrappers provide a neat layer between the C world (where functions are the common approach) and the Fortran world (where routines are the common approach). So my vote goes to the current design with wrappers.

    Regarding the examples, the different coding styles were left there on purpose. I prepared some examples and Maksims prepared others. And we did not like the style of each other :-) The lesson learnt is that every Fortran programmer has a different style and we want to take the chance of providing examples also in several styles. This increases the chances that a random Fortran programmer will open an example pleasing his eye and will "read further". I think I like this conclusion and would like to leave it like that, I do not see a stong need for consistency of examples as long as the codegen.py can digest it.

  4. Jakub Kurzak

    I see the points on both sides. I think it's about time to merge this pull request, though. Please continue the discussion on plasma-dev and create tickets in the issue tracker if necessary.