File petsc.spec of Package petsc

#
# spec file for package petsc
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via http://bugs.opensuse.org/
#


%global flavor @BUILD_FLAVOR@%{nil}

%define pname petsc
%define vers 3.8.3
%define _vers 3_8_3
%define so_ver 3

ExcludeArch:    s390 s390x

%if 0%{?is_opensuse} || 0%{?is_backports}
%undefine DisOMPI3
%else
%define DisOMPI3 ExclusiveArch:  do_not_build
%endif

%if "%flavor" == ""
%dfine package_name %pname
ExclusiveArch:  do_not_build
%endif

%if "%flavor" == "doc"
%define makedoc 1
BuildArch:      noarch
%{bcond_with hpc}
%endif

%if "%flavor" == "serial"
%{bcond_with hpc}
%endif

%if "%flavor" == "openmpi"
%define mpi_family openmpi
%{bcond_with hpc}
%endif

%if "%flavor" == "mvapich2"
%define mpi_family mvapich2
%{bcond_with hpc}
%endif

%if "%flavor" == "gnu-openmpi-hpc"
%{?DisOMPI1}
%define mpi_family openmpi
%define compiler_family gnu
%undefine c_f_ver
%define mpi_vers 1
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu-openmpi3-hpc"
%{?DisOMPI3}
%define mpi_family openmpi
%define compiler_family gnu
%undefine c_f_ver
%define mpi_vers 3
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu-openmpi2-hpc"
%{?DisOMPI2}
%define mpi_family openmpi
%define compiler_family gnu
%undefine c_f_ver
%define mpi_vers 2
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu-mvapich2-hpc"
%define mpi_family mvapich2
%define compiler_family gnu
%undefine c_f_ver
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu-mpich-hpc"
%define mpi_family mpich
%define compiler_family gnu
%undefine c_f_ver
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu7-openmpi-hpc"
%{?DisOMPI1}
%define mpi_family openmpi
%define compiler_family gnu
%define c_f_ver 7
%define mpi_vers 1
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu7-openmpi3-hpc"
%{?DisOMPI3}
%define mpi_family openmpi
%define compiler_family gnu
%define c_f_ver 7
%define mpi_vers 3
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu7-mvapich2-hpc"
%define mpi_family mvapich2
%define compiler_family gnu
%define c_f_ver 7
%{bcond_without hpc}
%endif

%if "%flavor" == "gnu7-mpich-hpc"
%define mpi_family mpich
%define compiler_family gnu
%define c_f_ver 7
%{bcond_without hpc}
%endif

%if %{without hpc}
%if 0%{!?package_name:1}
%define package_name() %{pname}%{?with_mpi:-%{mpi_family}}
%endif
%define libname() lib%{pname}%{so_ver}%{?with_mpi:-%{mpi_family}}
%else
%{hpc_init -c %compiler_family -m %mpi_family %{?c_f_ver:-v %{c_f_ver}} %{?mpi_ver:-V %{mpi_ver}} %{?ext:-e %{ext}}}

%define package_name() %{hpc_package_name %_vers}
%define libname() lib%{pname}%{expand:%%{hpc_package_name_tail %{**}}}
%global libname_plain %{libname}
%endif

%if 0%{?mpi_family:1}
%{bcond_without mpi}
%else
%{bcond_with mpi}
%endif

%if %{without hpc}
 %if %{without mpi}
%define p_base %{_prefix}/
 %else
%{!?mpi_family:%global mpi_family openmpi}
%define p_base %{_libdir}/mpi/gcc/%{mpi_family}/
%define n_pref %{?with_mpi:%{mpi_family}-}
 %endif # mpi
%define p_prefix %{p_libdir}/petsc/%{version}/%petsc_arch
%else # hpc
%define p_base %{hpc_prefix}/
%define p_prefix %{hpc_prefix}
%endif

%define p_libdir %{p_base}%_lib
%define p_include %{p_base}include

%define petsc_arch linux-gnu-c-opt

Name:           %{package_name}
Summary:        Portable Extensible Toolkit for Scientific Computation
License:        BSD-2-Clause
Group:          Development/Libraries/C and C++
Version:        %vers
Release:        0

Source:         ftp://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-%{version}.tar.gz
Patch0:         petsc-3.3-p2-fix-shared-libs-sonames.patch
Patch1:         petsc-3.3-p2-no-rpath.patch
Patch2:         petsc-3.3-p2-dont-check-for-option-mistakes.patch
Patch3:         petsc-3.3-fix-error-detection-in-makefile.patch 
Patch4:         petsc-3.7-fix-pastix-detection.patch
Patch5:         Python-Fix-a-number-of-scripts-to-by-Python-3-compliant.patch
Url:            http://www.mcs.anl.gov/petsc/
BuildRoot:      %{_tmppath}/%{name}-%{version}-build
%if 0%{!?makedoc:1}
BuildRequires:  fdupes
BuildRequires:  pkg-config
BuildRequires:  python2
BuildRequires:  python3
%if 0%{?suse_version} >= 1315
BuildRequires:  hwloc-devel
%endif

%if %{without hpc}
BuildRequires:  Modules
BuildRequires:  blas-devel
BuildRequires:  gcc-c++
BuildRequires:  gcc-fortran
BuildRequires:  lapack-devel
BuildRequires:  metis-devel
BuildRequires:  suitesparse-devel

 %if %{with mpi}
BuildRequires:  %{mpi_family}-devel
BuildRequires:  blacs-%{mpi_family}-devel
BuildRequires:  hdf5-%{mpi_family}-devel
BuildRequires:  hypre-%{mpi_family}-devel
BuildRequires:  libptscotch-%{mpi_family}-devel
BuildRequires:  libptscotch-parmetis-%{mpi_family}-devel
BuildRequires:  pastix-%{mpi_family}-devel
BuildRequires:  scalapack-%{mpi_family}-devel
 %endif
%else
BuildRequires:  %{compiler_family}%{?c_f_ver}-compilers-hpc-macros-devel
BuildRequires:  %{mpi_family}%{?mpi_vers}-%{compiler_family}%{?c_f_ver}-hpc-macros-devel
BuildRequires:  hdf5%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc-devel
BuildRequires:  libopenblas%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-hpc-devel
BuildRequires:  libscalapack2%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc-devel
BuildRequires:  lua-lmod
BuildRequires:  suse-hpc
%endif

BuildRequires:  valgrind
BuildRequires:  xz
BuildRequires:  zlib-devel
%endif # !?makedoc

%description
PETSc is a suite of data structures and routines for the scalable
(parallel) solution of scientific applications modeled by partial 
differential equations.

%package -n %{libname %_vers}
Summary:        Devel files for petsc
Group:          System/Libraries
%if %{with hpc}
%{hpc_requires}
Requires:       libhdf5%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc
Requires:       libscalapack2%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc
%endif

%description -n %{libname %_vers}
PETSc is a suite of data structures and routines for the scalable
(parallel) solution of scientific applications modeled by partial 
differential equations.

%{?with_hpc:%{hpc_master_package -n %{libname_plain} -l -L}}

%package %{?n_pre}devel
Summary:        Devel files for petsc
Group:          Development/Libraries/C and C++
Requires:       %{libname} = %{version}
%if %{without hpc}
Requires:       Modules
Requires:       suitesparse-devel
 %if %{without mpi}
Requires:       metis-devel
 %else
Requires:       %{libname %_vers} = %{version}
Requires:       blacs-%{mpi_family}-devel
Requires:       hdf5-%{mpi_family}-devel
Requires:       hypre-%{mpi_family}-devel
Requires:       libptscotch-%{mpi_family}-devel
Requires:       libptscotch-parmetis-%{mpi_family}-devel
Requires:       scalapack-%{mpi_family}-devel
 %endif
%else # with hpc
Requires:       %{libname %_vers} = %{version}
Requires:       hdf5%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc-devel
Requires:       libopenblas%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-hpc-devel
Requires:       libscalapack2%{?hpc_ext}-%{compiler_family}%{?c_f_ver}-%{mpi_family}%{?mpi_vers}-hpc-devel
%hpc_requires_devel
%endif

%description %{?n_pre}devel
PETSc is a suite of data structures and routines for the scalable
(parallel) solution of scientific applications modeled by partial 
differential equations.

%{?with_hpc:%{hpc_master_package -a devel}}

%package doc
Summary:        Documentation for petsc
Group:          Documentation/HTML

%description doc
This package contains the documentation for petsc.

%if %{with hpc}
%package saws
Summary:        PETsc SAWs infrastructure
#Requires:      saws
#Requires:      jshon
Group:          Productivity/Scientific/Other
Requires:       %{libname %_vers} = %{version}

%description saws
This package contains the files to interface with SAWs
(Scientific Application Web server). SAWs itself is not
yet supported by %{?is_opensuse:open}SUSE.
%endif

%prep

%setup -q -n petsc-%{version}
%patch0 -p1 -b .soname
%patch1 -p1 -b .rpath
%patch2 -p1 -b .option-mistakes
%patch3 -p1 -b .error-detect
%patch4 -p1 -b .pastix-detect
%patch5 -p1

%if 0%{?makedoc:1}
%files doc
%defattr(-,root,root,-)
%doc docs/*
%else # !?makedoc

%if 0 && %{without hpc}
cat > %{_sourcedir}/baselibs.conf  <<EOF
%{libname %_vers}
%{name}-devel
  requires -blas-<targettype>
  requires -lapack-<targettype>
  requires " %{libname %_vers}-<targettype> = <version>"
EOF
%endif

%build

%if %{without hpc}
export PETSC_DIR=${RPM_BUILD_DIR}/petsc-%{version}
export PETSC_ARCH=%petsc_arch
%{?with_mpi:export LD_LIBRARY_PATH=%{p_libdir}}
%else
%hpc_setup
module load phdf5 scalapack openblas
%endif
%ifarch ppc64le ppc64 s390 aarch64
export ARCHCFLAGS=-fPIC
%endif

./config/configure.py \
	--CFLAGS="$RPM_OPT_FLAGS $ARCHCFLAGS" \
	--FFLAGS="$RPM_OPT_FLAGS $ARCHCFLAGS" \
	--CXXFLAGS="$RPM_OPT_FLAGS $ARCHCFLAGS" \
	--prefix=%{p_prefix} \
        --with-clanguage=C++ \
        --with-c-support \
	--with-fortran-interfaces=1 \
	--with-debugging=no \
	--with-shared-libraries \
	--with-batch=0 \
%if %{without hpc}
	--PETSC_DIR=$PETSC_DIR \
        --with-suitesparse=1 \
        --with-suitesparse-lib=[%{_libdir}/libklu.so,%{_libdir}/libumfpack.so,%{_libdir}/libcholmod.so,%{_libdir}/libcolamd.so,%{_libdir}/libccolamd.so,%{_libdir}/libcamd.so,%{_libdir}/libamd.so,%{_libdir}/libsuitesparseconfig.so,%{_libdir}/librt.so] \
        --with-suitesparse-include=%{_includedir}/suitesparse \
 %if %{without mpi}
	--with-mpi=0 \
 %else
	--with-mpi=1 \
        --with-mpi-dir=%{p_base}\
        --with-blacs=1 \
        --with-blacs-include=%{p_include} \
        --with-blacs-lib=[%{p_libdir}/libblacs.so] \
        --with-pastix=1 \
        --with-pastix-pkg-config=%{p_libdir}/pkgconfig \
        --with-ptscotch=1 \
        --with-ptscotch-include=%{p_include} \
        --with-ptscotch-lib=[%{p_libdir}/libptscotch.so,%{p_libdir}/libptscotcherr.so,%{p_libdir}/libptscotcherrexit.so,%{p_libdir}/libptscotchparmetis.so] \
        --with-scalapack=1 \
        --with-scalapack-include=%{p_include} \
        --with-scalapack-lib=[%{p_libdir}/libscalapack.so] \
        --with-hypre=1 \
        --with-hypre-include=%{p_include}/hypre \
        --with-hypre-lib=%{p_libdir}/libHYPRE.so \
        --with-hdf5=1 \
        --with-hdf5-lib=%{p_libdir}/libhdf5.so \
        --with-hdf5-include=%{p_include}
 %endif
%else # with hpc
        --with-blas-lapack-lib=$OPENBLAS_LIB/libopenblas.so \
        --with-scalapack-dir=$SCALAPACK_DIR \
        --with-hdf5=1 \
        --with-hdf5-lib=$HDF5_LIB/libhdf5.so \
        --with-hdf5-include=$HDF5_INC
%endif

make 

%install

%if %{without hpc}
export PETSC_DIR=${RPM_BUILD_DIR}/petsc-%{version}
export PETSC_ARCH=%petsc_arch
%endif

make install DESTDIR=%{buildroot}%p_prefix
rm -f %{buildroot}%{p_prefix}/share/petsc/examples/src/*/examples/*/output/*.out
rm -f %{buildroot}%{p_prefix}/share/petsc/examples/src/*/*/examples/*/output/*.out
rm -f %{buildroot}%{p_prefix}/share/petsc/examples/src/*/*/*/examples/*/output/*.out
rm -f %{buildroot}%{p_prefix}/lib/petsc/conf/*.log
rm -f %{buildroot}%{p_prefix}/lib/petsc/conf/.DIR

pushd %{buildroot}%{p_prefix}/lib
ln -sf libpetsc.so.%{version} libpetsc.so
popd

%if %{without hpc}

rm -rf %{buildroot}%{p_prefix}/lib/petsc/conf/*.log
rm -rf %{buildroot}%{p_prefix}/lib/petsc/conf/*.init
rm -rf %{buildroot}%{p_prefix}/lib/petsc/conf/*.py
rm -rf %{buildroot}%{p_prefix}/lib/petsc/conf/modules

# move include dirs outside ptesc dir
mv %{buildroot}%{p_prefix}/include %{buildroot}%{p_base}/
ln -s %{p_include} %{buildroot}%{p_prefix}/include

# create symlink for libs between %%libdir and petscdir
pushd %{buildroot}%{p_libdir}
for f in petsc/%{version}/%petsc_arch/lib/*.so*; do
   ln -s $f .
done
popd

# Module files 
mkdir -p %{buildroot}/usr/share/modules/%{name}-%{petsc_arch}
cat << EOF > %{buildroot}/usr/share/modules/%{name}-%{petsc_arch}/%version%{?with_mpi:-%{mpi_family}}
#%%Module
proc ModulesHelp { } {
        global dotversion
        puts stderr "\tLoads the %{name}-%{petsc_arch} %version Environment"
}

module-whatis  "Loads the %{name}-%{petsc_arch} %version Environment."
conflict %{name}-%{petsc_arch}
setenv PETSC_ARCH %{petsc_arch}
setenv PETSC_DIR  %{p_libdir}/petsc/%{version}/%{petsc_arch}
prepend-path LD_LIBRARY_PATH %{p_libdir}/petsc/%{version}/%{petsc_arch}/lib

EOF
%else # with hpc

if [ ! -d %{buildroot}%{p_libdir} -a -d %{buildroot}%{p_base}/lib ]
then
    mkdir -p %{buildroot}%{p_libdir}
    mv  %{buildroot}%{p_base}/lib/lib*.so %{buildroot}%{p_base}/lib/lib*.so.* %{buildroot}%{p_libdir}
    mv  %{buildroot}%{p_base}/lib/pkgconfig  %{buildroot}%{p_libdir}
fi

for i in update.py \
    bin/FASTMathInstaller.py \
    bin/TOPSGenerator.py \
    bin/petscnagupgrade.py \
    bin/configVars.py bin/update.py \
    lib/petsc/conf/reconfigure-arch-linux2-cxx-opt.py \
    lib/petsc/conf/uninstall.py
do
    rm -f %{buildroot}%{p_prefix}/$i
done

for file in %{hpc_bindir}/parseargs.py \
    %{hpc_bindir}/petsc_conf.py \
    %{hpc_bindir}/PetscBinaryIO.py \
    %{hpc_bindir}/PetscBinaryIOTrajectory.py
do
    %{hpc_python_mv_to_sitearch $file}
done
rm -rf %{buildroot}/%{hpc_bindir}/win32fe
rm -f  %{buildroot}/%{hpc_bindir}/uncrustify.cfg \
       %{buildroot}/%{hpc_bindir}/sendToJenkins \
       %{buildroot}/%{hpc_libdir}/rules

%{hpc_shebang_prepend_list %{buildroot}%{hpc_bindir}/*.py}

%hpc_shebang_sanitize_scripts %{buildroot}%{p_prefix}/bin
%hpc_shebang_sanitize_scripts %{buildroot}%{p_prefix}/lib/petsc

tmp=$(mktemp /tmp/bad-XXXXXX})
for file in $(find %{buildroot}%{p_prefix} -name "*.py"); do
    %{hpc_verify_python3 $file} || echo "$file" >> $tmp
done
[ -s $tmp ] && { echo "One or more python script not Python 3 compliant!"; cat $tmp; exit 1; }
rm -f $tmp

pyton_sitesearch_path=%{hpc_python_sitearch_no_singlespec}
%hpc_write_modules_files
#%%Module1.0#####################################################################

proc ModulesHelp { } {

puts stderr " "
puts stderr "This module loads the PETSc library built with the %{compiler_family} compiler"
puts stderr "toolchain and the %{mpi_family} MPI stack."
puts stderr " "

puts stderr "\nVersion %{version}\n"

}
module-whatis "Name: %{pname} built with %{compiler_family} compiler and %{mpi_family} MPI"
module-whatis "Version: %{version}"
module-whatis "Category: runtime library"
module-whatis "Description: %{SUMMARY:0}"
module-whatis "%{url}"

set     version                     %{version}

# Require phdf5 (and scalapack for gnu compiler families)

if [ expr [ module-info mode load ] || [module-info mode display ] ] {
    if {  ![is-loaded phdf5]  } {
        module load phdf5
    }
    if { ![is-loaded openblas]  } {
        module load openblas
    }
    if { ![is-loaded scalapack]  } {
        module load scalapack
    }
}

prepend-path    PATH                %{hpc_bindir}
prepend-path    LD_LIBRARY_PATH     %{hpc_libdir}
if {[file isdirectory  $pyton_sitesearch_path]} {
prepend-path    PYTHONPATH          $pyton_sitesearch_path
}

setenv          %{hpc_upcase %pname}_DIR        %{hpc_prefix}
if {[file isdirectory  %{hpc_bindir}]} {
setenv          %{hpc_upcase %pname}_BIN        %{hpc_bindir}
}
if {[file isdirectory  %{hpc_includedir}]} {
prepend-path    LIBRARY_PATH        %{hpc_libdir}
prepend-path    CPATH               %{hpc_includedir}
prepend-path    C_INCLUDE_PATH      %{hpc_includedir}
prepend-path    CPLUS_INCLUDE_PATH  %{hpc_includedir}
prepend-path    INCLUDE                         %{hpc_includedir}
%hpc_modulefile_add_pkgconfig_path

setenv          %{hpc_upcase %pname}_INC        %{hpc_includedir}
setenv          %{hpc_upcase %pname}_LIB        %{hpc_libdir}
}
EOF
%endif  # with hpc

# clean up non-include files
find %{buildroot}%{p_include} -name \*.html  -exec rm {} \;
find %{buildroot}%{p_include} -name makefile -exec rm {} \;

sed -i \
	-e 's!^\(#define PETSC_LIB_DIR\).*$!\1 "'%{p_prefix}/lib'"!' \
	-e 's!^\(#define PETSC_DIR\).*$!\1 "'%{p_prefix}'"!' \
	%{buildroot}%{p_include}/petscconf.h

# remove buildroot
find %{buildroot}%{p_prefix}/lib/petsc/conf/ %{buildroot}%{p_prefix}/bin/ -type f -print0 | \
while IFS= read -r -d $'\0' line ; do
  if file -e soft $line | grep -q "text" ; then
    sed -i -e 's!%{buildroot}!!g' $line
  fi
done

for i in $(find  %{buildroot}%{p_prefix}/share -perm /a+x -and -type f)
do
    head -1 $i | grep -q "#!" || chmod a-x $i
done

%fdupes %{buildroot}%{p_include}

##
%post -n %{libname %_vers} -p /sbin/ldconfig

%postun -n %{libname %_vers} 
/sbin/ldconfig
%{?with_hpc:%{hpc_module_delete_if_default}}

%files -n %{libname %_vers}
%defattr(-,root,root,-)
%doc docs/manual.pdf
%if %{without hpc}
%dir %{p_libdir}/petsc
%dir %{p_libdir}/petsc/%{version}
%else
%hpc_dirs
%hpc_modules_files
%endif # with hpc
%dir %{p_prefix}
%dir %{p_prefix}/lib
%{p_libdir}/*.so.*
%{!?with_hpc:%{p_prefix}/lib/*.so.*}
%{p_prefix}/share
%{dirname:%{hpc_python_sitearch_no_singlespec}}
%exclude %{p_prefix}/share/petsc/examples
%exclude %{p_prefix}/share/petsc/saws

%files %{?n_pre}devel
%defattr(-,root,root,-)
%{p_prefix}/bin
%exclude %{p_prefix}/bin/saws
%{p_prefix}/include
%{p_prefix}/lib/petsc
%{p_prefix}/%{!?with_hpc:lib}%{?with_hpc:%_lib}/pkgconfig
%{p_include}/*
%{p_libdir}/*.so
%if %{without hpc}
%{p_prefix}/lib/*.so
%dir %{_datadir}/modules/%{name}-%{petsc_arch}
%{_datadir}/modules/%{name}-%{petsc_arch}/%version%{?with_mpi:-%{mpi_family}}
%endif
%{p_prefix}/share/petsc/examples

%if %{with hpc}
%files saws
%defattr(-,root,root,-)
%{p_prefix}/bin/saws
%{p_prefix}/share/petsc/saws
%endif

%endif # !?makedoc

%changelog
openSUSE Build Service is sponsored by