--- /dev/null
+/* Copyright (c) 2013-2014. The SimGrid Team.
+ * All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ * University Research and Technology
+ * Corporation. All rights reserved.
+ * Copyright (c) 2004-2006 The University of Tennessee and The University
+ * of Tennessee Research Foundation. All rights
+ * reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ * University of Stuttgart. All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Additional copyrights may follow
+ */
+
+ /* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* Copyright (c) 2001-2014, The Ohio State University. All rights
+ * reserved.
+ *
+ * This file is part of the MVAPICH2 software package developed by the
+ * team members of The Ohio State University's Network-Based Computing
+ * Laboratory (NBCL), headed by Professor Dhabaleswar K. (DK) Panda.
+ *
+ * For detailed copyright and licensing information, please refer to the
+ * copyright file COPYRIGHT in the top level MVAPICH2 directory.
+ *
+ */
+
+#include "colls_private.h"
+#include "coll_tuned_topo.h"
+
+int smpi_coll_tuned_barrier_mvapich2_pair(MPI_Comm comm)
+{
+
+ int size, rank;
+ int d, dst, src;
+ int mpi_errno = MPI_SUCCESS;
+
+ size = smpi_comm_size(comm);
+ /* Trivial barriers return immediately */
+ if (size == 1)
+ return MPI_SUCCESS;
+
+ rank = smpi_comm_rank(comm);
+ int N2_prev = 1;
+ /* N2_prev = greatest power of two < size of Comm */
+ for( N2_prev = 1; N2_prev <= size; N2_prev <<= 1 );
+ N2_prev >>= 1;
+
+ int surfeit = size - N2_prev;
+
+ /* Perform a combine-like operation */
+ if (rank < N2_prev) {
+ if (rank < surfeit) {
+ /* get the fanin letter from the upper "half" process: */
+ dst = N2_prev + rank;
+ smpi_mpi_recv(NULL, 0, MPI_BYTE, dst, COLL_TAG_BARRIER,
+ comm, MPI_STATUS_IGNORE);
+ }
+
+ /* combine on embedded N2_prev power-of-two processes */
+ for (d = 1; d < N2_prev; d <<= 1) {
+ dst = (rank ^ d);
+ smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, dst, COLL_TAG_BARRIER, NULL,
+ 0, MPI_BYTE, dst, COLL_TAG_BARRIER, comm,
+ MPI_STATUS_IGNORE);
+ }
+
+ /* fanout data to nodes above N2_prev... */
+ if (rank < surfeit) {
+ dst = N2_prev + rank;
+ smpi_mpi_send(NULL, 0, MPI_BYTE, dst, COLL_TAG_BARRIER,
+ comm);
+ }
+ } else {
+ /* fanin data to power of 2 subset */
+ src = rank - N2_prev;
+ smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, src, COLL_TAG_BARRIER,
+ NULL, 0, MPI_BYTE, src, COLL_TAG_BARRIER,
+ comm, MPI_STATUS_IGNORE);
+ }
+
+ return mpi_errno;
+
+}