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

Replace Numerial Recipes LU decomp routines with LAPACK ones #227

Merged
2 changes: 1 addition & 1 deletion .github/workflows/Intel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
rm GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
sudo apt-get update
sudo apt-get install intel-oneapi-openmp intel-oneapi-compiler-fortran-2023.2.1 intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2023.2.1
sudo apt-get install intel-oneapi-openmp intel-oneapi-compiler-fortran-2023.2.1 intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2023.2.1 intel-oneapi-mkl-devel-2023.2.0
echo "source /opt/intel/oneapi/setvars.sh" >> ~/.bash_profile

- name: checkout
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/Linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ jobs:

- name: build
run: |
sudo apt install libopenblas-serial-dev
cd ip
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH="~/" -DOPENMP=${{ matrix.openmp }} ${{ matrix.options }} ..
cmake -DCMAKE_PREFIX_PATH="~/" -DOPENMP=${{ matrix.openmp }} ${{ matrix.options }} -DCMAKE_INSTALL_PREFIX=~/install -DBLA_VENDOR=OpenBLAS ..
make -j2 VERBOSE=1
make install
# Ensure that manual setting of '-DBLA_VENDOR=...' is reflected in output CMake config
if [ $(grep -c "BLA_VENDOR OpenBLAS" ~/install/lib/cmake/ip/ip-config.cmake) -eq 0 ]; then
echo "OpenBLAS not set as BLA_VENDOR in ip-config.cmake!"
exit 1
fi

- name: test
run: |
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/Spack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:

- name: spack-build-and-test
run: |
sudo apt install libopenblas-serial-dev
git clone -c feature.manyFiles=true https://github.com/spack/spack
. spack/share/spack/setup-env.sh
spack env create ip-env
Expand All @@ -43,9 +44,11 @@ jobs:
precision=$(echo ${{ matrix.variants }} | grep -oP " precision=\K[4d8]")
if [ "$precision" == "d" ]; then spack add grib-util@develop ; fi
spack external find cmake gmake
spack external find --path /usr/lib/x86_64-linux-gnu/openblas-serial openblas
spack config add "packages:lapack:buildable:false"
spack concretize
# Run installation and run CTest suite
spack install --verbose --fail-fast --test root
spack install --fail-fast --test root
# Run 'spack load' and check that key build options were respected
spack load ip
if [[ "${{ matrix.variants }}" =~ "+shared" ]]; then suffix="so" ; else suffix="a"; fi
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/developer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install doxygen
sudo apt-get install doxygen libopenblas-dev
python3 -m pip install gcovr

- name: checkout
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ if(OPENMP)
find_package(OpenMP REQUIRED COMPONENTS Fortran)
endif()

find_package(LAPACK REQUIRED)

# Set compiler flags.
if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|IntelLLVM)$")
set(CMAKE_Fortran_FLAGS "-g -traceback -assume byterecl -fp-model strict -fpp -auto ${CMAKE_Fortran_FLAGS}")
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ Code Manager: [Alex Richert](mailto:[email protected])

### Prerequisites

This package does not link to any other libraries, but requires CMake (version
3.15+) to build.
This package requires a BLAS/LAPACK library to provide several LU decomposition-related
routines, and requires CMake (version 3.15+) to build. In spack-stack, OpenBLAS will
be used as the provider of BLAS/LAPACK routines for all compilers.

### Installing

Expand Down
3 changes: 3 additions & 0 deletions cmake/PackageConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ if(@OPENMP@)
find_dependency(OpenMP COMPONENTS Fortran)
endif()

set(BLA_VENDOR @BLA_VENDOR@)
find_dependency(LAPACK)

# The target name needs to be one that's built, even if the dependent
# build does not use that version.
if(@BUILD_4@)
Expand Down
5 changes: 5 additions & 0 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ where for certain regions of certain grids, floating point differences between
field values. Some applications may therefore benefit from the use of 8-byte
reals (libip_d or libip_8).

NCEPLIBS-ip uses several BLAS/LAPACK routines in the splat() subroutine, and
therefore requires an external BLAS/LAPACK provider. In practice, this should
generally be OpenBLAS, which is the [spack-stack](https://github.com/JCSDA/spack-stack)
BLAS/LAPACK provider.

## Interpolation

### Interpolation Methods
Expand Down
11 changes: 11 additions & 0 deletions spack/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Ip(CMakePackage):
depends_on("sp precision=4", when="@4.1:4 precision=4")
depends_on("sp precision=d", when="@4.1:4 precision=d")
depends_on("sp precision=8", when="@4.1:4 precision=8")
depends_on("lapack", when="@develop")

def cmake_args(self):
args = [
Expand All @@ -88,6 +89,16 @@ def cmake_args(self):
if self.spec.satisfies("@5:"):
args.append(self.define_from_variant("BUILD_DEPRECATED", "deprecated"))

if self.spec.satisfies("@develop"):
# Use the LAPACK provider set by Spack even if the compiler supports native BLAS
bla_vendors = {"openblas": "OpenBLAS"}
lapack_provider = self.spec["lapack"].name
if lapack_provider in bla_vendors.keys():
bla_vendor = bla_vendors[lapack_provider]
else:
bla_vendor = "All"
args.append(self.define("BLA_VENDOR", bla_vendor))

return args

def setup_run_environment(self, env):
Expand Down
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ip_mercator_grid_mod.F90 ip_polar_stereo_grid_mod.F90
ip_rot_equid_cylind_egrid_mod.F90 ip_rot_equid_cylind_grid_mod.F90
ip_constants_mod.F90 ip_grids_mod.F90 ip_grid_factory_mod.F90
ip_interpolators_mod.F90 earth_radius_mod.F90 polfix_mod.F90
fftpack.F lapack_gen.F ncpus.F spanaly.f spdz2uv.f speps.f spfft1.f spffte.f
fftpack.F ncpus.F spanaly.f spdz2uv.f speps.f spfft1.f spffte.f
spfftpt.f splaplac.f splat.F splegend.f sppad.f spsynth.f sptezd.f sptez.f
sptezmd.f sptezm.f sptezmv.f sptezv.f sptgpm.f sptgpmv.f sptgps.f sptgpsv.f
sptgpt.f sptgptv.f sptrand.f sptran.f sptranf0.f sptranf1.f sptranf.f sptranfv.f
Expand Down Expand Up @@ -77,6 +77,7 @@ foreach(kind ${kinds})
if(OpenMP_Fortran_FOUND)
target_link_libraries(${lib_name} PUBLIC OpenMP::OpenMP_Fortran)
endif()
target_link_libraries(${lib_name} PUBLIC LAPACK::LAPACK)

list(APPEND LIB_TARGETS ${lib_name})

Expand Down
116 changes: 0 additions & 116 deletions src/lapack_gen.F

This file was deleted.

22 changes: 17 additions & 5 deletions src/splat.F
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ SUBROUTINE SPLAT(IDRT,JMAX,SLAT,WLAT)
$ 146.870307625, 150.011882457, 153.153458019, 156.295034268 /
REAL:: DLT,D1=1.
REAL AWORK((JMAX+1)/2,((JMAX+1)/2)),BWORK(((JMAX+1)/2))
INTEGER:: JHE,JHO,J0=0
INTEGER:: JHE,JHO,J0=0, INFO
INTEGER IPVT((JMAX+1)/2)
PARAMETER(PI=3.14159265358979,C=(1.-(2./PI)**2)*0.25)
C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down Expand Up @@ -133,8 +133,14 @@ SUBROUTINE SPLAT(IDRT,JMAX,SLAT,WLAT)
BWORK(JS)=-D1/(4*(JS-1)**2-1)
ENDDO

call ludcmp(awork,jho,jhe,ipvt)
call lubksb(awork,jho,jhe,ipvt,bwork)
! Call LAPACK routines
#if (LSIZE==4)
CALL SGETRF(JHO, JHO, AWORK, JHE, IPVT, INFO)
CALL SGETRS('N', JHO, 1, AWORK, JHE, IPVT, BWORK, JHO, INFO)
#else
CALL DGETRF(JHO, JHO, AWORK, JHE, IPVT, INFO)
CALL DGETRS('N', JHO, 1, AWORK, JHE, IPVT, BWORK, JHO, INFO)
#endif

WLAT(1)=0.
DO J=1,JHO
Expand Down Expand Up @@ -170,8 +176,14 @@ SUBROUTINE SPLAT(IDRT,JMAX,SLAT,WLAT)
BWORK(JS)=-D1/(4*(JS-1)**2-1)
ENDDO

call ludcmp(awork,jho,jhe,ipvt,d)
call lubksb(awork,jho,jhe,ipvt,bwork)
! Call LAPACK routines
#if (LSIZE==4)
CALL SGETRF(JHO, JHO, AWORK, JHE, IPVT, INFO)
CALL SGETRS('N', JHO, 1, AWORK, JHE, IPVT, BWORK, JHO, INFO)
#else
CALL DGETRF(JHO, JHO, AWORK, JHE, IPVT, INFO)
CALL DGETRS('N', JHO, 1, AWORK, JHE, IPVT, BWORK, JHO, INFO)
#endif

WLAT(1)=0.
DO J=1,JHO
Expand Down
Loading