# -*- 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           cmake 1.1
PortGroup           github 1.0
PortGroup           linear_algebra 1.0
PortGroup           mpi 1.0

github.setup        pghysels STRUMPACK 7.1.4 v
name                strumpack
revision            1
categories          math science
license             BSD
maintainers         {@barracuda156 gmail.com:vital.had} openmaintainer
description         Structured Matrix Package (LBNL)
long_description    STRUMPACK (STRUctured Matrix PACKage) is a software library \
                    providing linear algebra routines and linear system solvers \
                    for sparse and for dense rank-structured linear systems.
homepage            https://portal.nersc.gov/project/sparse/strumpack
checksums           rmd160  54bca9bc3bc5301822ebb31bae8ebd4c96eaf62e \
                    sha256  9ce61092e8e4b38475ff22bcbe31a89b82957036f82fea046759605dce007c7d \
                    size    2011922
github.tarball_from archive

depends_lib-append      port:metis \
                        port:scotch
depends_build-append    port:util-linux

compiler.cxx_standard   2014
compiler.openmp_version 4.5
compilers.choose        fc f90 cc cxx
compilers.setup         require_fortran

# Do not dump all headers into a generic include:
post-patch {
    reinplace "s|DESTINATION include|DESTINATION include/strumpack|g" ${worksrcpath}/CMakeLists.txt ${worksrcpath}/src/CMakeLists.txt
    foreach d {BLR clustering dense fortran HODLR HSS iterative kernel matlab misc python sparse structured} {
        fs-traverse f ${worksrcpath}/src/${d} {
            if {[file isfile ${f}]} {
                if {[regexp "\.txt" ${f}]} {
                    reinplace "s|DESTINATION include|DESTINATION include/strumpack|g" ${f}
                }
            }
        }
    }
}

pre-configure {
    if {[variant_isset openblas]} {
        configure.args-append  \
                    -DTPL_BLAS_LIBRARIES=${prefix}/lib/libopenblas.dylib \
                    -DTPL_LAPACK_LIBRARIES=${prefix}/lib/libopenblas.dylib
    } elseif {[variant_isset accelerate]} {
        configure.args-append  \
                    -DTPL_BLAS_LIBRARIES=vecLibFort \
                    -DTPL_LAPACK_LIBRARIES=vecLibFort
    }
}

configure.env-append \
                    GETOPT=${prefix}/bin/getopt

# In order to enable Bpack, Parmetis, Zfp etc., MPICH-based build is a requirement.
configure.args-append \
                    -DBUILD_SHARED_LIBS=ON \
                    -DSTRUMPACK_COUNT_FLOPS=OFF \
                    -DSTRUMPACK_MESSAGE_COUNTER=OFF \
                    -DSTRUMPACK_TASK_TIMERS=OFF \
                    -DSTRUMPACK_USE_BLAS64=OFF \
                    -DSTRUMPACK_USE_CUDA=OFF \
                    -DSTRUMPACK_USE_GETOPT=ON \
                    -DSTRUMPACK_USE_HIP=OFF \
                    -DSTRUMPACK_USE_MPI=OFF \
                    -DSTRUMPACK_USE_OPENMP=ON \
                    -DSTRUMPACK_USE_SYCL=OFF \
                    -DTPL_ENABLE_BPACK=OFF \
                    -DTPL_ENABLE_COMBBLAS=OFF \
                    -DTPL_ENABLE_MAGMA=OFF \
                    -DTPL_ENABLE_MATLAB=OFF \
                    -DTPL_ENABLE_PAPI=OFF \
                    -DTPL_ENABLE_PARMETIS=OFF \
                    -DTPL_ENABLE_PTSCOTCH=OFF \
                    -DTPL_ENABLE_SCOTCH=ON \
                    -DTPL_ENABLE_SLATE=OFF \
                    -DTPL_ENABLE_ZFP=OFF \
                    -DTPL_METIS_PREFIX=${prefix}

if {[string match *clang* ${configure.compiler}]} {
    configure.ldflags-append \
                    -L${prefix}/lib/libomp \
                    -lomp
}

# MPICH version builds but tests performance is questionable.
if {[mpi_variant_isset]} {
    PortGroup       active_variants 1.1

    # A hack until mpich-default is enabled for PPC:
    if {${os.platform} eq "darwin" && ${os.arch} eq "powerpc"} {
        mpi.setup   require_fortran \
                    -gcc44 -gcc45 -gcc46 -gcc47 -gcc48 -gcc49 -gcc5 \
                    -clang -fortran
    } else {
        mpi.setup   require_fortran \
                    -gcc44 -gcc45 -gcc46 -gcc47 -gcc48 -gcc49 -gcc5
    }

    depends_lib-append \
                    port:bpack \
                    port:gklib \
                    port:parmetis \
                    port:scalapack \
                    port:scotch \
                    port:zfp
    require_active_variants \
                    port:gklib openmp
    require_active_variants \
                    port:metis openmp

    pre-configure {
        configure.args-append \
                    -DMPI_RUN_COMMAND=${prefix}/bin/${mpi.exec} \
                    -DMPIEXEC_EXECUTABLE=${prefix}/bin/${mpi.exec}
    }

    configure.args-replace \
                    -DSTRUMPACK_USE_MPI=OFF -DSTRUMPACK_USE_MPI=ON \
                    -DTPL_ENABLE_BPACK=OFF -DTPL_ENABLE_BPACK=ON \
                    -DTPL_ENABLE_PARMETIS=OFF -DTPL_ENABLE_PARMETIS=ON \
                    -DTPL_ENABLE_ZFP=OFF -DTPL_ENABLE_ZFP=ON

    if {![catch {set result [active_variants bpack mpi]}]} {
        if {$result} {
            if {![variant_isset mpi]} {
                return -code error "bpack has mpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants bpack openmpi]}]} {
        if {$result} {
            if {![variant_isset openmpi]} {
                return -code error "bpack has openmpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants parmetis mpi]}]} {
        if {$result} {
            if {![variant_isset mpi]} {
                return -code error "parmetis has mpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants parmetis openmpi]}]} {
        if {$result} {
            if {![variant_isset openmpi]} {
                return -code error "parmetis has openmpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants scalapack mpi]}]} {
        if {$result} {
            if {![variant_isset mpi]} {
                return -code error "scalapack has mpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants scalapack openmpi]}]} {
        if {$result} {
            if {![variant_isset openmpi]} {
                return -code error "scalapack has openmpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants scotch mpi]}]} {
        if {$result} {
            if {![variant_isset mpi]} {
                return -code error "scotch has mpi enabled, please use the same variant."
            }
        }
    }

    if {![catch {set result [active_variants scotch openmpi]}]} {
        if {$result} {
            if {![variant_isset openmpi]} {
                return -code error "scotch has openmpi enabled, please use the same variant."
            }
        }
    }
}

depends_test-append port:wget

# FIXME: There are some failures on ppc: https://github.com/pghysels/STRUMPACK/issues/83
# Possibly precision-related. But anyway, do not use this to launch rockets.
test.run            yes
test.cmd            ctest

platform powerpc {
    test.env-append OMP_NUM_THREADS=1
}
