| 1 | //
 | 
|---|
| 2 | // message.h
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // Author: Curtis Janssen <cljanss@limitpt.com>
 | 
|---|
| 7 | // Maintainer: LPS
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // This file is part of the SC Toolkit.
 | 
|---|
| 10 | //
 | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 14 | // any later version.
 | 
|---|
| 15 | //
 | 
|---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 19 | // GNU Library General Public License for more details.
 | 
|---|
| 20 | //
 | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 24 | //
 | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
| 26 | //
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #ifdef __GNUC__
 | 
|---|
| 29 | #pragma interface
 | 
|---|
| 30 | #endif
 | 
|---|
| 31 | 
 | 
|---|
| 32 | #ifndef _util_group_message_h
 | 
|---|
| 33 | #define _util_group_message_h
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #include <map>
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #include <math.h>
 | 
|---|
| 38 | #include <util/class/class.h>
 | 
|---|
| 39 | #include <util/state/state.h>
 | 
|---|
| 40 | #include <util/keyval/keyval.h>
 | 
|---|
| 41 | #include <util/group/topology.h>
 | 
|---|
| 42 | 
 | 
|---|
| 43 | namespace sc {
 | 
|---|
| 44 | 
 | 
|---|
| 45 | template <class T>
 | 
|---|
| 46 | class GrpReduce {
 | 
|---|
| 47 |   public:
 | 
|---|
| 48 |     virtual ~GrpReduce() {};
 | 
|---|
| 49 |     virtual void reduce(T*target, T*data, int n) = 0;
 | 
|---|
| 50 | };
 | 
|---|
| 51 | 
 | 
|---|
| 52 | template <class T>
 | 
|---|
| 53 | class GrpSumReduce: public GrpReduce<T> {
 | 
|---|
| 54 |   public:
 | 
|---|
| 55 |     ~GrpSumReduce() {};
 | 
|---|
| 56 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 57 | };
 | 
|---|
| 58 | 
 | 
|---|
| 59 | template <class T>
 | 
|---|
| 60 | class GrpMinReduce: public GrpReduce<T> {
 | 
|---|
| 61 |   public:
 | 
|---|
| 62 |     ~GrpMinReduce() {};
 | 
|---|
| 63 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 64 | };
 | 
|---|
| 65 | 
 | 
|---|
| 66 | template <class T>
 | 
|---|
| 67 | class GrpMaxReduce: public GrpReduce<T> {
 | 
|---|
| 68 |   public:
 | 
|---|
| 69 |     ~GrpMaxReduce() {};
 | 
|---|
| 70 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 71 | };
 | 
|---|
| 72 | 
 | 
|---|
| 73 | template <class T>
 | 
|---|
| 74 | class GrpArithmeticAndReduce: public GrpReduce<T> {
 | 
|---|
| 75 |   public:
 | 
|---|
| 76 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 77 | };
 | 
|---|
| 78 | 
 | 
|---|
| 79 | template <class T>
 | 
|---|
| 80 | class GrpArithmeticOrReduce: public GrpReduce<T> {
 | 
|---|
| 81 |   public:
 | 
|---|
| 82 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 83 | };
 | 
|---|
| 84 | 
 | 
|---|
| 85 | template <class T>
 | 
|---|
| 86 | class GrpArithmeticXOrReduce: public GrpReduce<T> {
 | 
|---|
| 87 |   public:
 | 
|---|
| 88 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 89 | };
 | 
|---|
| 90 | 
 | 
|---|
| 91 | template <class T>
 | 
|---|
| 92 | class GrpProductReduce: public GrpReduce<T> {
 | 
|---|
| 93 |   public:
 | 
|---|
| 94 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 95 | };
 | 
|---|
| 96 | 
 | 
|---|
| 97 | template <class T>
 | 
|---|
| 98 | class GrpFunctionReduce: public GrpReduce<T> {
 | 
|---|
| 99 |   private:
 | 
|---|
| 100 |     void (*func_)(T*target,T*data,int nelement);
 | 
|---|
| 101 |   public:
 | 
|---|
| 102 |     GrpFunctionReduce(void(*func)(T*,T*,int)):func_(func) {}
 | 
|---|
| 103 |     void reduce(T*target, T*data, int nelement);
 | 
|---|
| 104 | };
 | 
|---|
| 105 | 
 | 
|---|
| 106 | /** The MessageGrp abstract class provides
 | 
|---|
| 107 |     a mechanism for moving data and objects between
 | 
|---|
| 108 |     nodes in a parallel machine. */
 | 
|---|
| 109 | class MessageGrp: public DescribedClass {
 | 
|---|
| 110 |   private:
 | 
|---|
| 111 |     // These are initialized by the initialize() member (see below).
 | 
|---|
| 112 |     int me_;
 | 
|---|
| 113 |     int n_;
 | 
|---|
| 114 |     int nclass_;
 | 
|---|
| 115 |     int gop_max_;
 | 
|---|
| 116 |     std::map<ClassDescP,int> classdesc_to_index_;
 | 
|---|
| 117 |     ClassDescP *index_to_classdesc_;
 | 
|---|
| 118 |   protected:
 | 
|---|
| 119 |     /** The classdesc_to_index_ and index_to_classdesc_ arrays
 | 
|---|
| 120 |         cannot be initialized by the MessageGrp CTOR, because
 | 
|---|
| 121 |         the MessageGrp specialization has not yet been initialized
 | 
|---|
| 122 |         and communication is not available.  CTOR's of specializations
 | 
|---|
| 123 |         of MessageGrp must call the initialize member in their body
 | 
|---|
| 124 |         to complete the initialization process. */
 | 
|---|
| 125 |     void initialize(int me, int n);
 | 
|---|
| 126 | 
 | 
|---|
| 127 |     Ref<MachineTopology> topology_;
 | 
|---|
| 128 | 
 | 
|---|
| 129 |     int debug_;
 | 
|---|
| 130 |   public:
 | 
|---|
| 131 |     MessageGrp();
 | 
|---|
| 132 |     MessageGrp(const Ref<KeyVal>&);
 | 
|---|
| 133 |     virtual ~MessageGrp();
 | 
|---|
| 134 |     
 | 
|---|
| 135 |     /// Returns the number of processors.
 | 
|---|
| 136 |     int n() { return n_; }
 | 
|---|
| 137 |     /// Returns my processor number.  In the range [0,n()).
 | 
|---|
| 138 |     int me() { return me_; }
 | 
|---|
| 139 | 
 | 
|---|
| 140 |     /** Returns a copy of this MessageGrp specialization that provides
 | 
|---|
| 141 |         an independent communication context. */
 | 
|---|
| 142 |     virtual Ref<MessageGrp> clone(void)=0;
 | 
|---|
| 143 |     
 | 
|---|
| 144 |     /** The default message group contains the primary message group to
 | 
|---|
| 145 |         be used by an application. */
 | 
|---|
| 146 |     static void set_default_messagegrp(const Ref<MessageGrp>&);
 | 
|---|
| 147 |     /// Returns the default message group.
 | 
|---|
| 148 |     static MessageGrp* get_default_messagegrp();
 | 
|---|
| 149 | 
 | 
|---|
| 150 |     /** Create a message group.  This routine looks for a -messagegrp
 | 
|---|
| 151 |         argument, then the environmental variable MESSAGEGRP to decide which
 | 
|---|
| 152 |         specialization of MessageGrp would be appropriate.  The
 | 
|---|
| 153 |         argument to -messagegrp should be either string for a
 | 
|---|
| 154 |         ParsedKeyVal constructor or a classname.  If this returns
 | 
|---|
| 155 |         null, it is up to the programmer to create a MessageGrp. */
 | 
|---|
| 156 |     static MessageGrp* initial_messagegrp(int &argc, char** &argv);
 | 
|---|
| 157 | 
 | 
|---|
| 158 |     /** Send messages sequentially to the target processor.
 | 
|---|
| 159 |         Similar members exist for each of the basic types. */
 | 
|---|
| 160 |     virtual void send(int target, const double* data, int ndata);
 | 
|---|
| 161 |     virtual void send(int target, const unsigned int* data, int ndata);
 | 
|---|
| 162 |     virtual void send(int target, const int* data, int ndata);
 | 
|---|
| 163 |     virtual void send(int target, const char* data, int nbyte);
 | 
|---|
| 164 |     virtual void send(int target, const unsigned char* data, int nbyte);
 | 
|---|
| 165 |     virtual void send(int target, const signed char* data, int nbyte);
 | 
|---|
| 166 |     virtual void send(int target, const short* data, int ndata);
 | 
|---|
| 167 |     virtual void send(int target, const long* data, int ndata);
 | 
|---|
| 168 |     virtual void send(int target, const float* data, int ndata);
 | 
|---|
| 169 |     void send(int target, double data) { send(target,&data,1); }
 | 
|---|
| 170 |     void send(int target, int data) { send(target,&data,1); }
 | 
|---|
| 171 |     virtual void raw_send(int target, const void* data, int nbyte) = 0;
 | 
|---|
| 172 | 
 | 
|---|
| 173 |     /** Send typed messages to the target processor.
 | 
|---|
| 174 |         Similar members exist for each of the basic types. */
 | 
|---|
| 175 |     virtual void sendt(int target, int type, const double* data, int ndata);
 | 
|---|
| 176 |     virtual void sendt(int target, int type, const unsigned int* data, int ndata);
 | 
|---|
| 177 |     virtual void sendt(int target, int type, const int* data, int ndata);
 | 
|---|
| 178 |     virtual void sendt(int target, int type, const char* data, int nbyte);
 | 
|---|
| 179 |     virtual void sendt(int target, int type, const unsigned char* data, int nbyte);
 | 
|---|
| 180 |     virtual void sendt(int target, int type, const signed char* data, int nbyte);
 | 
|---|
| 181 |     virtual void sendt(int target, int type, const short* data, int ndata);
 | 
|---|
| 182 |     virtual void sendt(int target, int type, const long* data, int ndata);
 | 
|---|
| 183 |     virtual void sendt(int target, int type, const float* data, int ndata);
 | 
|---|
| 184 |     void sendt(int target, int type, double data) {sendt(target,type,&data,1);}
 | 
|---|
| 185 |     void sendt(int target, int type, int data) {sendt(target,type,&data,1);}
 | 
|---|
| 186 |     virtual void raw_sendt(int target, int type, const void* data, int nbyte) = 0;
 | 
|---|
| 187 | 
 | 
|---|
| 188 |     /** Receive messages sent sequentually from the sender.
 | 
|---|
| 189 |         Similar members exist for each of the basic types. */
 | 
|---|
| 190 |     virtual void recv(int sender, double* data, int ndata);
 | 
|---|
| 191 |     virtual void recv(int sender, unsigned int* data, int ndata);
 | 
|---|
| 192 |     virtual void recv(int sender, int* data, int ndata);
 | 
|---|
| 193 |     virtual void recv(int sender, char* data, int nbyte);
 | 
|---|
| 194 |     virtual void recv(int sender, unsigned char* data, int nbyte);
 | 
|---|
| 195 |     virtual void recv(int sender, signed char* data, int nbyte);
 | 
|---|
| 196 |     virtual void recv(int sender, short* data, int ndata);
 | 
|---|
| 197 |     virtual void recv(int sender, long* data, int ndata);
 | 
|---|
| 198 |     virtual void recv(int sender, float* data, int ndata);
 | 
|---|
| 199 |     void recv(int sender, double& data) { recv(sender,&data,1); }
 | 
|---|
| 200 |     void recv(int sender, int& data) { recv(sender,&data,1); }
 | 
|---|
| 201 |     virtual void raw_recv(int sender, void* data, int nbyte) = 0;
 | 
|---|
| 202 | 
 | 
|---|
| 203 |     /** Receive messages sent by type.
 | 
|---|
| 204 |         Similar members exist for each of the basic types. */
 | 
|---|
| 205 |     virtual void recvt(int type, double* data, int ndata);
 | 
|---|
| 206 |     virtual void recvt(int type, unsigned int* data, int ndata);
 | 
|---|
| 207 |     virtual void recvt(int type, int* data, int ndata);
 | 
|---|
| 208 |     virtual void recvt(int type, char* data, int nbyte);
 | 
|---|
| 209 |     virtual void recvt(int type, unsigned char* data, int nbyte);
 | 
|---|
| 210 |     virtual void recvt(int type, signed char* data, int nbyte);
 | 
|---|
| 211 |     virtual void recvt(int type, short* data, int ndata);
 | 
|---|
| 212 |     virtual void recvt(int type, long* data, int ndata);
 | 
|---|
| 213 |     virtual void recvt(int type, float* data, int ndata);
 | 
|---|
| 214 |     void recvt(int type, double& data) { recvt(type,&data,1); }
 | 
|---|
| 215 |     void recvt(int type, int& data) { recvt(type,&data,1); }
 | 
|---|
| 216 |     virtual void raw_recvt(int type, void* data, int nbyte) = 0;
 | 
|---|
| 217 | 
 | 
|---|
| 218 |     /// Ask if a given typed message has been received.
 | 
|---|
| 219 |     virtual int probet(int type) = 0;
 | 
|---|
| 220 | 
 | 
|---|
| 221 |     /** Do broadcasts of various types of data.
 | 
|---|
| 222 |         Similar members exist for each of the basic types. */
 | 
|---|
| 223 |     virtual void bcast(double* data, int ndata, int from = 0);
 | 
|---|
| 224 |     virtual void bcast(unsigned int* data, int ndata, int from = 0);
 | 
|---|
| 225 |     virtual void bcast(int* data, int ndata, int from = 0);
 | 
|---|
| 226 |     virtual void bcast(char* data, int nbyte, int from = 0);
 | 
|---|
| 227 |     virtual void bcast(unsigned char* data, int nbyte, int from = 0);
 | 
|---|
| 228 |     virtual void bcast(signed char* data, int nbyte, int from = 0);
 | 
|---|
| 229 |     virtual void bcast(short* data, int ndata, int from = 0);
 | 
|---|
| 230 |     virtual void bcast(long* data, int ndata, int from = 0);
 | 
|---|
| 231 |     virtual void bcast(float* data, int ndata, int from = 0);
 | 
|---|
| 232 |     virtual void raw_bcast(void* data, int nbyte, int from = 0);
 | 
|---|
| 233 |     void bcast(double& data, int from = 0) { bcast(&data, 1, from); }
 | 
|---|
| 234 |     void bcast(int& data, int from = 0) { bcast(&data, 1, from); }
 | 
|---|
| 235 | 
 | 
|---|
| 236 |     /** Collect data distributed on the nodes to a big array replicated
 | 
|---|
| 237 |         on each node. */
 | 
|---|
| 238 |     virtual void raw_collect(const void *part, const int *lengths,
 | 
|---|
| 239 |                              void *whole, int bytes_per_datum=1);
 | 
|---|
| 240 |     void collect(const double *part, const int *lengths, double *whole);
 | 
|---|
| 241 | 
 | 
|---|
| 242 |     /** Global sum reduction.
 | 
|---|
| 243 |         Similar members exist for each of the basic types. */
 | 
|---|
| 244 |     virtual void sum(double* data, int n, double* = 0, int target = -1);
 | 
|---|
| 245 |     virtual void sum(unsigned int* data, int n, unsigned int* = 0, int target = -1);
 | 
|---|
| 246 |     virtual void sum(int* data, int n, int* = 0, int target = -1);
 | 
|---|
| 247 |     virtual void sum(char* data, int n, char* = 0, int target = -1);
 | 
|---|
| 248 |     virtual void sum(unsigned char* data, int n,
 | 
|---|
| 249 |                      unsigned char* = 0, int target = -1);
 | 
|---|
| 250 |     virtual void sum(signed char* data, int n,
 | 
|---|
| 251 |                      signed char* = 0, int target = -1);
 | 
|---|
| 252 |     void sum(double& data) { sum(&data, 1); }
 | 
|---|
| 253 |     void sum(int& data) { sum(&data, 1); }
 | 
|---|
| 254 |     /** Global maximization.
 | 
|---|
| 255 |         Similar members exist for each of the basic types. */
 | 
|---|
| 256 |     virtual void max(double* data, int n, double* = 0, int target = -1);
 | 
|---|
| 257 |     virtual void max(int* data, int n, int* = 0, int target = -1);
 | 
|---|
| 258 |     virtual void max(unsigned int* data, int n, unsigned int* = 0, int target = -1);
 | 
|---|
| 259 |     virtual void max(char* data, int n, char* = 0, int target = -1);
 | 
|---|
| 260 |     virtual void max(unsigned char* data, int n,
 | 
|---|
| 261 |                      unsigned char* = 0, int target = -1);
 | 
|---|
| 262 |     virtual void max(signed char* data, int n,
 | 
|---|
| 263 |                      signed char* = 0, int target = -1);
 | 
|---|
| 264 |     void max(double& data) { max(&data, 1); }
 | 
|---|
| 265 |     void max(int& data) { max(&data, 1); }
 | 
|---|
| 266 |     /** Global minimization.
 | 
|---|
| 267 |         Similar members exist for each of the basic types. */
 | 
|---|
| 268 |     virtual void min(double* data, int n, double* = 0, int target = -1);
 | 
|---|
| 269 |     virtual void min(int* data, int n, int* = 0, int target = -1);
 | 
|---|
| 270 |     virtual void min(unsigned int* data, int n, unsigned int* = 0, int target = -1);
 | 
|---|
| 271 |     virtual void min(char* data, int n, char* = 0, int target = -1);
 | 
|---|
| 272 |     virtual void min(unsigned char* data, int n,
 | 
|---|
| 273 |                      unsigned char* = 0, int target = -1);
 | 
|---|
| 274 |     virtual void min(signed char* data, int n,
 | 
|---|
| 275 |                      signed char* = 0, int target = -1);
 | 
|---|
| 276 |     void min(double& data) { min(&data, 1); }
 | 
|---|
| 277 |     void min(int& data) { min(&data, 1); }
 | 
|---|
| 278 |     /** Global generic reduction.
 | 
|---|
| 279 |         Similar members exist for each of the basic types. */
 | 
|---|
| 280 |     virtual void reduce(double*, int n, GrpReduce<double>&,
 | 
|---|
| 281 |                         double*scratch = 0, int target = -1);
 | 
|---|
| 282 |     virtual void reduce(int*, int n, GrpReduce<int>&,
 | 
|---|
| 283 |                         int*scratch = 0, int target = -1);
 | 
|---|
| 284 |     virtual void reduce(unsigned int*, int n, GrpReduce<unsigned int>&,
 | 
|---|
| 285 |                         unsigned int*scratch = 0, int target = -1);
 | 
|---|
| 286 |     virtual void reduce(char*, int n, GrpReduce<char>&,
 | 
|---|
| 287 |                         char*scratch = 0, int target = -1);
 | 
|---|
| 288 |     virtual void reduce(unsigned char*, int n, GrpReduce<unsigned char>&,
 | 
|---|
| 289 |                         unsigned char*scratch = 0, int target = -1);
 | 
|---|
| 290 |     virtual void reduce(signed char*, int n, GrpReduce<signed char>&,
 | 
|---|
| 291 |                         signed char*scratch = 0, int target = -1);
 | 
|---|
| 292 |     virtual void reduce(short*, int n, GrpReduce<short>&,
 | 
|---|
| 293 |                         short*scratch = 0, int target = -1);
 | 
|---|
| 294 |     virtual void reduce(float*, int n, GrpReduce<float>&,
 | 
|---|
| 295 |                         float*scratch = 0, int target = -1);
 | 
|---|
| 296 |     virtual void reduce(long*, int n, GrpReduce<long>&,
 | 
|---|
| 297 |                         long*scratch = 0, int target = -1);
 | 
|---|
| 298 |     void reduce(double& data, GrpReduce<double>& r) { reduce(&data, 1, r); }
 | 
|---|
| 299 |     void reduce(int& data, GrpReduce<int>& r) { reduce(&data, 1, r); }
 | 
|---|
| 300 | 
 | 
|---|
| 301 |     /// Synchronize all of the processors.
 | 
|---|
| 302 |     virtual void sync();
 | 
|---|
| 303 | 
 | 
|---|
| 304 |     /// Return the MachineTopology object.
 | 
|---|
| 305 |     Ref<MachineTopology> topology() { return topology_; }
 | 
|---|
| 306 | 
 | 
|---|
| 307 |     /** Each message group maintains an association of ClassDesc with
 | 
|---|
| 308 |         a global index so SavableState information can be sent between
 | 
|---|
| 309 |         nodes without needing to send the classname and look up the
 | 
|---|
| 310 |         ClassDesc with each transfer.  These routines return information
 | 
|---|
| 311 |         about that mapping. */
 | 
|---|
| 312 |     int classdesc_to_index(const ClassDesc*);
 | 
|---|
| 313 |     const ClassDesc* index_to_classdesc(int);
 | 
|---|
| 314 |     int nclass() const { return nclass_; }
 | 
|---|
| 315 | };
 | 
|---|
| 316 | 
 | 
|---|
| 317 | struct message_struct {
 | 
|---|
| 318 |   void *buf;
 | 
|---|
| 319 |   int size;
 | 
|---|
| 320 |   int type;
 | 
|---|
| 321 |   struct message_struct *p;
 | 
|---|
| 322 |   };
 | 
|---|
| 323 | typedef struct message_struct message_t;
 | 
|---|
| 324 | 
 | 
|---|
| 325 | 
 | 
|---|
| 326 | /** ProcMessageGrp provides a concrete specialization
 | 
|---|
| 327 |     of MessageGrp that supports only one node. */
 | 
|---|
| 328 | class ProcMessageGrp: public MessageGrp {
 | 
|---|
| 329 |   private:
 | 
|---|
| 330 |     // Messages are stored in these linked lists
 | 
|---|
| 331 |     message_t *sync_messages;
 | 
|---|
| 332 |     message_t *type_messages;
 | 
|---|
| 333 | 
 | 
|---|
| 334 |     void sendit(message_t *& messages, int dest, int msgtype, const void* buf, int bytes);
 | 
|---|
| 335 |     void recvit(message_t *& messages, int source, int type, void* buf, int bytes,
 | 
|---|
| 336 |                 int& last_size, int& last_type);
 | 
|---|
| 337 |         
 | 
|---|
| 338 |   public:
 | 
|---|
| 339 |     ProcMessageGrp();
 | 
|---|
| 340 |     ProcMessageGrp(const Ref<KeyVal>&);
 | 
|---|
| 341 |     ~ProcMessageGrp();
 | 
|---|
| 342 | 
 | 
|---|
| 343 |     Ref<MessageGrp> clone(void);
 | 
|---|
| 344 |     
 | 
|---|
| 345 |     void raw_send(int target, const void* data, int nbyte);
 | 
|---|
| 346 |     void raw_sendt(int target, int type, const void* data, int nbyte);
 | 
|---|
| 347 |     void raw_recv(int sender, void* data, int nbyte);
 | 
|---|
| 348 |     void raw_recvt(int type, void* data, int nbyte);
 | 
|---|
| 349 |     void raw_bcast(void* data, int nbyte, int from);
 | 
|---|
| 350 |     int probet(int type);
 | 
|---|
| 351 |     void sync();
 | 
|---|
| 352 | };
 | 
|---|
| 353 | 
 | 
|---|
| 354 | /** Uses integer message types to send and receive messages.
 | 
|---|
| 355 |     Message group specializations that use the MPI library
 | 
|---|
| 356 |     and the Paragon NX can be conveniently implemented in terms
 | 
|---|
| 357 |     of this. */
 | 
|---|
| 358 | class intMessageGrp: public MessageGrp {
 | 
|---|
| 359 |   protected:
 | 
|---|
| 360 |     int msgtype_nbit; // the total number of bits available
 | 
|---|
| 361 |     int ctl_nbit; // control information bits
 | 
|---|
| 362 |     int seq_nbit; // sequence information bits
 | 
|---|
| 363 |     int typ_nbit; // type information bits
 | 
|---|
| 364 |     int src_nbit; // source information bits
 | 
|---|
| 365 | 
 | 
|---|
| 366 |     // Masks for the fields in the type.
 | 
|---|
| 367 |     int ctl_mask;
 | 
|---|
| 368 |     int seq_mask;
 | 
|---|
| 369 |     int typ_mask;
 | 
|---|
| 370 |     int src_mask;
 | 
|---|
| 371 | 
 | 
|---|
| 372 |     // Shifts to construct a message type.
 | 
|---|
| 373 |     int ctl_shift;
 | 
|---|
| 374 |     int seq_shift;
 | 
|---|
| 375 |     int typ_shift;
 | 
|---|
| 376 |     int src_shift;
 | 
|---|
| 377 | 
 | 
|---|
| 378 |     int msgtype_typ(int msgtype);
 | 
|---|
| 379 |     int typ_msgtype(int usrtype);
 | 
|---|
| 380 |     int seq_msgtype(int source, int seq);
 | 
|---|
| 381 | 
 | 
|---|
| 382 |     // The next sequence number for each node is stored in these.
 | 
|---|
| 383 |     int *source_seq;
 | 
|---|
| 384 |     int *target_seq;
 | 
|---|
| 385 |     
 | 
|---|
| 386 |     /// Must be implemented by specializations.
 | 
|---|
| 387 |     virtual void basic_send(int target, int type, const void* data, int nbyte) = 0;
 | 
|---|
| 388 |     /// Must be implemented by specializations.
 | 
|---|
| 389 |     virtual void basic_recv(int type, void* data, int nbyte) = 0;
 | 
|---|
| 390 |     /// Must be implemented by specializations.
 | 
|---|
| 391 |     virtual int basic_probe(int type) = 0;
 | 
|---|
| 392 | 
 | 
|---|
| 393 |     intMessageGrp();
 | 
|---|
| 394 |     intMessageGrp(const Ref<KeyVal>&);
 | 
|---|
| 395 | 
 | 
|---|
| 396 |     void initialize(int me, int n, int nbits);
 | 
|---|
| 397 |   public:
 | 
|---|
| 398 |     ~intMessageGrp();
 | 
|---|
| 399 | 
 | 
|---|
| 400 |     void raw_send(int target, const void* data, int nbyte);
 | 
|---|
| 401 |     void raw_recv(int sender, void* data, int nbyte);
 | 
|---|
| 402 |     void raw_sendt(int target, int type, const void* data, int nbyte);
 | 
|---|
| 403 |     void raw_recvt(int type, void* data, int nbyte);
 | 
|---|
| 404 | 
 | 
|---|
| 405 |     int probet(int);
 | 
|---|
| 406 | 
 | 
|---|
| 407 |     int leftover_ctl_bits();
 | 
|---|
| 408 | };
 | 
|---|
| 409 | 
 | 
|---|
| 410 | }
 | 
|---|
| 411 | 
 | 
|---|
| 412 | #include <util/group/messaget.h>
 | 
|---|
| 413 | 
 | 
|---|
| 414 | #endif
 | 
|---|
| 415 | 
 | 
|---|
| 416 | 
 | 
|---|
| 417 | // Local Variables:
 | 
|---|
| 418 | // mode: c++
 | 
|---|
| 419 | // c-file-style: "CLJ"
 | 
|---|
| 420 | // End:
 | 
|---|