Commit 87eae923 authored by Thomas Jahns's avatar Thomas Jahns 🤸
Browse files

Enable building serial version of library.

parent 46d58ab5
......@@ -130,53 +130,69 @@ ACX_FORTRAN_PACKAGE([NetCDF],[netcdf.inc],,,dnl
dnl ######################################################################
dnl Checks for MPI.
dnl ######################################################################
AC_ARG_ENABLE([MPI],
[AC_HELP_STRING([--enable-MPI],dnl
[compile for and use MPI environment @<:@default: yes@:>@])])
AS_IF([test x"$enable_MPI" = xno],
[MPI=""
MPI_LIB=""],
[enable_MPI=yes
MPI="${FPP_DEFOPT}MPI"
ACX_FORTRAN_PACKAGE([MPI], [mpif.h],,,dnl
[AC_MSG_FAILURE([Required include mpif.h not found or not compilable.])],dnl
[mpi_waitall],[mpi mpi_f90 mpi_f77 mpich],[[-lmpi_f77 -lmpi],[-lmpi]],,dnl
[AC_MSG_FAILURE([Cannot link MPI programs.])],[])
[AC_MSG_WARN([Required include mpif.h not found or not compilable.])
enable_MPI=no],[mpi_waitall],dnl
[mpi mpi_f90 mpi_f77 mpich],[[-lmpi_f77 -lmpi],[-lmpi]],,dnl
[AC_MSG_WARN([Cannot link Fortran MPI programs.])
enable_MPI=no],[])
ACX_C_PACKAGE([MPI],[mpi.h],,,dnl
[AC_MSG_FAILURE([Required header mpi.h not found or not compilable.])],dnl
[MPI_Waitall],[mpi mpich],,,dnl
[AC_MSG_FAILURE([Cannot link MPI programs.])])])
save_CFLAGS="$CFLAGS"
CFLAGS="$MPI_C_INCLUDE $CFLAGS"
save_LIBS="$LIBS"
LIBS="$MPI_C_LIB $LIBS"
AC_CHECK_FUNCS([MPI_Comm_f2c])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
[AC_MSG_WARN([Required header mpi.h not found or not compilable.])
enable_MPI=no],[MPI_Waitall],[mpi mpich],,,dnl
[AC_MSG_WARN([Cannot link C MPI programs.])
enable_MPI=no])
AS_IF([test x"$enable_MPI" = xyes],
[save_CFLAGS="$CFLAGS"
CFLAGS="$MPI_C_INCLUDE $CFLAGS"
save_LIBS="$LIBS"
LIBS="$MPI_C_LIB $LIBS"
AC_CHECK_FUNCS([MPI_Comm_f2c])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
])
])
AS_IF([test x"$enable_MPI" = xyes],
[AC_DEFINE([USE_MPI],[1],[use MPI parallel process environment])])
AM_CONDITIONAL([USE_MPI],dnl
[test x"$enable_MPI" = xyes])
dnl ######################################################################
dnl Checks for ParMeTis
dnl ######################################################################
AS_IF([test x"$enable_MPI" = xyes],
[ACX_C_PACKAGE([ParMeTis],[parmetis.h],[@%:@include <mpi.h>],[$MPI_C_INCLUDE],dnl
[AC_MSG_FAILURE([Header for required package ParMeTis not found.])],dnl
AC_ARG_ENABLE([ParMeTis],
[AC_HELP_STRING([--enable-ParMeTis],dnl
[Provide wrapper for ParMeTis graph partitioners @<:@default: yes@:>@])])
AS_IF([test x"$enable_MPI" = xyes -a x"$enable_ParMeTis" != xno],
[enable_ParMeTis=yes
ACX_C_PACKAGE([ParMeTis],[parmetis.h],[@%:@include <mpi.h>],dnl
[$MPI_C_INCLUDE],dnl
[AC_MSG_WARN([Header for package ParMeTis not found.])
enable_ParMeTis=no],dnl
[ParMETIS_V3_PartKway],[parmetis],[[-lmetis],[-lmetis $MPI_C_LIB],[-lmetis -lm],[-lmetis -lm $MPI_C_LIB]],[$MPI_C_LIB],dnl
[AC_MSG_FAILURE([Cannot link with required package ParMeTis library.])])])
dnl determine the exact type used by metis to represent node indices
save_CFLAGS="$CFLAGS"
CFLAGS="$MPI_C_INCLUDE $PARMETIS_C_INCLUDE $CFLAGS"
TJ_FIND_INTEGRAL_TYPE([idxtype],[METIS_C_IDXTYPE],[@%:@include <mpi.h>
[AC_MSG_WARN([Cannot link with package ParMeTis library.])
enable_ParMeTis=no])])
dnl determine the exact type used by metis to represent node indices
AS_IF([test x"$enable_ParMeTis" = xyes],
[save_CFLAGS="$CFLAGS"
CFLAGS="$MPI_C_INCLUDE $PARMETIS_C_INCLUDE $CFLAGS"
TJ_FIND_INTEGRAL_TYPE([idxtype],[METIS_C_IDXTYPE],[@%:@include <mpi.h>
@%:@include <parmetis.h>])
dnl next determine corresponding Fortran type kind
ACX_FORTRAN_TYPE_KIND([integer],[METIS_FC_IDXTYPE_KIND],[idxtype],,dnl
dnl next determine corresponding Fortran type kind
ACX_FORTRAN_TYPE_KIND([integer],[METIS_FC_IDXTYPE_KIND],[idxtype],,dnl
[@%:@include <mpi.h>
@%:@include <parmetis.h>],[METIS_FC_IDXTYPE_KIND=$acx_fortran_kind_subst])
CFLAGS="$save_CFLAGS"
AC_SUBST([METIS_FC_IDXTYPE_KIND])
CFLAGS="$save_CFLAGS"
AC_SUBST([METIS_FC_IDXTYPE_KIND])
])
AM_CONDITIONAL([USE_PARMETIS],dnl
[test x"$enable_ParMeTis" = xyes])
dnl ######################################################################
dnl ######################################################################
......
......@@ -212,6 +212,9 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* use MPI parallel process environment */
#undef USE_MPI
/* Version number of package */
#undef VERSION
......
......@@ -12,6 +12,18 @@ libscalesppm_a_SOURCES=ppm/core.c ppm/scales_ppm.f90 \
ppm/general_block_decomposition.f90 \
ppm/scales_ppm_base.f90
EXTRA_libscalesppm_a_SOURCES = ppm/graph_partition_mpi.f90
AM_FPPFLAGS =
if USE_MPI
AM_FCFLAGS += $(FPP_DEFOPT)USE_MPI
endif
if USE_PARMETIS
AM_FCFLAGS += $(FPP_DEFOPT)USE_PARMETIS
libscalesppm_a_SOURCES += ppm/graph_partition_mpi.f90 \
ppm/parmetis_wrap.c
endif
clean-local:
-rm -f *.@FCMODEXT@ i.*.L
......
......@@ -6,47 +6,13 @@
#endif
#include <stdio.h>
#include <cfortran.h>
#include <parmetis.h>
#include "core.h"
#ifdef HAVE_MPI_COMM_F2C
void ParMETIS_V3_PartKway_Wrapper(
idxtype *vtxdist,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *ncon,
int *nparts,
float *tpwgts,
float *ubvec,
int *options,
int *edgecut,
idxtype *part,
MPI_Fint *comm_f)
{
MPI_Comm comm_c;
comm_c = MPI_Comm_f2c((MPI_Fint)*comm_f);
ParMETIS_V3_PartKway(vtxdist, xadj, adjncy, vwgt,
adjwgt, wgtflag, numflag, ncon,
nparts, tpwgts, ubvec, options,
edgecut, part, &comm_c);
}
FCALLSCSUB15(ParMETIS_V3_PartKway_Wrapper, PARMETIS_V3_PARTKWAY,
parmetis_v3_partkway,
PINT, PINT, PINT, PINT, PINT, PINT, PINT, PINT,
PINT, PFLOAT, PFLOAT, PINT, PINT, PINT, PVOID)
#endif
void
abort_ppm_fwrap(MPI_Fint *comm_f, const char *msg, const char *source, int line)
{
#ifdef HAVE_MPI_COMM_F2C
#if defined(USE_MPI) && defined(HAVE_MPI_COMM_F2C)
MPI_Comm comm_c = MPI_Comm_f2c((MPI_Fint)*comm_f);
#else
MPI_Comm comm_c = *comm_f;
......@@ -57,12 +23,15 @@ abort_ppm_fwrap(MPI_Fint *comm_f, const char *msg, const char *source, int line)
FCALLSCSUB4(abort_ppm_fwrap, ABORT_PPM_F, abort_ppm_f, PVOID, STRING,
STRING, INT)
void
abort_ppm_default(MPI_Comm *comm, const char *msg, const char *source, int line)
{
fprintf(stderr, "Fatal error in %s, line %d: %s\n", source, line, msg);
#ifdef USE_MPI
MPI_Abort(*comm, 1);
#else
abort();
#endif
}
abort_func abort_ppm = abort_ppm_default;
......
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef USE_MPI
#include <mpi.h>
#else
typedef int MPI_Comm;
typedef int MPI_Fint;
#endif
typedef void (*abort_func)(MPI_Comm *comm, const char *msg,
const char *source, int line);
......
MODULE graph_partition_mpi
USE iso_c_binding, ONLY: c_int
USE scales_ppm_base, ONLY: abort_ppm
INCLUDE 'mpif.h'
#include <ppm.inc>
EXTERNAL :: parmetis_v3_partkway
PUBLIC :: graph_partition
CONTAINS
SUBROUTINE graph_partition(num_vertices, edge_list_lens, &
edge_lists, partition_out, comm, &
balance, num_vertex_weights, vertex_weights, edge_weights)
INTEGER(ppm_idx), INTENT(in) :: num_vertices
INTEGER(ppm_idx), INTENT(in) :: edge_list_lens(:)
INTEGER(ppm_idx), INTENT(in) :: edge_lists(:)
INTEGER, INTENT(out) :: partition_out(*)
INTEGER, INTENT(in) :: comm
REAL(4), OPTIONAL, INTENT(in) :: balance(:, :)
INTEGER, OPTIONAL, INTENT(in) :: num_vertex_weights
INTEGER(ppm_idx), OPTIONAL, INTENT(in) :: vertex_weights(:)
INTEGER(ppm_idx), OPTIONAL, INTENT(in) :: edge_weights(:)
INTEGER(c_int) :: wgtflag
INTEGER :: comm_size, comm_rank, ierror, i
INTEGER, ALLOCATABLE :: vtxdist(:)
INTEGER :: metis_options(0:2), edge_cut
INTEGER, PARAMETER :: max_msg_len=1024
CHARACTER(len=max_msg_len) :: msg
CALL mpi_comm_size(comm, comm_size, ierror)
IF (ierror /= MPI_SUCCESS) THEN
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
CALL mpi_comm_rank(comm, comm_rank, ierror)
IF (ierror /= MPI_SUCCESS) THEN
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
! build table of node distribution
ALLOCATE(vtxdist(0:comm_size))
i = INT(num_vertices)
CALL mpi_allgather(i, 1, MPI_INTEGER, &
vtxdist(1:comm_size), 1, MPI_INTEGER, comm, ierror)
IF (ierror /= MPI_SUCCESS) then
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
vtxdist(0) = 1
vtxdist(comm_rank + 1) = i
DO i = 1, comm_size
vtxdist(i) = vtxdist(i) + vtxdist(i - 1)
END DO
wgtflag = 0
IF (PRESENT(vertex_weights)) wgtflag = 2
IF (PRESENT(edge_weights)) wgtflag = IOR(wgtflag, 1)
metis_options(0) = 0
! FIXME: handle balance not present case
! FIXME: the 4 needs to be replaced with sp -> import mo_kinds
CALL parmetis_v3_partkway(vtxdist, edge_list_lens, edge_lists, &
vertex_weights, edge_weights, wgtflag, 1, num_vertex_weights, &
comm_size, balance, REAL(1.05, 4), metis_options, edge_cut, &
partition_out, comm)
END SUBROUTINE graph_partition
END MODULE graph_partition_mpi
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <parmetis.h>
#include <cfortran.h>
#ifdef HAVE_MPI_COMM_F2C
void ParMETIS_V3_PartKway_Wrapper(
idxtype *vtxdist,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *ncon,
int *nparts,
float *tpwgts,
float *ubvec,
int *options,
int *edgecut,
idxtype *part,
MPI_Fint *comm_f)
{
MPI_Comm comm_c;
comm_c = MPI_Comm_f2c((MPI_Fint)*comm_f);
ParMETIS_V3_PartKway(vtxdist, xadj, adjncy, vwgt,
adjwgt, wgtflag, numflag, ncon,
nparts, tpwgts, ubvec, options,
edgecut, part, &comm_c);
}
FCALLSCSUB15(ParMETIS_V3_PartKway_Wrapper, PARMETIS_V3_PARTKWAY,
parmetis_v3_partkway,
PINT, PINT, PINT, PINT, PINT, PINT, PINT, PINT,
PINT, PFLOAT, PFLOAT, PINT, PINT, PINT, PVOID)
#endif
MODULE scales_ppm
USE iso_c_binding
USE scales_ppm_base, ONLY: abort_ppm
#ifdef USE_PARMETIS
USE graph_partition_mpi, ONLY: graph_partition
#endif
IMPLICIT NONE
INCLUDE 'mpif.h'
#ifdef USE_PARMETIS
#include <ppm.inc>
EXTERNAL :: parmetis_v3_partkway
PUBLIC :: graph_partition, abort_ppm, &
initialize_scales_ppm
PUBLIC :: graph_partition
#endif
PUBLIC :: abort_ppm, initialize_scales_ppm
CONTAINS
SUBROUTINE graph_partition(num_vertices, edge_list_lens, &
edge_lists, partition_out, comm, &
balance, num_vertex_weights, vertex_weights, edge_weights)
INTEGER(ppm_idx), INTENT(in) :: num_vertices
INTEGER(ppm_idx), INTENT(in) :: edge_list_lens(:)
INTEGER(ppm_idx), INTENT(in) :: edge_lists(:)
INTEGER, INTENT(out) :: partition_out(*)
INTEGER, INTENT(in) :: comm
REAL(4), OPTIONAL, INTENT(in) :: balance(:, :)
INTEGER, OPTIONAL, INTENT(in) :: num_vertex_weights
INTEGER(ppm_idx), OPTIONAL, INTENT(in) :: vertex_weights(:)
INTEGER(ppm_idx), OPTIONAL, INTENT(in) :: edge_weights(:)
INTEGER(c_int) :: wgtflag
INTEGER :: comm_size, comm_rank, ierror, i
INTEGER, ALLOCATABLE :: vtxdist(:)
INTEGER :: metis_options(0:2), edge_cut
INTEGER, PARAMETER :: max_msg_len=1024
CHARACTER(len=max_msg_len) :: msg
CALL mpi_comm_size(comm, comm_size, ierror)
IF (ierror /= MPI_SUCCESS) THEN
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
CALL mpi_comm_rank(comm, comm_rank, ierror)
IF (ierror /= MPI_SUCCESS) THEN
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
! build table of node distribution
ALLOCATE(vtxdist(0:comm_size))
i = INT(num_vertices)
CALL mpi_allgather(i, 1, MPI_INTEGER, &
vtxdist(1:comm_size), 1, MPI_INTEGER, comm, ierror)
IF (ierror /= MPI_SUCCESS) then
CALL mpi_error_string(ierror, msg, max_msg_len, ierror)
CALL abort_ppm(msg, __FILE__, __LINE__, comm)
END IF
vtxdist(0) = 1
vtxdist(comm_rank + 1) = i
DO i = 1, comm_size
vtxdist(i) = vtxdist(i) + vtxdist(i - 1)
END DO
wgtflag = 0
IF (PRESENT(vertex_weights)) wgtflag = 2
IF (PRESENT(edge_weights)) wgtflag = IOR(wgtflag, 1)
metis_options(0) = 0
! FIXME: handle balance not present case
! FIXME: the 4 needs to be replaced with sp -> import mo_kinds
CALL parmetis_v3_partkway(vtxdist, edge_list_lens, edge_lists, &
vertex_weights, edge_weights, wgtflag, 1, num_vertex_weights, &
comm_size, balance, REAL(1.05, 4), metis_options, edge_cut, &
partition_out, comm)
END SUBROUTINE graph_partition
SUBROUTINE initialize_scales_ppm
END SUBROUTINE initialize_scales_ppm
END MODULE scales_ppm
MODULE scales_ppm_base
IMPLICIT NONE
#ifdef USE_MPI
INCLUDE 'mpif.h'
#else
INTEGER, PARAMETER :: mpi_comm_world = 0
#endif
PRIVATE
PUBLIC :: abort_ppm, assertion
CONTAINS
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment