Functions

pcu.c File Reference

The PCU communication interface. More...

Go to the source code of this file.

Functions

int PCU_Comm_Init (void)
 Initializes the PCU library.
int PCU_Comm_Free (void)
 Frees all PCU library structures.
int PCU_Comm_Self (void)
 Returns the communication rank of the calling thread.
int PCU_Comm_Peers (void)
 Returns the number of threads in the program.
void PCU_Comm_Begin (void)
 Begins a PCU communication phase.
int PCU_Comm_Pack (int to_rank, const void *data, size_t size)
 Packs data to be sent to to_rank.
int PCU_Comm_Send (void)
 Sends all buffers for this communication phase.
bool PCU_Comm_Listen (void)
 Tries to receive a buffer for this communication phase.
int PCU_Comm_Sender (void)
 Returns in * from_rank the sender of the current received buffer.
bool PCU_Comm_Unpacked (void)
 Returns true if the current received buffer has been unpacked.
int PCU_Comm_Unpack (void *data, size_t size)
 Unpacks a block of data from the current received buffer.
void PCU_Barrier (void)
 Blocking barrier over all threads.
void PCU_Add_Doubles (double *p, size_t n)
 Performs an Allreduce sum of double arrays.
void PCU_Min_Doubles (double *p, size_t n)
 Performs an Allreduce minimum of double arrays.
void PCU_Max_Doubles (double *p, size_t n)
 Performs an Allreduce maximum of double arrays.
void PCU_Add_Ints (int *p, size_t n)
 Performs an Allreduce sum of integers.
void PCU_Add_Longs (long *p, size_t n)
 Performs an Allreduce sum of long integers.
void PCU_Add_SizeTs (size_t *p, size_t n)
 Performs an Allreduce sum of size_t unsigned integers.
void PCU_Min_SizeTs (size_t *p, size_t n)
 Performs an Allreduce minimum of size_t unsigned integers.
void PCU_Max_SizeTs (size_t *p, size_t n)
 Performs an Allreduce maximum of size_t unsigned integers.
void PCU_Exscan_Ints (int *p, size_t n)
 Performs an exclusive prefix sum of integer arrays.
void PCU_Exscan_Longs (long *p, size_t n)
 See PCU_Exscan_Ints.
void PCU_Min_Ints (int *p, size_t n)
 Performs an Allreduce minimum of int arrays.
void PCU_Max_Ints (int *p, size_t n)
 Performs an Allreduce maximum of int arrays.
int PCU_Or (int c)
 Performs a parallel logical OR reduction.
int PCU_And (int c)
 Performs a parallel logical AND reduction.
int PCU_Proc_Self (void)
 Returns the unique rank of the calling process.
int PCU_Proc_Peers (void)
 Returns the number of processes.
int PCU_Comm_Rank (int *rank)
 Similar to PCU_Comm_Self, returns the rank as an argument.
int PCU_Comm_Size (int *size)
 Similar to PCU_Comm_Peers, returns the size as an argument.
bool PCU_Comm_Initialized (void)
 Returns true iff PCU has been initialized.
int PCU_Comm_Start (PCU_Method method)
 Deprecated, see PCU_Comm_Begin.
int PCU_Comm_Packed (int to_rank, size_t *size)
 Returns in * size the number of bytes being sent to to_rank.
int PCU_Comm_Write (int to_rank, const void *data, size_t size)
 Packs a message to be sent to to_rank.
bool PCU_Comm_Receive (void)
 Convenience wrapper over Listen and Unpacked.
bool PCU_Comm_Read (int *from_rank, void **data, size_t *size)
 Receives a message for this communication phase.
void PCU_Debug_Open (void)
 Open file debugN.txt, where N = PCU_Comm_Self().
void PCU_Debug_Print (const char *format,...)
 like fprintf, contents go to debugN.txt
int PCU_Comm_From (int *from_rank)
 Similar to PCU_Comm_Sender, returns the rank as an argument.
int PCU_Comm_Received (size_t *size)
 Returns in * size the bytes in the current received buffer.
void * PCU_Comm_Extract (size_t size)
 Extracts a block of data from the current received buffer.
void PCU_Switch_Comm (MPI_Comm new_comm)
 Reinitializes PCU with a new MPI communicator.
MPI_Comm PCU_Get_Comm (void)
 Return the current MPI communicator.
double PCU_Time (void)
 Return the time in seconds since some time in the past.

Detailed Description

The PCU communication interface.

Definition in file pcu.c.


Function Documentation

void PCU_Add_Doubles ( double *  p,
size_t  n 
)

Performs an Allreduce sum of double arrays.

This function must be called by all ranks at the same time. p must point to an array of n doubles. After this call, p[i] will contain the sum of all p[i]'s given by each rank.

Definition at line 253 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Add_Doubles called before Comm_Init");
  pcu_allreduce(&(get_msg()->coll),pcu_add_doubles,p,n*sizeof(double));
}

void PCU_Comm_Begin ( void   ) 

Begins a PCU communication phase.

This function must be called by all threads in the MPI job at the beginning of each phase of communication. After calling this function, each thread may call functions like PCU_Comm_Pack or PCU_Comm_Write.

Definition at line 119 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Begin called before Comm_Init");
  pcu_msg_start(get_msg());
}

void* PCU_Comm_Extract ( size_t  size  ) 

Extracts a block of data from the current received buffer.

This function should be called after a successful PCU_Comm_Receive. The next size bytes of the current received buffer are unpacked, and an internal pointer to that data is returned. The returned pointer must not be freed by the user.

Definition at line 668 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Extract called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    return pcu_order_unpack(m->order,size);
  return pcu_msg_unpack(m,size);
}

int PCU_Comm_Free ( void   ) 

Frees all PCU library structures.

This function must be called by all MPI processes after all other calls to PCU, and before calling MPI_Finalize.

Definition at line 74 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Free called before Comm_Init");
  if (global_pmsg.order)
    pcu_order_free(global_pmsg.order);
  pcu_free_msg(&global_pmsg);
  pcu_pmpi_finalize();
  global_state = uninit;
  return PCU_SUCCESS;
}

int PCU_Comm_Init ( void   ) 

Initializes the PCU library.

This function must be called by all MPI processes before calling any other PCU functions. MPI_Init or MPI_Init_thread should be called before this function.

Definition at line 55 of file pcu.c.

{
  if (global_state != uninit)
    reel_fail("nested calls to Comm_Init");
  pcu_pmpi_init(MPI_COMM_WORLD);
  pcu_set_mpi(&pcu_pmpi);
  pcu_make_msg(&global_pmsg);
  global_state = init;
  /* turn ordering on by default, call
     PCU_Comm_Order(false) after PCU_Comm_Init
     to disable this */
  PCU_Comm_Order(true);
  return PCU_SUCCESS;
}

bool PCU_Comm_Listen ( void   ) 

Tries to receive a buffer for this communication phase.

Either this function or PCU_Comm_Read should be called at least once by all threads during the communication phase, after PCU_Comm_Send is called. The result will be false if and only if the communication phase is over and there are no more buffers to receive. Otherwise, a buffer was received. Its contents are retrievable through PCU_Comm_Unpack, and its metadata through PCU_Comm_Sender and PCU_Comm_Received. Users should unpack all data from this buffer before calling this function again, because the previously received buffer is destroyed by the call.

Definition at line 168 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Listen called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    return pcu_order_receive(m->order, m);
  return pcu_msg_receive(m);
}

int PCU_Comm_Pack ( int  to_rank,
const void *  data,
size_t  size 
)

Packs data to be sent to to_rank.

This function appends the block of size bytes starting at data to the buffer being sent to to_rank. This function should be called after PCU_Comm_Start and before PCU_Comm_Send.

Definition at line 132 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Pack called before Comm_Init");
  if ((to_rank < 0)||(to_rank >= pcu_mpi_size()))
    reel_fail("Invalid rank in Comm_Pack");
  memcpy(pcu_msg_pack(get_msg(),to_rank,size),data,size);
  return PCU_SUCCESS;
}

int PCU_Comm_Packed ( int  to_rank,
size_t *  size 
)

Returns in * size the number of bytes being sent to to_rank.

Returns the size of the buffer being sent to to_rank. This function should be called after PCU_Comm_Start and before PCU_Comm_Send.

Definition at line 543 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Packed called before Comm_Init");
  if ((to_rank < 0)||(to_rank >= pcu_mpi_size()))
    reel_fail("Invalid rank in Comm_Packed");
  *size = pcu_msg_packed(get_msg(),to_rank);
  return PCU_SUCCESS;
}

int PCU_Comm_Peers ( void   ) 

Returns the number of threads in the program.

when called from a non-threaded MPI process, this function is equivalent to MPI_Comm_size(MPI_COMM_WORLD,size).

Definition at line 106 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Peers called before Comm_Init");
  return pcu_mpi_size();
}

bool PCU_Comm_Read ( int *  from_rank,
void **  data,
size_t *  size 
)

Receives a message for this communication phase.

This function tries to receive a message packed by PCU_Comm_Write. If a the communication phase is over and there are no more messages to receive, this function returns false. Otherwise, * from_rank will be the rank which sent the message, data will point to the start of the message data, and size will be the number of bytes of message data. If this function is used, PCU_Comm_Receive should not be used. Note that the address * data points into a PCU buffer, so it is strongly recommended that this data be read and not modified.

Definition at line 595 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Read called before Comm_Init");
  if (!PCU_Comm_Receive())
    return false;
  *from_rank = PCU_Comm_Sender();
  PCU_COMM_UNPACK(*size);
  *data = PCU_Comm_Extract(*size);
  return true;
}

int PCU_Comm_Received ( size_t *  size  ) 

Returns in * size the bytes in the current received buffer.

This function should be called after a successful PCU_Comm_Receive. The size returned will be the total received size regardless of how much unpacking has been done.

Definition at line 650 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Received called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    *size = pcu_order_received_size(m->order);
  else
    *size = pcu_msg_received_size(m);
  return PCU_SUCCESS;
}

int PCU_Comm_Self ( void   ) 

Returns the communication rank of the calling thread.

when called from a non-threaded MPI process, this function is equivalent to MPI_Comm_rank(MPI_COMM_WORLD,rank).

Ranks are consecutive from 0 to $pt-1$ for a program with $p$ processes and $t$ threads per process. Ranks are contiguous within a process, so that the $t$ threads in process $i$ are numbered from $ti$ to $ti+t-1$.

Definition at line 95 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Self called before Comm_Init");
  return pcu_mpi_rank();
}

int PCU_Comm_Send ( void   ) 

Sends all buffers for this communication phase.

This function should be called by all threads in the MPI job after calls to PCU_Comm_Pack or PCU_Comm_Write and before calls to PCU_Comm_Listen or PCU_Comm_Read. All buffers from this thread are sent out and receiving may begin after this call.

Definition at line 149 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Send called before Comm_Init");
  pcu_msg_send(get_msg());
  return PCU_SUCCESS;
}

int PCU_Comm_Sender ( void   ) 

Returns in * from_rank the sender of the current received buffer.

This function should be called after a successful PCU_Comm_Listen.

Definition at line 181 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Sender called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    return pcu_order_received_from(m->order);
  return pcu_msg_received_from(m);
}

int PCU_Comm_Unpack ( void *  data,
size_t  size 
)

Unpacks a block of data from the current received buffer.

This function should be called after a successful PCU_Comm_Listen. data must point to a block of memory of at least size bytes, into which the next size bytes of the current received buffer will be written. Subsequent calls will begin unpacking where this call left off, so that the entire received buffer can be unpacked by a sequence of calls to this function. Users must ensure that there remain size bytes to be unpacked, PCU_Comm_Unpacked can help with this.

Definition at line 214 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Unpack called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    memcpy(data,pcu_order_unpack(m->order,size),size);
  else
    memcpy(data,pcu_msg_unpack(m,size),size);
  return PCU_SUCCESS;
}

bool PCU_Comm_Unpacked ( void   ) 

Returns true if the current received buffer has been unpacked.

This function should be called after a successful PCU_Comm_Listen.

Definition at line 194 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Unpacked called before Comm_Init");
  pcu_msg* m = get_msg();
  if (m->order)
    return pcu_order_unpacked(m->order);
  return pcu_msg_unpacked(m);
}

int PCU_Comm_Write ( int  to_rank,
const void *  data,
size_t  size 
)

Packs a message to be sent to to_rank.

This function packs a message into the buffer being sent to to_rank. Messages packed by this function can be received using the function PCU_Comm_Read. This function should be called after PCU_Comm_Start and before PCU_Comm_Send. If this function is used, PCU_Comm_Pack should not be used.

Definition at line 562 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Comm_Write called before Comm_Init");
  if ((to_rank < 0)||(to_rank >= pcu_mpi_size()))
    reel_fail("Invalid rank in Comm_Write");
  pcu_msg* msg = get_msg();
  PCU_MSG_PACK(msg,to_rank,size);
  memcpy(pcu_msg_pack(msg,to_rank,size),data,size);
  return PCU_SUCCESS;
}

void PCU_Exscan_Ints ( int *  p,
size_t  n 
)

Performs an exclusive prefix sum of integer arrays.

This function must be called by all ranks at the same time. p must point to an array of n integers. After this call, p[i] will contain the sum of all p[i]'s given by ranks lower than the calling rank.

Definition at line 389 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Exscan_Ints called before Comm_Init");
  int* originals;
  NOTO_MALLOC(originals,n);
  for (size_t i=0; i < n; ++i)
    originals[i] = p[i];
  pcu_scan(&(get_msg()->coll),pcu_add_ints,p,n*sizeof(int));
  //convert inclusive scan to exclusive
  for (size_t i=0; i < n; ++i)
    p[i] -= originals[i];
  noto_free(originals);
}

MPI_Comm PCU_Get_Comm ( void   ) 

Return the current MPI communicator.

Returns the communicator given to the most recent PCU_Switch_Comm call, or MPI_COMM_WORLD otherwise.

Definition at line 697 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Get_Comm called before Comm_Init");
  return pcu_pmpi_comm();
}

void PCU_Switch_Comm ( MPI_Comm  new_comm  ) 

Reinitializes PCU with a new MPI communicator.

All of PCU's logic is based off two duplicates of this communicator, so you can safely get PCU to act on sub-groups of processes using this function. This call should be collective over all processes in the previous communicator.

Definition at line 685 of file pcu.c.

{
  if (global_state == uninit)
    reel_fail("Switch_Comm called before Comm_Init");
  pcu_pmpi_switch(new_comm);
}

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines