| [0b990d] | 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:
 | 
|---|