RCCE_comm.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //***************************************************************************************
  2. // Communicator manipulation and accessor routines.
  3. //***************************************************************************************
  4. //
  5. // Author: Rob F. Van der Wijngaart
  6. // Intel Corporation
  7. // Date: 12/22/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. // FUNCTION: RCCE_comm_split
  28. // RCCE_comm_split works like MPI_Comm_split, but:
  29. // 1. Always uses the default global communicator as the basis, not an
  30. // arbitrary communicator
  31. // 2. Uses the rank of the UE in the global communicator as the key
  32. // 3. Uses a function, operating on UE's global rank, to compute color
  33. //--------------------------------------------------------------------------------------
  34. int RCCE_comm_split(
  35. int (*color)(int, void *), // function returning a color value for given ue and aux
  36. void *aux, // optional user-supplied data structure
  37. RCCE_COMM *comm // new communicator
  38. ) {
  39. int i, my_color, error;
  40. if (!comm) return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_UNDEFINED));
  41. // start with a barrier to make sure all UEs are participating, unless we are still
  42. // defining the global communicator; there is no danger in skipping the barrier in
  43. // that case, because the global communicator is defined in RCCE_init, which must be
  44. // called by all cores before any other RCCE calls
  45. if (comm != &RCCE_COMM_WORLD) RCCE_barrier(&RCCE_COMM_WORLD);
  46. // determine the size of the communicator
  47. my_color = color(RCCE_IAM, aux);
  48. comm->size = 0;
  49. for (i=0; i<RCCE_NP; i++) {
  50. if (color(i, aux) == my_color) {
  51. if (i == RCCE_IAM) comm->my_rank = comm->size;
  52. comm->member[comm->size++] = i;
  53. }
  54. }
  55. // note: we only need to allocate new synch flags if the communicator has not yet been
  56. // initialized. It is legal to overwrite an initialized communcator, in which case the
  57. // membership may change, but the same synchronization flags can be used
  58. if (comm->initialized == RCCE_COMM_INITIALIZED) return(RCCE_SUCCESS);
  59. if(error=RCCE_flag_alloc(&(comm->gather)))
  60. return(RCCE_error_return(RCCE_debug_comm,error));
  61. if(error=RCCE_flag_alloc(&(comm->release)))
  62. return(RCCE_error_return(RCCE_debug_comm,error));
  63. comm->initialized = RCCE_COMM_INITIALIZED;
  64. return(RCCE_SUCCESS);
  65. }
  66. // DO NOT USE THIS FUNCTION IN NON-GORY MODE UNTIL MALLOC_FREE HAS BEEN IMPLEMENTED
  67. int RCCE_comm_free(RCCE_COMM *comm) {
  68. printf("DO NOT USE IN NON-GORY MODE UNTIL MALLOC_FREE HAS BEEN IMPLEMENTED\n");
  69. if (comm->initialized != RCCE_COMM_INITIALIZED)
  70. return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED));
  71. RCCE_flag_free(&(comm->gather));
  72. RCCE_flag_free(&(comm->release));
  73. comm->initialized = RCCE_COMM_NOT_INITIALIZED;
  74. return(RCCE_SUCCESS);
  75. }
  76. //--------------------------------------------------------------------------------------
  77. // FUNCTION: RCCE_comm_size
  78. // returns the number of UEs inside the communicator
  79. //--------------------------------------------------------------------------------------
  80. int RCCE_comm_size(
  81. RCCE_COMM comm, // communicator
  82. int *size // return value (size)
  83. ) {
  84. if (comm.initialized == RCCE_COMM_INITIALIZED) {
  85. *size = comm.size;
  86. return(RCCE_SUCCESS);
  87. }
  88. else return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED));
  89. }
  90. //--------------------------------------------------------------------------------------
  91. // FUNCTION: RCCE_comm_rank
  92. // returns the rank of the calling UE inside the communicator
  93. //--------------------------------------------------------------------------------------
  94. int RCCE_comm_rank(
  95. RCCE_COMM comm, // communicator
  96. int *rank // return value (rank)
  97. ) {
  98. if (comm.initialized == RCCE_COMM_INITIALIZED) {
  99. *rank = comm.my_rank;
  100. return(RCCE_SUCCESS);
  101. }
  102. else return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_COMM_INITIALIZED));
  103. }
  104. //--------------------------------------------------------------------------------------
  105. // FUNCTION: RCCE_global_color
  106. // use this trivial color function to define global communicator
  107. //--------------------------------------------------------------------------------------
  108. int RCCE_global_color(int rank, void *nothing) {return(1);}