Commit 6460b047 authored by Pavel Kus's avatar Pavel Kus

introduced test project for C

matrix for the test not prepared (called with zero matrix)
list of gitlab tests temporarily reduced
parent e4e42c43
......@@ -25,4 +25,9 @@ m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
*/m4/libtool.m4
*/m4/ltoptions.m4
*/m4/ltsugar.m4
*/m4/ltversion.m4
*/m4/lt~obsolete.m4
test_programs.am
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -655,7 +655,14 @@ EXTRA_DIST = \
test_project_2stage/configure.ac \
test_project_2stage/fdep \
test_project_2stage/m4 \
test_project_2stage/src/test_real2.F90
test_project_2stage/src/test_real2.F90 \
test_project_C/Makefile.am \
test_project_C/autogen.sh \
test_project_C/configure.ac \
test_project_C/fdep \
test_project_C/m4 \
test_project_C/src/test_real.c \
test_project_C/src/test_blacs_infrastructure.F90
if ENABLE_LEGACY
EXTRA_DIST += \
......
## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
AM_FCFLAGS = @FC_MODINC@modules @FC_MODOUT@modules $(ELPA_FCFLAGS)
AM_CFLAGS = $(ELPA_CFLAGS)
AM_LDFLAGS = $(ELPA_LIBS)
#bindir = $(abs_top_builddir)
bin_PROGRAMS = test_real
test_real_SOURCES = src/test_real.c src/test_blacs_infrastructure.F90
distclean-local:
-rm config-f90.h
#!/bin/sh -e
mkdir -p m4/
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
autoreconf --force --install --verbose "$srcdir"
AC_PREREQ([2.69])
AC_INIT([elpa_test_project],[2017.05.002], elpa-library@rzg.mpg.de)
elpaversion="2017.05.002"
AC_CONFIG_SRCDIR([src/test_real.c])
AM_INIT_AUTOMAKE([foreign -Wall subdir-objects])
# Without this, automake tries to be smart and rebuilt
# the autoconf generated files such as configure, aclocal.m4, etc.,
# in case the timestamps of files such as configure.ac are newer
#
# This only makes trouble for end users with out-of-date autoconf versions
# that cannot produce these files
AM_MAINTAINER_MODE([disable])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_SILENT_RULES([yes])
rm -rf config.h config-f90.h
AX_CHECK_GNU_MAKE()
if test x$_cv_gnu_make_command = x ; then
AC_MSG_ERROR([Need GNU Make])
fi
AC_CHECK_PROG(CPP_FOUND,cpp,yes,no)
if test x"${CPP_FOUND}" = xno; then
AC_MSG_ERROR([no cpp found])
fi
# gnu-make fortran module dependencies
m4_include([fdep/fortran_dependencies.m4])
FDEP_F90_GNU_MAKE_DEPS
AC_PROG_INSTALL
AM_PROG_CC_C_O
AM_PROG_AR
AM_PROG_AS
AC_LANG([Fortran])
m4_include([m4/ax_prog_fc_mpi.m4])
dnl check whether an mpi compiler is available;
dnl if not abort since it is mandatory
AX_PROG_FC_MPI([],[have_mpi=yes],[have_mpi=no
if test x"${have_mpi}" = xno; then
AC_MSG_ERROR([no mpi found])
fi])
AC_FC_FREEFORM
AC_FC_MODULE_FLAG
AC_FC_MODULE_OUTPUT_FLAG
AC_MSG_CHECKING(whether OpenMP usage is specified)
AC_ARG_WITH([openmp],
AS_HELP_STRING([--with-openmp],
[use OpenMP threading, default no.]),
[with_openmp=yes],
[with_openmp=no])
AC_MSG_RESULT([${with_openmp}])
if test x"${enable_openmp}" = x"yes"; then
with_openmp=yes
AC_MSG_CHECKING(whether --enable-openmp is specified)
AC_MSG_RESULT([${enable_openmp}])
fi
AM_CONDITIONAL([WITH_OPENMP],[test x"$with_openmp" = x"yes"])
if test x"${with_openmp}" = x"yes"; then
AC_DEFINE([WITH_OPENMP], [1], [use OpenMP threading])
AX_ELPA_OPENMP
elpa="elpa_openmp-$elpaversion"
else
elpa="elpa-$elpaversion"
fi
# Here comes the ELPA specific part
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES([ELPA],[${elpa}],[],[AC_MSG_ERROR(["Need ${elpa}"])])
PKG_CHECK_VAR([ELPA_FCFLAGS],[${elpa}],[fcflags])
LT_INIT
AC_SUBST([FC_MODINC])
AC_SUBST([FC_MODOUT])
rm -rf modules/ .fortran_dependencies/
mkdir modules
AC_CONFIG_FILES([
Makefile
])
AC_OUTPUT
grep "^#define" config.h > config-f90.h
Copyright (c) 2013 Lorenz Hüdepohl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
fdep
----
fdep is a small set of scripts to teach autoconf/automake (using GNU make)
about the additional dependencies in Fortran 90 files due to modules.
With this, Fortran files can be listed in any order in Makefile.am and parallel
builds work.
Usage
-----
Put this project as a directory "fdep" in your source code, place the two
lines
m4_include([fdep/fortran_dependencies.m4])
FDEP_F90_GNU_MAKE_DEPS
in your configure.ac, and add a single line
@FORTRAN_MODULE_DEPS@
in your Makefile.am. All .F90 files of all programs in bin_PROGRAMS and all
libraries in lib_LTLIBRARIES will now be scanned for modules and the
resulting dependencies will be honoured.
What is the problem with Fortran 90 modules and make dependencies?
------------------------------------------------------------------
In Fortran 90 source files one can define any number of "modules", containing
variable and function definitions. The names of the modules defined in a file
can be arbitrary.
In another source file these modules can be used, informing the Fortran
compiler about the definitions in these modules (e.g. to do type-checking).
This creates a problem, as the compiler has to know somehow where the module
is defined.
The usual solution employed by almost every Fortran compiler is to create
special "module" files for each module contained in a source file during
compilation. Their file name is derived by a compiler-specific recipe of the
modules identifier (usually the lower-cased module's identifier plus ".mod",
so "foo_module.mod" and "some_other_module.mod"). When the compiler
encounters a "use" statement during the compilation of another file, it
confers to this file to import the definitions of the module.
That means, you cannot compile files using modules defined in yet un-compiled
files, one has to tell make about this dependency.
(A primitive solution to this problem is listing the file in a pre-sorted
order, so that files defining modules are compiled first.
However, that way the dependency-graph make knows about is incomplete and
parallel builds will fail with a high probability)
How does fdep solve this problem technically?
---------------------------------------------
As the name of the module files can be an arbitrary (and some compilers might
even save the module definitions in some completely different way), fdep
tells make about the module dependencies as a relation directly between
object files, e.g. when a file 'b.f90' is using any module of file 'a.f90',
fdep adds a dependency of
b.o: a.o
More specifically, the perl-script fortran_dependencies.pl is run by make to
create a file .fortran_dependencies/dependencies.mk, which is then included.
To do this, first every source file (for every defined program and library)
is scanned for lines with "module" or "use" statements. These are saved in
two additional files (.use_mods and .def_mods) per source file and contain
lists of defined and required modules. The perl script then reads these in
and produces the appropriate rules.
Drawbacks
---------
GNU make is required. The detailed dependency graph due to "module" and "use"
statements is only available after pre-processing, when autoconf and even
configure is long over. To still get proper dependencies, fdep uses GNU
make's feature to include generated sub-Makefiles during a running make
invocation.
License
-------
fdep is released under the MIT License. See the LICENSE file for details.
Contributing
------------
Send your patches or pull-request to dev@stellardeath.org
AC_DEFUN([FDEP_F90_GNU_MAKE_DEPS],[
AC_MSG_CHECKING([for GNU make])
for a in "$MAKE" make gmake gnumake ; do
if test -z "$a" ; then continue ; fi ;
if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
_fdep_gnu_make_command=$a ;
break;
fi
done ;
AC_MSG_RESULT([$_fdep_gnu_make_command])
if test x$_fdep_gnu_make_command = x ; then
AC_MSG_ERROR([Need GNU Make])
fi
AC_SUBST([FORTRAN_MODULE_DEPS], ["
CLEANFILES +=
include ${srcdir}/fdep/fortran_dependencies.mk
"])
AM_SUBST_NOTMAKE([FORTRAN_MODULE_DEPS])
])
_f90_verbose = $(_f90_verbose_$(V))
_f90_verbose_ = $(_f90_verbose_$(AM_DEFAULT_VERBOSITY))
_f90_verbose_0 = @echo " $1";
_f90_targets = $(subst -,_,$(patsubst %.la,%_la,$(patsubst %.a,%_a,$(patsubst %.so,%_so,$(PROGRAMS) $(LTLIBRARIES)))))
FORTRAN_CPP ?= cpp -P -traditional -Wall -Werror
# $1 source files
#
# returns: file without any .F90 .f90 .F .f extension
define strip_fortran_ext
$(patsubst %.F90,%,$(patsubst %.f90,%,$(patsubst %.F,%,$(patsubst %.f,%,$1))))
endef
# $1 program
#
# returns:
# '1' if object files for target $1 are prefixed due to 'per-target' flags,
# '' (the empty string) otherwise. See the automake manual for 'per-target'
# compilation
#
define is_per_target
$(if $(filter $(call strip_fortran_ext,$(firstword $(call fortran_sources,$1))),$(patsubst %.o,%,$(patsubst %.lo,%,$($1_OBJECTS)))),,1)
endef
# $1 top-level target name (i.e. an entry of _f90_targets)
#
# returns: all target source files matching *.F90 *.f90 *.F *.f
define fortran_sources
$(filter %.F90 %.f90 %.F %.f,$($1_SOURCES))
endef
# $1 top-level target name
#
# returns: the appropriate extension (i.e. 'o' for normal programs, '.lo' for libraries)
define object_extension
$(if $(filter $1,$(PROGRAMS)),o,lo)
endef
# $1 source_file
# $2 stem
# $3 program
define module_targets
$(eval _$3_use_mods += $(dir $1)$2$(call strip_fortran_ext,$(notdir $1)).use_mods.$3.$(call object_extension,$3))
$(dir $1)$2$(call strip_fortran_ext,$(notdir $1)).use_mods.$3.$(call object_extension,$3): $1 $(dir $1)$(am__dirstamp)
$(call _f90_verbose,F90 USE [$3] $$<)$(FORTRAN_CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $($p_CPPFLAGS) $(CPPFLAGS) -o /dev/stdout $$< | grep -i -o '^ *use [^ ,!:]*' | sort -u > $$@
$(eval _$3_def_mods += $(dir $1)$2$(call strip_fortran_ext,$(notdir $1)).def_mods.$3.$(call object_extension,$3))
$(dir $1)$2$(call strip_fortran_ext,$(notdir $1)).def_mods.$3.$(call object_extension,$3): $1 $(dir $1)$(am__dirstamp)
$(call _f90_verbose,F90 MOD [$3] $$<)$(FORTRAN_CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $($p_CPPFLAGS) $(CPPFLAGS) -o /dev/stdout $$< | grep -i -o '^ *module [^!]*' | grep -v "\<procedure\>" > $$@ || true
endef
$(foreach p,$(_f90_targets),$(if $(call is_per_target,$p),$(foreach s,$(call fortran_sources,$p),$(eval $(call module_targets,$s,$p-,$p))),$(foreach s,$(call fortran_sources,$p),$(eval $(call module_targets,$s,,$p)))))
_f90_depdir=$(abs_builddir)/.fortran_dependencies
_f90_depfile = $(_f90_depdir)/dependencies.mk
define is_clean
$(if $(filter-out mostlyclean clean distclean maintainer-clean,$(MAKECMDGOALS)),0,1)
endef
define _fdep_newline
endef
ifneq ($(call is_clean),1)
include $(_f90_depfile)
endif
$(_f90_depfile): $(top_srcdir)/fdep/fortran_dependencies.pl $(foreach p,$(_f90_targets),$(_$p_use_mods) $(_$p_def_mods)) | $(foreach p,$(_f90_targets),$(_f90_depdir)/$p)
$(call _f90_verbose,F90 DEPS $@)echo > $@; $(foreach p,$(_f90_targets),$(top_srcdir)/fdep/fortran_dependencies.pl $p $(_$p_use_mods) $(_$p_def_mods) >> $@ || { rm $@; exit 1; } ;$(_fdep_newline))
$(_f90_depdir):
@mkdir $@
$(foreach p,$(_f90_targets),$(_f90_depdir)/$p): | $(_f90_depdir)
@mkdir $@
CLEANFILES += $(foreach p,$(_f90_targets),$(_$p_def_mods) $(_$p_use_mods))
CLEANFILES += $(foreach p,$(_f90_targets),$(_f90_depdir)/$p/*)
CLEANFILES += $(_f90_depfile)
#!/usr/bin/perl -w
use strict;
my %defs = ();
my %uses = ();
my $use_re = qr/^\s*use\s+(\S+)\s*$/;
my $def_re = qr/^\s*module\s+(\S+)\s*$/;
sub add_use {
my ($file, $module) = @_;
if (defined($defs{$module}) && $defs{$module} eq $file) {
# do not add self-dependencies
return;
}
if (!defined($uses{$file})) {
$uses{$file} = { $module => 1 };
} else {
$uses{$file}{$module} = 1;
}
}
sub add_def {
my ($file, $module) = @_;
if (!defined($defs{$module})) {
$defs{$module} = $file;
if (defined($uses{$file}) && defined($uses{$file}{$module})) {
delete $uses{$file}{$module};
}
} else {
die "Module $module both defined in $file, $defs{$module}";
}
}
my $p = shift;
foreach my $file (@ARGV) {
my $re;
my $add;
my $object;
if (defined($ENV{V}) && $ENV{V} ge "2") {
print STDERR "fdep: Considering file $file\n";
}
if ($file =~ /^(.*)\.def_mods.$p(\..*)$/) {
$re = $def_re;
$add = \&add_def;
$object = $1 . $2;
} elsif ($file =~ /^(.*)\.use_mods.$p(\..*)$/) {
$re = $use_re;
$add = \&add_use;
$object = $1 . $2;
} else {
die "Unrecognized file extension for '$file'\nExpected (.*)\.def_mods.$p(\..*) or (.*)\.use_mods.$p(\..*)";
}
open(FILE,"<",$file) || die "\nCan't open $file: $!\n\n";
while(<FILE>) {
chomp;
$_ = lc($_);
if ($_ =~ $re) {
&$add($object, $1);
} else {
die "Cannot parse module statement '$_', was expecting $re";
}
}
close(FILE)
}
foreach my $object (sort keys %uses) {
for my $m (keys %{$uses{$object}}) {
if (defined $defs{$m}) {
print "$object: ", $defs{$m}, "\n";
} elsif (defined($ENV{V}) && $ENV{V} ge "1") {
print STDERR "fdep: Warning: Cannot find definition of module $m in files for program $p, might be external\n";
}
}
}
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_fc_mpi.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_FC_MPI([MPI-WANTED-TEST[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]])
#
# DESCRIPTION
#
# This macro tries to find out how to compile Fortran77 programs that use
# MPI (Message Passing Interface), a standard API for parallel process
# communication (see http://www-unix.mcs.anl.gov/mpi/). The macro has to
# be used instead of the standard macro AC_PROG_FC and will replace the
# standard variable FC with the found compiler.
#
# MPI-WANTED-TEST is used to test whether MPI is actually wanted by the
# user. If MPI-WANTED_TEST is omitted or if it succeeds, the macro will
# try to find out how to use MPI, if it fails, the macro will call
# AC_PROG_CC to find a standard C compiler instead.
#
# When MPI is found, ACTION-IF-FOUND will be executed, if MPI is not found
# (or MPI-WANTED-TEST fails) ACTION-IF-NOT-FOUND is executed. If
# ACTION-IF-FOUND is not set, the macro will define HAVE_MPI.
#
# The following example demonstrates usage of the macro:
#
# # If --with-mpi=auto is used, try to find MPI, but use standard FC compiler if it is not found.
# # If --with-mpi=yes is used, try to find MPI and fail if it isn't found.
# # If --with-mpi=no is used, use a standard FC compiler instead.
# AC_ARG_WITH(mpi, [AS_HELP_STRING([--with-mpi],
# [compile with MPI (parallelization) support. If none is found,
# MPI is not used. Default: auto])
# ],,[with_mpi=auto])
#
# AX_PROG_FC_MPI([test x"$with_mpi" != xno],[use_mpi=yes],[
# use_mpi=no
# if test x"$with_mpi" = xyes; then
# AC_MSG_FAILURE([MPI compiler requested, but couldn't use MPI.])
# else
# AC_MSG_WARN([No MPI compiler found, won't use MPI.])
# fi
# ])
#
# LICENSE
#
# Copyright (c) 2010,2011 Olaf Lenz <olenz@icp.uni-stuttgart.de>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_PROG_FC_MPI], [
AC_PREREQ(2.50)
# Check for compiler
# Needs to be split off into an extra macro to ensure right expansion
# order.
AC_REQUIRE([_AX_PROG_FC_MPI],[_AX_PROG_FC_MPI([$1])])
AS_IF([test x"$_ax_prog_fc_mpi_mpi_wanted" = xno],
[ _ax_prog_fc_mpi_mpi_found=no ],
[
AC_LANG_PUSH([Fortran])
# test whether MPI_INIT is available
# We do not use AC_SEARCH_LIBS here, as it caches its outcome and
# thus disallows corresponding calls in the other AX_PROG_*_MPI
# macros.
for lib in NONE mpichf90 fmpi fmpich; do
save_LIBS=$LIBS
if test x"$lib" = xNONE; then
AC_MSG_CHECKING([for function MPI_INIT])
else
AC_MSG_CHECKING([for function MPI_INIT in -l$lib])
LIBS="-l$lib $LIBS"
fi
AC_LINK_IFELSE([AC_LANG_CALL([],[MPI_INIT])],
[ _ax_prog_fc_mpi_mpi_found=yes ],
[ _ax_prog_fc_mpi_mpi_found=no ])
AC_MSG_RESULT($_ax_prog_fc_mpi_mpi_found)
if test "x$_ax_prog_fc_mpi_mpi_found" = "xyes"; then
break;
fi
LIBS=$save_LIBS
done
# Check for header
AS_IF([test x"$_ax_prog_fc_mpi_mpi_found" = xyes], [
AC_MSG_CHECKING([for mpif.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[[
include 'mpif.h'
]])],
[ AC_MSG_RESULT(yes)],
[ AC_MSG_RESULT(no)
_ax_prog_fc_mpi_mpi_found=no
])
])
AC_LANG_POP([Fortran])
])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
AS_IF([test x"$_ax_prog_fc_mpi_mpi_found" = xyes], [
ifelse([$2],,[AC_DEFINE(HAVE_MPI,1,[Define if you have the MPI library.])],[$2])
:
],[
$3
:
])
])dnl AX_PROG_FC_MPI
dnl _AX_PROG_FC_MPI is an internal macro required by AX_PROG_FC_MPI.
dnl To ensure the right expansion order, the main function AX_PROG_FC_MPI
dnl has to be split into two parts. This part looks for the MPI
dnl compiler, while the other one tests whether an MPI program can be
dnl compiled.
dnl
AC_DEFUN([_AX_PROG_FC_MPI], [
AC_ARG_VAR(MPIFC,[MPI Fortran compiler command])
ifelse([$1],,[_ax_prog_fc_mpi_mpi_wanted=yes],[
AC_MSG_CHECKING([whether to compile using MPI])
if $1; then
_ax_prog_fc_mpi_mpi_wanted=yes
else
_ax_prog_fc_mpi_mpi_wanted=no
fi
AC_MSG_RESULT($_ax_prog_fc_mpi_mpi_wanted)
])
if test x"$_ax_prog_fc_mpi_mpi_wanted" = xyes; then
if test -z "$FC" && test -n "$MPIFC"; then
FC="$MPIFC"
else
AC_CHECK_TOOLS([FC], [mpiifort mpifort mpif95 mpxlf95_r mpxlf95 ftn mpif90 mpxlf90_r mpxlf90 mpf90 cmpif90c sxmpif90 mpif77 hf77 mpxlf_r mpxlf mpifrt mpf77 cmpifc xlf95 pgf95 pathf95 ifort g95 f95 fort ifc efc openf95 sunf95 crayftn gfortran lf95 ftn xlf90 f90 pgf90 pghpf pathf90 epcf90 sxf90 openf90 sunf90 xlf f77 frt pgf77 pathf77 g77 cf77 fort77 fl32 af77])
fi
fi
AC_PROG_FC
])dnl _AX_PROG_FC_MPI
! This file is part of ELPA.
!
! The ELPA library was originally created by the ELPA consortium,
! consisting of the following organizations:
!
! - Max Planck Computing and Data Facility (MPCDF), formerly known as
! Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
! - Bergische Universität Wuppertal, Lehrstuhl für angewandte
! Informatik,
! - Technische Universität München, Lehrstuhl für Informatik mit
! Schwerpunkt Wissenschaftliches Rechnen ,
! - Fritz-Haber-Institut, Berlin, Abt. Theorie,
! - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
! Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
! and
! - IBM Deutschland GmbH
!
!
! More information can be found here:
! http://elpa.mpcdf.mpg.de/
!
! ELPA is free software: you can redistribute it and/or modify
! it under the terms of the version 3 of the license of the
! GNU Lesser General Public License as published by the Free
! Software Foundation.
!
! ELPA is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
! along with ELPA. If not, see <http://www.gnu.org/licenses/>
!
! ELPA reflects a substantial effort on the part of the original
! ELPA consortium, and we ask you to respect the spirit of the
! license that we chose: i.e., please contribute any changes you
! may have back to the original ELPA library distribution, and keep
! any derivatives of ELPA under the same license that we chose for
! the original distribution, the GNU Lesser General Public License.
!
!
#include "config-f90.h"
#define WITH_MPI 1
module test_blacs_infrastructure
use iso_c_binding
use mpi
integer, parameter :: ik = C_INT32_T
contains
!c> void set_up_blacsgrid_f(int mpi_comm_parent, int np_rows, int np_cols, char layout,
!c> int* my_blacs_ctxt, int *my_prow, int *my_pcol);
subroutine set_up_blacsgrid(mpi_comm_parent, np_rows, np_cols, layout, &
my_blacs_ctxt, my_prow, my_pcol) bind(C, name="set_up_blacsgrid_f")
!use test_util
implicit none
integer(kind=c_int), intent(in), value :: mpi_comm_parent, np_rows, np_cols
character(len=1), intent(in), value :: layout
integer(kind=c_int), intent(out) :: my_blacs_ctxt, my_prow, my_pcol
#ifdef WITH_MPI
integer :: np_rows_, np_cols_
#endif
if (layout /= 'R' .and. layout /= 'C') then
print *, "layout must be 'R' or 'C'"
stop 1
end if
my_blacs_ctxt = mpi_comm_parent
#ifdef WITH_MPI
call BLACS_Gridinit(my_blacs_ctxt, layout, np_rows, np_cols)
call BLACS_Gridinfo(my_blacs_ctxt, np_rows_, np_cols_, my_prow, my_pcol)
if (np_rows /= np_rows_) then
print *, "BLACS_Gridinfo returned different values for np_rows as set by BLACS_Gridinit"
stop 1
endif
if (np_cols /= np_cols_) then
print *, "BLACS_Gridinfo returned different values for np_cols as set by BLACS_Gridinit"
stop 1
endif
#else
my_prow = 0
my_pcol = 0
#endif
end subroutine
subroutine set_up_blacs_descriptor(na, nblk, my_prow, my_pcol, &
np_rows, np_cols, na_rows, &
na_cols, sc_desc, my_blacs_ctxt, info)
use elpa_utilities, only : error_unit
!use test_util
implicit none
integer(kind=ik), intent(in) :: na, nblk, my_prow, my_pcol, np_rows, &
np_cols, &
my_blacs_ctxt, info
integer(kind=ik), intent(out) :: na_rows, na_cols, sc_desc(1:9)
#ifdef WITH_MPI
integer(kind=ik), external :: numroc
integer(kind=ik) :: mpierr
sc_desc(:) = 0
! determine the neccessary size of the distributed matrices,
! we use the scalapack tools routine NUMROC
na_rows = numroc(na, nblk, my_prow, 0, np_rows)
na_cols = numroc(na, nblk, my_pcol, 0, np_cols)
! set up the scalapack descriptor for the checks below
! For ELPA the following restrictions hold:
! - block sizes in both directions must be identical (args 4 a. 5)
! - first row and column of the distributed matrix must be on
! row/col 0/0 (arg 6 and 7)
call descinit(sc_desc, na, na, nblk, nblk, 0, 0, my_blacs_ctxt, na_rows, info)
if (info .ne. 0) then
write(error_unit,*) 'Error in BLACS descinit! info=',info
write(error_unit,*) 'Most likely this happend since you want to use'
write(error_unit,*) 'more MPI tasks than are possible for your'
write(error_unit,*) 'problem size (matrix size and blocksize)!'
write(error_unit,*) 'The blacsgrid can not be set up properly'
write(error_unit,*) 'Try reducing the number of MPI tasks...'
call MPI_ABORT(mpi_comm_world, 1, mpierr)
endif
#else /* WITH_MPI */
na_rows = na
na_cols = na
#endif /* WITH_MPI */
end subroutine