Context.h 9.76 KB
Newer Older
Francois Gygi committed
1 2
////////////////////////////////////////////////////////////////////////////////
//
Francois Gygi committed
3 4 5 6
// Copyright (c) 2008 The Regents of the University of California
//
// This file is part of Qbox
//
Francois Gygi committed
7 8
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
Francois Gygi committed
9 10 11 12 13 14
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
//
Francois Gygi committed
15 16 17 18 19 20 21 22
// Context.h
//
////////////////////////////////////////////////////////////////////////////////

#ifndef CONTEXT_H
#define CONTEXT_H

#include <iosfwd>
23
#include <string>
24 25 26
#include <vector>
#include <cassert>
#include "blacs.h"
Francois Gygi committed
27
#include <mpi.h>
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

struct ContextRep
{
  private:

  int ictxt_;
  int myrow_;
  int mycol_;
  int nprow_;
  int npcol_;
  int size_;
  int myproc_;
  int mype_;
  bool onpe0_;
  bool active_;

  std::vector<int> pmap_;
  MPI_Comm comm_;

  // keep assignment and copy constructors private
  ContextRep& operator=(const ContextRep& c);
  ContextRep(const ContextRep& c);

  public:

  int ictxt() const { return ictxt_; }
  int myrow() const { return myrow_; }
  int mycol() const { return mycol_; }
  int nprow() const { return nprow_; }
  int npcol() const { return npcol_; }

  // number of processes in the context
  // returns -1 if current process is not part of this context
  int size() const { return size_; }
  // position of current process in row-major order
  // returns -1 if current process is not part of this context
  int myproc() const { return myproc_; }
  int mype() const { return mype_; }
  int pmap(int irow, int icol) const { return pmap_[irow+nprow_*icol]; }

  bool onpe0(void) const { return onpe0_; }
  bool active(void) const { return active_; }
  void abort(int ierr) const { Cblacs_abort(ictxt_,ierr); }
  void barrier(void) const { Cblacs_barrier(ictxt_,"A"); }
  void barrier(char scope) const { Cblacs_barrier(ictxt_,&scope); }

  void dsend(int m, int n, double* a, int lda, int rdest, int cdest) const;
  void drecv(int m, int n, double* a, int lda, int rsrc, int csrc) const;
  void dsum(char scope, char topology, int m, int n, double* a, int lda,
            int rdest, int cdest) const;
  void dmax(char scope, char topology, int m, int n, double* a, int lda,
            int rdest, int cdest) const;
  void dmax(char scope, char topology, int m, int n, double* a, int lda,
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
  void dmin(char scope, char topology, int m, int n, double* a, int lda,
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
  void dmin(char scope, char topology, int m, int n, double* a, int lda,
            int rdest, int cdest) const;
  void dbcast_send(char scope, char topology,
                   int m, int n, double* a,int lda) const;
  void dbcast_recv(char scope, char topology, int m, int n, double* a, int lda,
               int rsrc, int csrc) const;
  void isend(int m, int n, int* a, int lda, int rdest, int cdest) const;
  void irecv(int m, int n, int* a, int lda, int rsrc, int csrc) const;
  void isum(char scope, char topology, int m, int n, int* a, int lda,
            int rdest, int cdest) const;
  void imax(char scope, char topology, int m, int n, int* a, int lda,
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
  void imax(char scope, char topology, int m, int n, int* a, int lda,
            int rdest, int cdest) const;
  void imin(char scope, char topology, int m, int n, int* a, int lda,
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
  void imin(char scope, char topology, int m, int n, int* a, int lda,
            int rdest, int cdest) const;
  void ibcast_send(char scope, char topology,
                   int m, int n, int* a,int lda) const;
  void ibcast_recv(char scope, char topology, int m, int n, int* a, int lda,
               int rsrc, int csrc) const;
  void string_send(std::string& s, int rdest, int cdest) const;
  void string_recv(std::string& s, int rsrc, int csrc) const;
  void string_bcast(std::string& s, int isrc) const;

  bool operator==(const ContextRep& c) const
  { return (ictxt_==c.ictxt());}

  MPI_Comm comm(void) const { return comm_; }

  // Constructors

  // construct a single-row ContextRep
  explicit ContextRep(MPI_Comm comm);

  // global ContextRep of size nprow * npcol with column major order
  explicit ContextRep(MPI_Comm comm, int nprow, int npcol);

  ~ContextRep();

  void print(std::ostream& os) const;
};
Francois Gygi committed
127 128 129 130

class Context
{
  private:
131

132 133
  ContextRep* rep;
  int* pcount;
Francois Gygi committed
134 135

  public:
136

Francois Gygi committed
137 138 139 140 141
  int ictxt() const;
  int myrow() const;
  int mycol() const;
  int nprow() const;
  int npcol() const;
142

Francois Gygi committed
143 144 145 146 147 148 149 150 151
  // number of processes in the context
  // returns -1 if current process is not part of this context
  int size() const;
  // position of current process in row-major order
  // returns -1 if current process is not part of this context
  int myproc() const;
  int mype() const;
  // process id of process (irow,icol)
  int pmap(int irow, int icol) const;
152

Francois Gygi committed
153 154
  bool onpe0(void) const;
  bool active(void) const;
155
  operator bool() const { return active(); }
Francois Gygi committed
156 157 158
  void abort(int ierr) const;
  void barrier(void) const;
  void barrier(char scope) const;
159

Francois Gygi committed
160 161 162
  // double communications
  void dsend(int m, int n, double* a, int lda, int rdest, int cdest) const;
  void drecv(int m, int n, double* a, int lda, int rsrc, int csrc) const;
163 164

  void dsum(char scope, char topology,
Francois Gygi committed
165 166 167
            int m, int n, double* a, int lda, int rdest, int cdest) const;
  void dsum(char scope, int m, int n, double* a, int lda) const;
  void dsum(int m, int n, double* a, int lda) const;
168 169 170

  void dmax(char scope, char topology,
            int m, int n, double* a, int lda,
Francois Gygi committed
171
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
172
  void dmax(char scope, char topology,
Francois Gygi committed
173 174 175
            int m, int n, double* a, int lda, int rdest, int cdest) const;
  void dmax(char scope, int m, int n, double* a, int lda) const;
  void dmax(int m, int n, double* a, int lda) const;
176 177 178

  void dmin(char scope, char topology,
            int m, int n, double* a, int lda,
Francois Gygi committed
179
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
180
  void dmin(char scope, char topology,
Francois Gygi committed
181 182 183
            int m, int n, double* a, int lda, int rdest, int cdest) const;
  void dmin(char scope, int m, int n, double* a, int lda) const;
  void dmin(int m, int n, double* a, int lda) const;
184 185

  void dbcast_send(char scope, char topology,
Francois Gygi committed
186 187 188
                   int m, int n, double* a, int lda) const;
  void dbcast_send(char scope, int m, int n, double* a, int lda) const;
  void dbcast_send(int m, int n, double* a, int lda) const;
189 190

  void dbcast_recv(char scope, char topology,
Francois Gygi committed
191
               int m, int n, double* a, int lda, int rsrc, int csrc) const;
192
  void dbcast_recv(char scope, int m, int n, double* a,
Francois Gygi committed
193 194
                   int lda,int rsrc, int csrc) const;
  void dbcast_recv(int m, int n, double* a, int lda,int rsrc, int csrc) const;
195

Francois Gygi committed
196 197 198
  // integer communications
  void isend(int m, int n, int* a, int lda, int rdest, int cdest) const;
  void irecv(int m, int n, int* a, int lda, int rsrc, int csrc) const;
199
  void isum(char scope, char topology,
Francois Gygi committed
200 201 202
            int m, int n, int* a, int lda, int rdest, int cdest) const;
  void isum(char scope, int m, int n, int* a, int lda) const;
  void isum(int m, int n, int* a, int lda) const;
203 204 205

  void imax(char scope, char topology,
            int m, int n, int* a, int lda,
Francois Gygi committed
206
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
207
  void imax(char scope, char topology,
Francois Gygi committed
208 209 210
            int m, int n, int* a, int lda, int rdest, int cdest) const;
  void imax(char scope, int m, int n, int* a, int lda) const;
  void imax(int m, int n, int* a, int lda) const;
211 212 213

  void imin(char scope, char topology,
            int m, int n, int* a, int lda,
Francois Gygi committed
214
            int* ra, int* ca, int rcflag, int rdest, int cdest) const;
215
  void imin(char scope, char topology,
Francois Gygi committed
216 217 218
            int m, int n, int* a, int lda, int rdest, int cdest) const;
  void imin(char scope, int m, int n, int* a, int lda) const;
  void imin(int m, int n, int* a, int lda) const;
219 220

  void ibcast_send(char scope, char topology,
Francois Gygi committed
221 222 223
                   int m, int n, int* a, int lda) const;
  void ibcast_send(char scope, int m, int n, int* a, int lda) const;
  void ibcast_send(int m, int n, int* a, int lda) const;
224 225

  void ibcast_recv(char scope, char topology,
Francois Gygi committed
226
                   int m, int n, int* a, int lda, int rsrc, int csrc) const;
227
  void ibcast_recv(char scope, int m, int n,
Francois Gygi committed
228 229
                   int* a, int lda,int rsrc, int csrc) const;
  void ibcast_recv(int m, int n, int* a, int lda,int rsrc, int csrc) const;
230

231 232 233
  void string_send(std::string& s, int rdest, int cdest) const;
  void string_recv(std::string& s, int rsrc, int csrc) const;
  void string_bcast(std::string& s, int isrc) const;
234

Francois Gygi committed
235
  bool operator==(const Context& ctxt) const;
236

Francois Gygi committed
237 238 239
  // MPI communicator for this context. Returns MPI_COMM_NULL if
  // this process is not part of the context
  MPI_Comm comm(void) const;
240

241 242
  void print(std::ostream& os) const;

Francois Gygi committed
243 244
  // Constructors

245 246 247
  // single-row Context
  explicit Context(MPI_Comm comm) : rep(new ContextRep(comm)),
    pcount(new int(1)) {}
248

249 250 251
  // nprow * npcol Context
  explicit Context(MPI_Comm comm, int nprow, int npcol):
    rep(new ContextRep(comm,nprow,npcol)), pcount(new int(1)) {}
252

253
  Context(const Context& c) : rep(c.rep), pcount(c.pcount) { (*pcount)++; }
254

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  Context& operator=(const Context& c)
  {
    if ( rep == c.rep ) return *this;
    if ( --(*pcount) == 0 )
    {
      delete rep;
      delete pcount;
    }
    rep = c.rep;
    pcount = c.pcount;
    (*pcount)++;
    return *this;
  }

  ~Context(void)
  {
    if ( --(*pcount) == 0 )
    {
      delete rep;
      delete pcount;
    }
  }
Francois Gygi committed
277
};
278

279
std::ostream& operator << ( std::ostream& os, const Context& ctxt );
Francois Gygi committed
280 281

#endif