Section: BLAS/LAPACK - BLAS95#
Adapted from: gjbex/Fortran-MOOC
This program demonstrates the BLAS95 linear algebra library in Fortran.#
In file sdot.f90#
module sdot_mod
public :: sdot
contains
REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)
! ====== UPDATE TO DOCUMENTATION ======
! To make the calling program compile, I took sdot.f90 from BLAS at
! https://netlib.org/blas/ and changed it into a module.
! I was not able to get the Intel MKL library to work and the Intel
! source code was not available.
! =========== DOCUMENTATION ===========
!
!* Online html documentation available at
! http://www.netlib.org/lapack/explore-html/
!
! Definition:
! ===========
!
! REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)
!
! .. Scalar Arguments ..
! INTEGER INCX,INCY,N
! ..
! .. Array Arguments ..
! REAL SX(*),SY(*)
! ..
!
!
!*> \par Purpose:
! =============
!>
!*> \verbatim
!*>
!*> SDOT forms the dot product of two vectors.
!*> uses unrolled loops for increments equal to one.
!*> \endverbatim
!*
!* Arguments:
!* ==========
!*
!*> \param[in] N
!*> \verbatim
!*> N is INTEGER
!*> number of elements in input vector(s)
!*> \endverbatim
!*>
!*> \param[in] SX
!*> \verbatim
!*> SX is REAL array, dimension ( 1 + ( N - 1 )*abs( INCX ) )
!*> \endverbatim
!*>
!*> \param[in] INCX
!*> \verbatim
!*> INCX is INTEGER
!*> storage spacing between elements of SX
!*> \endverbatim
!*>
!*> \param[in] SY
!*> \verbatim
!*> SY is REAL array, dimension ( 1 + ( N - 1 )*abs( INCY ) )
!*> \endverbatim
!*>
!*> \param[in] INCY
!*> \verbatim
!*> INCY is INTEGER
!*> storage spacing between elements of SY
!*> \endverbatim
!*
!* Authors:
!* ========
!*
!*> \author Univ. of Tennessee
!*> \author Univ. of California Berkeley
!*> \author Univ. of Colorado Denver
!*> \author NAG Ltd.
!*
!*> \ingroup single_blas_level1
!*
!*> \par Further Details:
!* =====================
!*>
!*> \verbatim
!*>
!*> jack dongarra, linpack, 3/11/78.
!*> modified 12/3/93, array(1) declarations changed to array(*)
!*> \endverbatim
!*>
!* =====================================================================
!*
!* -- Reference BLAS level1 routine --
!* -- Reference BLAS is a software package provided by Univ. of Tennessee, --
!* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
!*
!* .. Scalar Arguments ..
INTEGER INCX,INCY,N
!* ..
!* .. Array Arguments ..
REAL SX(*),SY(*)
!* ..
!*
!* =====================================================================
!*
!* .. Local Scalars ..
REAL STEMP
INTEGER I,IX,IY,M,MP1
!* ..
!* .. Intrinsic Functions ..
INTRINSIC MOD
!* ..
STEMP = 0.0e0
SDOT = 0.0e0
IF (N.LE.0) RETURN
IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
!*
!* code for both increments equal to 1
!*
!*
!* clean-up loop
!*
M = MOD(N,5)
IF (M.NE.0) THEN
DO I = 1,M
STEMP = STEMP + SX(I)*SY(I)
END DO
IF (N.LT.5) THEN
SDOT=STEMP
RETURN
END IF
END IF
MP1 = M + 1
DO I = MP1,N,5
STEMP = STEMP + SX(I)*SY(I) + SX(I+1)*SY(I+1) + &
SX(I+2)*SY(I+2) + SX(I+3)*SY(I+3) + SX(I+4)*SY(I+4)
END DO
ELSE
!*
!* code for unequal increments or equal increments
!* not equal to 1
!*
IX = 1
IY = 1
IF (INCX.LT.0) IX = (-N+1)*INCX + 1
IF (INCY.LT.0) IY = (-N+1)*INCY + 1
DO I = 1,N
STEMP = STEMP + SX(IX)*SY(IY)
IX = IX + INCX
IY = IY + INCY
END DO
END IF
SDOT = STEMP
RETURN
!*
!* End of SDOT
!*
end function sdot
end module sdot_mod
In file section_blas_lapack_blas95_dot_blas95.f90#
program dot_test
use :: sdot_mod
implicit none
integer, parameter :: v_size = 5
integer :: i
real, dimension(v_size) :: vector1 = [ (0.5*I, i=1, v_size) ], &
vector2 = [ (0.1*i, i=1, v_size) ]
real, dimension(v_size, v_size) :: matrix = reshape( &
[ (real(i), i=1, v_size*v_size) ], [ v_size, v_size ] &
)
print '(A25, *(F5.1))', 'vector 1: ', vector1
print '(A25, *(F5.1))', 'vector 2: ', vector2
print '(A25, F6.2)', 'vector 1 . vector 2 =', &
sdot(v_size, vector1, 1, vector2, 1)
print *
print '(A)', 'matrix:'
do i = 1, size(matrix, 1)
print '(*(F5.1))', matrix(i, :)
end do
print *
print '(A, F6.1)', 'col 2 . col 4:', &
sdot(v_size, matrix(:, 2), 1, matrix(:, 4), 1)
print *
print '(A, F6.1)', 'row 2 . row 4:', &
sdot(v_size, matrix(2, :), 1, matrix(4, :), 1)
print *
end program dot_test
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()
code_dir = root_dir + "/" + "Fortran_Code/Section_BLAS_LAPACK_BLAS95"
os.chdir(code_dir)
build_status = os.system("fpm build 2>/dev/null")
Run the Program using FPM (Fortran Package Manager)#
The program is run and the output is saved into a data file data.dat.
exec_status = os.system("fpm run 2>/dev/null")
vector 1: 0.5 1.0 1.5 2.0 2.5
vector 2: 0.1 0.2 0.3 0.4 0.5
vector 1 . vector 2 = 2.75
matrix:
1.0 6.0 11.0 16.0 21.0
2.0 7.0 12.0 17.0 22.0
3.0 8.0 13.0 18.0 23.0
4.0 9.0 14.0 19.0 24.0
5.0 10.0 15.0 20.0 25.0
col 2 . col 4: 730.0
row 2 . row 4:1090.0