GithubHelp home page GithubHelp logo

14ngiestas / mfi Goto Github PK

View Code? Open in Web Editor NEW
37.0 6.0 2.0 1.4 MB

Modern Fortran Interfaces to BLAS and LAPACK

License: MIT License

Fortran 99.65% Makefile 0.35%
lapack blas linear-algebra modern-fortran fortran interfaces-fortran

mfi's People

Contributors

14ngiestas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

awvwgk skphy

mfi's Issues

zherk has an incorrect interface

The interface from netlib for zherk says that alpha and beta should be double precision but the generated interface is

pure subroutine zherk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
import :: REAL64
integer, parameter :: wp = REAL64
complex(wp), intent(in) :: a(lda,)
complex(wp), intent(inout) :: c(ldc,
)
character, intent(in) :: trans
character, intent(in) :: uplo
complex(wp), intent(in) :: alpha
complex(wp), intent(in) :: beta
integer, intent(in) :: n
integer, intent(in) :: k
integer, intent(in) :: lda
integer, intent(in) :: ldc
end subroutine

with alpha and beta complex which is incorrect

Common interface to cuBLAS

For a variant of my set of BLAS wrappers I had to incorporate support for NVIDIA's cuBLAS as well at some point, which requires usage of OpenACC to perform the copyin/copyout to the device. While cuBLAS mostly shares the BLAS API it is still a vendor extension to it.

Are you planning to support vendor specific extension to the BLAS/LAPACK API in this interface as well?

Strange use of type literals in generated code

There are lots of cases in the generated code of the use of 1_wp and 0_wp. An example is here in mfi_saxpy (blas.f90)

pure subroutine mfi_saxpy(x, y, a, incx, incy)
    integer, parameter :: wp = REAL32
    real(wp), intent(in) :: x(:)
    real(wp), intent(inout) :: y(:)
    real(wp), intent(in), optional :: a
    real(wp) :: local_a
    integer, intent(in), optional :: incx
    integer :: local_incx
    integer, intent(in), optional :: incy
    integer :: local_incy
    integer :: n
    if (present(a)) then
        local_a = a
    else
        local_a = 1
    end if
    if (present(incx)) then
        local_incx = incx
    else
        local_incx = 1_wp
    end if
    if (present(incy)) then
        local_incy = incy
    else
        local_incy = 1_wp
    end if
    N = size(X)
    call f77_axpy(n,local_a,x,local_incx,y,local_incy)
end subroutine

This will create integer literals of that kind-- probably 32/64 bit but it is not even guaranteed that integer(kind=wp) exists since wp is a kind for real numbers. I believe these should be just 1 or 0.

The _wp should be on the real constants and these should be specified with a "." to indicate that they are real literals.

eg I believe the generated code should be

pure subroutine mfi_saxpy(x, y, a, incx, incy)
    integer, parameter :: wp = REAL32
    real(wp), intent(in) :: x(:)
    real(wp), intent(inout) :: y(:)
    real(wp), intent(in), optional :: a
    real(wp) :: local_a
    integer, intent(in), optional :: incx
    integer :: local_incx
    integer, intent(in), optional :: incy
    integer :: local_incy
    integer :: n
    if (present(a)) then
        local_a = a
    else
        local_a = 1.0_wp
    end if
    if (present(incx)) then
        local_incx = incx
    else
        local_incx = 1
    end if
    if (present(incy)) then
        local_incy = incy
    else
        local_incy = 1
    end if
    N = size(X)
    call f77_axpy(n,local_a,x,local_incx,y,local_incy)
end subroutine

Ambiguous interface

The interface is the same in the current fortran standard:

interface fun
pure function real_fun(x)
    real(REAL32) :: x
end function

pure function double_fun(x)
    real(REAL64) :: x
end function
end interface

Tests and benchmarks

How to consistently generate tests?

BLAS

  • NETLIB's BLAS/TESTING z and c are basically the same apart from constants literals (E vs D), types (COMPLEX*16 vs COMPLEX), and obviously the function prefixes z and c. The same happens to s and d prefixes.
  • It seems to test all combinations of parameters
  • I'll need to extract the data from the src code

LAPACK

  • It uses a lot of *.in *.out files
  • It looks like it follows the same pattern of BLAS/TESTING in the prefix

There is a problem with module procedure <blas_routine>

It seems I need to explicitly define the F77 to each interface in order to use a "type agnostic" F77 BLAS function

~$ fypp blas.fpp blas.90
~$ gfortran blas.f90 /usr/lib/libblas.a
blas.f90:77:21:

   77 |     module procedure dzasum
      |                     1
Error: Procedure ‘dzasum’ in generic interface 'f77_asum' at (1) is neither function nor subroutine
blas.f90:51:21:

   51 |     module procedure zaxpy
      |                     1
Error: Procedure ‘zaxpy’ in generic interface 'f77_axpy' at (1) is neither function nor subroutine
blas.f90:259:21:

Generic interfaces

Hello @14NGiestas,

Digging through the BLAS forum, I found a document describing a "Fortran 95 thin BLAS": http://www.netlib.org/blas/blast-forum/f95thinblas.pdf

The document proposes to build generic interfaces with respect to:

  • data type
  • precision
  • rank
  • argument list

I believe that the LAPACK 95 and Intel MKL Fortran Interfaces for LAPACK 95 are partial or even full implementations of this proposal. It seems kind of annoying that their interfaces diverged slightly. NAG on the other hand seems to only export the low level interfaces, however inspection of the LAPACK 95 interface files shows that NAG was also involved in their development.

I assume you would like this layer to work with any compiler/custom LAPACK library, so it makes to sense (re)build the modern/generic interfaces from the low-level ones. It does feel though, like re-inventing the wheel.

I am interested in what do you think can be done differently using fypp?

The LAPACK 95 seems to have integrated some error checking of arguments. This is one of the things which could be perhaps simplified with fypp.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.