Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fortran interface for lapack dense solver #353

Merged
merged 8 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ Fixed scaling bug in `SUNMatScaleAddI_Sparse` for non-square matrices.
Fixed missing soversions in some `SUNLinearSolver` and `SUNNonlinearSolver`
CMake targets.

Added Fortran support for the LAPACK dense `SUNLinearSolver` implementations.

Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA
and fixed the targets used for rocBLAS and rocSPARSE.

Added the fourth order ERK method `ARKODE_SOFRONIOU_SPALETTA_5_3_4`.


## Changes to SUNDIALS in release 6.6.1

Updated the Tpetra NVector interface to support Trilinos 14.
Expand Down
3 changes: 3 additions & 0 deletions doc/arkode/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,11 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Added the fourth order ERK method ``ARKODE_SOFRONIOU_SPALETTA_5_3_4``.


Changes in v5.6.1
-----------------

Expand Down
2 changes: 2 additions & 0 deletions doc/cvode/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Changes in v6.6.1
-----------------

Expand Down
2 changes: 2 additions & 0 deletions doc/cvodes/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Changes in v6.6.1
-----------------

Expand Down
2 changes: 2 additions & 0 deletions doc/ida/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Changes in v6.6.1
-----------------

Expand Down
2 changes: 2 additions & 0 deletions doc/idas/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Changes in v5.6.1
-----------------

Expand Down
2 changes: 2 additions & 0 deletions doc/kinsol/guide/source/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Fixed scaling bug in ``SUNMatScaleAddI_Sparse`` for non-square matrices.
Fixed missing soversions in some ``SUNLinearSolver`` and ``SUNNonlinearSolver``
CMake targets.

Added Fortran support for the LAPACK dense ``SUNLinearSolver`` implementation.

Changes in v6.6.1
-----------------

Expand Down
56 changes: 56 additions & 0 deletions examples/sunlinsol/lapackdense/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ set(sunlinsol_lapackdense_dependencies
test_sunlinsol
)

# If building F2003 tests
if (BUILD_FORTRAN_MODULE_INTERFACE)
set(sunlinsol_lapackdense_fortran_examples
"test_fsunlinsol_lapackdense_mod\;10 0 0\;"
"test_fsunlinsol_lapackdense_mod\;100 0 0\;"
"test_fsunlinsol_lapackdense_mod\;500 0 0\;"
"test_fsunlinsol_lapackdense_mod\;1000 0 0\;"
)
endif()

# Add source directory to include directories
include_directories(. ..)

Expand Down Expand Up @@ -82,6 +92,52 @@ foreach(example_tuple ${sunlinsol_lapackdense_examples})

endforeach(example_tuple ${sunlinsol_lapackdense_examples})

# Add the build and install targets for each example
foreach(example_tuple ${sunlinsol_lapackdense_fortran_examples})

# parse the example tuple
list(GET example_tuple 0 example)
list(GET example_tuple 1 example_args)
list(GET example_tuple 2 example_type)

# check if this example has already been added, only need to add
# example source files once for testing with different inputs
if(NOT TARGET ${example})
# example source files
add_executable(${example} ${example}.f90
${SUNDIALS_SOURCE_DIR}/examples/utilities/test_utilities.f90
${SUNDIALS_SOURCE_DIR}/examples/sunlinsol/test_sunlinsol.f90)

# folder to organize targets in an IDE
set_target_properties(${example} PROPERTIES FOLDER "Examples")

# set fortran module directory to avoid name collisions
set_target_properties(${example} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

# libraries to link against
target_link_libraries(${example}
sundials_nvecserial
sundials_fnvecserial_mod
sundials_sunlinsollapackdense
sundials_fsunlinsollapackdense_mod
${EXE_EXTRA_LINK_LIBS})

# check if example args are provided and set the test name
if("${example_args}" STREQUAL "")
set(test_name ${example})
else()
string(REGEX REPLACE " " "_" test_name ${example}_${example_args})
endif()

# add example to regression tests
sundials_add_test(${test_name} ${example}
TEST_ARGS ${example_args}
EXAMPLE_TYPE ${example_type}
NODIFF)
endif()

endforeach(example_tuple ${sunlinsol_lapackdense_fortran_examples})


if(EXAMPLES_INSTALL)

Expand Down
185 changes: 185 additions & 0 deletions examples/sunlinsol/lapackdense/test_fsunlinsol_lapackdense_mod.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
! -----------------------------------------------------------------
! Programmer(s): Daniel R. Reynolds @ SMU
! -----------------------------------------------------------------
! SUNDIALS Copyright Start
! Copyright (c) 2002-2023, Lawrence Livermore National Security
! and Southern Methodist University.
! All rights reserved.
!
! See the top-level LICENSE and NOTICE files for details.
!
! SPDX-License-Identifier: BSD-3-Clause
! SUNDIALS Copyright End
! -----------------------------------------------------------------
! This file tests the Fortran 2003 interface to the SUNDIALS
! LAPACK-Dense SUNLinearSolver implementation.
! -----------------------------------------------------------------

module test_fsunlinsol_lapackdense
use, intrinsic :: iso_c_binding
use test_utilities
implicit none

integer(C_LONG), private, parameter :: N = 100

contains

integer(C_INT) function unit_tests() result(fails)
use, intrinsic :: iso_c_binding
use fsundials_nvector_mod
use fsundials_matrix_mod
use fsundials_linearsolver_mod
use fnvector_serial_mod
use fsunmatrix_dense_mod
use fsunlinsol_lapackdense_mod
use test_sunlinsol

implicit none

type(SUNLinearSolver), pointer :: LS ! test linear solver
type(SUNMatrix), pointer :: A, I ! test matrices
type(N_Vector), pointer :: x, b ! test vectors
real(C_DOUBLE), pointer :: colj(:), colIj(:) ! matrix column data
real(C_DOUBLE), pointer :: xdata(:) ! x vector data
real(C_DOUBLE) :: tmpr ! temporary real value
integer(C_LONG) :: j, k
integer(C_INT) :: tmp

fails = 0

A => FSUNDenseMatrix(N, N, sunctx)
I => FSUNDenseMatrix(N, N, sunctx)
x => FN_VNew_Serial(N, sunctx)
b => FN_VNew_Serial(N, sunctx)

! fill A matrix with uniform random data in [0, 1/N)
do j=1, N
colj => FSUNDenseMatrix_Column(A, j-1)
do k=1, N
call random_number(tmpr)
colj(k) = tmpr / N
end do
end do

! create anti-identity matrix
j = N
do k=1, N
colj => FSUNDenseMatrix_Column(I, j-1)
colj(k) = ONE
j = j-1
end do

! add anti-identity to ensure the solver needs to do row-swapping
do k=1, N
do j=1, N
colj => FSUNDenseMatrix_Column(A, j-1)
colIj => FSUNDenseMatrix_Column(I, j-1)
colj(k) = colj(k) + colIj(k)
end do
end do

! fill x vector with uniform random data in [0, 1)
xdata => FN_VGetArrayPointer(x)
do j=1, N
call random_number(tmpr)
xdata(j) = tmpr
end do

! create RHS vector for linear solve
fails = FSUNMatMatvec(A, x, b)
if (fails /= 0) then
call FSUNMatDestroy(A)
call FSUNMatDestroy(I)
call FN_VDestroy(x)
call FN_VDestroy(b)
return
end if

! create dense linear solver
LS => FSUNLinSol_LapackDense(x, A, sunctx)

! run tests
fails = fails + Test_FSUNLinSolInitialize(LS, 0)
fails = fails + Test_FSUNLinSolSetup(LS, A, 0)
fails = fails + Test_FSUNLinSolSolve(LS, A, x, b, 100*UNIT_ROUNDOFF, 0)

fails = fails + Test_FSUNLinSolGetType(LS, SUNLINEARSOLVER_DIRECT, 0)
fails = fails + Test_FSUNLinSolLastFlag(LS, 0)
fails = fails + Test_FSUNLinSolSpace(LS, 0)

! cleanup
tmp = FSUNLinSolFree(LS)
call FSUNMatDestroy(A)
call FSUNMatDestroy(I)
call FN_VDestroy(x)
call FN_VDestroy(b)

end function unit_tests

end module

integer(C_INT) function check_vector(X, Y, tol) result(failure)
use, intrinsic :: iso_c_binding
use fsundials_nvector_mod
use test_utilities

implicit none
type(N_Vector) :: x, y
real(C_DOUBLE) :: tol, maxerr
integer(C_LONG) :: i, xlen, ylen
real(C_DOUBLE), pointer :: xdata(:), ydata(:)

failure = 0

xdata => FN_VGetArrayPointer(x)
ydata => FN_VGetArrayPointer(y)

xlen = FN_VGetLength(x)
ylen = FN_VGetLength(y)

if (xlen /= ylen) then
print *, 'FAIL: check_vector: different data array lengths'
failure = 1
return
end if

do i = 1, xlen
failure = failure + FNEQTOL(xdata(i), ydata(i), tol)
end do

if (failure > 0) then
maxerr = ZERO
do i = 1, xlen
maxerr = max(abs(xdata(i)-ydata(i))/abs(ydata(i)), maxerr)
end do
write(*,'(A,E14.7,A,E14.7,A)') &
"FAIL: check_vector failure: maxerr = ", maxerr, " (tol = ", tol, ")"
end if

end function check_vector

program main
!======== Inclusions ==========
use, intrinsic :: iso_c_binding
use test_fsunlinsol_lapackdense

!======== Declarations ========
implicit none
integer(C_INT) :: fails = 0

!============== Introduction =============
print *, 'LAPACK-Dense SUNLinearSolver Fortran 2003 interface test'

call Test_Init(c_null_ptr)

fails = unit_tests()
if (fails /= 0) then
print *, 'FAILURE: n unit tests failed'
stop 1
else
print *,'SUCCESS: all unit tests passed'
end if

call Test_Finalize()

end program main
4 changes: 4 additions & 0 deletions scripts/shared
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ echo " --- Add sunlinsol/lapackdense module to $tarfile"

$tar $tarfile $distrobase/src/sunlinsol/lapackdense/CMakeLists.txt
$tar $tarfile $distrobase/src/sunlinsol/lapackdense/sunlinsol_lapackdense.c
$tar $tarfile $distrobase/src/sunlinsol/lapackdense/fmod/CMakeLists.txt
$tar $tarfile $distrobase/src/sunlinsol/lapackdense/fmod/fsunlinsol_lapackdense_mod.c
$tar $tarfile $distrobase/src/sunlinsol/lapackdense/fmod/fsunlinsol_lapackdense_mod.f90

echo " --- Add sunlinsol/magmadense module to $tarfile"

Expand Down Expand Up @@ -713,6 +716,7 @@ $tar $tarfile $distrobase/examples/sunlinsol/kokkos/CMakeLists.txt
$tar $tarfile $distrobase/examples/sunlinsol/lapackband/test_sunlinsol_lapackband.c
$tar $tarfile $distrobase/examples/sunlinsol/lapackband/CMakeLists.txt
$tar $tarfile $distrobase/examples/sunlinsol/lapackdense/test_sunlinsol_lapackdense.c
$tar $tarfile $distrobase/examples/sunlinsol/lapackdense/test_fsunlinsol_lapackdense_mod.f90
$tar $tarfile $distrobase/examples/sunlinsol/lapackdense/CMakeLists.txt

$tar $tarfile $distrobase/examples/sunlinsol/magmadense/test_sunlinsol_magmadense.cpp
Expand Down
5 changes: 5 additions & 0 deletions src/sunlinsol/lapackdense/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ sundials_add_library(sundials_sunlinsollapackdense
)

message(STATUS "Added SUNLINSOL_LAPACKDENSE module")

# Add module if F2003 interface is enabled
if(BUILD_FORTRAN_MODULE_INTERFACE)
add_subdirectory(fmod)
endif()
32 changes: 32 additions & 0 deletions src/sunlinsol/lapackdense/fmod/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ----------------------------------------------------------------------
# Programmer(s): Cody J. Balos @ LLNL
# ----------------------------------------------------------------------
# SUNDIALS Copyright Start
# Copyright (c) 2002-2023, Lawrence Livermore National Security
# and Southern Methodist University.
# All rights reserved.
#
# See the top-level LICENSE and NOTICE files for details.
#
# SPDX-License-Identifier: BSD-3-Clause
# SUNDIALS Copyright End
# ----------------------------------------------------------------------
# CMakeLists.txt file for the F2003 LAPACK dense SUNLinearSolver
# object library
# ----------------------------------------------------------------------

sundials_add_f2003_library(sundials_fsunlinsollapackdense_mod
SOURCES
fsunlinsol_lapackdense_mod.f90 fsunlinsol_lapackdense_mod.c
OBJECT_LIBRARIES
sundials_fgeneric_mod_obj
LINK_LIBRARIES
PUBLIC sundials_fsunmatrixdense_mod
OUTPUT_NAME
sundials_fsunlinsollapackdense_mod
VERSION
${sunlinsollib_VERSION}
SOVERSION
${sunlinsollib_SOVERSION}
)
message(STATUS "Added SUNLINSOL_LAPACKDENSE F2003 interface")
Loading