AC_PREREQ(2.59)
AC_INIT(configure.in)

dnl
dnl Set the directory that contains support scripts such as install-sh and
dnl config.guess
dnl
AC_CONFIG_AUX_DIR(../../../../../confdb)

dnl
dnl Definitions will be placed in this file rather than in the DEFS variable
dnl
AC_CONFIG_HEADER(include/mpidi_ch3i_nemesis_conf.h)
AH_TOP([/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*  
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */
#ifndef MPIDI_CH3I_NEMESIS_CONF_H_INCLUDED
#define MPIDI_CH3I_NEMESIS_CONF_H_INCLUDED
])
AH_BOTTOM([#endif])

echo "RUNNING CONFIGURE FOR THE NEMESIS CHANNEL"
dnl
dnl First check that we have a clean build if we are doing a VPATH build
PAC_VPATH_CHECK()

PAC_PROG_MAKE

AC_C_INLINE

dnl AC_CHECK_HEADER(net/if.h) fails on Solaris; extra header files needed
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
],,lac_cv_header_net_if_h=yes,lac_cv_header_net_if_h=no)

echo "checking for net/if.h... $lac_cv_header_net_if_h"

if test "$lac_cv_header_net_if_h" = "yes" ; then
    AC_DEFINE(HAVE_NET_IF_H, 1, [Define if you have the <net/if.h> header file.])
fi

AC_CHECK_HEADERS(				\
	assert.h				\
	netdb.h					\
	sys/ioctl.h				\
	sys/socket.h				\
	sys/sockio.h				\
	sys/types.h				\
	errno.h					\
	sys/ipc.h				\
	sys/shm.h)

# netinet/in.h often requires sys/types.h first.  With AC 2.57, check_headers
# does the right thing, which is to test whether the header is found 
# by the compiler, but this can cause problems when the header needs 
# other headers.  2.57 changes the syntax (!) of check_headers to allow 
# additional headers.
AC_CACHE_CHECK([for netinet/in.h],ac_cv_header_netinet_in_h,[
AC_TRY_COMPILE([#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <netinet/in.h>],[int a=0;],
    ac_cv_header_netinet_in_h=yes,
    ac_cv_header_netinet_in_h=no)])
if test "$ac_cv_header_netinet_in_h" = yes ; then
    AC_DEFINE(HAVE_NETINET_IN_H,1,[Define if netinet/in.h exists])
fi


AC_ARG_ENABLE(fast,
[--enable-fast - pick the appropriate options for fast execution.  This
                turns off error checking and timing collection],,
enable_fast=no)
if test "$enable_fast" = "yes" ; then
    AC_DEFINE(ENABLE_NO_SCHED_YIELD,1,[Define to remove sched_yield()s in polling loops])
fi

AC_ARG_WITH(gm, [--with-gm=path - specify path where gm include directory and lib directory can be found],
if test "${with_gm}" != "yes" -a "${with_gm}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_gm}/lib -L${with_gm}/lib64"
    CPPFLAGS="$CPPFLAGS -I${with_gm}/include"
fi,)
AC_ARG_WITH(gm-include, [--with-gm-include=path - specify path to gm include directory],
if test "${with_gm_include}" != "yes" -a "${with_gm_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_gm_include}"
fi,)
AC_ARG_WITH(gm-lib, [--with-gm-lib=path - specify path to gm lib directory],
if test "${with_gm_lib}" != "yes" -a "${with_gm_lib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_gm_lib}"
fi,)

if test "${nemesis_network}" == "gm" ; then 
    AC_CHECK_HEADER([gm.h], , [
        AC_MSG_ERROR(['gm.h not found.  Did you specify --with-gm= or --with-gm-include=?'])
    ])
    AC_CHECK_LIB(gm, gm_init, , [
        AC_MSG_ERROR(['gm library not found.  Did you specify --with-gm= or --with-gm-lib=?'])
    ])
fi;

AC_ARG_WITH(ib, [--with-ib=path - specify path where InfiniBand include directory and lib directory can be found],
if test "${with_ib}" != "yes" -a "${with_ib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_ib}/lib -L${with_ib}/lib64"
    CPPFLAGS="$CPPFLAGS -I${with_ib}/include -I${with_ib}/include/infiniband"
fi,)
AC_ARG_WITH(ib-include, [--with-ib-include=path - specify path to InfiniBand include directory],
if test "${with_ib_include}" != "yes" -a "${with_ib_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_ib_include}"
fi,)
AC_ARG_WITH(ib-lib, [--with-ib-lib=path - specify path to InfiniBand lib directory],
if test "${with_ib_lib}" != "yes" -a "${with_ib_lib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_ib_lib}"
fi,)

if test "${nemesis_network}" == "ib" ; then 
    AC_CHECK_HEADER([verbs.h], , [
        AC_MSG_ERROR(['verbs.h not found.  Did you specify --with-ib= or --with-ib-include=?'])
    ])
    AC_CHECK_LIB(ibverbs, ibv_open_device, , [
        AC_MSG_ERROR(['InfiniBand library not found.  Did you specify --with-ib= or --with-ib-lib=?'])
    ])
fi;

AC_ARG_WITH(mx, [--with-mx=path - specify path where mx include directory and lib directory can be found],
if test "${with_mx}" != "yes" -a "${with_mx}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_mx}/lib"
    CPPFLAGS="$CPPFLAGS -I${with_mx}/include"
fi,)
AC_ARG_WITH(mx-include, [--with-mx-include=path - specify path to mx include directory],
if test "${with_mx_include}" != "yes" -a "${with_mx_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_mx_include}"
fi,)
AC_ARG_WITH(mx-lib, [--with-mx-lib=path - specify path to mx lib directory],
if test "${with_mx_lib}" != "yes" -a "${with_mx_lib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_mx_lib}"
fi,)

if test "${nemesis_network}" == "mx" ; then
    AC_CHECK_HEADER([myriexpress.h], , [
        AC_MSG_ERROR(['myriexpress.h not found.  Did you specify --with-mx= or --with-mx-include=?'])
    ])
    #mx_init is a macro, switch to mx_finalize to find the symbol
    AC_CHECK_LIB(myriexpress, mx_finalize, , [
        AC_MSG_ERROR(['myriexpress library not found.  Did you specify --with-mx= or --with-mx-lib=?'])
    ])
fi;


AC_ARG_WITH(elan, [--with-elan=path - specify path where elan include directory and lib directory can be found],
if test "${with_elan}" != "yes" -a "${with_elan}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_elan}/lib"
    CPPFLAGS="$CPPFLAGS -I${with_elan}/include"	
fi,)
AC_ARG_WITH(elan-include, [--with-elan-include=path - specify path to elan include directory],
if test "${with_elan_include}" != "yes" -a "${with_elan_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_elan_include}"
fi,)
AC_ARG_WITH(elan-lib, [--with-elan-lib=path - specify path to elan lib directory],
if test "${with_elan_lib}" != "yes" -a "${with_elan_lib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_elan_lib}"
fi,)
AC_ARG_WITH(qsnet-include, [--with-qsnet-include=path - specify path to qsnet include directory],
if test "${with_qsnet_include}" != "yes" -a "${with_qsnet_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_qsnet_include}"
fi,)
    
if test "${nemesis_network}" == "elan" ; then
echo "=== You're about to use the experimental Nemesis/Elan network module." 
echo "=== This module has not been thoroughly tested and some performance issues remain."

    AC_CHECK_HEADER([elan.h], , [
	AC_MSG_ERROR(['elan.h not found.  Did you specify --with-elan= or --with-elan-include=? or --with-qsnet-include=?'])
    ])
    AC_CHECK_LIB(elan, elan_baseInit, , [
        AC_MSG_ERROR(['elan library not found.  Did you specify --with-elan= or --with-elan-lib=? or --with-qsnet-include=?'])
    ])
fi;

AC_ARG_WITH(sctp, [--with-sctp=path - specify path where sctp include directory and lib directory can be found],
if test "${with_sctp}" != "yes" -a "${with_sctp}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_sctp}/lib"
    CPPFLAGS="$CPPFLAGS -I${with_sctp}/include"
fi,)
AC_ARG_WITH(sctp-include, [--with-sctp-include=path - specify path to sctp include directory],
if test "${with_sctp_include}" != "yes" -a "${with_sctp_include}" != "no" ; then
    CPPFLAGS="$CPPFLAGS -I${with_sctp_include}"
fi,)
AC_ARG_WITH(sctp-lib, [--with-sctp-lib=path - specify path to sctp lib directory],
if test "${with_sctp_lib}" != "yes" -a "${with_sctp_lib}" != "no" ; then
    LDFLAGS="$LDFLAGS -L${with_sctp_lib}"
fi,)

if test "${nemesis_network}" == "sctp" ; then 
    AC_CHECK_HEADER([netinet/sctp.h], , [
        AC_MSG_ERROR(['sctp.h not found.  Did you specify --with-sctp= or --with-sctp-include=?'])
    ])
    AC_CHECK_LIB(sctp, sctp_recvmsg, , [
        AC_MSG_ERROR(['sctp library not found.  Did you specify --with-sctp= or --with-sctp-lib=?'])
    ])
fi;


case "${nemesis_network}" in
     elan )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_ELAN_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     gm )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_GM_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     mx )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_MX_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     tcp )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_TCP_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     newtcp )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_NEWTCP_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     sctp )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_SCTP_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     ib )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_IB_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
     * )
          AC_DEFINE(MPID_NEM_NET_MODULE, MPID_NEM_NO_MODULE, [Choose elan, gm, mx, tcp, sctp, ib, or no network]) ;;
esac

AC_ARG_ENABLE(nemesis-dbg-nolocal, [--enable-nemesis-dbg-nolocal - enables debugging mode where shared-memory communication is disabled],
    AC_DEFINE(ENABLED_NO_LOCAL, 1, [Define to disable shared-memory communication for debugging]))

AC_ARG_ENABLE(nemesis-dbg-localoddeven, [--enable-nemesis-dbg-localoddeven - enables debugging mode where shared-memory communication is enabled only between even processes or odd processes on a node],
    AC_DEFINE(ENABLED_ODD_EVEN_CLIQUES, 1, [Define to enable debugging mode where shared-memory communication is done only between even procs or odd procs]))

AC_ARG_WITH(papi, [--with-papi[=path] - specify path where papi include and lib directories can be found],, with_papi=no)

if test "${with_papi}" != "no" ; then
    if test "${with_papi}" != "yes" ; then
        PAPI_INCLUDE="-I${with_papi}/include"
        CPPFLAGS="$CPPFLAGS $PAPI_INCLUDE"
#	LDFLAGS="$LDFLAGS -L${with_papi}/lib"
	LIBS="${with_papi}/lib/libpapi.a $LIBS"
	LIBS="${with_papi}/lib/libperfctr.a $LIBS"
    fi

    AC_CHECK_HEADER([papi.h], , [AC_MSG_ERROR(['papi.h not found in ${with_papi}/include.  Did you specify the correct path with --with-papi=?'])])

    echo -n "checking for papi libraries... "
    AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <papi.h>]],
				   [[PAPI_library_init(PAPI_VER_CURRENT);]])], [echo "yes"], 
				   [echo "yes" ; AC_MSG_ERROR(['Cannot link with papi:  Cannot find ${with_papi}/lib/libpapi.a or ${with_papi}/lib/libperfctr.a'])])


#    AC_CHECK_LIB(papi, PAPI_accum, , [AC_MSG_ERROR(['papi library not found.  Did you specify --with-papi=?'])])
#    AC_CHECK_LIB(perfctr, perfctr_info, , [AC_MSG_ERROR(['perfctr library not found.  Did you specify --with-papi=?'])])
fi

AC_ARG_ENABLE(checkpointing, [--enable-checkpointing - enable checkpointing],, enable_checkpointing=no)
AC_ARG_WITH(ckpt-dir, [--with-ckpt-dir=path - (checkpointing) specify path to ckpt directory],, with_ckpt_dir=no)
AC_ARG_WITH(cli-dir, [--with-cli-dir=path - (checkpointing) specify path to cli directory],, with_cli_dir=no)

if test "$enable_checkpointing" != "no" ; then
    if test "$with_ckpt_dir" != "no" ; then
        CPPFLAGS="$CPPFLAGS -I${with_ckpt_dir}"
        LDFLAGS="$LDFLAGS -L${with_ckpt_dir} -Wl,-rpath,${with_ckpt_dir}"
    fi
    if test "$with_cli_dir" != "no" ; then
        CPPFLAGS="$CPPFLAGS -I${with_cli_dir}"
        LDFLAGS="$LDFLAGS -L${with_cli_dir}"
    fi
    AC_CHECK_HEADER([cli.h], , [AC_MSG_ERROR(['cli.h not found.  Did you specify --with-cli-dir=?'])])
    AC_CHECK_LIB(cli, cli_init, , [AC_MSG_ERROR(['cli library not found.  Did you specify --with-cli-dir=?'])], -lckpt)

    AC_CHECK_HEADER([ckpt.h], , [AC_MSG_ERROR(['ckpt.h not found.  Did you specify --with-ckpt-dir=?'])])
    AC_CHECK_LIB(ckpt, ckpt_init, , [AC_MSG_ERROR(['ckpt library not found.  Did you specify --with-ckpt-dir=?'])])
    AC_DEFINE(ENABLED_CHECKPOINTING, 1, [Define to enable nemesis checkpointing])
fi

# handle missing mkstemp, or missing mkstemp declaration
AC_CHECK_FUNCS(mkstemp)
AC_CHECK_FUNCS(rand)
AC_CHECK_FUNCS(srand)

# check how to allocate shared memory
AC_ARG_WITH(shared-memory, [--with-shared-memory[=auto|sysv|mmap] - create shared memory using sysv or mmap (dafault is auto)],,
    with_shared_memory=auto)

if test "$with_shared_memory" = auto -o "$with_shared_memory" = mmap; then
    found_mmap_funcs=yes
    AC_CHECK_FUNCS(mmap munmap, , found_mmap_funcs=no)
    if test "$found_mmap_funcs" = yes ; then
        with_shared_memory=mmap
        AC_MSG_NOTICE([Using a memory-mapped file for shared memory])
    elif test "$with_shared_memory" = mmap ; then
        AC_MSG_ERROR([cannot support shared memory:  mmap() or munmap() not found])
    fi
fi
if test "$with_shared_memory" = auto -o "$with_shared_memory" = sysv; then
    found_sysv_shm_funcs=yes
    AC_CHECK_FUNCS(shmget shmat shmctl shmdt, , found_sysv_shm_funcs=no)
    if test "$found_sysv_shm_funcs" = yes ; then
        AC_DEFINE(HAVE_SYSV_SHARED_MEM,1,[Define if we have sysv shared memory])
        AC_MSG_NOTICE([Using SYSV shared memory])
    elif test "$with_shared_memory" = sysv ; then
        AC_MSG_ERROR([cannot support shared memory:  sysv shared memory functions functions not found])
    else
        AC_MSG_ERROR([cannot support shared memory:  need either sysv shared memory functions or mmap in order to support shared memory])
    fi
fi

if test "$found_sysv_shm_funcs" = yes ; then
   AC_CHECK_FUNCS(strtoll, , AC_MSG_ERROR([cannot find strtoll function needed by sysv shared memory implementation]))
fi

AC_ARG_ENABLE(nemesis-shm-collectives, [--enable-nemesis-shm-collectives - enables use of shared memory for collective comunication within a node],
    AC_DEFINE(ENABLED_SHM_COLLECTIVES, 1, [Define to enable shared-memory collectives]))


# These are defines to turn on different optimizations.  Turn them off only for testing
AC_DEFINE(MPID_NEM_INLINE,1,[Define to turn on the inlining optimizations in Nemesis code])
AC_DEFINE(PREFETCH_CELL,1,[Define to turn on the prefetching optimization in Nemesis code])	
AC_DEFINE(USE_FASTBOX,1,[Define to use the fastboxes in Nemesis code])	


AC_SUBST(device_name)
AC_SUBST(channel_name)
AC_SUBST(nemesis_network)

AC_SUBST(mmx_copy_s)
AC_SUBST(PAPI_INCLUDE)
AC_SUBST(AS, [as])
AC_SUBST(AR)
AC_SUBST(RANLIB)
AC_SUBST(MPILIBNAME)
AC_SUBST(CC)
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
PAC_CC_SUBDIR_SHLIBS
AC_SUBST(master_top_srcdir)
AC_SUBST(master_top_builddir)
dnl
dnl Dependency handling
AC_SUBST(MAKE_DEPEND_C)

AC_OUTPUT(Makefile src/Makefile nemesis/Makefile nemesis/src/Makefile nemesis/utils/Makefile nemesis/utils/replacements/Makefile nemesis/utils/monitor/Makefile nemesis/net_mod/Makefile nemesis/net_mod/elan_module/Makefile  nemesis/net_mod/gm_module/Makefile nemesis/net_mod/mx_module/Makefile nemesis/net_mod/tcp_module/Makefile nemesis/net_mod/newtcp_module/Makefile nemesis/net_mod/sctp_module/Makefile nemesis/net_mod/ib_module/Makefile nemesis/net_mod/none_module/Makefile localdefs)
