# -*- 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
# $Id: Portfile 112010 2013-10-09 14:36:57Z michaelld@macports.org $

PortSystem          1.0
PortGroup           muniversal 1.0

name                itsol
version             2.0.0

license             GPL-2+
categories          math
platforms           darwin
maintainers         michaelld openmaintainer

description         ITerative SOLvers for sparse linear systems.

long_description    ITSOL is a library of iterative solvers for general sparse linear systems of equations. \
                    ITSOL can be viewed as an extension of the itsol module in SPARSKIT. It is written in C \
                    and offers a selection of recently developed preconditioners. The preconditioner suite includes: \
                    ILUK (ILU preconditioner with level of fill) \
                    ILUT (ILU preconditioner with threshold) \
                    ILUC (Crout version of ILUT) \
                    VBILUK (variable block preconditioner with level of fill - with automatic block detection) \
                    VBILUT (variable block preconditioner with threshold - with automatic block detection) \
                    ARMS (Algebraic Recursive Multilevel Solvers -- includes actually several methods - \
                    In particular the standard ARMS and the ddPQ version which uses nonsymmetric permutations). \
                    Note that ITSOL is a scalar package.

homepage            http://www-users.cs.umn.edu/~saad/software/ITSOL/

set distname        ITSOL_2
master_sites        http://www-users.cs.umn.edu/~saad/software/ITSOL/
checksums           rmd160 fe61d6602df541a30e0f3b587ac123bd6f1d318e \
                    sha256 de8f2726e2dbc248e8ccebdbc9ce8515ad47a8c8595cca87264c22b44845736a

patchfiles          patch-INC_protos.h.diff \
                    patch-SRC.diff \
                    patch-makefile.diff

depends_lib         path:lib/libgcc/libgcc_s.1.dylib:libgcc

#########################
# set up fortran variants

set gcc_versions {4.3 4.4 4.5 4.6 4.7 4.8 4.9}
set gcc_default "4.8"

# create g95 variant, with full conflicts of GCC versions

set gcc_conflicts ""
foreach ver ${gcc_versions} {
    set gcc_ver_no_dot gcc[join [split ${ver} "."] ""]
    set gcc_conflicts "${gcc_conflicts} ${gcc_ver_no_dot}"
}

# atlas does not provide a +g95 variant, so if +g95 is used,
# +accelerate must also be used.  +accelerate will work with +gccXY,
# so this is all a bit complex to check for.  Setting 'requires' here
# does not yet seem to work with 'port' to get [+]accelerate; leaving
# it out does work, so doing that and checking for this condition
# later, for now.

eval [subst {
    variant g95 conflicts ${gcc_conflicts} \
        description "Build with MacPorts g95 as the Fortran Compiler" {
            depends_build-append port:g95
            configure.fc ${prefix}/bin/g95
        }
}]

# create GCC variants, with partial conflicts of other GCC versions

foreach ver1 ${gcc_versions} {

    set gcc_ver1_no_dot gcc[join [split ${ver1} "."] ""]

    set gcc_conflicts "conflicts g95"
    foreach ver2 ${gcc_versions} {
        if {${ver1} == ${ver2}} {
            continue
        }
        set gcc_ver2_no_dot gcc[join [split ${ver2} "."] ""]
        set gcc_conflicts "${gcc_conflicts} ${gcc_ver2_no_dot}"
    }

    eval [subst {
        variant ${gcc_ver1_no_dot} ${gcc_conflicts} \
            description {Build with the MacPorts ${gcc_ver1_no_dot} as the Fortran Compiler} {
                depends_build-append port:${gcc_ver1_no_dot}
                configure.fc ${prefix}/bin/gfortran-mp-${ver1}
            }
    }]
}

######################
# set up BLAS variants

# atlas does not work with g95, so always conflict with it

variant atlas description {use BLAS from MacPorts' atlas port} \
    conflicts g95 accelerate {}

# accelerate works with any fortran variant

variant accelerate description \
    {use BLAS from Apple's Accelerate.framework [might be buggy]} \
    conflicts atlas {}

##################
# variant checking

set gcc_default_no_dot gcc[join [split ${gcc_default} "."] ""]

set fortran_variant_selection ""
if {[variant_isset g95]} {
    set fortran_variant_selection "g95"
} else {
    foreach ver ${gcc_versions} {
        set gcc_ver_no_dot gcc[join [split ${ver} "."] ""]
        if {[variant_isset ${gcc_ver_no_dot}]} {
            set fortran_variant_selection "${gcc_ver_no_dot}"
        }
    }
}

if {${fortran_variant_selection} eq ""} {
    default_variants +${gcc_default_no_dot}

    # check for -${gcc_default_no_dot} alone

    set fortran_variant_selection ""
    if {[variant_isset g95]} {
        set fortran_variant_selection "g95"
    } else {
        foreach ver ${gcc_versions} {
            set gcc_ver_no_dot gcc[join [split ${ver} "."] ""]
            if {[variant_isset ${gcc_ver_no_dot}]} {
                set fortran_variant_selection "${gcc_ver_no_dot}"
            }
        }
    }

    if {${fortran_variant_selection} eq ""} {
        ui_error "\n\nYou cannot use the -${gcc_default_no_dot} variant alone; a Fortran compiler is required.\n"
        return -code error "Invalid variant selection"
s    }
}

# check for BLAS default variant, use +atlas if nothing else

set blas_variant_selection ""
if {[variant_isset g95] || [variant_isset accelerate]} {
    set blas_variant_selection "accelerate"
} else {
    set blas_variant_selection "atlas"
}

default_variants +${blas_variant_selection}

# make sure that either +accelerate or +atlas is selected

if {![variant_isset accelerate] && ![variant_isset atlas]} {
    ui_error "\n\nYou cannot use the -${blas_variant_selection} variant alone; you must select either the +accelerate or +atlas variant.\n"
    return -code error "Invalid variant selection"
}

#######################
# figure out BLAS flags

if {[variant_isset accelerate]} {

    configure.ldflags-append "-Wl,-framework -Wl,Accelerate"

} else {

    depends_lib-append       port:atlas
    configure.ldflags-append "-llapack -lcblas -lf77blas -latlas"

}

##########################
# configure MacPorts build

use_configure        yes
configure.cmd        make
configure.pre_args   lib
configure.env-append PREFIX=${prefix}
configure.universal_args
destroot.env-append  PREFIX=${prefix}

pre-fetch {

    # check for +accelerate.  Apple's VecLib has bugs that can cause
    # crashes, while Atlas does not have these issues.  Print a
    # warning if this variant is in use, but do not force the use of
    # +atlas (for now).

    if {[variant_isset accelerate]} {
        ui_msg "\nWARNING: The +accelerate variant has been selected, using Apple's Vector Libraries which have known bugs that can cause crashes.  The +atlas variant does not have these issues, and is generally considered a better way to go.\n"
    }
}
