# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0
PortGroup           mpi 1.0

name                feast
version             4.0
revision            0
categories          science
platforms           darwin
maintainers         {dstrubbe @dstrubbe} openmaintainer
license             BSD

description         A free high-performance numerical library for solving Hermitian and non-Hermitian eigenvalue problems

long_description    The FEAST eigensolver package is a free high-performance numerical library for solving Hermitian \
    and non-Hermitian eigenvalue problems, and obtaining all the eigenvalues and (right/left) eigenvectors within a given \
    search interval or arbitrary domain in the complex plane. Its originality lies with a new transformative numerical \
    approach to the traditional eigenvalue algorithm design - the FEAST algorithm. The algorithm takes its inspiration from \
    the density-matrix representation and contour integration technique in quantum mechanics. It contains elements from \
    complex analysis, numerical linear algebra and approximation theory, and it can be defined as an optimal subspace \
    iteration method using approximate spectral projectors. FEAST's main building block is a numerical quadrature \
    computation consisting of solving independent linear systems along a complex contour, each with multiple right-hand \
    sides. A Rayleigh-Ritz procedure is then used to generate a reduced dense eigenvalue problem orders of magnitude \
    smaller than the original one. The FEAST eigensolver combines simplicity and efficiency and it offers many important \
    capabilities for achieving high performance, robustness, accuracy, and scalability on parallel architectures. \
    NOTE: Without an MPI variant, builds libfeast.a. With MPI, builds libpfeast.a.

homepage            http://www.feast-solver.org
# note: below will have to be updated for a new version
master_sites        http://www.ecs.umass.edu/~polizzi/feast/m4-0/
extract.suffix      .tgz
distname            ${name}_${version}

checksums           rmd160  f06d7a9e7646451533dfc1398564c0c6eaef8cdf \
                    sha1    1da96e25f57cfffe9a2d510a971df194f9621ddb \
                    sha256  2b084e785df658d3146cee51f29dc325babf3da1ac7a0cc248c3dd64a666943d \
                    size    29601256

use_configure       no
worksrcdir          FEAST/${version}/src

compilers.choose    cc fc
# g95 does not support OpenMP
mpi.setup           default require_fortran -g95
configure.optflags  -O3
# avoid gcc10 compilation type mismatch errors in /src/kernel/dzfeast.f90 and src/kernel/libnum.f90
compilers.allow_arguments_mismatch yes

use_parallel_build  yes

# also could be openblas or atlas. Use vecLibFort since it is quickest to install.
depends_test-append  port:vecLibFort
# needed for clang or llvm, only for tests in fact, but very quick to install
if {![gcc_variant_isset]} {
    depends_test-append port:libomp
}

pre-build {
    configure.fcflags-append  -ffree-line-length-none -ffixed-line-length-none -fopenmp -cpp
    # they say option 2 only works with ifort. compiles and links fine with gcc5, but segfaults in tests
    build.args-append  OPTION=1 CC=${configure.cc} CFLAGS="${configure.cflags}" F90=${configure.fc} \
        F90FLAGS="${configure.fcflags}" MKL=no

    if {[mpi_variant_isset]} {
        build.args-append PF90=${mpi.fc} PF90FLAGS="${configure.fcflags} -DMPI"
        build.target-append pfeast
    } else {
        build.target        feast
    }
}

# OPTION 1, +mpich or +openmpi: all sbev(x) C/F, serial/MPI (8 total) hang, no segfaults
# These are probably related to the need to patch the spike files about OpenMP, since they are banded.
#  +gfortran -mpich +clang37 everything passes.
#  +gfortran +mpich  clang[Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)]   serial sbev's hang
#  +gfortran +mpich +clang37 serial sbev's hang.

test.run            yes
test.dir            ${worksrcpath}/../example
pre-test {
    set libblas "-lvecLibFort"
    if {[gcc_variant_isset]} {
        set libomp  "-lgomp"
    } else {
        # clang
        set libomp  "${prefix}/lib/libomp/libomp.dylib"
    }
    if {[mpi_variant_isset]} {
        if {[mpi_variant_name] eq "mpich" || [mpi_variant_name] eq "mpich-devel"} {
            set mpiflib  "-lmpifort"
        } else {
            set mpiflib  "-lmpi_mpifh ${compilers.libfortran}"
        }
    } else {
        set mpiflib "${compilers.libfortran}"
    }

    set libs_general "${libblas} ${libomp}"
    
    test.args-append  C=${configure.cc} CFLAGS="${configure.cflags}" \
        F90=${configure.fc} F90FLAGS="${configure.fcflags}" \
        FORT=${configure.fc} FFLAGS="${configure.fcflags}"

    if {[mpi_variant_isset]} {
        test.args-append FLIBS="${libs_general} ../../lib/x64/libpfeast.a" \
            CLIBS="${libs_general} ../../lib/x64/libpfeast.a ${mpiflib}" \
            MPIRUN=${mpi.exec} PC=${mpi.cc} PF90=${mpi.f90}
        system -W ${test.dir} "echo 'test:\n\tulimit -t 200 && cd PFEAST-L1L2L3 && make N=${build.jobs} rall\n\tulimit -t 200 && cd PFEAST-L2 && make N=${build.jobs} rall\n\tulimit -t 200 && cd PFEAST-L2L3 && make N=${build.jobs} rall\n' >> Makefile"
    } else {
        test.args-append FLIBS="${libs_general} ../../lib/x64/libfeast.a" CLIBS="${libs_general} ../../lib/x64/libfeast.a ${mpiflib}"
        system -W ${test.dir} "echo 'test:\n\tulimit -t 200 && cd FEAST && make rall\n' >> Makefile"
    }
    # note: ulimit is to handle jobs that hang, and make them just fail.

    # in serial: all pass except F90sparse_dfeast_scsrpev-- failed.
    
    # results with default variants (mpich): 31 pass, 4 fail:
    # PF90sparse_dfeast_scsrpev -- failed
    # PCsparse_dfeast_scsrpev  -- failed
    # PF90sparse_pdfeast_scsrpev -- failed
    # PCsparse_pdfeast_scsrpev  -- failed
}

post-test {
    ui_notice "Examine log files (examples/*/*.log) for test results."
}

destroot {
    file mkdir ${destroot}${prefix}/share/doc/feast
    xinstall ${worksrcpath}/../doc/feast.pdf ${destroot}${prefix}/share/doc/feast
    xinstall {*}[glob ${worksrcpath}/../include/*] ${destroot}${prefix}/include/
    xinstall {*}[glob ${worksrcpath}/../lib/x64/*] ${destroot}${prefix}/lib/
}

notes {
    Users should fill out the short anonymous questionnaire, providing guidance for the FEAST project to better serve the scientific community:
    http://www.ecs.umass.edu/~polizzi/feast/registration.htm
}

livecheck.type      regex
livecheck.url       http://www.ecs.umass.edu/~polizzi/feast/
livecheck.regex     FEAST version v(\[0-9.\]+) release
