├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── INSTALL.md ├── LICENSE ├── Mac-MPI-Accelerate.cmake ├── Makefile.am ├── README.md ├── VERSION ├── autogen.sh ├── configure.ac ├── m4 ├── aclocal.m4 ├── aclocal_am.m4 ├── aclocal_atomic.m4 ├── aclocal_attr_alias.m4 ├── aclocal_bugfix.m4 ├── aclocal_cache.m4 ├── aclocal_cc.m4 ├── aclocal_cxx.m4 ├── aclocal_f77.m4 ├── aclocal_f77new.m4 ├── aclocal_fc.m4 ├── aclocal_libs.m4 ├── aclocal_make.m4 ├── aclocal_mpi.m4 ├── aclocal_romio.m4 ├── aclocal_runlog.m4 ├── aclocal_shl.m4 ├── aclocal_subcfg.m4 ├── aclocal_util.m4 ├── ax_prefix_config_h.m4 └── ax_tls.m4 ├── src ├── CMakeLists.txt ├── bigmpi.h ├── bigmpi_impl.h ├── collectives_x.c ├── fileio_x.c ├── likely.h ├── neighborhood_collectives_x.c ├── reductions_x.c ├── rma_x.c ├── sendrecv_x.c ├── type_contiguous_x.c ├── type_hindexed_x.c ├── utils.c └── vcollectives_x.c ├── test ├── CMakeLists.txt ├── Makefile.mk ├── README.md ├── devel │ ├── Makefile.mk │ ├── README.md │ ├── aint_overflow.c │ ├── in_place_user_def_reduce.c │ ├── preprocessor.c │ ├── rounding.c │ └── type_create_struct.c ├── mpi │ ├── Makefile.mk │ ├── README.md │ ├── bcast.c │ ├── reduce_scatter.c │ └── scatterv.c ├── perf │ ├── Makefile │ ├── reductions.c │ ├── typecontig.c │ └── typepiggy.c ├── test_allgather_x.c ├── test_allreduce_x.c ├── test_alltoall_x.c ├── test_assert_x.c ├── test_bcast_x.c ├── test_contig_x.c ├── test_factorize.c ├── test_gather_x.c ├── test_irsend_irecv_x.c ├── test_isend_irecv_x.c ├── test_issend_irecv_x.c ├── test_reduce_x.c ├── test_rma2_x.c ├── test_rma_x.c ├── test_rsend_recv_x.c ├── test_scatter_x.c ├── test_send_recv_x.c ├── test_sendrecv_x.c ├── test_ssend_recv_x.c └── verify_buffer.h └── travis ├── build-run.sh ├── install-autotools.sh ├── install-deps.sh └── install-mpi.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.o 3 | *.x 4 | *~ 5 | Makefile.in 6 | aclocal.m4 7 | autom4te.cache/ 8 | configure 9 | src/bigmpiconf.h.in 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: c 3 | os: 4 | - linux 5 | - osx 6 | compiler: 7 | - gcc 8 | - clang 9 | matrix: 10 | allow_failures: 11 | - env: MPI_IMPL=openmpi 12 | env: 13 | - MPI_IMPL=mpich 14 | - MPI_IMPL=openmpi 15 | before_install: 16 | - export TRAVIS_ROOT=$HOME/travis 17 | - mkdir -p $TRAVIS_ROOT 18 | - sh ./travis/install-autotools.sh $TRAVIS_ROOT 19 | - export PATH=$TRAVIS_ROOT/bin:$PATH 20 | install: 21 | - sh ./travis/install-mpi.sh $TRAVIS_ROOT $MPI_IMPL 22 | script: 23 | - sh ./travis/build-run.sh $TRAVIS_ROOT $MPI_IMPL 24 | after_failure: 25 | - find . -name config.log -exec grep -L "configure: exit 0" {} ";" | xargs cat 26 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(DEFINED PROJECT_NAME) 2 | set(BigMPI_SUBPROJECT ON) 3 | endif() 4 | 5 | project(BigMPI) 6 | 7 | cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR) 8 | 9 | set(PACKAGE_NAME BigMPI) 10 | 11 | # set macosx_rpath 12 | set(CMAKE_MACOSX_RPATH 1) 13 | 14 | # find and use detected mpi 15 | find_package(MPI) 16 | 17 | # generic function to add user-configurable options. 18 | function(add_config_option name help_message default) 19 | if(NOT DEFINED ${name}) 20 | set(${name} "${default}") 21 | set(${name} "${default}" CACHE STRING "${help_message}" FORCE) 22 | endif() 23 | 24 | set(OPTIONS_LIST "${OPTIONS_LIST}\n\n * ${name}=\"${${name}}\",\n default=\"${default}\"\n ${help_message}" PARENT_SCOPE) 25 | endfunction(add_config_option) 26 | 27 | add_config_option(BIGMPI_MAX_INT "Determines which element count BigMPI will assume to be safe." 1000000) 28 | add_config_option(BIGMPI_VCOLLS "Selects which flavor should be used for the implementation of vector collectives (valid options: RMA, P2P, NBHD_ALLTOALLW)" RMA) 29 | add_config_option(LIB_LINKAGE_TYPE "Controls which type of library to build. Suggested: SHARED on Linux (creates a shared object \"bigmpi.so\"), STATIC should work for builds on Cray and Windows." "SHARED" false) 30 | add_config_option(TEST_COVERAGE_VERBOSITY "Sets the verbosity of the test coverage reoprt (0 = off, 1 = summary, 2 = verbose listing)" 1) 31 | 32 | message("-- The following options have been configured:") 33 | message(${OPTIONS_LIST}) 34 | message("") 35 | 36 | if (BIGMPI_MAX_INT) 37 | add_definitions(-DBIGMPI_MAX_INT=${BIGMPI_MAX_INT}) 38 | endif() 39 | 40 | add_definitions(-DBIGMPI_VCOLLS_${BIGMPI_VCOLLS}) 41 | 42 | set_property(GLOBAL PROPERTY C_STANDARD 99) 43 | 44 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") 45 | include_directories(${MPI_INCLUDE_PATH}) 46 | 47 | string(APPEND CMAKE_C_COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") 48 | string(APPEND CMAKE_EXE_LINKER_FLAGS "${MPI_LINK_FLAGS}") 49 | 50 | add_custom_target(bigmpi_test echo "Tests passed.") 51 | 52 | add_subdirectory(src) 53 | add_subdirectory(test) 54 | 55 | 56 | # compute test coverage: 57 | 58 | # will search all files matching WILDCARD for occurences of MPIX_Foo() 59 | function(list_mpix_functions WILDCARD RESULT) 60 | file(GLOB files "${WILDCARD}") 61 | set(akku ) 62 | 63 | foreach(file ${files}) 64 | file(READ "${file}" file_content) 65 | string(REPLACE ";" "" result1 "${file_content}") 66 | string(REGEX MATCH "MPIX_[A-Za-z0-9_]+" matches "${result1}") 67 | 68 | if(matches) 69 | set(len_old "A") 70 | set(len_new "B") 71 | 72 | while(NOT (len_old EQUAL len_new)) 73 | string(REGEX REPLACE "(.*)(MPIX_[A-Za-z0-9_]+)(.+)" "\\2;\\1 " result2 "${result1}") 74 | set(result1 "${result2}") 75 | 76 | set(len_old "${len_new}") 77 | string(LENGTH "${result1}" len_new ) 78 | endwhile() 79 | 80 | list(APPEND akku "${result1}") 81 | endif() 82 | endforeach() 83 | 84 | list(REMOVE_DUPLICATES akku) 85 | list(SORT akku) 86 | set("${RESULT}" "${akku}" PARENT_SCOPE) 87 | endfunction() 88 | 89 | list_mpix_functions("src/bigmpi.h" all_mpix_functions) 90 | list_mpix_functions("test/*.c" tested_mpix_functions) 91 | list(LENGTH all_mpix_functions num_all_mpix_functions) 92 | list(LENGTH tested_mpix_functions num_tested_mpix_functions) 93 | 94 | set(message_level STATUS) 95 | if(num_all_mpix_functions GREATER num_tested_mpix_functions) 96 | set(message_level WARNING) 97 | endif() 98 | 99 | if(TEST_COVERAGE_VERBOSITY GREATER 0) 100 | message("${message_level}" "Test coverage: ${num_tested_mpix_functions}/${num_all_mpix_functions} functions.") 101 | endif() 102 | 103 | if(TEST_COVERAGE_VERBOSITY STREQUAL 2) 104 | foreach(func ${all_mpix_functions}) 105 | list(FIND tested_mpix_functions "${func}" found) 106 | 107 | if(found EQUAL -1) 108 | message(STATUS "${func}() UNTESTED") 109 | endif() 110 | endforeach() 111 | endif() 112 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | ## Autotools 4 | ``` 5 | cd $(BIGMPI_SOURCE_DIR) && ./autogen.sh 6 | cd $(BIGMPI_BUILD_DIR) && $(BIGMPI_SOURCE_DIR)/configure CC=mpicc 7 | ``` 8 | (add `--prefix` if you want to `make install` somewhere) 9 | 10 | ## CMake 11 | ``` 12 | cmake $(BIGMPI_SOURCE_DIR) -DCMAKE_C_COMPILER=mpicc 13 | ``` 14 | 15 | # Build 16 | 17 | ``` 18 | make 19 | make check 20 | ``` 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013, 2014 Argonne National Laboratory 4 | Copyright (c) 2014 Friedrich-Alexander-Universitaet Erlangen-Nuernberg 5 | Copyright (c) 2014 Intel Corporation 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Mac-MPI-Accelerate.cmake: -------------------------------------------------------------------------------- 1 | # MPI wrappers assumed to be in path 2 | set(COMPILER_DIR ) 3 | set(CMAKE_C_COMPILER ${COMPILER_DIR}mpicc) 4 | set(CMAKE_CXX_COMPILER ${COMPILER_DIR}mpicxx) 5 | set(CMAKE_Fortran_COMPILER ${COMPILER_DIR}mpif90) 6 | 7 | set(MPI_C_COMPILER ${CMAKE_C_COMPILER}) 8 | set(MPI_CXX_COMPILER ${CMAKE_CXX_COMPILER}) 9 | set(MPI_Fortran_COMPILER ${CMAKE_Fortran_COMPILER}) 10 | 11 | if(CMAKE_BUILD_TYPE MATCHES PureDebug OR 12 | CMAKE_BUILD_TYPE MATCHES HybridDebug) 13 | set(C_FLAGS "-g") 14 | set(CXX_FLAGS "-g") 15 | else() 16 | set(C_FLAGS "-O3") 17 | set(CXX_FLAGS "-O3") 18 | endif() 19 | 20 | set(OpenMP_CXX_FLAGS "-fopenmp") 21 | 22 | set(MATH_LIBS "-framework Accelerate") 23 | set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 24 | set(BUILD_SHARED_LIBS ON) 25 | set(CMAKE_EXE_LINKER_FLAGS "") 26 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014. See LICENSE in top-level directory. 3 | # 4 | 5 | ACLOCAL_AMFLAGS = -I m4 6 | AM_CPPFLAGS = -I$(top_srcdir)/src 7 | 8 | lib_LTLIBRARIES = libbigmpi.la 9 | 10 | noinst_LTLIBRARIES = libbigmpii.la 11 | 12 | libbigmpi_la_SOURCES = src/collectives_x.c \ 13 | src/vcollectives_x.c \ 14 | src/neighborhood_collectives_x.c \ 15 | src/reductions_x.c \ 16 | src/rma_x.c \ 17 | src/sendrecv_x.c \ 18 | src/fileio_x.c \ 19 | src/type_contiguous_x.c \ 20 | src/type_hindexed_x.c \ 21 | src/utils.c 22 | 23 | libbigmpi_la_LDFLAGS = -version-info $(libbigmpi_abi_version) 24 | 25 | libbigmpii_la_SOURCES = $(libbigmpi_la_SOURCES) 26 | libbigmpii_la_LDFLAGS = $(libbigmpi_abi_version) 27 | 28 | include_HEADERS = src/bigmpi.h src/bigmpi_impl.h 29 | 30 | bin_PROGRAMS = 31 | check_PROGRAMS = 32 | TESTS = 33 | XFAIL_TESTS = 34 | 35 | MPIEXEC = mpiexec -n 2 36 | TESTS_ENVIRONMENT = $(MPIEXEC) 37 | 38 | include test/Makefile.mk 39 | 40 | .PHONY: checkprogs 41 | checkprogs: $(check_PROGRAMS) 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Build Status 2 | ============ 3 | 4 | We are still struggling to get Travis working properly. Right now, only MPICH on Linux is tested and with an artificially low `INT_MAX` (1048576). 5 | 6 | [![Build Status](https://travis-ci.org/jeffhammond/BigMPI.svg?branch=master)](https://travis-ci.org/jeffhammond/BigMPI) 7 | 8 | BigMPI 9 | ====== 10 | 11 | _See the ExaMPI14 [paper](http://dl.acm.org/citation.cfm?id=2690884) 12 | ([free copy](https://github.com/jeffhammond/BigMPI-paper)) 13 | for a detailed analysis of large-count issues in MPI._ 14 | 15 | Interface to MPI for large messages, i.e. those where the count argument 16 | exceeds `INT_MAX` but is still less than `SIZE_MAX`. 17 | BigMPI is designed for the common case where one has a 64b address 18 | space and is unable to do MPI communication on more than 2^31 elements 19 | despite having sufficient memory to allocate such buffers. 20 | BigMPI does not attempt to support large-counts on systems where 21 | C `int` and `void*` are both 32b. 22 | 23 | ## Motivation 24 | 25 | The MPI standard provides a wide range of communication functions that 26 | take a C `int` argument for the element count, thereby limiting this 27 | value to `INT_MAX` or less. 28 | This means that one cannot send, e.g. 3 billion bytes using the `MPI_BYTE` 29 | datatype, or a vector of 5 billion integers using the `MPI_INT` type, as 30 | two examples. 31 | There is a natural workaround using MPI derived datatypes, but this is 32 | a burden on users who today may not be using derived datatypes. 33 | 34 | This project aspires to make it as easy as possible to support arbitrarily 35 | large counts (2^63 elements exceeds the local storage compacity of computers 36 | for the foreseeable future). 37 | 38 | This is an example of the code change required to support large counts using 39 | BigMPI: 40 | ``` 41 | #ifdef BIGMPI 42 | MPIX_Bcast_x(stuff, large_count /* MPI_Count */, MPI_BYTE, 0, MPI_COMM_WORLD); 43 | #else // cannot use count>INT_MAX 44 | MPI_Bcast(stuff, not_large_count /* int */, MPI_BYTE, 0, MPI_COMM_WORLD); 45 | #endif 46 | ``` 47 | 48 | ## Interface 49 | 50 | The API follows the pattern of `MPI_Type_size(_x)` in that all BigMPI 51 | functions are identical to their corresponding MPI ones except that 52 | they end with `_x` to indicate that the count arguments have the type 53 | `MPI_Count` instead of `int`. 54 | BigMPI functions use the MPIX namespace because they are not in the 55 | MPI standard. 56 | 57 | ## Limitations 58 | 59 | Even though `MPI_Count` might be 128b, BigMPI only supports 60 | 64b counts (because of `MPI_Aint` limitations and a desire to use `size_t` 61 | in unit tests), so BigMPI is not going to solve your problem if you 62 | want to communicate more than 8 EiB of data in a single message. 63 | Such computers do not exist nor is it likely that they will exist 64 | in the foreseeable future. 65 | 66 | BigMPI only supports built-in datatypes. If you are already using 67 | derived-datatypes, then you should already be able to handle large 68 | counts without BigMPI. 69 | 70 | Support for `MPI_IN_PLACE` is not implemented in some cases and 71 | implemented inefficiently in others. 72 | Using `MPI_IN_PLACE` is discouraged at the present time. 73 | We hope to support it more effectively in the future. 74 | 75 | BigMPI requires C99. If your compiler does not support C99, get a 76 | new compiler. 77 | 78 | BigMPI only has C bindings right now. 79 | Fortran 2003 bindings are planned. 80 | If C++ bindings are important to you, please create an issue for this. 81 | 82 | ## Supported Functions 83 | 84 | I believe that point-to-point, one-sided, broadcast and reductions 85 | are the only functions worth supporting but I added some of the other 86 | collectives anyways. 87 | The v-collectives require a point-to-point implementation, but 88 | we do not believe this causes a significant loss of performance. 89 | 90 | ## Technical details 91 | 92 | [MPIX_Type_contiguous_x](https://github.com/jeffhammond/BigMPI/blob/master/src/type_contiguous_x.c) 93 | does the heavy lifting. It's pretty obvious how it works. 94 | The datatypes engine will turn this into a contiguous datatype internally 95 | and thus the underlying communication will be efficient. 96 | MPI implementations need to be count-safe for this to work, but they need 97 | to be count-safe period if the Forum is serious about datatypes being 98 | the solution rather than `MPI_Count` everywhere. 99 | 100 | All of the communication functions follow the same pattern, which is 101 | clearly seen in [MPIX_Send_x](https://github.com/jeffhammond/BigMPI/blob/master/src/sendrecv_x.c). 102 | I've optimized for the common case when count is smaller than 2^31 103 | with a `likely_if` macro to minimize the performance hit of BigMPI 104 | for this more common use case 105 | (hopefully so that users don't insert a branch for this themselves) 106 | 107 | The most obvious optimization I can see doing is to implement 108 | `MPIX_Type_contiguous_x` using internals of the MPI implementation 109 | instead of calling six MPI datatype functions. 110 | I have started implemented this in MPICH already: 111 | https://github.com/jeffhammond/mpich/tree/type_contiguous_x. 112 | 113 | ## Authors 114 | 115 | * Jeff Hammond 116 | * Andreas Schäfer 117 | * Rob Latham 118 | 119 | ## Related 120 | 121 | * [MPI: A Message-Passing Interface Standard - Version 4.0](https://www.mpi-forum.org/docs/mpi-4.0/mpi40-report.pdf) 122 | * [BigMPI paper](https://github.com/jeffhammond/BigMPI-paper) 123 | * [Big MPI--large-count and displacement support--collective chapter](https://github.com/mpi-forum/mpi-issues/issues/80) 124 | * [MPI Forum Large Count working group](https://github.com/mpiwg-large-count/large-count-issues/issues) 125 | 126 | ## Background 127 | 128 | * ["Why size_t matters" by Dan Saks](http://www.embedded.com/electronics-blogs/programming-pointers/4026076/Why-size-t-matters) 129 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | # Version 2 | BIGMPI_VERSION=0.1 3 | 4 | # For libtool ABI versioning rules see: 5 | # http://www.nondot.org/sabre/Mirrored/libtool-2.1a/libtool_6.html#SEC36 6 | 7 | # 1. If the library source code has changed at all since the last 8 | # update, then increment revision (`c:r:a' becomes `c:r+1:a'). 9 | # 10 | # 2. If any interfaces have been added, removed, or changed since 11 | # the last update, increment current, and set revision to 0. 12 | # 13 | # 3. If any interfaces have been added since the last public 14 | # release, then increment age. 15 | # 16 | # 4. If any interfaces have been removed since the last public 17 | # release, then set age to 0. 18 | 19 | libbigmpi_abi_version=1:0:0 20 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | autoreconf=${AUTORECONF:-autoreconf} 3 | $autoreconf ${autoreconf_args:-"-vif"} 4 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl 2 | dnl Copyright (C) 2014. See LICENSE in top-level directory. 3 | dnl 4 | 5 | AC_PREREQ(2.62) 6 | 7 | AC_INIT([bigmpi],[0]) 8 | AC_CONFIG_AUX_DIR(m4) 9 | AC_CONFIG_MACRO_DIR(m4) 10 | AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.11 color-tests parallel-tests subdir-objects]) 11 | 12 | LT_PREREQ([2.2.6]) 13 | 14 | ## Bug in libtool adds -O2 and -g by default 15 | if test ! -z "$MPICC" ; then 16 | CC=$MPICC 17 | export CC 18 | fi 19 | PAC_PUSH_FLAG(CFLAGS) 20 | AC_PROG_CC(mpicc) 21 | AM_PROG_CC_C_O 22 | 23 | # automake 1.12 seems to require this, but automake 1.11 doesn't recognize it 24 | # must come before LT_INIT 25 | m4_ifdef([AM_PROG_AR],[AM_PROG_AR]) 26 | 27 | LT_INIT(disable-shared) 28 | PAC_POP_FLAG(CFLAGS) 29 | 30 | ## Non-verbose make 31 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 32 | 33 | ## Version checks 34 | if test -s "$srcdir/VERSION" ; then 35 | . $srcdir/VERSION 36 | export BIGMPI_VERSION 37 | else 38 | AC_MSG_ERROR([Version information not found. Configuration aborted.]) 39 | fi 40 | 41 | # ABI version 42 | AC_SUBST(libbigmpi_abi_version) 43 | 44 | # Release version 45 | # Produce a numeric version assuming the following format: 46 | # Version: [MAJ].[MIN].[REV][EXT][EXT_NUMBER] 47 | # Example: 1.0.7rc1 has 48 | # MAJ = 1 49 | # MIN = 0 50 | # REV = 7 51 | # EXT = rc 52 | # EXT_NUMBER = 1 53 | # 54 | # Converting to numeric version will convert EXT to a format number: 55 | # ALPHA (a) = 0 56 | # BETA (b) = 1 57 | # RC (rc) = 2 58 | # PATCH (p) = 3 59 | # Regular releases are treated as patch 0 60 | # 61 | # Numeric version will have 1 digit for MAJ, 2 digits for MIN, 62 | # 2 digits for REV, 1 digit for EXT and 2 digits for EXT_NUMBER. 63 | changequote(<<,>>) 64 | V1=`expr $BIGMPI_VERSION : '\([0-9]*\)\.[0-9]*\.*[0-9]*[a-zA-Z]*[0-9]*'` 65 | V2=`expr $BIGMPI_VERSION : '[0-9]*\.\([0-9]*\)\.*[0-9]*[a-zA-Z]*[0-9]*'` 66 | V3=`expr $BIGMPI_VERSION : '[0-9]*\.[0-9]*\.*\([0-9]*\)[a-zA-Z]*[0-9]*'` 67 | V4=`expr $BIGMPI_VERSION : '[0-9]*\.[0-9]*\.*[0-9]*\([a-zA-Z]*\)[0-9]*'` 68 | V5=`expr $BIGMPI_VERSION : '[0-9]*\.[0-9]*\.*[0-9]*[a-zA-Z]*\([0-9]*\)'` 69 | changequote([,]) 70 | 71 | if test "$V2" -le 9 ; then V2=0$V2 ; fi 72 | if test "$V3" = "" ; then V3=0; fi 73 | if test "$V3" -le 9 ; then V3=0$V3 ; fi 74 | if test "$V4" = "a" ; then 75 | V4=0 76 | elif test "$V4" = "b" ; then 77 | V4=1 78 | elif test "$V4" = "rc" ; then 79 | V4=2 80 | elif test "$V4" = "" ; then 81 | V4=3 82 | V5=0 83 | elif test "$V4" = "p" ; then 84 | V4=3 85 | fi 86 | if test "$V5" -le 9 ; then V5=0$V5 ; fi 87 | 88 | BIGMPI_NUMVERSION=`expr $V1$V2$V3$V4$V5 + 0` 89 | AC_SUBST(BIGMPI_NUMVERSION) 90 | AC_SUBST(BIGMPI_VERSION) 91 | 92 | AC_CONFIG_HEADER(src/bigmpiconf.h) 93 | AH_TOP([/* -*- Mode: C; c-basic-offset:4 ; -*- */ 94 | /* 95 | * (C) 2014 by Jeff Hammond. 96 | * See LICENSE in top-level directory. 97 | */ 98 | #ifndef _BIGMPICONF_H_ 99 | #define _BIGMPICONF_H_ 100 | ]) 101 | AH_BOTTOM([#endif /* _BIGMPICONF_H_ */]) 102 | 103 | PAC_ARG_STRICT 104 | PAC_CC_FUNCTION_NAME_SYMBOL 105 | 106 | ## Error checking functionality 107 | #AC_ARG_ENABLE(error-checking, 108 | #AC_HELP_STRING([--enable-error-checking],[Enable error checking functionality]), 109 | #enable_error_checking=$enableval, 110 | #enable_error_checking=yes) 111 | #if test "$enable_error_checking" = "yes" ; then 112 | #AC_DEFINE(ERROR_CHECKING,1,[Define if error checking is enabled]) 113 | #fi 114 | 115 | ## Check if __VA_ARGS__ is defined by the compiler 116 | PAC_C_MACRO_VA_ARGS 117 | 118 | ## const and restrict 119 | AC_C_CONST 120 | AC_C_RESTRICT 121 | 122 | ## Chcek for C99 123 | AC_PROG_CC_C99 124 | if test "$ac_cv_prog_cc_c99" = "no" ; then 125 | AC_ERROR([C99 not supported by the compiler]) 126 | fi 127 | 128 | AC_CHECK_HEADERS([execinfo.h stdint.h inttypes.h]) 129 | AC_TYPE_UINT8_T 130 | 131 | ## Debugging support 132 | AC_ARG_ENABLE(g, AC_HELP_STRING([--enable-g],[Enable Debugging]), 133 | [ debug=$enableval ], 134 | [ debug=no ]) 135 | AC_MSG_CHECKING(debugging support) 136 | AC_MSG_RESULT($debug) 137 | if test "$debug" = "yes"; then 138 | CFLAGS="$CFLAGS -g -O0" 139 | fi 140 | 141 | ## Safety checks 142 | AC_ARG_ENABLE(safety-checks, AC_HELP_STRING([--disable-safety-checks],[Disable safety checks for better performance]), 143 | [ safety_enabled=$enableval ], 144 | [ safety_enabled=yes ]) 145 | AC_MSG_CHECKING(whether safety checks are enabled) 146 | AC_MSG_RESULT($safety_enabled) 147 | if test "$safety_enabled" = "no"; then 148 | AC_DEFINE(NO_SEATBELTS,1,[Defined when safety checks are disabled]) 149 | fi 150 | 151 | ## Try to avoid using MPI_Type_create_struct 152 | AC_ARG_ENABLE(type-struct, AC_HELP_STRING([--disable-type-struct],[Try to avoid using MPI_Type_create_struct]), 153 | [ type_struct=$enableval ], 154 | [ type_struct=no ]) 155 | AC_MSG_CHECKING(whether MPI_Type_create_struct is to be avoided) 156 | AC_MSG_RESULT($type_struct) 157 | if test "$type_struct" = "no"; then 158 | AC_DEFINE(BIGMPI_AVOID_TYPE_STRUCT,1,[Defined when MPI_Type_create_struct is to be avoided]) 159 | fi 160 | 161 | ## Set BigMPI max int to something other than INT_MAX 162 | ## Look for with_aint_size in MPICH configure stuff for examples. 163 | AC_ARG_WITH(max-int, AC_HELP_STRING([--with-max-int=num],[Override INT_MAX as maximum integer]),, 164 | [ with_max_int=0 ]) 165 | AC_MSG_CHECKING(for maximum integer override) 166 | AC_MSG_RESULT($with_max_int) 167 | if test "$with_max_int" -gt 0; then 168 | AC_DEFINE_UNQUOTED(BIGMPI_MAX_INT,$with_max_int,[Maximum integer]) 169 | fi 170 | 171 | ## Pipeline reductions instead of using user-defined operations 172 | AC_ARG_ENABLE(reduce-pipelining, AC_HELP_STRING([--enable-reduce-pipelining],[Use pipelined reductions]), 173 | [ pipelined_reductions=$enableval ], 174 | [ pipelined_reductions=yes ]) 175 | AC_MSG_CHECKING(pipelined reductions) 176 | AC_MSG_RESULT($pipelined_reductions) 177 | if test "$pipelined_reductions" = "yes"; then 178 | AC_DEFINE(BIGMPI_CLEAVER,1,[Defined when pipelined reductions are to be used]) 179 | fi 180 | 181 | ## Documentation 182 | AC_PATH_PROG([DOXYGEN],[doxygen],,$PATH) 183 | AC_SUBST(DOXYGEN) 184 | 185 | AC_SUBST(top_srcdir) 186 | 187 | ## Final output 188 | AC_OUTPUT(Makefile) 189 | -------------------------------------------------------------------------------- /m4/aclocal.m4: -------------------------------------------------------------------------------- 1 | dnl This version of aclocal.m4 simply includes all of the individual 2 | dnl components 3 | builtin(include,aclocal_am.m4) 4 | builtin(include,aclocal_bugfix.m4) 5 | builtin(include,aclocal_cache.m4) 6 | builtin(include,aclocal_cc.m4) 7 | builtin(include,aclocal_atomic.m4) 8 | dnl aclocal_cross.m4 uses autoconf features dated back to 2.13. 9 | dnl too old to be useful, 07/14/2010. 10 | dnl builtin(include,aclocal_cross.m4) 11 | builtin(include,aclocal_cxx.m4) 12 | builtin(include,aclocal_f77.m4) 13 | builtin(include,aclocal_f77new.m4) 14 | builtin(include,aclocal_util.m4) 15 | builtin(include,aclocal_subcfg.m4) 16 | builtin(include,aclocal_make.m4) 17 | builtin(include,aclocal_mpi.m4) 18 | builtin(include,aclocal_shl.m4) 19 | dnl fortran90.m4 defines [Fortran 90] as an AC_LANG 20 | dnl which works for autoconf 2.63 and older, 07/14/2010. 21 | dnl builtin(include,fortran90.m4) 22 | builtin(include,aclocal_runlog.m4) 23 | builtin(include,aclocal_fc.m4) 24 | builtin(include,aclocal_libs.m4) 25 | builtin(include,aclocal_attr_alias.m4) 26 | builtin(include,ax_tls.m4) 27 | builtin(include,aclocal_romio.m4) 28 | dnl Add the libtool files that libtoolize wants 29 | dnl Comment these out until libtool support is enabled. 30 | dnl May need to change this anyway, since libtoolize 31 | dnl does not seem to understand builtin 32 | dnl builtin(include,libtool.m4) 33 | dnl builtin(include,ltoptions.m4) 34 | dnl builtin(include,ltversion.m4) 35 | dnl builtin(include,ltsugar.m4) 36 | dnl builtin(include,lt~obsolete.m4) 37 | -------------------------------------------------------------------------------- /m4/aclocal_am.m4: -------------------------------------------------------------------------------- 1 | dnl AM_IGNORE is an extension that tells (a patched) automake not to 2 | dnl include the specified AC_SUBST variable in the Makefile.in that 3 | dnl automake generates. We don't use AC_DEFUN, since aclocal will 4 | dnl then complain that AM_IGNORE is a duplicate (if you are using the 5 | dnl patched automake/aclocal). 6 | m4_ifdef([AM_IGNORE],[],[m4_define([AM_IGNORE],[])]) 7 | -------------------------------------------------------------------------------- /m4/aclocal_atomic.m4: -------------------------------------------------------------------------------- 1 | dnl /*D PAC_C_MEMATOMIC - Try and determine how to implement memory-atomic 2 | dnl operations with the selected C compiler 3 | dnl 4 | dnl Synopsis: 5 | dnl PAC_C_MEMATOMIC 6 | dnl 7 | dnl Notes: 8 | dnl Defines names of the following form 9 | dnl + HAVE_GCC_ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - gcc __asm__ will issue 10 | dnl mfence, lfence, or sfence 11 | dnl . HAVE___ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - __asm _emit will issue 12 | dnl mfence, lfence, or sfence 13 | dnl . HAVE_ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - asm("...") will issue 14 | dnl mfence, lfence, or sfence 15 | dnl . HAVE__INTERLOCKEDEXCHANGE - _InterlockedExchange intrinsic is available 16 | dnl (IA64) 17 | dnl . HAVE_GCC_ASM_SPARC_MEMBAR - gcc __asm__ will issue SPARC architecture 18 | dnl memory barrier instruction 19 | dnl . HAVE_SOLARIS_ASM_SPARC_MEMBAR - Solaris asm() will issue SPARC 20 | dnl architecture memory barrier instruction 21 | dnl . HAVE_GCC_ASM_SPARC_STBAR - gcc __asm__ will issue stbar 22 | dnl - HAVE_SOLARIS_ASM_SPARC_STBAR - Solaris __asm() will issue stbar 23 | dnl 24 | dnl D*/ 25 | AC_DEFUN([PAC_C_MEMATOMIC],[ 26 | AC_CACHE_CHECK([for x86 mfence instruction using __asm__], 27 | pac_cv_have_gcc_asm_and_x86_mfence,[ 28 | AC_TRY_RUN([ 29 | int main(int argc, char **argv) 30 | { 31 | __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0xf0" ::: "memory" ); 32 | exit(0); 33 | } 34 | ], 35 | pac_cv_have_gcc_asm_and_x86_mfence=yes,pac_cv_have_gcc_asm_and_x86_mfence=no)]) 36 | 37 | if test "$pac_cv_have_gcc_asm_and_x86_mfence" = "yes" ; then 38 | AC_DEFINE(HAVE_GCC_ASM_AND_X86_MFENCE, 1, [Define if using gcc on a x86 system with the mfence instruction]) 39 | fi 40 | 41 | AC_CACHE_CHECK([for x86 sfence instruction using __asm__], 42 | pac_cv_have_gcc_asm_and_x86_sfence,[ 43 | AC_TRY_RUN([ 44 | int main(int argc, char **argv) 45 | { 46 | __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0xf8" ::: "memory" ); 47 | exit(0); 48 | } 49 | ], 50 | pac_cv_have_gcc_asm_and_x86_sfence=yes,pac_cv_have_gcc_asm_and_x86_sfence=no)]) 51 | 52 | if test "$pac_cv_have_gcc_asm_and_x86_sfence" = "yes" ; then 53 | AC_DEFINE(HAVE_GCC_ASM_AND_X86_SFENCE, 1, [Define if using gcc on a x86 system with the sfence instruction]) 54 | fi 55 | 56 | AC_CACHE_CHECK([for x86 lfence instruction using __asm__], 57 | pac_cv_have_gcc_asm_and_x86_lfence,[ 58 | AC_TRY_RUN([ 59 | int main(int argc, char **argv) 60 | { 61 | __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0xe8" ::: "memory" ); 62 | exit(0); 63 | } 64 | ], 65 | pac_cv_have_gcc_asm_and_x86_lfence=yes,pac_cv_have_gcc_asm_and_x86_lfence=no)]) 66 | 67 | if test "$pac_cv_have_gcc_asm_and_x86_lfence" = "yes" ; then 68 | AC_DEFINE(HAVE_GCC_ASM_AND_X86_LFENCE, 1, [Define if using gcc on a x86 system with the lfence instruction]) 69 | fi 70 | 71 | dnl Some compilers, like icc, may want __asm _emit 72 | AC_CACHE_CHECK([for x86 mfence instruction using __asm], 73 | pac_cv_have___asm_and_x86_mfence,[ 74 | AC_TRY_RUN([ 75 | int main(int argc, char **argv) 76 | { 77 | __asm _emit 0x0f __asm _emit 0xae __asm _emit 0xf0 ; 78 | exit(0); 79 | } 80 | ], 81 | pac_cv_have___asm_and_x86_mfence=yes,pac_cv_have___asm_and_x86_mfence=no)]) 82 | 83 | if test "$pac_cv_have___asm_and_x86_mfence" = "yes" ; then 84 | AC_DEFINE(HAVE___ASM_AND_X86_MFENCE, 1, [Define if using __asm on a x86 system with the mfence instruction]) 85 | fi 86 | 87 | AC_CACHE_CHECK([for x86 sfence instruction using __asm], 88 | pac_cv_have___asm_and_x86_sfence,[ 89 | AC_TRY_RUN([ 90 | int main(int argc, char **argv) 91 | { 92 | __asm sfence ; 93 | exit(0); 94 | } 95 | ], 96 | pac_cv_have___asm_and_x86_sfence=yes,pac_cv_have___asm_and_x86_sfence=no)]) 97 | 98 | if test "$pac_cv_have___asm_and_x86_sfence" = "yes" ; then 99 | AC_DEFINE(HAVE___ASM_AND_X86_SFENCE, 1, [Define if using __asm on a x86 system with the sfence instruction]) 100 | fi 101 | 102 | AC_CACHE_CHECK([for x86 lfence instruction using __asm], 103 | pac_cv_have___asm_and_x86_lfence,[ 104 | AC_TRY_RUN([ 105 | int main(int argc, char **argv) 106 | { 107 | __asm _emit 0x0f __asm _emit 0xae __asm _emit 0xe8 ; 108 | exit(0); 109 | } 110 | ], 111 | pac_cv_have___asm_and_x86_lfence=yes,pac_cv_have___asm_and_x86_lfence=no)]) 112 | 113 | if test "$lac_cv_have___asm_and_x86_lfence" = "yes" ; then 114 | AC_DEFINE(HAVE___ASM_AND_X86_LFENCE, 1, [Define if using __asm on a x86 system with the lfence instruction]) 115 | fi 116 | 117 | dnl 118 | dnl Some compilers, such as pgcc, may require additional arguments. 119 | dnl pgcc may need -Masmkeyword flag. We may want to try this with and 120 | dnl without adding -Masmkeyword to CFLAGS 121 | 122 | AC_CACHE_CHECK([for x86 mfence instruction using asm()], 123 | pac_cv_have_asm_and_x86_mfence,[ 124 | AC_TRY_RUN([ 125 | int main(int argc, char **argv) 126 | { 127 | asm("_emit 0x0f __asm _emit 0xae __asm _emit 0xf0"); 128 | exit(0); 129 | } 130 | ], 131 | pac_cv_have_asm_and_x86_mfence=yes,pac_cv_have_asm_and_x86_mfence=no)]) 132 | 133 | if test "$pac_cv_have_asm_and_x86_mfence" = "yes" ; then 134 | AC_DEFINE(HAVE_ASM_AND_X86_MFENCE, 1, [Define if using asm() on a x86 system with the mfence instruction]) 135 | fi 136 | 137 | AC_CACHE_CHECK([for x86 sfence instruction using asm()], 138 | pac_cv_have_asm_and_x86_sfence,[ 139 | AC_TRY_RUN([ 140 | int main(int argc, char **argv) 141 | { 142 | asm("sfence"); 143 | exit(0); 144 | } 145 | ], 146 | pac_cv_have_asm_and_x86_sfence=yes,pac_cv_have_asm_and_x86_sfence=no)]) 147 | 148 | if test "$pac_cv_have_asm_and_x86_sfence" = "yes" ; then 149 | AC_DEFINE(HAVE_ASM_AND_X86_SFENCE, 1, [Define if using asm() on a x86 system with the sfence instruction]) 150 | fi 151 | 152 | AC_CACHE_CHECK([for x86 lfence instruction using asm()], 153 | pac_cv_have_asm_and_x86_lfence,[ 154 | AC_TRY_RUN([ 155 | int main(int argc, char **argv) 156 | { 157 | asm("_emit 0x0f __asm _emit 0xae __asm _emit 0xe8"); 158 | exit(0); 159 | } 160 | ], 161 | pac_cv_have_asm_and_x86_lfence=yes,pac_cv_have_asm_and_x86_lfence=no)]) 162 | 163 | if test "$pac_cv_have_asm_and_x86_lfence" = "yes" ; then 164 | AC_DEFINE(HAVE_ASM_AND_X86_LFENCE, 1, [Define if using asm() on a x86 system with the lfence instruction]) 165 | fi 166 | 167 | AC_CACHE_CHECK([for _InterlockedExchange intrinsic], 168 | pac_cv_have__InterlockedExchange,[ 169 | AC_TRY_RUN([ 170 | int main(int argc, char **argv) 171 | { 172 | unsigned long lock, *lock_ptr; 173 | lock_ptr = &lock; 174 | _InterlockedExchange(lock_ptr, 1); 175 | exit(0); 176 | } 177 | ], 178 | pac_cv_have__InterlockedExchange=yes,pac_cv_have__InterlockedExchange=no)]) 179 | 180 | if test "$pac_cv_have__InterlockedExchange" = "yes" ; then 181 | AC_DEFINE(HAVE__INTERLOCKEDEXCHANGE, 1, [Define if _InterlockedExchange intrinsic is available]) 182 | fi 183 | 184 | AC_CACHE_CHECK([for SPARC membar instruction with gcc], 185 | pac_cv_gcc_sparc_membar,[ 186 | AC_TRY_RUN([ 187 | int main(int argc, char **argv){ 188 | __asm__ __volatile__ ( "membar #StoreLoad | #StoreStore" : : : "memory" ); 189 | exit(0); 190 | }],pac_cv_gcc_sparc_membar=yes,pac_cv_gcc_sparc_membar=no)]) 191 | if test "$pac_cv_gcc_sparc_membar" = yes ; then 192 | AC_DEFINE(HAVE_GCC_ASM_SPARC_MEMBAR,1,[Define if gcc asm membar supported]) 193 | fi 194 | 195 | AC_CACHE_CHECK([for SPARC membar instruction with Solaris C], 196 | pac_cv_solaris_sparc_membar,[ 197 | AC_TRY_RUN([ 198 | int main(int argc, char **argv){ 199 | __asm ( "membar #StoreLoad | #StoreStore"); 200 | exit(0); 201 | }],pac_cv_solaris_sparc_membar=yes,pac_cv_solaris_sparc_membar=no)]) 202 | if test "$pac_cv_solaris_sparc_membar" = yes ; then 203 | AC_DEFINE(HAVE_SOLARIS_ASM_SPARC_MEMBAR,1,[Define if solaris asm membar supported]) 204 | fi 205 | 206 | AC_CACHE_CHECK([for SPARC stbar instruction with gcc], 207 | pac_cv_gcc_sparc_stbar,[ 208 | AC_TRY_RUN([ 209 | int main(int argc, char **argv){ 210 | __asm__ __volatile__ ( "stbar" : : : "memory" ); 211 | exit(0); 212 | }],pac_cv_gcc_sparc_stbar=yes,pac_cv_gcc_sparc_stbar=no)]) 213 | if test "$pac_cv_gcc_sparc_stbar" = yes ; then 214 | AC_DEFINE(HAVE_GCC_ASM_SPARC_STBAR,1,[Define if gcc asm stbar supported]) 215 | fi 216 | 217 | AC_CACHE_CHECK([for SPARC stbar instruction with Solaris C], 218 | pac_cv_solaris_sparc_stbar,[ 219 | AC_TRY_RUN([ 220 | int main(int argc, char **argv){ 221 | __asm ( "stbar" ); 222 | exit(0); 223 | }],pac_cv_solaris_sparc_stbar=yes,pac_cv_solaris_sparc_stbar=no)]) 224 | if test "$pac_cv_solaris_sparc_stbar" = yes ; then 225 | AC_DEFINE(HAVE_SOLARIS_ASM_SPARC_STBAR,1,[Define if solaris asm stbar supported]) 226 | fi 227 | ]) -------------------------------------------------------------------------------- /m4/aclocal_bugfix.m4: -------------------------------------------------------------------------------- 1 | dnl This internal macro fails to work properly with OTHER internal macros. 2 | dnl Basically, if the prologue is [], then no message should be generated. 3 | dnl This macro is in autoconf 2.52 4 | m4_define([AC_LANG_PROGRAM(Fortran 77)], 5 | [m4_if([$1],[[[]]],,[m4_ifval([$1], 6 | [m4_warn([syntax], [$0: ignoring PROLOGUE: $1])])])dnl 7 | program main 8 | $2 9 | end]) 10 | 11 | 12 | dnl/*D 13 | dnl PAC_PROG_CHECK_INSTALL_WORKS - Check whether the install program in INSTALL 14 | dnl works. 15 | dnl 16 | dnl Synopsis: 17 | dnl PAC_PROG_CHECK_INSTALL_WORKS 18 | dnl 19 | dnl Output Effect: 20 | dnl Sets the variable 'INSTALL' to the value of 'ac_sh_install' if 21 | dnl a file cannot be installed into a local directory with the 'INSTALL' 22 | dnl program 23 | dnl 24 | dnl Notes: 25 | dnl The 'AC_PROG_INSTALL' scripts tries to avoid broken versions of 26 | dnl install by avoiding directories such as '/usr/sbin' where some 27 | dnl systems are known to have bad versions of 'install'. Unfortunately, 28 | dnl this is exactly the sort of test-on-name instead of test-on-capability 29 | dnl that 'autoconf' is meant to eliminate. The test in this script 30 | dnl is very simple but has been adequate for working around problems 31 | dnl on Solaris, where the '/usr/sbin/install' program (known by 32 | dnl autoconf to be bad because it is in /usr/sbin) is also reached by a 33 | dnl soft link through /bin, which autoconf believes is good. 34 | dnl 35 | dnl No variables are cached to ensure that we do not make a mistake in 36 | dnl our choice of install program. 37 | dnl 38 | dnl The Solaris configure requires the directory name to immediately 39 | dnl follow the '-c' argument, rather than the more common 40 | dnl.vb 41 | dnl args sourcefiles destination-dir 42 | dnl.ve 43 | dnl D*/ 44 | AC_DEFUN([PAC_PROG_CHECK_INSTALL_WORKS],[ 45 | if test -z "$INSTALL" ; then 46 | AC_MSG_RESULT([No install program available]) 47 | else 48 | # first make any "confdb/install-sh -c" into an absolute path 49 | # this is a hack, but it's still much cleaner than anything else I could 50 | # come up with (see tt#1007) [goodell@] 51 | AS_CASE(["$INSTALL"], 52 | [/*],[:], 53 | [*install-sh*],[INSTALL="$master_top_srcdir/$INSTALL"]) 54 | 55 | # Check that this install really works 56 | rm -f conftest 57 | echo "Test file" > conftest 58 | if test ! -d .conftest ; then mkdir .conftest ; fi 59 | AC_MSG_CHECKING([whether install works]) 60 | if $INSTALL conftest .conftest >/dev/null 2>&1 ; then 61 | installOk=yes 62 | else 63 | installOk=no 64 | fi 65 | rm -rf .conftest conftest 66 | AC_MSG_RESULT($installOk) 67 | if test "$installOk" = no ; then 68 | if test -n "$ac_install_sh" ; then 69 | INSTALL=$ac_install_sh 70 | else 71 | AC_MSG_ERROR([Unable to find working install]) 72 | fi 73 | fi 74 | fi 75 | ]) 76 | -------------------------------------------------------------------------------- /m4/aclocal_cxx.m4: -------------------------------------------------------------------------------- 1 | dnl PAC_PROG_CXX - reprioritize the C++ compiler search order 2 | AC_DEFUN([PAC_PROG_CXX],[ 3 | PAC_PUSH_FLAG([CXXFLAGS]) 4 | AC_PROG_CXX([g++ icpc pgCC xlC pathCC cl]) 5 | PAC_POP_FLAG([CXXFLAGS]) 6 | ]) 7 | 8 | dnl This is from crypt.to/autoconf-archive, slightly modified. 9 | dnl It defines bool as int if it is not availalbe 10 | dnl 11 | AC_DEFUN([AC_CXX_BOOL], 12 | [AC_CACHE_CHECK(whether the compiler recognizes bool as a built-in type, 13 | ac_cv_cxx_bool, 14 | [AC_LANG_SAVE 15 | AC_LANG_CPLUSPLUS 16 | AC_TRY_COMPILE([ 17 | int f(int x){return 1;} 18 | int f(char x){return 1;} 19 | int f(bool x){return 1;} 20 | ],[bool b = true; return f(b);], 21 | ac_cv_cxx_bool=yes, ac_cv_cxx_bool=no) 22 | AC_LANG_RESTORE 23 | ]) 24 | if test "$ac_cv_cxx_bool" != yes; then 25 | AC_DEFINE(bool,int,[define if bool is a built-in type]) 26 | fi 27 | ]) 28 | 29 | dnl This is from crypt.to/autoconf-archive, slightly modified (name defined) 30 | dnl 31 | AC_DEFUN([AC_CXX_EXCEPTIONS], 32 | [AC_CACHE_CHECK(whether the compiler supports exceptions, 33 | ac_cv_cxx_exceptions, 34 | [AC_LANG_SAVE 35 | AC_LANG_CPLUSPLUS 36 | AC_TRY_COMPILE(,[try { throw 1; } catch (int i) { return i; }], 37 | ac_cv_cxx_exceptions=yes, ac_cv_cxx_exceptions=no) 38 | AC_LANG_RESTORE 39 | ]) 40 | if test "$ac_cv_cxx_exceptions" = yes; then 41 | AC_DEFINE(HAVE_CXX_EXCEPTIONS,,[define if the compiler supports exceptions]) 42 | fi 43 | ]) 44 | 45 | dnl This is from crypt.to/autoconf-archive 46 | dnl 47 | AC_DEFUN([AC_CXX_NAMESPACES], 48 | [AC_CACHE_CHECK(whether the compiler implements namespaces, 49 | ac_cv_cxx_namespaces, 50 | [AC_LANG_SAVE 51 | AC_LANG_CPLUSPLUS 52 | AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}], 53 | [using namespace Outer::Inner; return i;], 54 | ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no) 55 | AC_LANG_RESTORE 56 | ]) 57 | if test "$ac_cv_cxx_namespaces" = yes; then 58 | AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces]) 59 | fi 60 | ]) 61 | 62 | dnl Some compilers support namespaces but don't know about std 63 | dnl 64 | AC_DEFUN([AC_CXX_NAMESPACE_STD], 65 | [AC_REQUIRE([AC_CXX_NAMESPACES]) 66 | AC_CACHE_CHECK(whether the compiler implements the namespace std, 67 | ac_cv_cxx_namespace_std, 68 | [ac_cv_cxx_namespace_std=no 69 | if test "$ac_cv_cxx_namespaces" = yes ; then 70 | AC_LANG_SAVE 71 | AC_LANG_CPLUSPLUS 72 | AC_TRY_COMPILE([ 73 | #include 74 | using namespace std;], 75 | [cout << "message\n";], 76 | ac_cv_cxx_namespace_std=yes, ac_cv_cxx_namespace_std=no) 77 | AC_LANG_RESTORE 78 | fi 79 | ]) 80 | if test "$ac_cv_cxx_namespace_std" = yes; then 81 | AC_DEFINE(HAVE_NAMESPACE_STD,,[define if the compiler implements namespace std]) 82 | fi 83 | ]) 84 | 85 | dnl/*D 86 | dnl PAC_CXX_CHECK_COMPILER_OPTION - Check that a C++ compiler option is 87 | dnl accepted without warning messages 88 | dnl 89 | dnl Synopsis: 90 | dnl PAC_CXX_CHECK_COMPILER_OPTION(optionname,action-if-ok,action-if-fail) 91 | dnl 92 | dnl Output Effects: 93 | dnl 94 | dnl If no actions are specified, a working value is added to 'CXXOPTIONS' 95 | dnl 96 | dnl Notes: 97 | dnl This is now careful to check that the output is different, since 98 | dnl some compilers are noisy. 99 | dnl 100 | dnl We are extra careful to prototype the functions in case compiler options 101 | dnl that complain about poor code are in effect. 102 | dnl 103 | dnl Because this is a long script, we have ensured that you can pass a 104 | dnl variable containing the option name as the first argument. 105 | dnl D*/ 106 | AC_DEFUN([PAC_CXX_CHECK_COMPILER_OPTION],[ 107 | AC_MSG_CHECKING([whether C++ compiler accepts option $1]) 108 | save_CXXFLAGS="$CXXFLAGS" 109 | CXXFLAGS="$1 $CXXFLAGS" 110 | rm -f conftest.out 111 | echo 'int foo(void);int foo(void){return 0;}' > conftest2.cpp 112 | echo 'int main(void);int main(void){return 0;}' > conftest.cpp 113 | if ${CXX-g++} $save_CXXFLAGS $CPPFLAGS -o conftest conftest.cpp $LDFLAGS >conftest.bas 2>&1 ; then 114 | if ${CXX-g++} $CXXFLAGS $CPPFLAGS -o conftest conftest.cpp $LDFLAGS >conftest.out 2>&1 ; then 115 | if diff -b conftest.out conftest.bas >/dev/null 2>&1 ; then 116 | AC_MSG_RESULT(yes) 117 | AC_MSG_CHECKING([whether routines compiled with $1 can be linked with ones compiled without $1]) 118 | rm -f conftest.out 119 | rm -f conftest.bas 120 | if ${CXX-g++} -c $save_CXXFLAGS $CPPFLAGS conftest2.cpp >conftest2.out 2>&1 ; then 121 | if ${CXX-g++} $CXXFLAGS $CPPFLAGS -o conftest conftest2.o conftest.cpp $LDFLAGS >conftest.bas 2>&1 ; then 122 | if ${CXX-g++} $CXXFLAGS $CPPFLAGS -o conftest conftest2.o conftest.cpp $LDFLAGS >conftest.out 2>&1 ; then 123 | if diff -b conftest.out conftest.bas >/dev/null 2>&1 ; then 124 | AC_MSG_RESULT(yes) 125 | CXXFLAGS="$save_CXXFLAGS" 126 | ifelse($2,,CXXOPTIONS="$CXXOPTIONS $1",$2) 127 | elif test -s conftest.out ; then 128 | cat conftest.out >&AC_FD_CC 129 | AC_MSG_RESULT(no) 130 | CXXFLAGS="$save_CXXFLAGS" 131 | $3 132 | else 133 | AC_MSG_RESULT(no) 134 | CXXFLAGS="$save_CXXFLAGS" 135 | $3 136 | fi 137 | else 138 | if test -s conftest.out ; then 139 | cat conftest.out >&AC_FD_CC 140 | fi 141 | AC_MSG_RESULT(no) 142 | CXXFLAGS="$save_CXXFLAGS" 143 | $3 144 | fi 145 | else 146 | # Could not link with the option! 147 | AC_MSG_RESULT(no) 148 | fi 149 | else 150 | if test -s conftest2.out ; then 151 | cat conftest2.out >&AC_FD_CC 152 | fi 153 | AC_MSG_RESULT(no) 154 | CXXFLAGS="$save_CXXFLAGS" 155 | $3 156 | fi 157 | else 158 | cat conftest.out >&AC_FD_CC 159 | AC_MSG_RESULT(no) 160 | $3 161 | CXXFLAGS="$save_CXXFLAGS" 162 | fi 163 | else 164 | AC_MSG_RESULT(no) 165 | $3 166 | if test -s conftest.out ; then cat conftest.out >&AC_FD_CC ; fi 167 | CXXFLAGS="$save_CXXFLAGS" 168 | fi 169 | else 170 | # Could not compile without the option! 171 | AC_MSG_RESULT(no) 172 | fi 173 | rm -f conftest* 174 | ]) 175 | -------------------------------------------------------------------------------- /m4/aclocal_f77new.m4: -------------------------------------------------------------------------------- 1 | dnl /*D 2 | dnl PAC_F77_WORKS_WITH_CPP 3 | dnl 4 | dnl Checks if Fortran 77 compiler works with C preprocessor 5 | dnl 6 | dnl Most systems allow the Fortran compiler to process .F and .F90 files 7 | dnl using the C preprocessor. However, some systems either do not 8 | dnl allow this or have serious bugs (OSF Fortran compilers have a bug 9 | dnl that generates an error message from cpp). The following test 10 | dnl checks to see if .F works, and if not, whether "cpp -P -C" can be used 11 | dnl D*/ 12 | AC_DEFUN([PAC_F77_WORKS_WITH_CPP],[ 13 | AC_REQUIRE([AC_PROG_CPP]) 14 | AC_MSG_CHECKING([whether Fortran 77 compiler processes .F files with C preprocessor]) 15 | AC_LANG_PUSH([Fortran 77]) 16 | saved_f77_ext=${ac_ext} 17 | ac_ext="F" 18 | saved_FFLAGS="$FFLAGS" 19 | FFLAGS="$FFLAGS $CPPFLAGS" 20 | AC_LANG_CONFTEST([ 21 | AC_LANG_SOURCE([ 22 | program main 23 | #define ASIZE 10 24 | integer a(ASIZE) 25 | end 26 | ]) 27 | ]) 28 | AC_COMPILE_IFELSE([],[ 29 | pac_cv_f77_accepts_F=yes 30 | ifelse([$1],[],[],[$1=""]) 31 | ],[ 32 | pac_cv_f77_accepts_F=no 33 | ifelse([$1],[],[:],[$1="false"]) 34 | ]) 35 | # Restore Fortran 77's ac_ext but not FFLAGS 36 | ac_ext="$saved_f77_ext" 37 | 38 | if test "$pac_cv_f77_accepts_F" != "yes" ; then 39 | pac_cpp_f77="$ac_cpp -C -P conftest.F > conftest.$ac_ext" 40 | PAC_RUNLOG_IFELSE([$pac_cpp_f77],[ 41 | if test -s conftest.${ac_ext} ; then 42 | AC_COMPILE_IFELSE([],[ 43 | pac_cv_f77_accepts_F="no, use cpp" 44 | ifelse([$1],[],[],[$1="$CPP -C -P"]) 45 | ],[]) 46 | rm -f conftest.${ac_ext} 47 | fi 48 | ],[]) 49 | fi 50 | FFLAGS="$saved_FFLAGS" 51 | rm -f conftest.F 52 | AC_LANG_POP([Fortran 77]) 53 | AC_MSG_RESULT([$pac_cv_f77_accepts_F]) 54 | ]) 55 | -------------------------------------------------------------------------------- /m4/aclocal_libs.m4: -------------------------------------------------------------------------------- 1 | 2 | dnl PAC_SET_HEADER_LIB_PATH(with_option) 3 | dnl This macro looks for the --with-xxx=, --with-xxx-include and --with-xxx-lib= 4 | dnl options and sets the library and include paths. 5 | AC_DEFUN([PAC_SET_HEADER_LIB_PATH],[ 6 | AC_ARG_WITH($1, 7 | AC_HELP_STRING([--with-$1=path], 8 | [specify path where $1 include directory and lib directory can be found]), 9 | if test "${with_$1}" != "yes" -a "${with_$1}" != "no" ; then 10 | # is adding lib64 by default really the right thing to do? What if 11 | # we are on a 32-bit host that happens to have both lib dirs available? 12 | LDFLAGS="$LDFLAGS -L${with_$1}/lib64 -L${with_$1}/lib" 13 | CPPFLAGS="$CPPFLAGS -I${with_$1}/include" 14 | WRAPPER_CFLAGS="$WRAPPER_CFLAGS -I${with_$1}/include" 15 | fi, 16 | ) 17 | AC_ARG_WITH($1-include, 18 | AC_HELP_STRING([--with-$1-include=path], 19 | [specify path where $1 include directory can be found]), 20 | if test "${with_$1_include}" != "yes" -a "${with_$1_include}" != "no" ; then 21 | CPPFLAGS="$CPPFLAGS -I${with_$1_include}" 22 | WRAPPER_CFLAGS="$WRAPPER_CFLAGS -I${with_$1_include}" 23 | fi, 24 | ) 25 | AC_ARG_WITH($1-lib, 26 | AC_HELP_STRING([--with-$1-lib=path], 27 | [specify path where $1 lib directory can be found]), 28 | if test "${with_$1_lib}" != "yes" -a "${with_$1_lib}" != "no" ; then 29 | LDFLAGS="$LDFLAGS -L${with_$1_lib}" 30 | fi, 31 | ) 32 | ]) 33 | 34 | 35 | dnl PAC_CHECK_HEADER_LIB(with_option, header.h, libname, function, action-if-yes, action-if-no) 36 | dnl This macro checks for a header and lib. It is assumed that the 37 | dnl user can specify a path to the includes and libs using --with-xxx=. 38 | dnl The xxx is specified in the "with_option" parameter. 39 | AC_DEFUN([PAC_CHECK_HEADER_LIB],[ 40 | failure=no 41 | AC_CHECK_HEADER([$2],,failure=yes) 42 | AC_CHECK_LIB($3,$4,,failure=yes) 43 | if test "$failure" = "no" ; then 44 | $5 45 | else 46 | $6 47 | fi 48 | ]) 49 | 50 | dnl PAC_CHECK_HEADER_LIB_FATAL(with_option, header.h, libname, function) 51 | dnl Similar to PAC_CHECK_HEADER_LIB, but errors out on failure 52 | AC_DEFUN([PAC_CHECK_HEADER_LIB_FATAL],[ 53 | PAC_CHECK_HEADER_LIB($1,$2,$3,$4,success=yes,success=no) 54 | if test "$success" = "no" ; then 55 | AC_MSG_ERROR(['$2 or lib$3 library not found. Did you specify --with-$1= or --with-$1-include= or --with-$1-lib=?']) 56 | fi 57 | ]) 58 | -------------------------------------------------------------------------------- /m4/aclocal_make.m4: -------------------------------------------------------------------------------- 1 | dnl 2 | dnl We need routines to check that make works. Possible problems with 3 | dnl make include 4 | dnl 5 | dnl It is really gnumake, and contrary to the documentation on gnumake, 6 | dnl it insists on screaming everytime a directory is changed. The fix 7 | dnl is to add the argument --no-print-directory to the make 8 | dnl 9 | dnl It is really BSD 4.4 make, and can't handle 'include'. For some 10 | dnl systems, this can be fatal; there is no fix (other than removing this 11 | dnl alleged make). 12 | dnl 13 | dnl It is the OSF V3 make, and can't handle a comment in a block of target 14 | dnl code. There is no acceptable fix. 15 | dnl 16 | dnl 17 | dnl 18 | dnl 19 | dnl Find a make program if none is defined. 20 | AC_DEFUN([PAC_PROG_MAKE_PROGRAM],[true 21 | if test "X$MAKE" = "X" ; then 22 | AC_CHECK_PROGS(MAKE,make gnumake nmake pmake smake) 23 | fi 24 | ])dnl 25 | 26 | dnl/*D 27 | dnl PAC_PROG_MAKE_INCLUDE - Check whether make supports include 28 | dnl 29 | dnl Synopsis: 30 | dnl PAC_PROG_MAKE_INCLUDE([action if true],[action if false]) 31 | dnl 32 | dnl Output Effect: 33 | dnl None 34 | dnl 35 | dnl Notes: 36 | dnl This checks for makes that do not support 'include filename'. Some 37 | dnl versions of BSD 4.4 make required '#include' instead; some versions of 38 | dnl 'pmake' have the same syntax. 39 | dnl 40 | dnl See Also: 41 | dnl PAC_PROG_MAKE 42 | dnl 43 | dnl D*/ 44 | AC_DEFUN([PAC_PROG_MAKE_INCLUDE],[ 45 | AC_CACHE_CHECK([whether make supports include],pac_cv_prog_make_include,[ 46 | AC_REQUIRE([PAC_PROG_MAKE_PROGRAM]) 47 | # This is needed for Mac OSX 10.5 48 | rm -rf conftest.dSYM 49 | rm -f conftest 50 | cat > conftest <<. 51 | ALL: 52 | @echo "success" 53 | . 54 | cat > conftest1 <<. 55 | include conftest 56 | . 57 | pac_str=`$MAKE -f conftest1 2>&1` 58 | # This is needed for Mac OSX 10.5 59 | rm -rf conftest.dSYM 60 | rm -f conftest conftest1 61 | if test "$pac_str" != "success" ; then 62 | pac_cv_prog_make_include="no" 63 | else 64 | pac_cv_prog_make_include="yes" 65 | fi 66 | ]) 67 | if test "$pac_cv_prog_make_include" = "no" ; then 68 | ifelse([$2],,:,[$2]) 69 | else 70 | ifelse([$1],,:,[$1]) 71 | fi 72 | ])dnl 73 | 74 | dnl/*D 75 | dnl PAC_PROG_MAKE_ALLOWS_COMMENTS - Check whether comments are allowed in 76 | dnl shell commands in a makefile 77 | dnl 78 | dnl Synopsis: 79 | dnl PAC_PROG_MAKE_ALLOWS_COMMENTS([false text]) 80 | dnl 81 | dnl Output Effect: 82 | dnl Issues a warning message if comments are not allowed in a makefile. 83 | dnl Executes the argument if one is given. 84 | dnl 85 | dnl Notes: 86 | dnl Some versions of OSF V3 make do not all comments in action commands. 87 | dnl 88 | dnl See Also: 89 | dnl PAC_PROG_MAKE 90 | dnl D*/ 91 | dnl 92 | AC_DEFUN([PAC_PROG_MAKE_ALLOWS_COMMENTS],[ 93 | AC_CACHE_CHECK([whether make allows comments in actions], 94 | pac_cv_prog_make_allows_comments,[ 95 | AC_REQUIRE([PAC_PROG_MAKE_PROGRAM]) 96 | # This is needed for Mac OSX 10.5 97 | rm -rf conftest.dSYM 98 | rm -f conftest 99 | cat > conftest <<. 100 | SHELL=/bin/sh 101 | ALL: 102 | @# This is a valid comment! 103 | @echo "success" 104 | . 105 | pac_str=`$MAKE -f conftest 2>&1` 106 | # This is needed for Mac OSX 10.5 107 | rm -rf conftest.dSYM 108 | rm -f conftest 109 | if test "$pac_str" != "success" ; then 110 | pac_cv_prog_make_allows_comments="no" 111 | else 112 | pac_cv_prog_make_allows_comments="yes" 113 | fi 114 | ]) 115 | if test "$pac_cv_prog_make_allows_comments" = "no" ; then 116 | AC_MSG_WARN([Your make does not allow comments in target code. 117 | Using this make may cause problems when building programs. 118 | You should consider using gnumake instead.]) 119 | ifelse([$1],,[$1]) 120 | fi 121 | ])dnl 122 | 123 | dnl/*D 124 | dnl PAC_PROG_MAKE_VPATH - Check whether make supports source-code paths. 125 | dnl 126 | dnl Synopsis: 127 | dnl PAC_PROG_MAKE_VPATH 128 | dnl 129 | dnl Output Effect: 130 | dnl Sets the variable 'VPATH' to either 131 | dnl.vb 132 | dnl VPATH = .:${srcdir} 133 | dnl.ve 134 | dnl or 135 | dnl.vb 136 | dnl .PATH: . ${srcdir} 137 | dnl.ve 138 | dnl 139 | dnl Notes: 140 | dnl The test checks that the path works with implicit targets (some makes 141 | dnl support only explicit targets with 'VPATH' or 'PATH'). 142 | dnl 143 | dnl NEED TO DO: Check that $< works on explicit targets. 144 | dnl 145 | dnl See Also: 146 | dnl PAC_PROG_MAKE 147 | dnl 148 | dnl D*/ 149 | AC_DEFUN([PAC_PROG_MAKE_VPATH],[ 150 | AC_SUBST(VPATH) 151 | dnl AM_IGNORE(VPATH) 152 | AC_CACHE_CHECK([for virtual path format], 153 | pac_cv_prog_make_vpath,[ 154 | AC_REQUIRE([PAC_PROG_MAKE_PROGRAM]) 155 | # This is needed for Mac OSX 10.5 156 | rm -rf conftest.dSYM 157 | rm -rf conftest* 158 | mkdir conftestdir 159 | cat >conftestdir/a.c < conftest <&1 | grep 'conftestdir/a.c'` 169 | if test -n "$ac_out" ; then 170 | pac_cv_prog_make_vpath="VPATH" 171 | else 172 | rm -f conftest 173 | cat > conftest <&1 | grep 'conftestdir/a.c'` 180 | if test -n "$ac_out" ; then 181 | pac_cv_prog_make_vpath=".PATH" 182 | else 183 | pac_cv_prog_make_vpath="neither VPATH nor .PATH works" 184 | fi 185 | fi 186 | # This is needed for Mac OSX 10.5 187 | rm -rf conftest.dSYM 188 | rm -rf conftest* 189 | ]) 190 | if test "$pac_cv_prog_make_vpath" = "VPATH" ; then 191 | VPATH='VPATH=.:${srcdir}' 192 | elif test "$pac_cv_prog_make_vpath" = ".PATH" ; then 193 | VPATH='.PATH: . ${srcdir}' 194 | fi 195 | ])dnl 196 | 197 | dnl/*D 198 | dnl PAC_PROG_MAKE_SET_CFLAGS - Check whether make sets CFLAGS 199 | dnl 200 | dnl Synopsis: 201 | dnl PAC_PROG_MAKE_SET_CFLAGS([action if true],[action if false]) 202 | dnl 203 | dnl Output Effects: 204 | dnl Executes the first argument if 'CFLAGS' is set by 'make'; executes 205 | dnl the second argument if 'CFLAGS' is not set by 'make'. 206 | dnl 207 | dnl Notes: 208 | dnl If 'CFLAGS' is set by make, you may wish to override that choice in your 209 | dnl makefile. 210 | dnl 211 | dnl See Also: 212 | dnl PAC_PROG_MAKE 213 | dnl D*/ 214 | AC_DEFUN([PAC_PROG_MAKE_SET_CFLAGS],[ 215 | AC_CACHE_CHECK([whether make sets CFLAGS], 216 | pac_cv_prog_make_set_cflags,[ 217 | AC_REQUIRE([PAC_PROG_MAKE_PROGRAM]) 218 | # This is needed for Mac OSX 10.5 219 | rm -rf conftest.dSYM 220 | rm -f conftest 221 | cat > conftest <&1` 227 | # This is needed for Mac OSX 10.5 228 | rm -rf conftest.dSYM 229 | rm -f conftest 230 | if test "$pac_str" = "XX" ; then 231 | pac_cv_prog_make_set_cflags="no" 232 | else 233 | pac_cv_prog_make_set_cflags="yes" 234 | fi 235 | ]) 236 | if test "$pac_cv_prog_make_set_cflags" = "no" ; then 237 | ifelse([$2],,:,[$2]) 238 | else 239 | ifelse([$1],,:,[$1]) 240 | fi 241 | ])dnl 242 | 243 | dnl/*D 244 | dnl PAC_PROG_MAKE_CLOCK_SKEW - Check whether there is a problem with 245 | dnl clock skew in suing make. 246 | dnl 247 | dnl Effect: 248 | dnl Sets the cache variable 'pac_cv_prog_make_found_clock_skew' to yes or no 249 | dnl D*/ 250 | AC_DEFUN([PAC_PROG_MAKE_CLOCK_SKEW],[ 251 | AC_CACHE_CHECK([whether clock skew breaks make], 252 | pac_cv_prog_make_found_clock_skew,[ 253 | AC_REQUIRE([PAC_PROG_MAKE_PROGRAM]) 254 | # This is needed for Mac OSX 10.5 255 | rm -rf conftest.dSYM 256 | rm -f conftest* 257 | cat > conftest < conftest.out 2>&1 262 | if grep -i skew conftest >/dev/null 2>&1 ; then 263 | pac_cv_prog_make_found_clock_skew=yes 264 | else 265 | pac_cv_prog_make_found_clock_skew=no 266 | fi 267 | # This is needed for Mac OSX 10.5 268 | rm -rf conftest.dSYM 269 | rm -f conftest* 270 | ]) 271 | dnl We should really do something if we detect clock skew. The question is, 272 | dnl what? 273 | if test "$pac_cv_prog_make_found_clock_skew" = "yes" ; then 274 | AC_MSG_WARN([Clock skew found by make. The configure and build may fail. 275 | Consider building in a local instead of NFS filesystem.]) 276 | fi 277 | ]) 278 | 279 | dnl/*D 280 | dnl PAC_PROG_MAKE - Checks for the varieties of MAKE, including support for 281 | dnl VPATH 282 | dnl 283 | dnl Synopsis: 284 | dnl PAC_PROG_MAKE 285 | dnl 286 | dnl Output Effect: 287 | dnl Sets 'MAKE' to the make program to use if 'MAKE' is not already set. 288 | dnl Sets the variable 'SET_CFLAGS' to 'CFLAGS =' if make sets 'CFLAGS'. 289 | dnl 290 | dnl Notes: 291 | dnl This macro uses 'PAC_PROG_MAKE_INCLUDE', 292 | dnl 'PAC_PROG_MAKE_ALLOWS_COMMENTS', 'PAC_PROG_MAKE_VPATH', and 293 | dnl 'PAC_PROG_MAKE_SET_CFLAGS'. See those commands for details about their 294 | dnl actions. 295 | dnl 296 | dnl It may call 'AC_PROG_MAKE_SET', which sets 'SET_MAKE' to 'MAKE = @MAKE@' 297 | dnl if the make program does not set the value of make, otherwise 'SET_MAKE' 298 | dnl is set to empty; if the make program echos the directory name, then 299 | dnl 'SET_MAKE' is set to 'MAKE = $MAKE'. 300 | dnl D*/ 301 | AC_DEFUN([PAC_PROG_MAKE],[ 302 | PAC_PROG_MAKE_PROGRAM 303 | PAC_PROG_MAKE_CLOCK_SKEW 304 | PAC_PROG_MAKE_INCLUDE 305 | PAC_PROG_MAKE_ALLOWS_COMMENTS 306 | PAC_PROG_MAKE_VPATH 307 | AC_SUBST(SET_CFLAGS) 308 | dnl AM_IGNORE(SET_CFLAGS) 309 | PAC_PROG_MAKE_SET_CFLAGS([SET_CFLAGS='CFLAGS=']) 310 | if test "$pac_cv_prog_make_echos_dir" = "no" ; then 311 | AC_PROG_MAKE_SET 312 | else 313 | SET_MAKE="MAKE=${MAKE-make}" 314 | fi 315 | ]) 316 | -------------------------------------------------------------------------------- /m4/aclocal_runlog.m4: -------------------------------------------------------------------------------- 1 | dnl 2 | dnl PAC_RUN_LOG mimics _AC_RUN_LOG which is autoconf internal routine. 3 | dnl We also make sure PAC_RUN_LOG can be used in AS_IF, so the last 4 | dnl test command should have terminating ]), i.e. without newline before ]). 5 | dnl 6 | AC_DEFUN([PAC_RUNLOG],[ 7 | { AS_ECHO(["$as_me:$LINENO: $1"]) >&AS_MESSAGE_LOG_FD 8 | (eval $1) 2>&AS_MESSAGE_LOG_FD 9 | ac_status=$? 10 | AS_ECHO(["$as_me:$LINENO: \$? = $ac_status"]) >&AS_MESSAGE_LOG_FD 11 | test $ac_status = 0; }]) 12 | dnl 13 | dnl PAC_COMMAND_IFELSE is written to replace AC_TRY_EVAL with added logging 14 | dnl to config.log, i.e. AC_TRY_EVAL does not log anything to config.log. 15 | dnl If autoconf provides AC_COMMAND_IFELSE or AC_EVAL_IFELSE, 16 | dnl AC_COMMAND_IFELSE dnl should be replaced by the official autoconf macros. 17 | dnl 18 | dnl PAC_COMMAND_IFELSE(COMMMAND,[ACTION-IF-RUN-OK],[ACTION-IF-RUN-FAIL]) 19 | dnl 20 | AC_DEFUN([PAC_COMMAND_IFELSE],[ 21 | dnl Should use _AC_DO_TOKENS but use AC_RUN_LOG instead 22 | dnl because _AC_XX is autoconf's undocumented macro. 23 | AS_IF([PAC_RUNLOG([$1])],[ 24 | $2 25 | ],[ 26 | AS_ECHO(["$as_me: program exited with status $ac_status"]) >&AS_MESSAGE_LOG_FD 27 | m4_ifvaln([$3],[ 28 | (exit $ac_status) 29 | $3 30 | ]) 31 | ]) 32 | ]) 33 | dnl 34 | dnl 35 | dnl 36 | AC_DEFUN([PAC_EVAL_IFELSE],[ 37 | dnl Should use _AC_DO_TOKENS but use AC_RUN_LOG instead 38 | dnl because _AC_XX is autoconf's undocumented macro. 39 | AS_IF([PAC_RUNLOG([$$1])],[ 40 | $2 41 | ],[ 42 | AS_ECHO(["$as_me: program exited with status $ac_status"]) >&AS_MESSAGE_LOG_FD 43 | m4_ifvaln([$3],[ 44 | (exit $ac_status) 45 | $3 46 | ]) 47 | ]) 48 | ]) 49 | dnl 50 | dnl 51 | dnl 52 | AC_DEFUN([PAC_RUNLOG_IFELSE],[ 53 | dnl pac_TESTLOG is the internal temporary logfile for this macro. 54 | pac_TESTLOG="pac_test.log" 55 | rm -f $pac_TESTLOG 56 | PAC_COMMAND_IFELSE([$1 > $pac_TESTLOG],[ 57 | ifelse([$2],[],[],[$2]) 58 | ],[ 59 | AS_ECHO(["*** $1 :"]) >&AS_MESSAGE_LOG_FD 60 | cat $pac_TESTLOG >&AS_MESSAGE_LOG_FD 61 | ifelse([$3],[],[],[$3]) 62 | ]) 63 | rm -f $pac_TESTLOG 64 | ]) 65 | -------------------------------------------------------------------------------- /m4/aclocal_subcfg.m4: -------------------------------------------------------------------------------- 1 | dnl PAC_RESET_ALL_FLAGS - Reset precious flags to those set by the user 2 | AC_DEFUN([PAC_RESET_ALL_FLAGS],[ 3 | if test "$FROM_MPICH2" = "yes" ; then 4 | CFLAGS="$USER_CFLAGS" 5 | CPPFLAGS="$USER_CPPFLAGS" 6 | CXXFLAGS="$USER_CXXFLAGS" 7 | FFLAGS="$USER_FFLAGS" 8 | FCFLAGS="$USER_FCFLAGS" 9 | LDFLAGS="$USER_LDFLAGS" 10 | LIBS="$USER_LIBS" 11 | fi 12 | ]) 13 | 14 | dnl PAC_RESET_LINK_FLAGS - Reset precious link flags to those set by the user 15 | AC_DEFUN([PAC_RESET_LINK_FLAGS],[ 16 | if test "$FROM_MPICH2" = "yes" ; then 17 | LDFLAGS="$USER_LDFLAGS" 18 | LIBS="$USER_LIBS" 19 | fi 20 | ]) 21 | 22 | dnl Sandbox configure with additional arguments 23 | dnl Usage: PAC_CONFIG_SUBDIR_ARGS(subdir,configure-args,action-if-success,action-if-failure) 24 | dnl 25 | dnl The subconfigure argument list is created based on "ac_precious_vars" 26 | dnl instead of explicitly use of well-known Makefile variables, like 27 | dnl CC/CFLAGS/CPPFLAGS..., this generalization is effective as long as 28 | dnl calling configure.in declares the needed variables to be passed down 29 | dnl to subconfigure as "precious" appropriately. The precious variable 30 | dnl can be created in the following ways: 31 | dnl 1) implicit declaration through use of autoconf macros, like 32 | dnl AC_PROG_CC (declares CC/CFLAGS/CPPFLAGS/LIBS/LDFLAGS), or 33 | dnl AC_PROG_F77 (declares F77/FFLAGS/FLIBS) ... 34 | dnl which are in turns invoked by other subconfigure. 35 | dnl When in doubt, check "ac_precious_var" in the calling configure. 36 | dnl 2) explicit "precious" declaration through AC_ARG_VAR. 37 | dnl Without correct "precious" declaration in the calling configure.in, 38 | dnl there would be variables not being included in the subconfigure 39 | dnl argument list. 40 | dnl 41 | dnl Note: I suspect this DEFUN body is underquoted in places, but it does not 42 | dnl seem to cause problems in practice yet. [goodell@ 2010-05-18] 43 | AC_DEFUN([PAC_CONFIG_SUBDIR_ARGS],[ 44 | AC_MSG_NOTICE([===== configuring $1 =====]) 45 | 46 | PAC_MKDIRS($1) 47 | pac_abs_srcdir=`(cd $srcdir && pwd)` 48 | 49 | if test -f $pac_abs_srcdir/$1/setup ; then 50 | . $pac_abs_srcdir/$1/setup 51 | fi 52 | 53 | pac_subconfigure_file="$pac_abs_srcdir/$1/configure" 54 | if test -x $pac_subconfigure_file ; then 55 | pac_subconfig_args="$2" 56 | 57 | # Set IFS so ac_configure_args can be tokenized 58 | # with extra " " tokens being skipped. 59 | saved_IFS="$IFS" 60 | IFS="'" 61 | for pac_arg in $ac_configure_args ; do 62 | case "$pac_arg" in 63 | # Ignore any null and leading blank strings. 64 | ""|" "*) 65 | ;; 66 | *) 67 | pac_pval="" 68 | # Restore saved IFS so ac_precious_vars which has 69 | # " " as separator can be correctly tokenized 70 | IFS="$saved_IFS" 71 | for pac_pvar in $ac_precious_vars ; do 72 | # check if configure argument token contains the 73 | # precious variable, i.e. "name_of_prec_var=". 74 | pvar_in_arg=`echo $pac_arg | grep "$pac_pvar="` 75 | if test "X$pvar_in_arg" != "X" ; then 76 | # check if current precious variable is set in env 77 | eval pvar_set=\${$pac_pvar+set} 78 | if test "$pvar_set" = "set" ; then 79 | # Append 'name_of_prec_var=value_of_prec_var' 80 | # to the subconfigure arguments list, where 81 | # value_of_prec_var is fetched from the env. 82 | eval pac_pval=\${$pac_pvar} 83 | pac_subconfig_args="$pac_subconfig_args '$pac_pvar=$pac_pval'" 84 | break 85 | fi 86 | fi 87 | done 88 | # since the precious variable is not set in the env., 89 | # append the corresponding configure argument token 90 | # to the subconfigure argument list. 91 | if test "X$pac_pval" = "X" ; then 92 | pac_subconfig_args="$pac_subconfig_args '$pac_arg'" 93 | fi 94 | # reset "'" as IFS to process ac_configure_args 95 | saved_IFS="$IFS" 96 | IFS="'" 97 | ;; 98 | esac 99 | done 100 | # Restore IFS. 101 | IFS="$saved_IFS" 102 | dnl echo "pac_subconfig_args = |$pac_subconfig_args|" 103 | 104 | dnl Add option to disable configure options checking 105 | if test "$enable_option_checking" = no ; then 106 | pac_subconfig_args="$pac_subconfig_args --disable-option-checking" 107 | fi 108 | 109 | AC_MSG_NOTICE([executing: $pac_subconfigure_file $pac_subconfig_args]) 110 | if (cd $1 && eval $pac_subconfigure_file $pac_subconfig_args) ; then 111 | ifelse([$3],[],[:],[$3]) 112 | else 113 | ifelse([$4],[],[:],[$4]) 114 | fi 115 | else 116 | if test -e $pac_subconfigure_file ; then 117 | AC_MSG_WARN([$pac_subconfigure_file exists but is not executable]) 118 | else 119 | AC_MSG_WARN([$pac_subconfigure_file does not exist]) 120 | fi 121 | fi 122 | 123 | AC_MSG_NOTICE([===== done with $1 configure =====]) 124 | 125 | # Check for any localdefs files. These may be created, so we 126 | # look in the local directory first. 127 | if test -f $1/localdefs ; then 128 | . $1/localdefs 129 | elif test -f $pac_abs_srcdir/$1/localdefs ; then 130 | . $pac_abs_srcdir/$1/localdefs 131 | fi 132 | ]) 133 | 134 | dnl Sandbox configure 135 | dnl Usage: PAC_CONFIG_SUBDIR(subdir,action-if-success,action-if-failure) 136 | AC_DEFUN([PAC_CONFIG_SUBDIR],[PAC_CONFIG_SUBDIR_ARGS([$1],[],[$2],[$3])]) 137 | 138 | -------------------------------------------------------------------------------- /m4/aclocal_util.m4: -------------------------------------------------------------------------------- 1 | dnl Nesting safe macros for saving variables 2 | dnl Usage: PAC_PUSH_FLAG(CFLAGS) 3 | AC_DEFUN([PAC_PUSH_FLAG],[ 4 | if test -z "${pac_save_$1_nesting}" ; then 5 | pac_save_$1_nesting=0 6 | fi 7 | eval pac_save_$1_${pac_save_$1_nesting}='"$$1"' 8 | pac_save_$1_nesting=`expr ${pac_save_$1_nesting} + 1` 9 | ]) 10 | 11 | dnl Usage: PAC_POP_FLAG(CFLAGS) 12 | AC_DEFUN([PAC_POP_FLAG],[ 13 | pac_save_$1_nesting=`expr ${pac_save_$1_nesting} - 1` 14 | eval $1="\$pac_save_$1_${pac_save_$1_nesting}" 15 | eval pac_save_$1_${pac_save_$1_nesting}="" 16 | ]) 17 | 18 | dnl Usage: PAC_PUSH_ALL_FLAGS 19 | AC_DEFUN([PAC_PUSH_ALL_FLAGS],[ 20 | PAC_PUSH_FLAG(CFLAGS) 21 | PAC_PUSH_FLAG(CPPFLAGS) 22 | PAC_PUSH_FLAG(CXXFLAGS) 23 | PAC_PUSH_FLAG(FFLAGS) 24 | PAC_PUSH_FLAG(FCFLAGS) 25 | PAC_PUSH_FLAG(LDFLAGS) 26 | PAC_PUSH_FLAG(LIBS) 27 | ]) 28 | 29 | dnl Usage: PAC_POP_ALL_FLAGS 30 | AC_DEFUN([PAC_POP_ALL_FLAGS],[ 31 | PAC_POP_FLAG(CFLAGS) 32 | PAC_POP_FLAG(CPPFLAGS) 33 | PAC_POP_FLAG(CXXFLAGS) 34 | PAC_POP_FLAG(FFLAGS) 35 | PAC_POP_FLAG(FCFLAGS) 36 | PAC_POP_FLAG(LDFLAGS) 37 | PAC_POP_FLAG(LIBS) 38 | ]) 39 | 40 | dnl PAC_PREFIX_FLAG - Save flag with a prefix 41 | dnl Usage: PAC_PREFIX_FLAG(PREFIX, FLAG) 42 | AC_DEFUN([PAC_PREFIX_FLAG],[ 43 | $1_$2=$$2 44 | export $1_$2 45 | AC_SUBST($1_$2) 46 | ]) 47 | 48 | dnl PAC_PREFIX_ALL_FLAGS - Save flags with a prefix 49 | dnl Usage: PAC_PREFIX_ALL_FLAGS(PREFIX) 50 | AC_DEFUN([PAC_PREFIX_ALL_FLAGS],[ 51 | PAC_PREFIX_FLAG($1, CFLAGS) 52 | PAC_PREFIX_FLAG($1, CPPFLAGS) 53 | PAC_PREFIX_FLAG($1, CXXFLAGS) 54 | PAC_PREFIX_FLAG($1, FFLAGS) 55 | PAC_PREFIX_FLAG($1, FCFLAGS) 56 | PAC_PREFIX_FLAG($1, LDFLAGS) 57 | PAC_PREFIX_FLAG($1, LIBS) 58 | ]) 59 | 60 | dnl Usage: PAC_APPEND_FLAG([-02], [CFLAGS]) 61 | dnl appends the given argument to the specified shell variable unless the 62 | dnl argument is already present in the variable 63 | AC_DEFUN([PAC_APPEND_FLAG],[ 64 | AC_REQUIRE([AC_PROG_FGREP]) 65 | AS_IF( 66 | [echo "$$2" | $FGREP -e '$1' >/dev/null 2>&1], 67 | [echo "$2(='$$2') contains '$1', not appending" >&AS_MESSAGE_LOG_FD], 68 | [echo "$2(='$$2') does not contain '$1', appending" >&AS_MESSAGE_LOG_FD 69 | $2="$$2 $1"] 70 | ) 71 | ]) 72 | 73 | dnl Usage: PAC_PREPEND_FLAG([-lpthread], [LIBS]) 74 | dnl Prepends the given argument to the specified shell variable unless the 75 | dnl argument is already present in the variable. 76 | dnl 77 | dnl This is typically used for LIBS and similar variables because libraries 78 | dnl should be added in reverse order. 79 | AC_DEFUN([PAC_PREPEND_FLAG],[ 80 | AC_REQUIRE([AC_PROG_FGREP]) 81 | AS_IF( 82 | [echo "$$2" | $FGREP -e '$1' >/dev/null 2>&1], 83 | [echo "$2(='$$2') contains '$1', not prepending" >&AS_MESSAGE_LOG_FD], 84 | [echo "$2(='$$2') does not contain '$1', prepending" >&AS_MESSAGE_LOG_FD 85 | $2="$1 $$2"] 86 | ) 87 | ]) 88 | 89 | 90 | dnl PAC_MKDIRS(path) 91 | dnl Create any missing directories in the path 92 | AC_DEFUN([PAC_MKDIRS],[ 93 | # Build any intermediate directories 94 | for dir in $1 ; do 95 | saveIFS="$IFS" 96 | IFS="/" 97 | tmp_curdir="" 98 | for tmp_subdir in $dir ; do 99 | tmp_curdir="${tmp_curdir}$tmp_subdir" 100 | if test ! -d "$tmp_curdir" ; then mkdir "$tmp_curdir" ; fi 101 | tmp_curdir="${tmp_curdir}/" 102 | done 103 | IFS="$saveIFS" 104 | done 105 | ]) 106 | 107 | # Find something to use for mkdir -p. Eventually, this will have a 108 | # script for backup. As of autoconf-2.63, AC_PROG_MKDIR_P was broken; 109 | # it was checking to see if it recognized the "version" of mkdir and 110 | # was deciding based on that. This should always be a feature test. 111 | AC_DEFUN([PAC_PROG_MKDIR_P],[ 112 | AC_CACHE_CHECK([whether mkdir -p works], 113 | pac_cv_mkdir_p,[ 114 | pac_cv_mkdir_p=no 115 | rm -rf .tmp 116 | if mkdir -p .tmp/.foo 1>/dev/null 2>&1 ; then 117 | if test -d .tmp/.foo ; then 118 | pac_cv_mkdir_p=yes 119 | fi 120 | fi 121 | rm -rf .tmp 122 | ]) 123 | if test "$pac_cv_mkdir_p" = "yes" ; then 124 | MKDIR_P="mkdir -p" 125 | export MKDIR_P 126 | else 127 | AC_MSG_WARN([mkdir -p does not work; the install step may fail]) 128 | fi 129 | AC_SUBST(MKDIR_P) 130 | ]) 131 | 132 | dnl Test for a clean VPATH directory. Provide this command with the names 133 | dnl of all of the generated files that might cause problems 134 | dnl (Makefiles won't cause problems because there's no VPATH usage for them) 135 | dnl 136 | dnl Synopsis 137 | dnl PAC_VPATH_CHECK([file-names],[directory-names]) 138 | dnl file-names should be files other than config.status and any header (e.g., 139 | dnl fooconf.h) file that should be removed. It is optional 140 | AC_DEFUN([PAC_VPATH_CHECK],[ 141 | # This is needed for Mac OSX 10.5 142 | rm -rf conftest.dSYM 143 | rm -f conftest* 144 | date >conftest$$ 145 | # If creating a file in the current directory does not show up in the srcdir 146 | # then we're doing a VPATH build (or something is very wrong) 147 | if test ! -s $srcdir/conftest$$ ; then 148 | pac_dirtyfiles="" 149 | pac_dirtydirs="" 150 | pac_header="" 151 | ifdef([AC_LIST_HEADER],[pac_header=AC_LIST_HEADER]) 152 | for file in config.status $pac_header $1 ; do 153 | if test -f $srcdir/$file ; then 154 | pac_dirtyfiles="$pac_dirtyfiles $file" 155 | fi 156 | done 157 | ifelse($2,,,[ 158 | for dir in $2 ; do 159 | if test -d $srcdir/$dir ; then 160 | pac_dirtydirs="$pac_dirtydirs $dir" 161 | fi 162 | done 163 | ]) 164 | 165 | if test -n "$pac_dirtyfiles" -o -n "$pac_dirtydirs" ; then 166 | # Create a nice message about what to remove 167 | rmmsg="" 168 | if test -n "$pac_dirtyfiles" ; then 169 | rmmsg="files $pac_dirtyfiles" 170 | fi 171 | if test -n "$pac_dirtydirs" ; then 172 | if test -n "$rmmsg" ; then 173 | rmmsg="$rmmsg and directories $pac_dirtydirs" 174 | else 175 | rmmsg="directories $pac_dirtydirs" 176 | fi 177 | fi 178 | if test -f $srcdir/Makefile ; then 179 | AC_MSG_ERROR([You cannot do a VPATH build if the source directory has been 180 | configured. Run "make distclean" in $srcdir first and make sure that the 181 | $rmmsg have been removed.]) 182 | else 183 | AC_MSG_ERROR([You cannot do a VPATH build if the source directory has been 184 | configured. Remove the $rmmsg in $srcdir.]) 185 | fi 186 | fi 187 | fi 188 | # This is needed for Mac OSX 10.5 189 | rm -rf conftest.dSYM 190 | rm -f conftest* 191 | ]) 192 | -------------------------------------------------------------------------------- /m4/ax_prefix_config_h.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://autoconf-archive.cryp.to/ax_prefix_config_h.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_PREFIX_CONFIG_H [(OUTPUT-HEADER [,PREFIX [,ORIG-HEADER]])] 8 | # 9 | # DESCRIPTION 10 | # 11 | # This is a new variant from ac_prefix_config_ this one will use a 12 | # lowercase-prefix if the config-define was starting with a 13 | # lowercase-char, e.g. "#define const", "#define restrict", or "#define 14 | # off_t", (and this one can live in another directory, e.g. 15 | # testpkg/config.h therefore I decided to move the output-header to be the 16 | # first arg) 17 | # 18 | # takes the usual config.h generated header file; looks for each of the 19 | # generated "#define SOMEDEF" lines, and prefixes the defined name (ie. 20 | # makes it "#define PREFIX_SOMEDEF". The result is written to the output 21 | # config.header file. The PREFIX is converted to uppercase for the 22 | # conversions. 23 | # 24 | # Defaults: 25 | # 26 | # OUTPUT-HEADER = $PACKAGE-config.h 27 | # PREFIX = $PACKAGE 28 | # ORIG-HEADER, from AM_CONFIG_HEADER(config.h) 29 | # 30 | # Your configure.ac script should contain both macros in this order, and 31 | # unlike the earlier variations of this prefix-macro it is okay to place 32 | # the AX_PREFIX_CONFIG_H call before the AC_OUTPUT invokation. 33 | # 34 | # Example: 35 | # 36 | # AC_INIT(config.h.in) # config.h.in as created by "autoheader" 37 | # AM_INIT_AUTOMAKE(testpkg, 0.1.1) # makes #undef VERSION and PACKAGE 38 | # AM_CONFIG_HEADER(config.h) # prep config.h from config.h.in 39 | # AX_PREFIX_CONFIG_H(mylib/_config.h) # prep mylib/_config.h from it.. 40 | # AC_MEMORY_H # makes "#undef NEED_MEMORY_H" 41 | # AC_C_CONST_H # makes "#undef const" 42 | # AC_OUTPUT(Makefile) # creates the "config.h" now 43 | # # and also mylib/_config.h 44 | # 45 | # if the argument to AX_PREFIX_CONFIG_H would have been omitted then the 46 | # default outputfile would have been called simply "testpkg-config.h", but 47 | # even under the name "mylib/_config.h" it contains prefix-defines like 48 | # 49 | # #ifndef TESTPKG_VERSION 50 | # #define TESTPKG_VERSION "0.1.1" 51 | # #endif 52 | # #ifndef TESTPKG_NEED_MEMORY_H 53 | # #define TESTPKG_NEED_MEMORY_H 1 54 | # #endif 55 | # #ifndef _testpkg_const 56 | # #define _testpkg_const _const 57 | # #endif 58 | # 59 | # and this "mylib/_config.h" can be installed along with other 60 | # header-files, which is most convenient when creating a shared library 61 | # (that has some headers) where some functionality is dependent on the 62 | # OS-features detected at compile-time. No need to invent some 63 | # "mylib-confdefs.h.in" manually. :-) 64 | # 65 | # Note that some AC_DEFINEs that end up in the config.h file are actually 66 | # self-referential - e.g. AC_C_INLINE, AC_C_CONST, and the AC_TYPE_OFF_T 67 | # say that they "will define inline|const|off_t if the system does not do 68 | # it by itself". You might want to clean up about these - consider an 69 | # extra mylib/conf.h that reads something like: 70 | # 71 | # #include 72 | # #ifndef _testpkg_const 73 | # #define _testpkg_const const 74 | # #endif 75 | # 76 | # and then start using _testpkg_const in the header files. That is also a 77 | # good thing to differentiate whether some library-user has starting to 78 | # take up with a different compiler, so perhaps it could read something 79 | # like this: 80 | # 81 | # #ifdef _MSC_VER 82 | # #include 83 | # #else 84 | # #include 85 | # #endif 86 | # #ifndef _testpkg_const 87 | # #define _testpkg_const const 88 | # #endif 89 | # 90 | # LAST MODIFICATION 91 | # 92 | # 2008-04-12 93 | # 94 | # COPYLEFT 95 | # 96 | # Copyright (c) 2008 Guido U. Draheim 97 | # Copyright (c) 2008 Marten Svantesson 98 | # Copyright (c) 2008 Gerald Point 99 | # 100 | # This program is free software; you can redistribute it and/or modify it 101 | # under the terms of the GNU General Public License as published by the 102 | # Free Software Foundation; either version 2 of the License, or (at your 103 | # option) any later version. 104 | # 105 | # This program is distributed in the hope that it will be useful, but 106 | # WITHOUT ANY WARRANTY; without even the implied warranty of 107 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 108 | # Public License for more details. 109 | # 110 | # You should have received a copy of the GNU General Public License along 111 | # with this program. If not, see . 112 | # 113 | # As a special exception, the respective Autoconf Macro's copyright owner 114 | # gives unlimited permission to copy, distribute and modify the configure 115 | # scripts that are the output of Autoconf when processing the Macro. You 116 | # need not follow the terms of the GNU General Public License when using 117 | # or distributing such scripts, even though portions of the text of the 118 | # Macro appear in them. The GNU General Public License (GPL) does govern 119 | # all other use of the material that constitutes the Autoconf Macro. 120 | # 121 | # This special exception to the GPL applies to versions of the Autoconf 122 | # Macro released by the Autoconf Macro Archive. When you make and 123 | # distribute a modified version of the Autoconf Macro, you may extend this 124 | # special exception to the GPL to apply to your modified version as well. 125 | 126 | AC_DEFUN([AX_PREFIX_CONFIG_H],[dnl 127 | AC_BEFORE([AC_CONFIG_HEADERS],[$0])dnl 128 | AC_CONFIG_COMMANDS([ifelse($1,,$PACKAGE-config.h,$1)],[dnl 129 | AS_VAR_PUSHDEF([_OUT],[ac_prefix_conf_OUT])dnl 130 | AS_VAR_PUSHDEF([_DEF],[ac_prefix_conf_DEF])dnl 131 | AS_VAR_PUSHDEF([_PKG],[ac_prefix_conf_PKG])dnl 132 | AS_VAR_PUSHDEF([_LOW],[ac_prefix_conf_LOW])dnl 133 | AS_VAR_PUSHDEF([_UPP],[ac_prefix_conf_UPP])dnl 134 | AS_VAR_PUSHDEF([_INP],[ac_prefix_conf_INP])dnl 135 | m4_pushdef([_script],[conftest.prefix])dnl 136 | m4_pushdef([_symbol],[m4_cr_Letters[]m4_cr_digits[]_])dnl 137 | _OUT=`echo ifelse($1, , $PACKAGE-config.h, $1)` 138 | _DEF=`echo _$_OUT | sed -e "y:m4_cr_letters:m4_cr_LETTERS[]:" -e "s/@<:@^m4_cr_Letters@:>@/_/g"` 139 | _PKG=`echo ifelse($2, , $PACKAGE, $2)` 140 | _LOW=`echo _$_PKG | sed -e "y:m4_cr_LETTERS-:m4_cr_letters[]_:"` 141 | _UPP=`echo $_PKG | sed -e "y:m4_cr_letters-:m4_cr_LETTERS[]_:" -e "/^@<:@m4_cr_digits@:>@/s/^/_/"` 142 | _INP=`echo "ifelse($3,,,$3)" | sed -e 's/ *//'` 143 | if test ".$_INP" = "."; then 144 | for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue 145 | case "$ac_file" in 146 | *.h) _INP=$ac_file ;; 147 | *) 148 | esac 149 | test ".$_INP" != "." && break 150 | done 151 | fi 152 | if test ".$_INP" = "."; then 153 | case "$_OUT" in 154 | */*) _INP=`basename "$_OUT"` 155 | ;; 156 | *-*) _INP=`echo "$_OUT" | sed -e "s/@<:@_symbol@:>@*-//"` 157 | ;; 158 | *) _INP=config.h 159 | ;; 160 | esac 161 | fi 162 | if test -z "$_PKG" ; then 163 | AC_MSG_ERROR([no prefix for _PREFIX_PKG_CONFIG_H]) 164 | else 165 | if test ! -f "$_INP" ; then if test -f "$srcdir/$_INP" ; then 166 | _INP="$srcdir/$_INP" 167 | fi fi 168 | AC_MSG_NOTICE(creating $_OUT - prefix $_UPP for $_INP defines) 169 | if test -f $_INP ; then 170 | echo "s/^@%:@undef *\\(@<:@m4_cr_LETTERS[]_@:>@\\)/@%:@undef $_UPP""_\\1/" > _script 171 | echo "s/^@%:@undef *\\(@<:@m4_cr_letters@:>@\\)/@%:@undef $_LOW""_\\1/" >> _script 172 | echo "s/^@%:@def[]ine *\\(@<:@m4_cr_LETTERS[]_@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_UPP""_\\1 \\" >> _script 173 | echo "@%:@def[]ine $_UPP""_\\1 \\2 \\" >> _script 174 | echo "@%:@endif/" >>_script 175 | echo "s/^@%:@def[]ine *\\(@<:@m4_cr_letters@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_LOW""_\\1 \\" >> _script 176 | echo "@%:@define $_LOW""_\\1 \\2 \\" >> _script 177 | echo "@%:@endif/" >> _script 178 | # now executing _script on _DEF input to create _OUT output file 179 | echo "@%:@ifndef $_DEF" >$tmp/pconfig.h 180 | echo "@%:@def[]ine $_DEF 1" >>$tmp/pconfig.h 181 | echo ' ' >>$tmp/pconfig.h 182 | echo /'*' $_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h 183 | 184 | sed -f _script $_INP >>$tmp/pconfig.h 185 | echo ' ' >>$tmp/pconfig.h 186 | echo '/* once:' $_DEF '*/' >>$tmp/pconfig.h 187 | echo "@%:@endif" >>$tmp/pconfig.h 188 | if cmp -s $_OUT $tmp/pconfig.h 2>/dev/null; then 189 | AC_MSG_NOTICE([$_OUT is unchanged]) 190 | else 191 | ac_dir=`AS_DIRNAME(["$_OUT"])` 192 | AS_MKDIR_P(["$ac_dir"]) 193 | rm -f "$_OUT" 194 | mv $tmp/pconfig.h "$_OUT" 195 | fi 196 | cp _script _configs.sed 197 | else 198 | AC_MSG_ERROR([input file $_INP does not exist - skip generating $_OUT]) 199 | fi 200 | rm -f conftest.* 201 | fi 202 | m4_popdef([_symbol])dnl 203 | m4_popdef([_script])dnl 204 | AS_VAR_POPDEF([_INP])dnl 205 | AS_VAR_POPDEF([_UPP])dnl 206 | AS_VAR_POPDEF([_LOW])dnl 207 | AS_VAR_POPDEF([_PKG])dnl 208 | AS_VAR_POPDEF([_DEF])dnl 209 | AS_VAR_POPDEF([_OUT])dnl 210 | ],[PACKAGE="$PACKAGE"])]) 211 | 212 | dnl implementation note: a bug report (31.5.2005) from Marten Svantesson points 213 | dnl out a problem where `echo "\1"` results in a Control-A. The unix standard 214 | dnl http://www.opengroup.org/onlinepubs/000095399/utilities/echo.html 215 | dnl defines all backslash-sequences to be inherently non-portable asking 216 | dnl for replacement mit printf. Some old systems had problems with that 217 | dnl one either. However, the latest libtool (!) release does export an $ECHO 218 | dnl (and $echo) that does the right thing - just one question is left: what 219 | dnl was the first version to have it? Is it greater 2.58 ? 220 | -------------------------------------------------------------------------------- /m4/ax_tls.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.nongnu.org/autoconf-archive/ax_tls.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_TLS 8 | # 9 | # DESCRIPTION 10 | # 11 | # Provides a test for the compiler support of thread local storage (TLS) 12 | # extensions. Defines TLS if it is found. Currently only knows about GCC 13 | # and MSVC. I think SunPro uses the same as GCC, and Borland apparently 14 | # supports either. 15 | # 16 | # LICENSE 17 | # 18 | # Copyright (c) 2008 Alan Woodland 19 | # 20 | # This program is free software: you can redistribute it and/or modify it 21 | # under the terms of the GNU General Public License as published by the 22 | # Free Software Foundation, either version 3 of the License, or (at your 23 | # option) any later version. 24 | # 25 | # This program is distributed in the hope that it will be useful, but 26 | # WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 28 | # Public License for more details. 29 | # 30 | # You should have received a copy of the GNU General Public License along 31 | # with this program. If not, see . 32 | # 33 | # As a special exception, the respective Autoconf Macro's copyright owner 34 | # gives unlimited permission to copy, distribute and modify the configure 35 | # scripts that are the output of Autoconf when processing the Macro. You 36 | # need not follow the terms of the GNU General Public License when using 37 | # or distributing such scripts, even though portions of the text of the 38 | # Macro appear in them. The GNU General Public License (GPL) does govern 39 | # all other use of the material that constitutes the Autoconf Macro. 40 | # 41 | # This special exception to the GPL applies to versions of the Autoconf 42 | # Macro released by the Autoconf Archive. When you make and distribute a 43 | # modified version of the Autoconf Macro, you may extend this special 44 | # exception to the GPL to apply to your modified version as well. 45 | 46 | AC_DEFUN([AX_TLS], [ 47 | AC_MSG_CHECKING(for thread local storage specifier) 48 | AC_CACHE_VAL(ac_cv_tls, [ 49 | ax_tls_keywords="__thread __declspec(thread) none" 50 | for ax_tls_keyword in $ax_tls_keywords; do 51 | case $ax_tls_keyword in 52 | none) ac_cv_tls=none ; break ;; 53 | *) 54 | # MPICH2 modification: This was an AC_TRY_COMPILE before, but 55 | # Darwin with non-standard compilers will accept __thread at 56 | # compile time but fail to link due to an undefined 57 | # "__emutls_get_address" symbol unless -lgcc_eh is added to the 58 | # link line. 59 | AC_LINK_IFELSE( 60 | [AC_LANG_PROGRAM([$ax_tls_keyword int bar = 5;],[++bar;])], 61 | [ac_cv_tls=$ax_tls_keyword ; break], 62 | [ac_cv_tls=none]) 63 | esac 64 | done 65 | ]) 66 | 67 | if test "$ac_cv_tls" != "none"; then 68 | # MPICH2 modification: this was "TLS" before instead of 69 | # "MPIU_TLS_SPECIFIER", but TLS had a reasonably high chance of conflicting 70 | # with a system library. 71 | AC_DEFINE_UNQUOTED([MPIU_TLS_SPECIFIER], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here]) 72 | fi 73 | AC_MSG_RESULT($ac_cv_tls) 74 | ]) 75 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_command( 2 | OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/bigmpiconf.h" 3 | COMMAND "./autogen.sh" 4 | COMMAND "./configure" 5 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/..") 6 | 7 | file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") 8 | add_library(bigmpi ${LIB_LINKAGE_TYPE} ${SOURCES} "bigmpiconf.h") 9 | 10 | target_link_libraries ( bigmpi ${MPI_LIBRARIES} ) 11 | 12 | set_target_properties ( bigmpi PROPERTIES PUBLIC_HEADER "bigmpi.h") 13 | 14 | if (NOT CMAKE_INSTALL_LIBDIR) 15 | set(CMAKE_INSTALL_LIBDIR lib) 16 | endif() 17 | 18 | if (NOT CMAKE_INSTALL_INCLUDEDIR) 19 | set(CMAKE_INSTALL_INCLUDEDIR include) 20 | endif() 21 | 22 | install(TARGETS bigmpi 23 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 24 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 25 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 26 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 27 | COMPONENT lib 28 | ) 29 | -------------------------------------------------------------------------------- /src/bigmpi_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef BIGMPI_IMPL_H 2 | #define BIGMPI_IMPL_H 3 | 4 | #include "bigmpiconf.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "bigmpi.h" 17 | 18 | #include "likely.h" 19 | 20 | #ifdef BIGMPI_MAX_INT 21 | static const MPI_Count bigmpi_int_max = BIGMPI_MAX_INT; 22 | static const MPI_Count bigmpi_count_max = (MPI_Count)BIGMPI_MAX_INT*BIGMPI_MAX_INT; 23 | #else 24 | #include 25 | #include 26 | static const MPI_Count bigmpi_int_max = INT_MAX; 27 | /* SIZE_MAX corresponds to size_t, which should be what MPI_Aint is. */ 28 | static const MPI_Count bigmpi_count_max = SIZE_MAX; 29 | #endif 30 | 31 | void BigMPI_Error_impl(const char *file, const int line, const char *func, const char *msg, ...); 32 | 33 | #define BigMPI_Error(...) BigMPI_Error_impl(__FILE__,__LINE__,__func__,__VA_ARGS__) 34 | 35 | void BigMPI_Convert_vectors(int num, 36 | int splat_old_count, 37 | const MPI_Count oldcount, 38 | const MPI_Count oldcounts[], 39 | int splat_old_type, 40 | const MPI_Datatype oldtype, 41 | const MPI_Datatype oldtypes[], 42 | int zero_new_displs, 43 | const MPI_Aint olddispls[], 44 | int newcounts[], 45 | MPI_Datatype newtypes[], 46 | MPI_Aint newdispls[]); 47 | 48 | #endif // BIGMPI_IMPL_H 49 | -------------------------------------------------------------------------------- /src/collectives_x.c: -------------------------------------------------------------------------------- 1 | #include "bigmpi_impl.h" 2 | 3 | int MPIX_Bcast_x(void *buf, MPI_Count count, MPI_Datatype datatype, int root, MPI_Comm comm) 4 | { 5 | int rc = MPI_SUCCESS; 6 | 7 | if (likely (count <= bigmpi_int_max )) { 8 | rc = MPI_Bcast(buf, (int)count, datatype, root, comm); 9 | } else { 10 | MPI_Datatype newtype; 11 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 12 | MPI_Type_commit(&newtype); 13 | rc = MPI_Bcast(buf, 1, newtype, root, comm); 14 | MPI_Type_free(&newtype); 15 | } 16 | return rc; 17 | } 18 | 19 | int MPIX_Gather_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 20 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) 21 | { 22 | int rc = MPI_SUCCESS; 23 | 24 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 25 | rc = MPI_Gather(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, root, comm); 26 | } else { 27 | MPI_Datatype newsendtype, newrecvtype; 28 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 29 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 30 | MPI_Type_commit(&newsendtype); 31 | MPI_Type_commit(&newrecvtype); 32 | rc = MPI_Gather(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, root, comm); 33 | MPI_Type_free(&newsendtype); 34 | MPI_Type_free(&newrecvtype); 35 | } 36 | return rc; 37 | } 38 | 39 | int MPIX_Scatter_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 40 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) 41 | { 42 | int rc = MPI_SUCCESS; 43 | 44 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 45 | rc = MPI_Scatter(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, root, comm); 46 | } else { 47 | MPI_Datatype newsendtype, newrecvtype; 48 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 49 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 50 | MPI_Type_commit(&newsendtype); 51 | MPI_Type_commit(&newrecvtype); 52 | rc = MPI_Scatter(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, root, comm); 53 | MPI_Type_free(&newsendtype); 54 | MPI_Type_free(&newrecvtype); 55 | } 56 | return rc; 57 | } 58 | 59 | int MPIX_Allgather_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 60 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, MPI_Comm comm) 61 | { 62 | int rc = MPI_SUCCESS; 63 | 64 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 65 | rc = MPI_Allgather(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, comm); 66 | } else { 67 | MPI_Datatype newsendtype, newrecvtype; 68 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 69 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 70 | MPI_Type_commit(&newsendtype); 71 | MPI_Type_commit(&newrecvtype); 72 | rc = MPI_Allgather(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, comm); 73 | MPI_Type_free(&newsendtype); 74 | MPI_Type_free(&newrecvtype); 75 | } 76 | return rc; 77 | } 78 | 79 | int MPIX_Alltoall_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 80 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, MPI_Comm comm) 81 | { 82 | int rc = MPI_SUCCESS; 83 | 84 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 85 | rc = MPI_Alltoall(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, comm); 86 | } else { 87 | MPI_Datatype newsendtype, newrecvtype; 88 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 89 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 90 | MPI_Type_commit(&newsendtype); 91 | MPI_Type_commit(&newrecvtype); 92 | rc = MPI_Alltoall(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, comm); 93 | MPI_Type_free(&newsendtype); 94 | MPI_Type_free(&newrecvtype); 95 | } 96 | return rc; 97 | } 98 | 99 | #if MPI_VERSION >= 3 100 | 101 | int MPIX_Ibcast_x(void *buf, MPI_Count count, MPI_Datatype datatype, int root, MPI_Comm comm, MPI_Request *request) 102 | { 103 | int rc = MPI_SUCCESS; 104 | 105 | if (likely (count <= bigmpi_int_max )) { 106 | rc = MPI_Ibcast(buf, (int)count, datatype, root, comm, request); 107 | } else { 108 | MPI_Datatype newtype; 109 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 110 | MPI_Type_commit(&newtype); 111 | rc = MPI_Ibcast(buf, 1, newtype, root, comm, request); 112 | MPI_Type_free(&newtype); 113 | } 114 | return rc; 115 | } 116 | 117 | int MPIX_Igather_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 118 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request) 119 | { 120 | int rc = MPI_SUCCESS; 121 | 122 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 123 | rc = MPI_Igather(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, root, comm, request); 124 | } else { 125 | MPI_Datatype newsendtype, newrecvtype; 126 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 127 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 128 | MPI_Type_commit(&newsendtype); 129 | MPI_Type_commit(&newrecvtype); 130 | rc = MPI_Igather(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, root, comm, request); 131 | MPI_Type_free(&newsendtype); 132 | MPI_Type_free(&newrecvtype); 133 | } 134 | return rc; 135 | } 136 | 137 | int MPIX_Iscatter_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 138 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request) 139 | { 140 | int rc = MPI_SUCCESS; 141 | 142 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 143 | rc = MPI_Iscatter(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, root, comm, request); 144 | } else { 145 | MPI_Datatype newsendtype, newrecvtype; 146 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 147 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 148 | MPI_Type_commit(&newsendtype); 149 | MPI_Type_commit(&newrecvtype); 150 | rc = MPI_Iscatter(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, root, comm, request); 151 | MPI_Type_free(&newsendtype); 152 | MPI_Type_free(&newrecvtype); 153 | } 154 | return rc; 155 | } 156 | 157 | int MPIX_Iallgather_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 158 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request) 159 | { 160 | int rc = MPI_SUCCESS; 161 | 162 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 163 | rc = MPI_Iallgather(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, comm, request); 164 | } else { 165 | MPI_Datatype newsendtype, newrecvtype; 166 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 167 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 168 | MPI_Type_commit(&newsendtype); 169 | MPI_Type_commit(&newrecvtype); 170 | rc = MPI_Iallgather(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, comm, request); 171 | MPI_Type_free(&newsendtype); 172 | MPI_Type_free(&newrecvtype); 173 | } 174 | return rc; 175 | } 176 | 177 | int MPIX_Ialltoall_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, 178 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request) 179 | { 180 | int rc = MPI_SUCCESS; 181 | 182 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 183 | rc = MPI_Ialltoall(sendbuf, (int)sendcount, sendtype, recvbuf, (int)recvcount, recvtype, comm, request); 184 | } else { 185 | MPI_Datatype newsendtype, newrecvtype; 186 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 187 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 188 | MPI_Type_commit(&newsendtype); 189 | MPI_Type_commit(&newrecvtype); 190 | rc = MPI_Ialltoall(sendbuf, 1, newsendtype, recvbuf, 1, newrecvtype, comm, request); 191 | MPI_Type_free(&newsendtype); 192 | MPI_Type_free(&newrecvtype); 193 | } 194 | return rc; 195 | } 196 | 197 | #endif 198 | -------------------------------------------------------------------------------- /src/likely.h: -------------------------------------------------------------------------------- 1 | /* Likely/Unlikely macros borrowed from MPICH via ARMCI-MPI */ 2 | 3 | /* These likely/unlikely macros provide static branch prediction hints to the 4 | * compiler, if such hints are available. Simply wrap the relevant expression in 5 | * the macro, like this: 6 | * 7 | * if (unlikely(ptr == NULL)) { 8 | * // ... some unlikely code path ... 9 | * } 10 | * 11 | * They should be used sparingly, especially in upper-level code. It's easy to 12 | * incorrectly estimate branching likelihood, while the compiler can often do a 13 | * decent job if left to its own devices. 14 | * 15 | * These macros are not namespaced because the namespacing is cumbersome. 16 | */ 17 | 18 | /* safety guard for now, add a configure check in the future */ 19 | #if ( defined(__GNUC__) && (__GNUC__ >= 3) ) || defined(__IBMC__) || defined(__INTEL_COMPILER) || defined(__clang__) 20 | # define unlikely(x_) __builtin_expect(!!(x_),0) 21 | # define likely(x_) __builtin_expect(!!(x_),1) 22 | #else 23 | # define unlikely(x_) (x_) 24 | # define likely(x_) (x_) 25 | #endif 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/rma_x.c: -------------------------------------------------------------------------------- 1 | #include "bigmpi_impl.h" 2 | 3 | int MPIX_Put_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 4 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win) 5 | { 6 | int rc = MPI_SUCCESS; 7 | 8 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 9 | rc = MPI_Put(origin_addr, origin_count, origin_datatype, 10 | target_rank, target_disp, target_count, target_datatype, win); 11 | } else { 12 | MPI_Datatype neworigin_datatype, newtarget_datatype; 13 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 14 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 15 | MPI_Type_commit(&neworigin_datatype); 16 | MPI_Type_commit(&newtarget_datatype); 17 | rc = MPI_Put(origin_addr, 1, neworigin_datatype, 18 | target_rank, target_disp, 1, newtarget_datatype, win); 19 | MPI_Type_free(&neworigin_datatype); 20 | MPI_Type_free(&newtarget_datatype); 21 | } 22 | return rc; 23 | } 24 | 25 | int MPIX_Get_x(void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 26 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, MPI_Win win) 27 | { 28 | int rc = MPI_SUCCESS; 29 | 30 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 31 | rc = MPI_Get(origin_addr, origin_count, origin_datatype, 32 | target_rank, target_disp, target_count, target_datatype, win); 33 | } else { 34 | MPI_Datatype neworigin_datatype, newtarget_datatype; 35 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 36 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 37 | MPI_Type_commit(&neworigin_datatype); 38 | MPI_Type_commit(&newtarget_datatype); 39 | rc = MPI_Get(origin_addr, 1, neworigin_datatype, 40 | target_rank, target_disp, 1, newtarget_datatype, win); 41 | MPI_Type_free(&neworigin_datatype); 42 | MPI_Type_free(&newtarget_datatype); 43 | } 44 | return rc; 45 | } 46 | 47 | int MPIX_Accumulate_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 48 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 49 | MPI_Op op, MPI_Win win) 50 | { 51 | int rc = MPI_SUCCESS; 52 | 53 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 54 | rc = MPI_Accumulate(origin_addr, origin_count, origin_datatype, 55 | target_rank, target_disp, target_count, target_datatype, 56 | op, win); 57 | } else { 58 | MPI_Datatype neworigin_datatype, newtarget_datatype; 59 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 60 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 61 | MPI_Type_commit(&neworigin_datatype); 62 | MPI_Type_commit(&newtarget_datatype); 63 | rc = MPI_Accumulate(origin_addr, 1, neworigin_datatype, 64 | target_rank, target_disp, 1, newtarget_datatype, op, win); 65 | MPI_Type_free(&neworigin_datatype); 66 | MPI_Type_free(&newtarget_datatype); 67 | } 68 | return rc; 69 | } 70 | 71 | #if MPI_VERSION >= 3 72 | 73 | int MPIX_Get_accumulate_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 74 | void *result_addr, MPI_Count result_count, MPI_Datatype result_datatype, 75 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 76 | MPI_Op op, MPI_Win win) 77 | { 78 | int rc = MPI_SUCCESS; 79 | 80 | if (likely (origin_count <= bigmpi_int_max && result_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 81 | rc = MPI_Get_accumulate(origin_addr, origin_count, origin_datatype, 82 | result_addr, result_count, result_datatype, 83 | target_rank, target_disp, target_count, target_datatype, 84 | op, win); 85 | } else { 86 | MPI_Datatype neworigin_datatype, newresult_datatype, newtarget_datatype; 87 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 88 | BigMPI_Type_contiguous(0,result_count, result_datatype, &newresult_datatype); 89 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 90 | MPI_Type_commit(&neworigin_datatype); 91 | MPI_Type_commit(&newresult_datatype); 92 | MPI_Type_commit(&newtarget_datatype); 93 | rc = MPI_Get_accumulate(origin_addr, 1, neworigin_datatype, 94 | result_addr, 1, newresult_datatype, 95 | target_rank, target_disp, 1, newtarget_datatype, 96 | op, win); 97 | MPI_Type_free(&neworigin_datatype); 98 | MPI_Type_free(&newresult_datatype); 99 | MPI_Type_free(&newtarget_datatype); 100 | } 101 | return rc; 102 | } 103 | 104 | int MPIX_Rput_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 105 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 106 | MPI_Win win, MPI_Request *request) 107 | { 108 | int rc = MPI_SUCCESS; 109 | 110 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 111 | rc = MPI_Rput(origin_addr, origin_count, origin_datatype, 112 | target_rank, target_disp, target_count, target_datatype, win, request); 113 | } else { 114 | MPI_Datatype neworigin_datatype, newtarget_datatype; 115 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 116 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 117 | MPI_Type_commit(&neworigin_datatype); 118 | MPI_Type_commit(&newtarget_datatype); 119 | rc = MPI_Rput(origin_addr, 1, neworigin_datatype, 120 | target_rank, target_disp, 1, newtarget_datatype, win, request); 121 | MPI_Type_free(&neworigin_datatype); 122 | MPI_Type_free(&newtarget_datatype); 123 | } 124 | return rc; 125 | } 126 | 127 | int MPIX_Rget_x(void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 128 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 129 | MPI_Win win, MPI_Request *request) 130 | { 131 | int rc = MPI_SUCCESS; 132 | 133 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 134 | rc = MPI_Rget(origin_addr, origin_count, origin_datatype, 135 | target_rank, target_disp, target_count, target_datatype, win, request); 136 | } else { 137 | MPI_Datatype neworigin_datatype, newtarget_datatype; 138 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 139 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 140 | MPI_Type_commit(&neworigin_datatype); 141 | MPI_Type_commit(&newtarget_datatype); 142 | rc = MPI_Rget(origin_addr, 1, neworigin_datatype, 143 | target_rank, target_disp, 1, newtarget_datatype, win, request); 144 | MPI_Type_free(&neworigin_datatype); 145 | MPI_Type_free(&newtarget_datatype); 146 | } 147 | return rc; 148 | } 149 | 150 | int MPIX_Raccumulate_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 151 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 152 | MPI_Op op, MPI_Win win, MPI_Request *request) 153 | { 154 | int rc = MPI_SUCCESS; 155 | 156 | if (likely (origin_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 157 | rc = MPI_Raccumulate(origin_addr, origin_count, origin_datatype, 158 | target_rank, target_disp, target_count, target_datatype, 159 | op, win, request); 160 | } else { 161 | MPI_Datatype neworigin_datatype, newtarget_datatype; 162 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 163 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 164 | MPI_Type_commit(&neworigin_datatype); 165 | MPI_Type_commit(&newtarget_datatype); 166 | rc = MPI_Raccumulate(origin_addr, 1, neworigin_datatype, 167 | target_rank, target_disp, 1, newtarget_datatype, op, win, request); 168 | MPI_Type_free(&neworigin_datatype); 169 | MPI_Type_free(&newtarget_datatype); 170 | } 171 | return rc; 172 | } 173 | 174 | int MPIX_Rget_accumulate_x(BIGMPI_CONST void *origin_addr, MPI_Count origin_count, MPI_Datatype origin_datatype, 175 | void *result_addr, MPI_Count result_count, MPI_Datatype result_datatype, 176 | int target_rank, MPI_Aint target_disp, MPI_Count target_count, MPI_Datatype target_datatype, 177 | MPI_Op op, MPI_Win win, MPI_Request * request) 178 | { 179 | int rc = MPI_SUCCESS; 180 | 181 | if (likely (origin_count <= bigmpi_int_max && result_count <= bigmpi_int_max && target_count <= bigmpi_int_max)) { 182 | rc = MPI_Rget_accumulate(origin_addr, origin_count, origin_datatype, 183 | result_addr, result_count, result_datatype, 184 | target_rank, target_disp, target_count, target_datatype, 185 | op, win, request); 186 | } else { 187 | MPI_Datatype neworigin_datatype, newresult_datatype, newtarget_datatype; 188 | BigMPI_Type_contiguous(0,origin_count, origin_datatype, &neworigin_datatype); 189 | BigMPI_Type_contiguous(0,result_count, result_datatype, &newresult_datatype); 190 | BigMPI_Type_contiguous(0,target_count, target_datatype, &newtarget_datatype); 191 | MPI_Type_commit(&neworigin_datatype); 192 | MPI_Type_commit(&newresult_datatype); 193 | MPI_Type_commit(&newtarget_datatype); 194 | rc = MPI_Rget_accumulate(origin_addr, 1, neworigin_datatype, 195 | result_addr, 1, newresult_datatype, 196 | target_rank, target_disp, 1, newtarget_datatype, 197 | op, win, request); 198 | MPI_Type_free(&neworigin_datatype); 199 | MPI_Type_free(&newresult_datatype); 200 | MPI_Type_free(&newtarget_datatype); 201 | } 202 | return rc; 203 | } 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /src/sendrecv_x.c: -------------------------------------------------------------------------------- 1 | #include "bigmpi_impl.h" 2 | 3 | int MPIX_Send_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) 4 | { 5 | int rc = MPI_SUCCESS; 6 | 7 | if (likely (count <= bigmpi_int_max )) { 8 | rc = MPI_Send(buf, (int)count, datatype, dest, tag, comm); 9 | } else { 10 | MPI_Datatype newtype; 11 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 12 | MPI_Type_commit(&newtype); 13 | rc = MPI_Send(buf, 1, newtype, dest, tag, comm); 14 | MPI_Type_free(&newtype); 15 | } 16 | return rc; 17 | } 18 | 19 | int MPIX_Recv_x(void *buf, MPI_Count count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) 20 | { 21 | int rc = MPI_SUCCESS; 22 | 23 | if (likely (count <= bigmpi_int_max )) { 24 | rc = MPI_Recv(buf, (int)count, datatype, source, tag, comm, status); 25 | } else { 26 | MPI_Datatype newtype; 27 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 28 | MPI_Type_commit(&newtype); 29 | rc = MPI_Recv(buf, 1, newtype, source, tag, comm, status); 30 | MPI_Type_free(&newtype); 31 | } 32 | return rc; 33 | } 34 | 35 | int MPIX_Isend_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request * request) 36 | { 37 | int rc = MPI_SUCCESS; 38 | 39 | if (likely (count <= bigmpi_int_max )) { 40 | rc = MPI_Isend(buf, (int)count, datatype, dest, tag, comm, request); 41 | } else { 42 | MPI_Datatype newtype; 43 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 44 | MPI_Type_commit(&newtype); 45 | rc = MPI_Isend(buf, 1, newtype, dest, tag, comm, request); 46 | MPI_Type_free(&newtype); 47 | } 48 | return rc; 49 | } 50 | 51 | int MPIX_Irecv_x(void *buf, MPI_Count count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request * request) 52 | { 53 | int rc = MPI_SUCCESS; 54 | 55 | if (likely (count <= bigmpi_int_max )) { 56 | rc = MPI_Irecv(buf, (int)count, datatype, source, tag, comm, request); 57 | } else { 58 | MPI_Datatype newtype; 59 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 60 | MPI_Type_commit(&newtype); 61 | rc = MPI_Irecv(buf, 1, newtype, source, tag, comm, request); 62 | MPI_Type_free(&newtype); 63 | } 64 | return rc; 65 | } 66 | 67 | int MPIX_Sendrecv_x(BIGMPI_CONST void *sendbuf, MPI_Count sendcount, MPI_Datatype sendtype, int dest, int sendtag, 68 | void *recvbuf, MPI_Count recvcount, MPI_Datatype recvtype, int source, int recvtag, 69 | MPI_Comm comm, MPI_Status *status) 70 | { 71 | int rc = MPI_SUCCESS; 72 | 73 | if (likely (sendcount <= bigmpi_int_max && recvcount <= bigmpi_int_max )) { 74 | rc = MPI_Sendrecv(sendbuf, (int)sendcount, sendtype, dest, sendtag, 75 | recvbuf, (int)recvcount, recvtype, source, recvtag, 76 | comm, status); 77 | } else if (sendcount <= bigmpi_int_max && recvcount > bigmpi_int_max ) { 78 | MPI_Datatype newrecvtype; 79 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 80 | MPI_Type_commit(&newrecvtype); 81 | rc = MPI_Sendrecv(sendbuf, (int)sendcount, sendtype, dest, sendtag, 82 | recvbuf, 1, newrecvtype, source, recvtag, 83 | comm, status); 84 | MPI_Type_free(&newrecvtype); 85 | } else if (sendcount > bigmpi_int_max && recvcount <= bigmpi_int_max ) { 86 | MPI_Datatype newsendtype; 87 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 88 | MPI_Type_commit(&newsendtype); 89 | rc = MPI_Sendrecv(sendbuf, 1, newsendtype, dest, sendtag, 90 | recvbuf, (int)recvcount, recvtype, source, recvtag, 91 | comm, status); 92 | MPI_Type_free(&newsendtype); 93 | } else { 94 | MPI_Datatype newsendtype, newrecvtype; 95 | BigMPI_Type_contiguous(0,sendcount, sendtype, &newsendtype); 96 | BigMPI_Type_contiguous(0,recvcount, recvtype, &newrecvtype); 97 | MPI_Type_commit(&newsendtype); 98 | MPI_Type_commit(&newrecvtype); 99 | rc = MPI_Sendrecv(sendbuf, 1, newsendtype, dest, sendtag, 100 | recvbuf, 1, newrecvtype, source, recvtag, 101 | comm, status); 102 | MPI_Type_free(&newsendtype); 103 | MPI_Type_free(&newrecvtype); 104 | } 105 | return rc; 106 | } 107 | 108 | int MPIX_Sendrecv_replace_x(void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int sendtag, 109 | int source, int recvtag, MPI_Comm comm, MPI_Status *status) 110 | { 111 | int rc = MPI_SUCCESS; 112 | 113 | if (likely (count <= bigmpi_int_max )) { 114 | rc = MPI_Sendrecv_replace(buf, (int)count, datatype, dest, sendtag, source, recvtag, comm, status); 115 | } else { 116 | MPI_Datatype newtype; 117 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 118 | MPI_Type_commit(&newtype); 119 | rc = MPI_Sendrecv_replace(buf, 1, newtype, dest, sendtag, source, recvtag, comm, status); 120 | MPI_Type_free(&newtype); 121 | } 122 | return rc; 123 | } 124 | 125 | 126 | int MPIX_Ssend_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) 127 | { 128 | int rc = MPI_SUCCESS; 129 | 130 | if (likely (count <= bigmpi_int_max )) { 131 | rc = MPI_Ssend(buf, (int)count, datatype, dest, tag, comm); 132 | } else { 133 | MPI_Datatype newtype; 134 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 135 | MPI_Type_commit(&newtype); 136 | rc = MPI_Ssend(buf, 1, newtype, dest, tag, comm); 137 | MPI_Type_free(&newtype); 138 | } 139 | return rc; 140 | } 141 | 142 | int MPIX_Rsend_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) 143 | { 144 | int rc = MPI_SUCCESS; 145 | 146 | if (likely (count <= bigmpi_int_max )) { 147 | rc = MPI_Rsend(buf, (int)count, datatype, dest, tag, comm); 148 | } else { 149 | MPI_Datatype newtype; 150 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 151 | MPI_Type_commit(&newtype); 152 | rc = MPI_Rsend(buf, 1, newtype, dest, tag, comm); 153 | MPI_Type_free(&newtype); 154 | } 155 | return rc; 156 | } 157 | 158 | int MPIX_Issend_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) 159 | { 160 | int rc = MPI_SUCCESS; 161 | 162 | if (likely (count <= bigmpi_int_max )) { 163 | rc = MPI_Issend(buf, (int)count, datatype, dest, tag, comm, request); 164 | } else { 165 | MPI_Datatype newtype; 166 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 167 | MPI_Type_commit(&newtype); 168 | rc = MPI_Issend(buf, 1, newtype, dest, tag, comm, request); 169 | MPI_Type_free(&newtype); 170 | } 171 | return rc; 172 | } 173 | 174 | int MPIX_Irsend_x(BIGMPI_CONST void *buf, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) 175 | { 176 | int rc = MPI_SUCCESS; 177 | 178 | if (likely (count <= bigmpi_int_max )) { 179 | rc = MPI_Irsend(buf, (int)count, datatype, dest, tag, comm, request); 180 | } else { 181 | MPI_Datatype newtype; 182 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 183 | MPI_Type_commit(&newtype); 184 | rc = MPI_Irsend(buf, 1, newtype, dest, tag, comm, request); 185 | MPI_Type_free(&newtype); 186 | } 187 | return rc; 188 | } 189 | 190 | #if MPI_VERSION >= 3 191 | 192 | int MPIX_Mrecv_x(void *buf, MPI_Count count, MPI_Datatype datatype, MPI_Message *message, MPI_Status *status) 193 | { 194 | int rc = MPI_SUCCESS; 195 | 196 | if (likely (count <= bigmpi_int_max )) { 197 | rc = MPI_Mrecv(buf, (int)count, datatype, message, status); 198 | } else { 199 | MPI_Datatype newtype; 200 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 201 | MPI_Type_commit(&newtype); 202 | rc = MPI_Mrecv(buf, 1, newtype, message, status); 203 | MPI_Type_free(&newtype); 204 | } 205 | return rc; 206 | } 207 | 208 | int MPIX_Imrecv_x(void *buf, MPI_Count count, MPI_Datatype datatype, MPI_Message *message, MPI_Request *request) 209 | { 210 | int rc = MPI_SUCCESS; 211 | 212 | if (likely (count <= bigmpi_int_max )) { 213 | rc = MPI_Imrecv(buf, (int)count, datatype, message, request); 214 | } else { 215 | MPI_Datatype newtype; 216 | BigMPI_Type_contiguous(0,count, datatype, &newtype); 217 | MPI_Type_commit(&newtype); 218 | rc = MPI_Imrecv(buf, 1, newtype, message, request); 219 | MPI_Type_free(&newtype); 220 | } 221 | return rc; 222 | } 223 | 224 | #endif 225 | -------------------------------------------------------------------------------- /src/type_contiguous_x.c: -------------------------------------------------------------------------------- 1 | #include "bigmpi_impl.h" 2 | 3 | /* This function does all the heavy lifting in BigMPI. */ 4 | 5 | #ifdef BIGMPI_AVOID_TYPE_CREATE_STRUCT 6 | #include 7 | /* 8 | * Synopsis 9 | * 10 | * int BigMPI_Factorize_count(MPI_Count c, int * a, int *b) 11 | * 12 | * Input Parameter 13 | * 14 | * c large count 15 | * 16 | * Output Parameters 17 | * 18 | * a, b integers such that c=a*b and a,blo; g--) { 33 | MPI_Count rem = in%g; 34 | if (rem==0) { 35 | *a = (int)g; 36 | *b = (int)(in/g); 37 | return 0; 38 | } 39 | } 40 | *a = 1; 41 | *b = -1; 42 | return 1; 43 | } 44 | #endif 45 | 46 | /* 47 | * Synopsis 48 | * 49 | * int BigMPI_Type_contiguous(MPI_Aint offset, 50 | * MPI_Count count, 51 | * MPI_Datatype oldtype, 52 | * MPI_Datatype * newtype) 53 | * 54 | * Input Parameters 55 | * 56 | * offset byte offset of the start of the contiguous chunk 57 | * count replication count (nonnegative integer) 58 | * oldtype old datatype (handle) 59 | * 60 | * Output Parameter 61 | * 62 | * newtype new datatype (handle) 63 | * 64 | * Notes 65 | * 66 | * Following the addition of the offset argument, this function no longer 67 | * matches the signature of MPI_Type_contiguous. This may constitute 68 | * breaking user experience for some people. However, the value of 69 | * adding it simplies the primary purpose of this function, which is to 70 | * do the heavy lifting _inside_ of BigMPI. In particular, it allows 71 | * us to use MPI_Alltoallw instead of MPI_Neighborhood_alltoallw. 72 | * 73 | */ 74 | int BigMPI_Type_contiguous(MPI_Aint offset, MPI_Count count, MPI_Datatype oldtype, MPI_Datatype * newtype) 75 | { 76 | /* The count has to fit into MPI_Aint for BigMPI to work. */ 77 | if ((uint64_t)count>(uint64_t)bigmpi_count_max) { 78 | printf("count (%llu) exceeds bigmpi_count_max (%llu)\n", 79 | (long long unsigned)count, (long long unsigned)bigmpi_count_max); 80 | fflush(stdout); 81 | } 82 | 83 | #ifdef BIGMPI_AVOID_TYPE_CREATE_STRUCT 84 | if (offset==0) { 85 | /* There is no need for this code path in homogeneous execution, 86 | * but it is useful to exercise anyways. */ 87 | int a, b; 88 | int prime = BigMPI_Factorize_count(count, &a, &b); 89 | if (!prime) { 90 | MPI_Type_vector(a, b, b, oldtype, newtype); 91 | return MPI_SUCCESS; 92 | } 93 | } 94 | #endif 95 | MPI_Count c = count/bigmpi_int_max; 96 | MPI_Count r = count%bigmpi_int_max; 97 | 98 | assert(c(uint64_t)bigmpi_count_max) { 44 | printf("count (%lld) exceeds bigmpi_count_max (%lld)\n", 45 | (long long unsigned)count, (long long unsigned)bigmpi_count_max); 46 | fflush(stdout); 47 | } 48 | 49 | types = malloc(count*sizeof(*types)); 50 | blocklens = malloc(count*sizeof(*blocklens)); 51 | 52 | for (i=0; i= 3 114 | 115 | /* 116 | * Synopsis 117 | * 118 | * int BigMPI_Create_graph_comm(MPI_Comm comm_old, int root, MPI_Comm * graph_comm) 119 | * 120 | * Input Parameter 121 | * 122 | * comm_old MPI communicator from which to create a graph comm 123 | * root integer id of root. if -1, create fully connected graph, 124 | * which is appropriate for the all___ collectives. 125 | * 126 | * Output Parameters 127 | * 128 | * graph_comm MPI topology communicator associated with input communicator 129 | * rc returns the rc from the MPI graph comm create function. 130 | * 131 | */ 132 | int BigMPI_Create_graph_comm(MPI_Comm comm_old, int root, MPI_Comm * comm_dist_graph) 133 | { 134 | int rank, size; 135 | MPI_Comm_rank(comm_old, &rank); 136 | MPI_Comm_size(comm_old, &size); 137 | 138 | /* in the all case (root == -1), every rank is a destination for every other rank; 139 | * otherwise, only the root is a destination. */ 140 | int indegree = (root == -1 || root==rank) ? size : 0; 141 | /* in the all case (root == -1), every rank is a source for every other rank; 142 | * otherwise, all non-root processes are the source for only one rank (the root). */ 143 | int outdegree = (root == -1 || root==rank) ? size : 1; 144 | 145 | int * sources = malloc(indegree*sizeof(int)); assert(sources!=NULL); 146 | int * destinations = malloc(outdegree*sizeof(int)); assert(destinations!=NULL); 147 | 148 | for (int i=0; i 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | int main(int argc, char * argv[]) 8 | { 9 | printf("INT_MAX = %d\n", INT_MAX); 10 | 11 | int a = (int)INT_MAX*100; 12 | MPI_Aint b = (MPI_Aint)INT_MAX*100; 13 | int64_t c = (int64_t)INT_MAX*100; 14 | uint64_t d = (uint64_t)INT_MAX*100; 15 | 16 | printf("a = %d\n", a); 17 | printf("b = %zu\n", b); 18 | printf("c = %lld\n", c); 19 | printf("d = %llu\n", d); 20 | 21 | int a2 = 100; 22 | MPI_Aint b2 = 100; 23 | int64_t c2 = 100; 24 | uint64_t d2 = 100; 25 | 26 | a2 *= INT_MAX; 27 | b2 *= INT_MAX; 28 | c2 *= INT_MAX; 29 | d2 *= INT_MAX; 30 | 31 | printf("a2 = %d\n", a2); 32 | printf("b2 = %zu\n", b2); 33 | printf("c2 = %lld\n", c2); 34 | printf("d2 = %llu\n", d2); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/devel/in_place_user_def_reduce.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void printer(void * invec, void * inoutvec, int * len, MPI_Datatype * type) 5 | { 6 | int rank; 7 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 8 | printf("%d: invec = %p inoutvec = %p len = %d \n", rank, invec, inoutvec, *len); 9 | return; 10 | } 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | MPI_Init(&argc, &argv); 15 | 16 | int rank, size; 17 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 18 | MPI_Comm_size(MPI_COMM_WORLD, &size); 19 | 20 | int commute = 1; 21 | MPI_Op myop; 22 | MPI_Op_create(printer, commute, &myop); 23 | 24 | int in[8] = {1,2,3,4,5,6,7,8}; 25 | int out[8] = {-1,-2,-3,-4,-5,-6,-7,-8}; 26 | 27 | printf("%d: MPI_IN_PLACE = %p in = %p out = %p \n", rank, MPI_IN_PLACE, in, out); 28 | 29 | MPI_Barrier(MPI_COMM_WORLD); 30 | fflush(stdout); 31 | MPI_Barrier(MPI_COMM_WORLD); 32 | 33 | if (rank==0) printf("out-of-place Allreduce \n"); 34 | MPI_Allreduce(in, out, 8, MPI_INT, myop, MPI_COMM_WORLD); 35 | MPI_Barrier(MPI_COMM_WORLD); 36 | fflush(stdout); 37 | MPI_Barrier(MPI_COMM_WORLD); 38 | 39 | if (rank==0) printf("in-place Allreduce \n"); 40 | MPI_Allreduce(MPI_IN_PLACE, out, 8, MPI_INT, myop, MPI_COMM_WORLD); 41 | MPI_Barrier(MPI_COMM_WORLD); 42 | fflush(stdout); 43 | MPI_Barrier(MPI_COMM_WORLD); 44 | 45 | MPI_Op_free(&myop); 46 | MPI_Finalize(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test/devel/preprocessor.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SUM 0x1 4 | 5 | void Bar(int a) { return; }; 6 | 7 | #define MAKE_FOO(OP) void FOO_##OP##_fn(){ Bar(MPI_##OP);\ 8 | return; } 9 | 10 | MAKE_FOO(SUM); 11 | 12 | int main(void) 13 | { 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/devel/rounding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char * argv[]) 4 | { 5 | printf("7/3 = %d\n",7/3); 6 | printf("8/3 = %d\n",8/3); 7 | return 0; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test/devel/type_create_struct.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | MPI_Init(&argc, &argv); 7 | 8 | MPI_Finalize(); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/mpi/Makefile.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2014. See LICENSE in top-level directory. 3 | # 4 | 5 | check_PROGRAMS += test/mpi/reduce_scatter \ 6 | test/mpi/scatterv \ 7 | # end 8 | 9 | TESTS += test/mpi/reduce_scatter \ 10 | test/mpi/scatterv \ 11 | # end 12 | 13 | -------------------------------------------------------------------------------- /test/mpi/README.md: -------------------------------------------------------------------------------- 1 | These tests are to verify the behavior of MPI itself, such as to make 2 | sure various functions are count-safe and that the datatype functions 3 | work as desired. 4 | -------------------------------------------------------------------------------- /test/mpi/bcast.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | int MPIX_Type_contiguous_x(MPI_Count count, MPI_Datatype oldtype, MPI_Datatype * newtype) 11 | { 12 | const MPI_Count bigmpi_int_max = (MPI_Count)INT_MAX; 13 | 14 | MPI_Count c = count/bigmpi_int_max; 15 | MPI_Count r = count%bigmpi_int_max; 16 | 17 | assert(c1) ? atol(argv[1]) : 1L<<31; 51 | if (rank==0) { 52 | printf("Test: %zu bytes\n",n); 53 | } 54 | 55 | char * ptr = NULL; 56 | MPI_Alloc_mem(n,MPI_INFO_NULL,&ptr); 57 | 58 | if (rank==0) { 59 | memset(ptr,255,n); 60 | } else { 61 | memset(ptr,0,n); 62 | } 63 | 64 | MPI_Datatype bigtype; 65 | MPIX_Type_contiguous_x(n,MPI_CHAR,&bigtype); 66 | MPI_Type_commit(&bigtype); 67 | 68 | if (0 && n<(size_t)INT_MAX) { 69 | if (rank==0) printf("Not using a contiguous datatype\n"); 70 | MPI_Bcast(ptr,(int)n,MPI_CHAR,0,MPI_COMM_WORLD); 71 | } else { 72 | if (rank==0) printf("Using a contiguous datatype\n"); 73 | MPI_Bcast(ptr,1,bigtype,0,MPI_COMM_WORLD); 74 | } 75 | 76 | size_t errors = 0; 77 | for (size_t i=0; i0) { 82 | printf("%d: There were %zu errors!\n", rank, errors); 83 | for (size_t i=0; i 2 | #include 3 | 4 | #include 5 | 6 | int main(int argc, char* argv[]) 7 | { 8 | MPI_Init(&argc, &argv); 9 | 10 | int rank, size; 11 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 12 | MPI_Comm_size(MPI_COMM_WORLD, &size); 13 | 14 | if (size!=4) { 15 | if (rank==0) printf("Use 4 processes\n"); 16 | MPI_Finalize(); 17 | return size; 18 | } 19 | 20 | { 21 | if (rank==0) printf("MPI_Reduce_scatter(sendbuf, recvbuf...\n"); 22 | fflush(stdout); 23 | MPI_Barrier(MPI_COMM_WORLD); 24 | 25 | int junk = rank+1; 26 | int sendbuf[4] = {junk, junk*2, junk*3, junk*4}; 27 | int recvbuf[1] = {0}; 28 | int recvcounts[4] = {1,1,1,1}; 29 | MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, MPI_INT, MPI_SUM, MPI_COMM_WORLD); 30 | printf("%d: sendbuf = {%d,%d,%d,%d}, recvbuf = {%d} \n", 31 | rank, sendbuf[0], sendbuf[1], sendbuf[2], sendbuf[3], recvbuf[0]); 32 | } 33 | 34 | fflush(stdout); 35 | usleep(1000); 36 | MPI_Barrier(MPI_COMM_WORLD); 37 | if (rank==0) printf("===================\n"); 38 | 39 | { 40 | if (rank==0) printf("MPI_Reduce_scatter(MPI_IN_PLACE, recvbuf...\n"); 41 | fflush(stdout); 42 | MPI_Barrier(MPI_COMM_WORLD); 43 | 44 | int junk = rank+1; 45 | int recvbuf[4] = {junk, junk*2, junk*3, junk*4}; 46 | int recvcounts[4] = {1,1,1,1}; 47 | MPI_Reduce_scatter(MPI_IN_PLACE, recvbuf, recvcounts, MPI_INT, MPI_SUM, MPI_COMM_WORLD); 48 | printf("%d: recvbuf = {%d,%d,%d,%d} \n", 49 | rank, recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]); 50 | } 51 | 52 | fflush(stdout); 53 | usleep(1000); 54 | MPI_Barrier(MPI_COMM_WORLD); 55 | if (rank==0) printf("===================\n"); 56 | 57 | { 58 | if (rank==0) printf("MPI_Reduce_scatter_block(sendbuf, recvbuf...\n"); 59 | fflush(stdout); 60 | MPI_Barrier(MPI_COMM_WORLD); 61 | 62 | int junk = rank+1; 63 | int sendbuf[4] = {junk, junk*2, junk*3, junk*4}; 64 | int recvbuf[1] = {0}; 65 | int recvcount = 1; 66 | MPI_Reduce_scatter_block(sendbuf, recvbuf, recvcount, MPI_INT, MPI_SUM, MPI_COMM_WORLD); 67 | printf("%d: sendbuf = {%d,%d,%d,%d}, recvbuf = {%d} \n", 68 | rank, sendbuf[0], sendbuf[1], sendbuf[2], sendbuf[3], recvbuf[0]); 69 | } 70 | 71 | fflush(stdout); 72 | usleep(1000); 73 | MPI_Barrier(MPI_COMM_WORLD); 74 | if (rank==0) printf("===================\n"); 75 | 76 | { 77 | if (rank==0) printf("MPI_Reduce_scatter_block(MPI_IN_PLACE, recvbuf...\n"); 78 | fflush(stdout); 79 | MPI_Barrier(MPI_COMM_WORLD); 80 | 81 | int junk = rank+1; 82 | int recvbuf[4] = {junk, junk*2, junk*3, junk*4}; 83 | int recvcount = 1; 84 | MPI_Reduce_scatter_block(MPI_IN_PLACE, recvbuf, recvcount, MPI_INT, MPI_SUM, MPI_COMM_WORLD); 85 | printf("%d: recvbuf = {%d,%d,%d,%d} \n", 86 | rank, recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]); 87 | } 88 | 89 | fflush(stdout); 90 | usleep(1000); 91 | MPI_Barrier(MPI_COMM_WORLD); 92 | if (rank==0) printf("===================\n"); 93 | 94 | { 95 | if (rank==0) printf("MPI_Reduce(sendbuf, tempbuf... + MPI_Scatter(tempbuf, recvcount...\n"); 96 | fflush(stdout); 97 | MPI_Barrier(MPI_COMM_WORLD); 98 | 99 | int junk = rank+1; 100 | int sendbuf[4] = {junk, junk*2, junk*3, junk*4}; 101 | int tempbuf[4] = {0,0,0,0}; 102 | int recvbuf[1] = {0}; 103 | int recvcount = 1; 104 | MPI_Reduce(sendbuf, tempbuf, 4*recvcount, MPI_INT, MPI_SUM, 0 /* root */, MPI_COMM_WORLD); 105 | MPI_Scatter(tempbuf, recvcount, MPI_INT, recvbuf, recvcount, MPI_INT, 0 /* root */, MPI_COMM_WORLD); 106 | printf("%d: sendbuf = {%d,%d,%d,%d}, recvbuf = {%d} \n", 107 | rank, sendbuf[0], sendbuf[1], sendbuf[2], sendbuf[3], recvbuf[0]); 108 | } 109 | 110 | fflush(stdout); 111 | usleep(1000); 112 | MPI_Barrier(MPI_COMM_WORLD); 113 | if (rank==0) printf("===================\n"); 114 | 115 | { 116 | if (rank==0) printf("MPI_Reduce(MPI_IN_PLACE, recvbuf... + MPI_Scatter(MPI_IN_PLACE, recvcount...\n"); 117 | fflush(stdout); 118 | MPI_Barrier(MPI_COMM_WORLD); 119 | 120 | int junk = rank+1; 121 | int recvbuf[4] = {junk, junk*2, junk*3, junk*4}; 122 | int recvcount = 1; 123 | MPI_Reduce(rank==0 ? MPI_IN_PLACE : recvbuf, rank==0 ? recvbuf : NULL, 124 | 4*recvcount, MPI_INT, MPI_SUM, 0 /* root */, MPI_COMM_WORLD); 125 | MPI_Scatter(recvbuf, recvcount, MPI_INT, rank==0 ? MPI_IN_PLACE : recvbuf, recvcount, MPI_INT, 0 /* root */, MPI_COMM_WORLD); 126 | printf("%d: recvbuf = {%d,%d,%d,%d} \n", 127 | rank, recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]); 128 | } 129 | 130 | MPI_Finalize(); 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /test/mpi/scatterv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | const unsigned int bignum = 3*1073741824; /* 3*2^30 < 2^32 */ 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | MPI_Init(&argc, &argv); 16 | 17 | int rank, size; 18 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 19 | MPI_Comm_size(MPI_COMM_WORLD, &size); 20 | 21 | if (size<2) { 22 | printf("Use more than 1 process for this test\n"); 23 | MPI_Finalize(); 24 | return 1; 25 | } 26 | 27 | int * counts = malloc(size*sizeof(int)); 28 | int * displs = malloc(size*sizeof(int)); 29 | 30 | for (int i=0; i0); 34 | } 35 | 36 | char * sendbuf = malloc(bignum); 37 | char * recvbuf = malloc(bignum/size); 38 | 39 | memset(sendbuf, rank==0 ? 1 : 0, bignum); 40 | memset(recvbuf, 0, bignum/size); 41 | 42 | MPI_Scatterv(sendbuf, counts, displs, MPI_CHAR, 43 | recvbuf, (int)(bignum/size), MPI_CHAR, 44 | 0, MPI_COMM_WORLD); 45 | 46 | free(counts); 47 | free(displs); 48 | 49 | free(sendbuf); 50 | free(recvbuf); 51 | 52 | MPI_Finalize(); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /test/perf/Makefile: -------------------------------------------------------------------------------- 1 | CC = mpicc 2 | CFLAGS = -O2 -Wall -std=c99 3 | 4 | TESTS = reductions typecontig typepiggy 5 | 6 | all: $(TESTS) 7 | 8 | %: %.c 9 | $(CC) $(CFLAGS) $< -o $@ 10 | 11 | clean: 12 | -rm -f $(TESTS) 13 | 14 | -------------------------------------------------------------------------------- /test/perf/reductions.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | static int verify_doubles(double *buf, int count, double expected_value) 11 | { 12 | int errors = 0; 13 | for (int i = 0; i < count; i++) { 14 | double absdiff = fabs(buf[i] - expected_value); 15 | if (absdiff>1.e-4) errors++; 16 | } 17 | return errors; 18 | } 19 | 20 | #define PASTE_BIGMPI_REDUCE_OP(OP) \ 21 | void BigMPI_##OP##_x(void * invec, void * inoutvec, int * len, MPI_Datatype * type) \ 22 | { \ 23 | MPI_Reduce_local(invec,inoutvec,*len,*type,MPI_##OP); \ 24 | } 25 | 26 | /* Create a BigMPI__x for all built-in ops. */ 27 | PASTE_BIGMPI_REDUCE_OP(MAX) 28 | PASTE_BIGMPI_REDUCE_OP(MIN) 29 | PASTE_BIGMPI_REDUCE_OP(SUM) 30 | PASTE_BIGMPI_REDUCE_OP(PROD) 31 | PASTE_BIGMPI_REDUCE_OP(LAND) 32 | PASTE_BIGMPI_REDUCE_OP(BAND) 33 | PASTE_BIGMPI_REDUCE_OP(LOR) 34 | PASTE_BIGMPI_REDUCE_OP(BOR) 35 | PASTE_BIGMPI_REDUCE_OP(LXOR) 36 | PASTE_BIGMPI_REDUCE_OP(BXOR) 37 | PASTE_BIGMPI_REDUCE_OP(MAXLOC) 38 | PASTE_BIGMPI_REDUCE_OP(MINLOC) 39 | 40 | #undef PASTE_BIGMPI_REDUCE_OP 41 | 42 | int BigMPI_Op_create(MPI_Op op, MPI_Op * userop) 43 | { 44 | int commute; 45 | MPI_Op_commutative(op, &commute); 46 | 47 | MPI_User_function * bigfn = NULL; 48 | 49 | if (op==MPI_MAX) bigfn = BigMPI_MAX_x; 50 | else if (op==MPI_MIN) bigfn = BigMPI_MIN_x; 51 | else if (op==MPI_SUM) bigfn = BigMPI_SUM_x; 52 | else if (op==MPI_PROD) bigfn = BigMPI_PROD_x; 53 | else if (op==MPI_LAND) bigfn = BigMPI_LAND_x; 54 | else if (op==MPI_BAND) bigfn = BigMPI_BAND_x; 55 | else if (op==MPI_LOR) bigfn = BigMPI_LOR_x; 56 | else if (op==MPI_BOR) bigfn = BigMPI_BOR_x; 57 | else if (op==MPI_LXOR) bigfn = BigMPI_LXOR_x; 58 | else if (op==MPI_BXOR) bigfn = BigMPI_BXOR_x; 59 | else if (op==MPI_MAXLOC) bigfn = BigMPI_MAXLOC_x; 60 | else if (op==MPI_MINLOC) bigfn = BigMPI_MINLOC_x; 61 | else { 62 | fprintf(stderr,"BigMPI does not support this op. Sorry. \n"); 63 | MPI_Abort(MPI_COMM_WORLD,1); 64 | } 65 | return MPI_Op_create(bigfn, commute, userop); 66 | } 67 | 68 | int BigMPI_Allreduce(const void *sendbuf, void *recvbuf, int count, 69 | MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) 70 | { 71 | MPI_Op userop; 72 | BigMPI_Op_create(op, &userop); 73 | MPI_Allreduce(sendbuf, recvbuf, count, datatype, userop, comm); 74 | MPI_Op_free(&userop); 75 | return MPI_SUCCESS; 76 | } 77 | 78 | int main(int argc, char * argv[]) 79 | { 80 | MPI_Init(&argc, &argv); 81 | 82 | int rank, size; 83 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 84 | MPI_Comm_size(MPI_COMM_WORLD, &size); 85 | 86 | int n = (argc > 1) ? atoi(argv[1]) : 1000; 87 | 88 | double * sbuf1 = NULL; 89 | double * rbuf1 = NULL; 90 | double * sbuf2 = NULL; 91 | double * rbuf2 = NULL; 92 | 93 | MPI_Aint bytes = n*sizeof(double); 94 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &sbuf1); 95 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &rbuf1); 96 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &sbuf2); 97 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &rbuf2); 98 | 99 | for (int i=0; i0) { 123 | printf("There were %d errors out of %d elements!\n", error1, n); 124 | for (int i=0; i0) { 132 | printf("There were %d errors out of %d elements!\n", error2, n); 133 | for (int i=0; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | const int bigmpi_int_max = INT_MAX; 10 | 11 | int MPIX_Type_contiguous_x(MPI_Count count, MPI_Datatype oldtype, MPI_Datatype * newtype) 12 | { 13 | MPI_Count c = count/bigmpi_int_max; 14 | MPI_Count r = count%bigmpi_int_max; 15 | 16 | MPI_Datatype chunks; 17 | MPI_Type_vector(c, bigmpi_int_max, bigmpi_int_max, oldtype, &chunks); 18 | 19 | MPI_Datatype remainder; 20 | MPI_Type_contiguous(r, oldtype, &remainder); 21 | 22 | MPI_Aint lb /* unused */, extent; 23 | MPI_Type_get_extent(oldtype, &lb, &extent); 24 | 25 | MPI_Aint remdisp = (MPI_Aint)c*bigmpi_int_max*extent; 26 | int blocklengths[2] = {1,1}; 27 | MPI_Aint displacements[2] = {0,remdisp}; 28 | MPI_Datatype types[2] = {chunks,remainder}; 29 | MPI_Type_create_struct(2, blocklengths, displacements, types, newtype); 30 | 31 | MPI_Type_free(&chunks); 32 | MPI_Type_free(&remainder); 33 | 34 | return MPI_SUCCESS; 35 | } 36 | 37 | int main(int argc, char* argv[]) 38 | { 39 | int rank=0, size=1; 40 | MPI_Init(&argc, &argv); 41 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 42 | MPI_Comm_size(MPI_COMM_WORLD, &size); 43 | 44 | int n = (argc>1) ? atoi(argv[1]) : 10000; 45 | //MPI_Datatype * dtout = malloc(n*sizeof(MPI_Datatype)); 46 | MPI_Datatype dtout; 47 | double t0 = MPI_Wtime(); 48 | for (int i=0; i 2 | #include 3 | #include 4 | 5 | int piggysize = 8; 6 | MPI_Datatype piggytype = MPI_CHAR; 7 | char piggybuf[8] = "01234567"; 8 | 9 | int MPIX_Type_piggy_x(int count, MPI_Datatype oldtype, MPI_Datatype * newtype) 10 | { 11 | int size; 12 | MPI_Type_size(oldtype,&size); 13 | 14 | int blocklengths[2] = {count,piggysize}; 15 | MPI_Aint displacements[2] = {0,(MPI_Aint)count * (MPI_Aint)size}; 16 | MPI_Datatype types[2] = {oldtype,piggytype}; 17 | MPI_Type_create_struct(2, blocklengths, displacements, types, newtype); 18 | 19 | return MPI_SUCCESS; 20 | } 21 | 22 | int main(int argc, char* argv[]) 23 | { 24 | int rank=0, size=1; 25 | MPI_Init(&argc, &argv); 26 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 27 | MPI_Comm_size(MPI_COMM_WORLD, &size); 28 | 29 | int n = (argc>1) ? atoi(argv[1]) : 10000; 30 | //MPI_Datatype * dtout = malloc(n*sizeof(MPI_Datatype)); 31 | MPI_Datatype dtout; 32 | double t0 = MPI_Wtime(); 33 | for (int i=0; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "bigmpi.h" 10 | #include "verify_buffer.h" 11 | 12 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 13 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 14 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 15 | 16 | int main(int argc, char * argv[]) 17 | { 18 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 19 | 20 | MPI_Init(&argc, &argv); 21 | 22 | int rank, size; 23 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 24 | MPI_Comm_size(MPI_COMM_WORLD, &size); 25 | 26 | if (size<1) { 27 | printf("Use 1 or more processes. \n"); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | int l = (argc > 1) ? atoi(argv[1]) : 2; 33 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 34 | MPI_Count n = l * test_int_max + m; 35 | 36 | char * buf_send = NULL; 37 | char * buf_recv = NULL; 38 | 39 | MPI_Alloc_mem((MPI_Aint)n * 1, MPI_INFO_NULL, &buf_send); 40 | assert(buf_send!=NULL); 41 | MPI_Alloc_mem((MPI_Aint)n * size, MPI_INFO_NULL, &buf_recv); 42 | assert(buf_recv!=NULL); 43 | 44 | for (MPI_Count j = 0; j < n; ++j) { 45 | buf_send[j] = (unsigned char)rank; 46 | } 47 | memset(buf_recv, -1, (size_t)n); 48 | 49 | /* collective communication */ 50 | MPIX_Allgather_x(buf_send, n, MPI_CHAR, 51 | buf_recv, n, MPI_CHAR, 52 | MPI_COMM_WORLD); 53 | 54 | size_t errors = 0; 55 | for (int i = 0; i < size; ++i) { 56 | errors += verify_buffer(buf_recv + i * n, n, i); 57 | } 58 | 59 | MPI_Free_mem(buf_send); 60 | MPI_Free_mem(buf_recv); 61 | 62 | if (rank==0 && errors==0) { 63 | printf("SUCCESS\n"); 64 | } 65 | 66 | MPI_Finalize(); 67 | 68 | int rc = (errors > 0) ? 1 : 0; 69 | return rc; 70 | } 71 | -------------------------------------------------------------------------------- /test/test_allreduce_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 18 | 19 | MPI_Init(&argc, &argv); 20 | 21 | int rank, size; 22 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 23 | MPI_Comm_size(MPI_COMM_WORLD, &size); 24 | 25 | if (size<1) { 26 | printf("Use 1 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | double * sbuf = NULL; 36 | double * rbuf = NULL; 37 | 38 | MPI_Aint bytes = n*sizeof(double); 39 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &sbuf); 40 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &rbuf); 41 | 42 | for (MPI_Count i=0; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "bigmpi.h" 10 | #include "verify_buffer.h" 11 | 12 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 13 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 14 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 15 | 16 | int main(int argc, char * argv[]) 17 | { 18 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 19 | 20 | MPI_Init(&argc, &argv); 21 | 22 | int rank, size; 23 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 24 | MPI_Comm_size(MPI_COMM_WORLD, &size); 25 | 26 | if (size<1) { 27 | printf("Use 1 or more processes. \n"); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | int l = (argc > 1) ? atoi(argv[1]) : 2; 33 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 34 | MPI_Count n = l * test_int_max + m; 35 | 36 | char * buf_send = NULL; 37 | char * buf_recv = NULL; 38 | 39 | MPI_Alloc_mem((MPI_Aint)n * size, MPI_INFO_NULL, &buf_send); 40 | assert(buf_send!=NULL); 41 | MPI_Alloc_mem((MPI_Aint)n * size, MPI_INFO_NULL, &buf_recv); 42 | assert(buf_recv!=NULL); 43 | 44 | for (int i = 0; i < size; ++i) { 45 | for (MPI_Count j = 0; j < n; ++j) { 46 | buf_send[i*n+j] = (unsigned char)i; 47 | } 48 | } 49 | memset(buf_recv, -1, (size_t)n); 50 | 51 | /* collective communication */ 52 | MPIX_Alltoall_x(buf_send, n, MPI_CHAR, 53 | buf_recv, n, MPI_CHAR, 54 | MPI_COMM_WORLD); 55 | 56 | size_t errors = verify_buffer(buf_recv, n, rank); 57 | 58 | MPI_Free_mem(buf_send); 59 | MPI_Free_mem(buf_recv); 60 | 61 | if (rank==0 && errors==0) { 62 | printf("SUCCESS\n"); 63 | } 64 | 65 | MPI_Finalize(); 66 | 67 | int rc = (errors > 0) ? 1 : 0; 68 | return rc; 69 | } 70 | -------------------------------------------------------------------------------- /test/test_assert_x.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014. See LICENSE in top-level directory. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include "bigmpi.h" 11 | 12 | int main(int argc, char ** argv) 13 | { 14 | MPI_Init(&argc, &argv); 15 | assert(0); 16 | MPI_Finalize(); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/test_bcast_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 18 | 19 | MPI_Init(&argc, &argv); 20 | 21 | int rank, size; 22 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 23 | MPI_Comm_size(MPI_COMM_WORLD, &size); 24 | 25 | if (size<1) { 26 | printf("Use 1 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank==0 ? size : 0, (size_t)n); 40 | 41 | /* collective communication */ 42 | MPIX_Bcast_x(buf, n, MPI_CHAR, 0 /* root */, MPI_COMM_WORLD); 43 | 44 | size_t errors = verify_buffer(buf, n, size); 45 | if (errors > 0) { 46 | printf("There were %zu errors!", errors); 47 | for (size_t i=0; i<(size_t)n; i++) { 48 | printf("buf[%zu] = %d (expected %d)\n", i, buf[i], size); 49 | } 50 | } 51 | if (rank==0 && errors==0) { 52 | printf("SUCCESS\n"); 53 | } 54 | 55 | MPI_Free_mem(buf); 56 | 57 | MPI_Finalize(); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /test/test_contig_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "bigmpi.h" 7 | 8 | 9 | static void print_typename(MPI_Datatype type) 10 | { 11 | char * name; 12 | if (type==MPI_CHAR ) name="MPI_CHAR "; 13 | else if (type==MPI_SIGNED_CHAR ) name="MPI_SIGNED_CHAR "; 14 | else if (type==MPI_UNSIGNED_CHAR ) name="MPI_UNSIGNED_CHAR "; 15 | else if (type==MPI_BYTE ) name="MPI_BYTE "; 16 | else if (type==MPI_WCHAR ) name="MPI_WCHAR "; 17 | else if (type==MPI_SHORT ) name="MPI_SHORT "; 18 | else if (type==MPI_UNSIGNED_SHORT ) name="MPI_UNSIGNED_SHORT "; 19 | else if (type==MPI_INT ) name="MPI_INT "; 20 | else if (type==MPI_UNSIGNED ) name="MPI_UNSIGNED "; 21 | else if (type==MPI_LONG ) name="MPI_LONG "; 22 | else if (type==MPI_UNSIGNED_LONG ) name="MPI_UNSIGNED_LONG "; 23 | else if (type==MPI_FLOAT ) name="MPI_FLOAT "; 24 | else if (type==MPI_DOUBLE ) name="MPI_DOUBLE "; 25 | else if (type==MPI_LONG_DOUBLE ) name="MPI_LONG_DOUBLE "; 26 | else if (type==MPI_LONG_LONG_INT ) name="MPI_LONG_LONG_INT "; 27 | else if (type==MPI_LONG_LONG ) name="MPI_LONG_LONG "; 28 | else if (type==MPI_UNSIGNED_LONG_LONG) name="MPI_UNSIGNED_LONG_LONG"; 29 | else name="NOT_PREDEFINED_TYPE "; 30 | printf("type = %s\n", name); 31 | return; 32 | } 33 | 34 | int main(int argc, char* argv[]) 35 | { 36 | const int e = 60; 37 | 38 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 39 | 40 | MPI_Init(&argc, &argv); 41 | 42 | int rank, size; 43 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 44 | MPI_Comm_size(MPI_COMM_WORLD, &size); 45 | 46 | MPI_Count n = 1; 47 | int errors = 0; 48 | for (int i=0; iINT_MAX || n>=(test_int_max*test_int_max) ) { 76 | MPI_Finalize(); 77 | return errors; 78 | } 79 | } 80 | } 81 | MPI_Finalize(); 82 | return errors; 83 | } 84 | -------------------------------------------------------------------------------- /test/test_factorize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __x86_64__ 10 | static inline unsigned long long rdtsc(void) 11 | { 12 | unsigned hi, lo; 13 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 14 | return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); 15 | } 16 | #endif 17 | 18 | /* This function is copied from src/type_contiguous_x.c and must be updated 19 | * manually if the implementation changes. It is an internal function so 20 | * it is static and therefore be cannot call the symbol from the library. */ 21 | 22 | /* 23 | * Synopsis 24 | * 25 | * int BigMPI_Factorize_count(MPI_Count c, int * a, int *b) 26 | * 27 | * Input Parameter 28 | * 29 | * c large count 30 | * 31 | * Output Parameters 32 | * 33 | * a, b integers such that c=a*b and a,blo; g--) { 44 | size_t rem = in%g; 45 | if (rem==0) { 46 | *a = (int)g; 47 | *b = (int)(in/g); 48 | return 0; 49 | } 50 | } 51 | *a = -1; 52 | *b = -1; 53 | return 1; 54 | } 55 | 56 | #define TIMING 57 | #define DEBUG 58 | 59 | int main(int argc, char* argv[]) 60 | { 61 | int rank=0, size=1; 62 | #ifdef PARALLEL 63 | MPI_Init(&argc, &argv); 64 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 65 | MPI_Comm_size(MPI_COMM_WORLD, &size); 66 | #endif 67 | MPI_Count max = (argc>1) ? atol(argv[1]) : 1LL<<60; 68 | MPI_Count inc = size; /* Incremement by nproc to distribute test work. */ 69 | 70 | #ifdef TIMING 71 | #ifdef PARALLEL 72 | double t0 = MPI_Wtime(); 73 | #else 74 | unsigned long long t0 = rdtsc(); 75 | #endif 76 | #endif 77 | for (MPI_Count count=1; count 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 18 | 19 | MPI_Init(&argc, &argv); 20 | 21 | int rank, size; 22 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 23 | MPI_Comm_size(MPI_COMM_WORLD, &size); 24 | 25 | if (size<1) { 26 | printf("Use 1 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf_send = NULL; 36 | char * buf_recv = NULL; 37 | 38 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf_send); 39 | MPI_Alloc_mem((MPI_Aint)n * size, MPI_INFO_NULL, &buf_recv); 40 | 41 | memset(buf_send, rank, (size_t)n); 42 | memset(buf_recv, -1, (size_t)n * size); 43 | 44 | /* collective communication */ 45 | MPIX_Gather_x(buf_send, n, MPI_CHAR, 46 | buf_recv, n, MPI_CHAR, 47 | 0 /* root */, MPI_COMM_WORLD); 48 | 49 | size_t errors = 0; 50 | if (rank==0) { 51 | for (int i = 0; i < size; ++i) { 52 | errors += verify_buffer(buf_recv + i * n, n, i); 53 | } 54 | } 55 | 56 | /* collective communication */ 57 | MPIX_Allgather_x(buf_send, n, MPI_CHAR, 58 | buf_recv, n, MPI_CHAR, 59 | MPI_COMM_WORLD); 60 | 61 | for (int i = 0; i < size; ++i) { 62 | errors += verify_buffer(buf_recv + i * n, n, i); 63 | } 64 | 65 | MPI_Free_mem(buf_send); 66 | MPI_Free_mem(buf_recv); 67 | 68 | if (rank==0 && errors==0) { 69 | printf("SUCCESS\n"); 70 | } 71 | 72 | MPI_Finalize(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /test/test_irsend_irecv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | MPI_Request req; 45 | 46 | /* pairwise communication */ 47 | if (rank==r) { 48 | MPIX_Irsend_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD, &req); 49 | } 50 | else if (rank==0) { 51 | MPIX_Irecv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, &req); 52 | } 53 | 54 | if (rank == 0 || rank==r) { 55 | MPI_Wait(&req, MPI_STATUS_IGNORE); 56 | } 57 | 58 | if (rank==0) { 59 | errors += verify_buffer(buf, n, r); 60 | if (errors > 0) { 61 | printf("There were %zu errors!", errors); 62 | } 63 | } 64 | } 65 | 66 | MPI_Free_mem(buf); 67 | 68 | if (rank==0 && errors==0) { 69 | printf("SUCCESS\n"); 70 | } 71 | 72 | MPI_Finalize(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /test/test_isend_irecv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | MPI_Request req; 45 | 46 | /* pairwise communication */ 47 | if (rank==r) { 48 | MPIX_Isend_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD, &req); 49 | } 50 | else if (rank==0) { 51 | MPIX_Irecv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, &req); 52 | } 53 | 54 | if (rank == 0 || rank==r) { 55 | MPI_Wait(&req, MPI_STATUS_IGNORE); 56 | } 57 | 58 | if (rank==0) { 59 | errors += verify_buffer(buf, n, r); 60 | if (errors > 0) { 61 | printf("There were %zu errors!", errors); 62 | } 63 | } 64 | } 65 | 66 | MPI_Free_mem(buf); 67 | 68 | if (rank==0 && errors==0) { 69 | printf("SUCCESS\n"); 70 | } 71 | 72 | MPI_Finalize(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /test/test_issend_irecv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | MPI_Request req; 45 | 46 | /* pairwise communication */ 47 | if (rank==r) { 48 | MPIX_Issend_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD, &req); 49 | } 50 | else if (rank==0) { 51 | MPIX_Irecv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, &req); 52 | } 53 | 54 | if (rank == 0 || rank==r) { 55 | MPI_Wait(&req, MPI_STATUS_IGNORE); 56 | } 57 | 58 | if (rank==0) { 59 | errors += verify_buffer(buf, n, r); 60 | if (errors > 0) { 61 | printf("There were %zu errors!", errors); 62 | } 63 | } 64 | } 65 | 66 | MPI_Free_mem(buf); 67 | 68 | if (rank==0 && errors==0) { 69 | printf("SUCCESS\n"); 70 | } 71 | 72 | MPI_Finalize(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /test/test_reduce_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 18 | 19 | MPI_Init(&argc, &argv); 20 | 21 | int rank, size; 22 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 23 | MPI_Comm_size(MPI_COMM_WORLD, &size); 24 | 25 | if (size<1) { 26 | printf("Use 1 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | double * sbuf = NULL; 36 | double * rbuf = NULL; 37 | 38 | MPI_Aint bytes = n*sizeof(double); 39 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &sbuf); 40 | MPI_Alloc_mem(bytes, MPI_INFO_NULL, &rbuf); 41 | 42 | for (MPI_Count i=0; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | #if MPI_VERSION >= 3 18 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 19 | 20 | MPI_Init(&argc, &argv); 21 | 22 | int rank, size; 23 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 24 | MPI_Comm_size(MPI_COMM_WORLD, &size); 25 | 26 | int l = (argc > 1) ? atoi(argv[1]) : 2; 27 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 28 | MPI_Count n = l * test_int_max + m; 29 | MPI_Count c = n/sizeof(double); 30 | 31 | double * baseptr = NULL; 32 | MPI_Win win; 33 | /* Allocate all the window memory on rank 0 */ 34 | MPI_Win_allocate((MPI_Aint)(rank==0 ? n : 0), sizeof(double), MPI_INFO_NULL, MPI_COMM_WORLD, &baseptr, &win); 35 | MPI_Win_lock_all(0, win); 36 | 37 | if (rank==0) { 38 | set_doubles(baseptr, c, 0.0); 39 | MPI_Win_sync(win); 40 | } 41 | MPI_Barrier(MPI_COMM_WORLD); 42 | 43 | double * buf = NULL; 44 | if ((size==1 && rank==0) || rank==1) { 45 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 46 | set_doubles(buf, c, 7.0); 47 | MPIX_Put_x(buf, c, MPI_DOUBLE, 0 /* target */, 0 /* disp */, c, MPI_DOUBLE, win); 48 | set_doubles(buf, c, 17.0); 49 | MPIX_Accumulate_x(buf, c, MPI_DOUBLE, 0 /* target */, 0 /* disp */, c, MPI_DOUBLE, MPI_SUM, win); 50 | set_doubles(buf, c, 0.0); 51 | MPIX_Get_x(buf, c, MPI_DOUBLE, 0 /* target */, 0 /* disp */, c, MPI_DOUBLE, win); 52 | 53 | double expected = 7.0 + 17.0; 54 | size_t errors = verify_doubles(buf, c, expected); 55 | if (errors > 0) { 56 | printf("There were %zu errors!", errors); 57 | for (size_t i=0; i<(size_t)c; i++) { 58 | printf("buf[%zu] = %lf (expected %lf)\n", i, buf[i], expected); 59 | } 60 | } 61 | if (errors==0) { 62 | printf("SUCCESS\n"); 63 | } 64 | } 65 | 66 | MPI_Win_unlock_all(win); 67 | MPI_Win_free(&win); 68 | 69 | MPI_Finalize(); 70 | 71 | #endif 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /test/test_rma_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "bigmpi.h" 10 | #include "verify_buffer.h" 11 | 12 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 13 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 14 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 15 | 16 | int main(int argc, char * argv[]) 17 | { 18 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 19 | 20 | MPI_Init(&argc, &argv); 21 | 22 | int rank, size; 23 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 24 | MPI_Comm_size(MPI_COMM_WORLD, &size); 25 | 26 | int l = (argc > 1) ? atoi(argv[1]) : 2; 27 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 28 | MPI_Count n = l * test_int_max + m; 29 | 30 | double * baseptr = NULL; 31 | MPI_Win win; 32 | MPI_Aint winsize = (rank==0 ? n : 0); 33 | #if MPI_VERSION >= 3 34 | /* Allocate all the window memory on rank 0 */ 35 | MPI_Win_allocate(winsize, sizeof(double), MPI_INFO_NULL, MPI_COMM_WORLD, &baseptr, &win); 36 | MPI_Win_lock_all(0, win); 37 | #else 38 | MPI_Alloc_mem(winsize*sizeof(double), MPI_INFO_NULL, &baseptr); 39 | MPI_Win_create(baseptr, size, sizeof(double), MPI_INFO_NULL, MPI_COMM_WORLD, &win); 40 | #endif 41 | 42 | if (rank==0) { 43 | for (size_t i=0; i<(n/sizeof(double)); i++) { 44 | baseptr[i] = 0.0; 45 | } 46 | #if MPI_VERSION >= 3 47 | MPI_Win_sync(win); 48 | #endif 49 | } 50 | MPI_Barrier(MPI_COMM_WORLD); 51 | 52 | double * buf = NULL; 53 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 54 | for (size_t i=0; i<(n/sizeof(double)); i++) { 55 | buf[i] = 1.0; 56 | } 57 | 58 | #if MPI_VERSION < 3 59 | MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0 /* target */, 0 /* assert */, win); 60 | #endif 61 | MPIX_Accumulate_x(buf, n/sizeof(double), MPI_DOUBLE, 62 | 0 /* target */, 0 /* disp */, n/sizeof(double), MPI_DOUBLE, MPI_SUM, win); 63 | #if MPI_VERSION >= 3 64 | MPI_Win_flush(0,win); 65 | #else 66 | MPI_Win_unlock(0,win); 67 | #endif 68 | 69 | MPI_Barrier(MPI_COMM_WORLD); 70 | 71 | if (rank==0) { 72 | #if MPI_VERSION >= 3 73 | MPI_Win_sync(win); 74 | #endif 75 | double expected = size; 76 | size_t errors = verify_doubles(baseptr, n/sizeof(double), expected); 77 | if (errors > 0) { 78 | printf("There were %zu errors!", errors); 79 | for (size_t i=0; i<(n/(sizeof(double))); i++) { 80 | printf("baseptr[%zu] = %lf (expected %lf)\n", i, baseptr[i], expected); 81 | } 82 | } 83 | if (errors==0) { 84 | printf("SUCCESS\n"); 85 | } 86 | } 87 | 88 | #if MPI_VERSION >= 3 89 | MPI_Win_unlock_all(win); 90 | #endif 91 | MPI_Win_free(&win); 92 | #if MPI_VERSION < 3 93 | MPI_Free_mem(baseptr); 94 | #endif 95 | 96 | MPI_Finalize(); 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /test/test_rsend_recv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | /* pairwise communication */ 45 | if (rank==r) { 46 | MPIX_Rsend_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD); 47 | } 48 | else if (rank==0) { 49 | MPIX_Recv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 50 | 51 | errors += verify_buffer(buf, n, r); 52 | if (errors > 0) { 53 | printf("There were %zu errors!", errors); 54 | } 55 | } 56 | } 57 | 58 | MPI_Free_mem(buf); 59 | 60 | if (rank==0 && errors==0) { 61 | printf("SUCCESS\n"); 62 | } 63 | 64 | MPI_Finalize(); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /test/test_scatter_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "bigmpi.h" 10 | #include "verify_buffer.h" 11 | 12 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 13 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 14 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 15 | 16 | int main(int argc, char * argv[]) 17 | { 18 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 19 | 20 | MPI_Init(&argc, &argv); 21 | 22 | int rank, size; 23 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 24 | MPI_Comm_size(MPI_COMM_WORLD, &size); 25 | 26 | if (size<1) { 27 | printf("Use 1 or more processes. \n"); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | int l = (argc > 1) ? atoi(argv[1]) : 2; 33 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 34 | MPI_Count n = l * test_int_max + m; 35 | 36 | char * buf_send = NULL; 37 | char * buf_recv = NULL; 38 | 39 | MPI_Alloc_mem((MPI_Aint)n * size, MPI_INFO_NULL, &buf_send); 40 | assert(buf_send!=NULL); 41 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf_recv); 42 | assert(buf_recv!=NULL); 43 | 44 | if (rank==0) { 45 | for (int i = 0; i < size; ++i) { 46 | for (MPI_Count j = 0; j < n; ++j) { 47 | buf_send[i*n+j] = (unsigned char)i; 48 | } 49 | } 50 | } 51 | memset(buf_recv, -1, (size_t)n); 52 | 53 | /* collective communication */ 54 | MPIX_Scatter_x(buf_send, n, MPI_CHAR, 55 | buf_recv, n, MPI_CHAR, 56 | 0 /* root */, MPI_COMM_WORLD); 57 | 58 | size_t errors = verify_buffer(buf_recv, n, rank); 59 | 60 | MPI_Free_mem(buf_send); 61 | MPI_Free_mem(buf_recv); 62 | 63 | if (rank==0 && errors==0) { 64 | printf("SUCCESS\n"); 65 | } 66 | 67 | MPI_Finalize(); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /test/test_send_recv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | /* pairwise communication */ 45 | if (rank==r) { 46 | MPIX_Send_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD); 47 | } 48 | else if (rank==0) { 49 | MPIX_Recv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 50 | 51 | errors += verify_buffer(buf, n, r); 52 | if (errors > 0) { 53 | printf("There were %zu errors!", errors); 54 | } 55 | } 56 | } 57 | 58 | MPI_Free_mem(buf); 59 | 60 | if (rank==0 && errors==0) { 61 | printf("SUCCESS\n"); 62 | } 63 | 64 | MPI_Finalize(); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /test/test_sendrecv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf_send = NULL; 36 | char * buf_recv = NULL; 37 | 38 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf_send); 39 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf_recv); 40 | 41 | memset(buf_send, rank, (size_t)n); 42 | memset(buf_recv, rank, (size_t)n); 43 | 44 | size_t errors = 0; 45 | 46 | for (int r = 1; r < size; r++) { 47 | 48 | /* pairwise communication */ 49 | if (rank==r) { 50 | MPIX_Sendrecv_x(buf_send, n, MPI_CHAR, 0 /* dst */, r /* tag */, 51 | buf_recv, n, MPI_CHAR, 0 /* src */, r /* tag */, 52 | MPI_COMM_WORLD, MPI_STATUS_IGNORE); 53 | 54 | errors = verify_buffer(buf_recv, n, 0); 55 | if (errors > 0) { 56 | printf("There were %zu errors!\n", errors); 57 | for (size_t i=0; i<(size_t)n; i++) { 58 | printf("buf_recv[%zu] = %d (expected %d)\n", i, buf_recv[i], r); 59 | } 60 | } 61 | } 62 | else if (rank==0) { 63 | MPIX_Sendrecv_x(buf_send, n, MPI_CHAR, r /* dst */, r /* tag */, 64 | buf_recv, n, MPI_CHAR, r /* src */, r /* tag */, 65 | MPI_COMM_WORLD, MPI_STATUS_IGNORE); 66 | 67 | errors = verify_buffer(buf_recv, n, r); 68 | if (errors > 0) { 69 | printf("There were %zu errors!\n", errors); 70 | for (size_t i=0; i<(size_t)n; i++) { 71 | printf("buf_recv[%zu] = %d (expected %d)\n", i, buf_recv[i], r); 72 | } 73 | } 74 | } 75 | } 76 | 77 | MPI_Free_mem(buf_send); 78 | MPI_Free_mem(buf_recv); 79 | 80 | if (rank==0 && errors==0) { 81 | printf("SUCCESS\n"); 82 | } 83 | 84 | MPI_Finalize(); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /test/test_ssend_recv_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "bigmpi.h" 9 | #include "verify_buffer.h" 10 | 11 | /* Yes, it is technically unsafe to cast MPI_Count to MPI_Aint or size_t without checking, 12 | * given that MPI_Count might be 128b and MPI_Aint and size_t might be 64b, but BigMPI 13 | * does not aspire to support communication of more than 8 EiB messages at a time. */ 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | MPI_Init(&argc, &argv); 18 | 19 | int rank, size; 20 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 21 | MPI_Comm_size(MPI_COMM_WORLD, &size); 22 | 23 | const MPI_Count test_int_max = BigMPI_Get_max_int(); 24 | 25 | if (size<2) { 26 | printf("Use 2 or more processes. \n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | int l = (argc > 1) ? atoi(argv[1]) : 2; 32 | int m = (argc > 2) ? atoi(argv[2]) : 17777; 33 | MPI_Count n = l * test_int_max + m; 34 | 35 | char * buf = NULL; 36 | 37 | MPI_Alloc_mem((MPI_Aint)n, MPI_INFO_NULL, &buf); 38 | 39 | memset(buf, rank, (size_t)n); 40 | 41 | size_t errors = 0; 42 | for (int r = 1; r < size; r++) { 43 | 44 | /* pairwise communication */ 45 | if (rank==r) { 46 | MPIX_Ssend_x(buf, n, MPI_CHAR, 0 /* dst */, r /* tag */, MPI_COMM_WORLD); 47 | } 48 | else if (rank==0) { 49 | MPIX_Recv_x(buf, n, MPI_CHAR, r /* src */, r /* tag */, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 50 | 51 | errors += verify_buffer(buf, n, r); 52 | if (errors > 0) { 53 | printf("There were %zu errors!", errors); 54 | } 55 | } 56 | } 57 | 58 | MPI_Free_mem(buf); 59 | 60 | if (rank==0 && errors==0) { 61 | printf("SUCCESS\n"); 62 | } 63 | 64 | MPI_Finalize(); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /test/verify_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef VERIFY_BUFFER_H 2 | #define VERIFY_BUFFER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | /* This is the generic buffer verification for when char is the 12 | * type and we use memset for assignment. */ 13 | static size_t verify_buffer(char *buf, MPI_Count count, int expected_value) 14 | { 15 | assert(count1.e-4) errors++; 32 | } 33 | return errors; 34 | } 35 | 36 | static void set_doubles(double *buf, MPI_Count count, double value) 37 | { 38 | assert(count, and then modified for Julia 4 | 5 | set -e 6 | set -x 7 | 8 | os=`uname` 9 | MPI_IMPL="$1" 10 | 11 | case "$os" in 12 | Darwin) 13 | echo "Mac" 14 | brew update 15 | case "$MPI_IMPL" in 16 | mpich|mpich3) 17 | brew install mpich 18 | ;; 19 | openmpi) 20 | brew install openmpi 21 | ;; 22 | *) 23 | echo "Unknown MPI implementation: $MPI_IMPL" 24 | exit 10 25 | ;; 26 | esac 27 | ;; 28 | 29 | Linux) 30 | echo "Linux" 31 | sudo apt-get update -q 32 | case "$MPI_IMPL" in 33 | mpich1) 34 | sudo apt-get install -q cmake gfortran mpich-shmem-bin libmpich-shmem1.0-dev 35 | ;; 36 | mpich2) 37 | sudo apt-get install -q cmake gfortran mpich2 libmpich2-3 libmpich2-dev 38 | ;; 39 | mpich|mpich3) 40 | sudo apt-get install -q cmake gfortran libcr0 default-jdk 41 | wget -q http://www.cebacad.net/files/mpich/ubuntu/mpich-3.2b3/mpich_3.2b3-1ubuntu_amd64.deb 42 | sudo dpkg -i ./mpich_3.2b3-1ubuntu_amd64.deb 43 | ;; 44 | openmpi) 45 | sudo apt-get install -q cmake gfortran openmpi-bin openmpi-common libopenmpi-dev 46 | ;; 47 | *) 48 | echo "Unknown MPI implementation: $MPI_IMPL" 49 | exit 20 50 | ;; 51 | esac 52 | ;; 53 | esac 54 | -------------------------------------------------------------------------------- /travis/install-mpi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This configuration file was taken originally from the mpi4py project 3 | # , and then modified for Julia 4 | 5 | set -e 6 | set -x 7 | 8 | os=`uname` 9 | TRAVIS_ROOT="$1" 10 | MPI_IMPL="$2" 11 | 12 | # this is where updated Autotools will be for Linux 13 | export PATH=$TRAVIS_ROOT/bin:$PATH 14 | 15 | case "$os" in 16 | Darwin) 17 | echo "Mac" 18 | brew update 19 | case "$MPI_IMPL" in 20 | mpich) 21 | brew info mpich 22 | brew install mpich 23 | ;; 24 | openmpi) 25 | brew info open-mpi 26 | brew install openmpi 27 | ;; 28 | *) 29 | echo "Unknown MPI implementation: $MPI_IMPL" 30 | exit 10 31 | ;; 32 | esac 33 | ;; 34 | 35 | Linux) 36 | echo "Linux" 37 | case "$MPI_IMPL" in 38 | mpich) 39 | if [ ! -d "$TRAVIS_ROOT/mpich" ]; then 40 | wget --no-check-certificate http://www.mpich.org/static/downloads/3.2/mpich-3.2.tar.gz 41 | tar -xzf mpich-3.2.tar.gz 42 | cd mpich-3.2 43 | mkdir build && cd build 44 | ../configure CFLAGS="-w" --prefix=$TRAVIS_ROOT/mpich --disable-fortran --disable-static 45 | make -j2 46 | make install 47 | else 48 | echo "MPICH already installed" 49 | fi 50 | ;; 51 | openmpi) 52 | if [ ! -d "$TRAVIS_ROOT/open-mpi" ]; then 53 | wget --no-check-certificate https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.2.tar.bz2 54 | tar -xjf openmpi-2.0.2.tar.bz2 55 | cd openmpi-2.0.2 56 | mkdir build && cd build 57 | ../configure CFLAGS="-w" --prefix=$TRAVIS_ROOT/open-mpi \ 58 | --without-verbs --without-fca --without-mxm --without-ucx \ 59 | --without-portals4 --without-psm --without-psm2 \ 60 | --without-libfabric --without-usnic \ 61 | --without-udreg --without-ugni --without-xpmem \ 62 | --without-alps --without-munge \ 63 | --without-sge --without-loadleveler --without-tm \ 64 | --without-lsf --without-slurm \ 65 | --without-pvfs2 --without-plfs \ 66 | --without-cuda --disable-oshmem \ 67 | --disable-mpi-fortran --disable-oshmem-fortran \ 68 | --disable-libompitrace \ 69 | --disable-static \ 70 | --enable-mpi-thread-multiple 71 | make -j2 72 | make install 73 | else 74 | echo "Open-MPI already installed" 75 | fi 76 | ;; 77 | *) 78 | echo "Unknown MPI implementation: $MPI_IMPL" 79 | exit 20 80 | ;; 81 | esac 82 | ;; 83 | esac 84 | --------------------------------------------------------------------------------