Section: BLAS/LAPACK - GEMV#

Adapted from: gjbex/Fortran-MOOC

This program demonstrates using the GEMV BLAS/LAPACK subroutine to perform a matrix vector product in Fortran.#

In file section_blas_lapack_gemv.f90

program gemv_test
    use :: util_mod
    implicit none
    integer, parameter :: rows = 3, cols = 2
    integer :: i
    real, dimension(rows, cols) :: A = reshape( [ (real(i), i=1, rows*cols) ], [ rows, cols ])
    real, dimension(cols) :: v = [ 1.0, 2.0 ]
    real, dimension(rows) :: u
    character(len=12) :: fmt_str = '(*(F6.1))'
   
    ! Define explicit interface for the BLAS subroutine sgemv
    interface
        subroutine sgemv(trans, m, n, alpha, A, lda, x, incx, beta, y, incy)
            character :: trans
            integer :: m, n, lda, incx, incy
            real :: alpha, beta
            real, dimension(lda, *) :: A
            real, dimension(*) :: x, y
        end subroutine sgemv
    end interface

    call print_matrix(A, 'A', fmt_str)
    call print_vector(v, 'v', fmt_str)
    call sgemv('n', rows, cols, 1.0, A, rows, v, 1, 0.0, u, 1)
    call print_vector(u, 'u', fmt_str)

end program gemv_test

In file util_mod.f90

module util_mod
    implicit none

    private

    public :: print_vector, print_matrix

contains

    subroutine print_vector(vector, label, fmt_str_in)
        implicit none
        real, dimension(:), intent(in) :: vector
        character(len=*), intent(in), optional :: label, fmt_str_in
        character(len=20) :: fmt_str

        if (present(fmt_str_in)) then
            fmt_str = fmt_str_in
        else
            fmt_str = '(*(E18.7))'
        end if
        if (present(label)) print '(A)', label
        print fmt_str, vector
    end subroutine print_vector

    subroutine print_matrix(matrix, label, fmt_str_in)
        implicit none
        real, dimension(:, :), intent(in) :: matrix
        character(len=*), intent(in), optional :: label, fmt_str_in
        character(len=20) :: fmt_str
        integer :: row

        if (present(fmt_str_in)) then
            fmt_str = fmt_str_in
        else
            fmt_str = '(*(E18.7))'
        end if
        if (present(label)) print '(A)', label
        do row = 1, size(matrix, 1)
            print fmt_str, matrix(row, :)
        end do
    end subroutine print_matrix

end module util_mod

The above program is compiled and run using Fortran Package Manager (fpm):

Build the Program using FPM (Fortran Package Manager)#

import os
root_dir = ""
root_dir = os.getcwd()

Since the code makes use of the LAPACK library, the following FPM configuration file (fpm.toml) was used:

name = "Section_BLAS_LAPACK_GEMV"

[build]
auto-executables = true
auto-tests = true
auto-examples = true
link = ["blas", "lapack"]

[install]
library = false

[[executable]]
name="Section_BLAS_LAPACK_GEMV"
source-dir="app"
main="section_blas_lapack_gemv.f90"
code_dir = root_dir + "/" + "Fortran_Code/Section_BLAS_LAPACK_GEMV"
os.chdir(code_dir)
build_status = os.system("fpm build 2>/dev/null")

Run the Program using FPM (Fortran Package Manager)#

exec_status = \
    os.system("fpm run 2>/dev/null")
A
   1.0   4.0
   2.0   5.0
   3.0   6.0
v
   1.0   2.0
u
   9.0  12.0  15.0