2#ifndef UTIL_MPI_SEND_RECV_H 
    3#define UTIL_MPI_SEND_RECV_H 
   78#include <util/mpi/MpiTraits.h> 
   79#include <util/containers/DArray.h> 
   80#include <util/containers/DMatrix.h> 
   99   void send(MPI::Comm& comm, T& data, 
int dest, 
int tag)
 
  101      if (!MpiTraits<T>::hasType)
 
  102         UTIL_THROW(
"No committed MPI type in send<T>");
 
  103      comm.Send(&data, 1, MpiTraits<T>::type, dest, tag); 
 
  117   template <
typename T>
 
  118   void recv(MPI::Comm& comm, T& data, 
int source, 
int tag)
 
  120      if (!MpiTraits<T>::hasType)
 
  121         UTIL_THROW(
"No committed MPI type in recv<T>");
 
  122      comm.Recv(&data, 1, MpiTraits<T>::type, source, tag); 
 
  135   template <
typename T>
 
  136   void bcast(MPI::Intracomm& comm, T& data, 
int root)
 
  138      if (!MpiTraits<T>::hasType)
 
  139         UTIL_THROW(
"No committed MPI type in bcast<T>");
 
  140      comm.Bcast(&data, 1, MpiTraits<T>::type, root); 
 
  157   template <
typename T>
 
  158   void send(MPI::Comm& comm, T* array, 
int count, 
int dest, 
int tag)
 
  160      if (MpiTraits<T>::hasType) {
 
  161         comm.Send(array, count, MpiTraits<T>::type, dest, tag); 
 
  165         for (
int i = 0; i < count; ++i) {
 
  166            send<T>(comm, array[i], dest, tag); 
 
  183   template <
typename T>
 
  184   void recv(MPI::Comm& comm, T* array, 
int count, 
int source, 
int tag)
 
  186      if (MpiTraits<T>::hasType) {
 
  187         comm.Recv(array, count, MpiTraits<T>::type, source, tag); 
 
  191         for (
int i = 0; i < count; ++i) {
 
  192            recv<T>(comm, array[i], source, tag); 
 
  208   template <
typename T>
 
  209   void bcast(MPI::Intracomm& comm, T* array, 
int count, 
int root)
 
  211      if (MpiTraits<T>::hasType) {
 
  212         comm.Bcast(array, count, MpiTraits<T>::type, root); 
 
  216         for (
int i = 0; i < count; ++i) {
 
  217            bcast<T>(comm, array[i], root); 
 
  236   template <
typename T>
 
  237   void send(MPI::Comm& comm, 
DArray<T>& array, 
int count, 
int dest, 
int tag)
 
  240      if (!(array.isAllocated())) {
 
  243      if (count > array.capacity()) {
 
  244         UTIL_THROW(
"Error: Logical size count > DArray capacity");
 
  247      if (MpiTraits<T>::hasType) {
 
  248         comm.Send(&array[0], count, MpiTraits<T>::type, dest, tag); 
 
  252         for (
int i = 0; i < count; ++i) {
 
  253            send<T>(comm, array[i], dest, tag); 
 
  270   template <
typename T>
 
  271   void recv(MPI::Comm& comm, 
DArray<T>& array, 
int count, 
int source, 
int tag)
 
  274      if (!(array.isAllocated())) {
 
  277      if (count > array.capacity()) {
 
  278         UTIL_THROW(
"Error: Logical size count > DArray capacity");
 
  281      if (MpiTraits<T>::hasType) {
 
  282         comm.Recv(&array[0], count, MpiTraits<T>::type, source, tag); 
 
  286         for (
int i = 0; i < count; ++i) {
 
  287            recv<T>(comm, array[i], source, tag); 
 
  303   template <
typename T>
 
  304   void bcast(MPI::Intracomm& comm, 
DArray<T>& array, 
int count, 
int root)
 
  307      if (!(array.isAllocated())) {
 
  310      if (count > array.capacity()) {
 
  311         UTIL_THROW(
"Error: Logical size count > DArray capacity");
 
  314      if (MpiTraits<T>::hasType) {
 
  315         comm.Bcast(&array[0], count, MpiTraits<T>::type, root); 
 
  319         for (
int i = 0; i < count; ++i) {
 
  320            bcast<T>(comm, array[i], root); 
 
  340   template <
typename T>
 
  341   void send(MPI::Comm& comm, 
DMatrix<T>& matrix, 
int m, 
int n, 
int dest, 
int tag)
 
  344      if (!(matrix.isAllocated())) {
 
  345         UTIL_THROW(
"Cannot read unallocated DMatrix");
 
  347      if (m > matrix.capacity1()) {
 
  348         UTIL_THROW(
"Error: Logical size m > DMatrix<T>::capacity1()");
 
  350      if (n > matrix.capacity2()) {
 
  351         UTIL_THROW(
"Error: Logical size n > DMatrix<T>::capacity2()");
 
  354      if (MpiTraits<T>::hasType) {
 
  355         int mp = matrix.capacity1();
 
  356         int np = matrix.capacity2();
 
  357         comm.Send(&matrix(0, 0), mp*np, MpiTraits<T>::type, dest, tag); 
 
  363         for (i = 0; i < m; ++i) {
 
  364            for (j = 0; j < n; ++j) {
 
  365               send<T>(comm, matrix(i, j), dest, tag); 
 
  384   template <
typename T>
 
  385   void recv(MPI::Comm& comm, 
DMatrix<T>& matrix, 
int m, 
int n, 
 
  389      if (!(matrix.isAllocated())) {
 
  390         UTIL_THROW(
"Cannot recv unallocated DMatrix");
 
  392      if (m > matrix.capacity1()) {
 
  393         UTIL_THROW(
"Error: Logical size m > DMatrix<T>::capacity1()");
 
  395      if (n > matrix.capacity2()) {
 
  396         UTIL_THROW(
"Error: Logical size n > DMatrix<T>::capacity2()");
 
  399      if (MpiTraits<T>::hasType) {
 
  400         int mp = matrix.capacity1();
 
  401         int np = matrix.capacity2();
 
  402         comm.Recv(&matrix(0, 0), mp*np, MpiTraits<T>::type, source, tag); 
 
  408         for (i = 0; i < m; ++i) {
 
  409            for (j = 0; j < n; ++j) {
 
  410               recv<T>(comm, matrix(i, j), source, tag); 
 
  428   template <
typename T>
 
  429   void bcast(MPI::Intracomm& comm, 
DMatrix<T>& matrix, 
int m, 
int n, 
int root)
 
  432      if (!(matrix.isAllocated())) {
 
  433         UTIL_THROW(
"Cannot bcast unallocated DMatrix");
 
  435      if (m > matrix.capacity1()) {
 
  436         UTIL_THROW(
"Error: Logical size m > DMatrix<T>::capacity1()");
 
  438      if (n > matrix.capacity2()) {
 
  439         UTIL_THROW(
"Error: Logical size n > DMatrix<T>::capacity2()");
 
  442      if (MpiTraits<T>::hasType) {
 
  443         int mp = matrix.capacity1();
 
  444         int np = matrix.capacity2();
 
  445         comm.Bcast(&matrix(0, 0), mp*np, MpiTraits<T>::type, root); 
 
  451         for (i = 0; i < m; ++i) {
 
  452            for (j = 0; j < n; ++j) {
 
  453               bcast<T>(comm, matrix(i, j), root); 
 
  465   void send<bool>(MPI::Comm& comm, 
bool& data, 
int dest, 
int tag);
 
  471   void recv<bool>(MPI::Comm& comm, 
bool& data, 
int source, 
int tag);
 
  477   void bcast<bool>(MPI::Intracomm& comm, 
bool& data, 
int root);
 
  485   send<std::string>(MPI::Comm& comm, std::string& data, 
int dest, 
int tag);
 
  491   recv<std::string>(MPI::Comm& comm, std::string& data, 
int source, 
int tag);
 
  497   void bcast<std::string>(MPI::Intracomm& comm, std::string& data, 
int root);
 
Dynamically allocatable contiguous array template.
 
Dynamically allocated Matrix.
 
File containing preprocessor macros for error handling.
 
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
 
Utility classes for scientific computation.