1//*************************************************************************************** 2// Communicator manipulation and accessor routines. 3//*************************************************************************************** 4// 5// Author: Rob F. Van der Wijngaart 6// Intel Corporation 7// Date: 04/26/2010 8// 9//*************************************************************************************** 10// 11// Copyright 2010 Intel Corporation 12// 13// Licensed under the Apache License, Version 2.0 (the "License"); 14// you may not use this file except in compliance with the License. 15// You may obtain a copy of the License at 16// 17// http://www.apache.org/licenses/LICENSE-2.0 18// 19// Unless required by applicable law or agreed to in writing, software 20// distributed under the License is distributed on an "AS IS" BASIS, 21// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22// See the License for the specific language governing permissions and 23// limitations under the License. 24// 25#include "RCCE_lib.h" 26 27//-------------------------------------------------------------------------------------- 28// FUNCTION: RCCE_comm_split 29// RCCE_comm_split works like MPI_Comm_split, but: 30// 1. Always uses the default global communicator as the basis, not an 31// arbitrary communicator 32// 2. Uses the rank of the UE in the global communicator as the key 33// 3. Uses a function, operating on UE's global rank, to compute color 34//-------------------------------------------------------------------------------------- 35int RCCE_comm_split( 36 int (*color)(int, void *), // function returning a color value for given ue and aux 37 void *aux, // optional user-supplied data structure 38 RCCE_COMM *comm // new communicator 39 ) { 40 41 int i, my_color, error; 42 43 if (!comm) return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_UNDEFINED)); 44 45 // start with a barrier to make sure all UEs are participating, unless we are still 46 // defining the global communicator; there is no danger in skipping the barrier in 47 // that case, because the global communicator is defined in RCCE_init, which must be 48 // called by all cores before any other RCCE calls 49 if (comm != &RCCE_COMM_WORLD) RCCE_barrier(&RCCE_COMM_WORLD); 50 51 // determine the size of the communicator 52 my_color = color(RCCE_IAM, aux); 53 54 comm->size = 0; 55 for (i=0; i<RCCE_NP; i++) { 56 if (color(i, aux) == my_color) { 57 if (i == RCCE_IAM) comm->my_rank = comm->size; 58 comm->member[comm->size++] = i; 59 } 60 } 61 62 // note: we only need to allocate new synch flags if the communicator has not yet been 63 // initialized. It is legal to overwrite an initialized communcator, in which case the 64 // membership may change, but the same synchronization flags can be used 65 if (comm->initialized == RCCE_COMM_INITIALIZED) return(RCCE_SUCCESS); 66 if(error=RCCE_flag_alloc(&(comm->gather))) 67 return(RCCE_error_return(RCCE_debug_comm,error)); 68 if(error=RCCE_flag_alloc(&(comm->release))) 69 return(RCCE_error_return(RCCE_debug_comm,error)); 70 comm->initialized = RCCE_COMM_INITIALIZED; 71 72 return(RCCE_SUCCESS); 73} 74 75// DO NOT USE THIS FUNCTION IN NON-GORY MODE UNTIL MALLOC_FREE HAS BEEN IMPLEMENTED 76int RCCE_comm_free(RCCE_COMM *comm) { 77 printf("DO NOT USE IN NON-GORY MODE UNTIL MALLOC_FREE HAS BEEN IMPLEMENTED\n"); 78 if (comm->initialized != RCCE_COMM_INITIALIZED) 79 return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED)); 80 RCCE_flag_free(&(comm->gather)); 81 RCCE_flag_free(&(comm->release)); 82 comm->initialized = RCCE_COMM_NOT_INITIALIZED; 83 84 return(RCCE_SUCCESS); 85} 86 87//-------------------------------------------------------------------------------------- 88// FUNCTION: RCCE_comm_size 89// returns the number of UEs inside the communicator 90//-------------------------------------------------------------------------------------- 91int RCCE_comm_size( 92 RCCE_COMM comm, // communicator 93 int *size // return value (size) 94 ) { 95 96 if (comm.initialized == RCCE_COMM_INITIALIZED) { 97 *size = comm.size; 98 return(RCCE_SUCCESS); 99 } 100 else return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED)); 101} 102 103//-------------------------------------------------------------------------------------- 104// FUNCTION: RCCE_comm_rank 105// returns the rank of the calling UE inside the communicator 106//-------------------------------------------------------------------------------------- 107int RCCE_comm_rank( 108 RCCE_COMM comm, // communicator 109 int *rank // return value (rank) 110 ) { 111 112 if (comm.initialized == RCCE_COMM_INITIALIZED) { 113 *rank = comm.my_rank; 114 return(RCCE_SUCCESS); 115 } 116 else return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED)); 117} 118 119//-------------------------------------------------------------------------------------- 120// FUNCTION: RCCE_global_color 121// use this trivial color function to define global communicator 122//-------------------------------------------------------------------------------------- 123int RCCE_global_color(int rank, void *nothing) {return(1);} 124