Appendix: Public Interface of the NetStream Class
/*************************************************************************** *** netstream.cc *** *** v1.6 - July 2001 *** *** *** *** v1.5 - March 2001 *** *** v1.0 - November 2000 *** *** *** *** v1.5 extends v1.0: *** *** .- Changes metods init() and finalize() to be static *** *** .- Incorporates process group management *** *** .- Do not consider LEDA anymore *** *** .- Contains a method "int my_pid()" for easy invokations *** *** .- Adds "unsigned" and "long double" input/output *** *** *** *** v1.6 extends v1.5: *** *** .- Internal in/out buffers for packed separated *** *** *** *** Communication services for LAN/WAN use following the message *** *** passing paradigm. *** *** STREAM C++ VERSION *** *** MPI implementation *** *** Developed by Enrique Alba *** ***************************************************************************/ #ifndef INC_netstream #define INC_netstream #include "mpi.h" #include <assert.h> // Class NetStream allows to define and use network streams through LAN and WAN #define REGULAR_STREAM_TAG 0 // Used for tagging MPI regular messages #define PACKED_STREAM_TAG 1 // Used for tagging MPI packet messages #define NET_TYPE MPI_Datatype // Network allowable data types #define NET_BOOL MPI_CHAR // Bools like chars #define NET_CHAR MPI_CHAR #define NET_SHORT MPI_SHORT #define NET_INT MPI_INT #define NET_LONG MPI_LONG #define NET_UNSIGNED_CHAR MPI_UNSIGNED_CHAR #define NET_UNSIGNED_SHORT MPI_UNSIGNED_SHORT #define NET_UNSIGNED MPI_UNSIGNED #define NET_UNSIGNED_LONG MPI_UNSIGNED_LONG #define NET_FLOAT MPI_FLOAT #define NET_DOUBLE MPI_DOUBLE #define NET_LONG_DOUBLE MPI_LONG_DOUBLE #define NET_BYTE MPI_BYTE #define NET_PACKED MPI_PACKED #define NET_Comm MPI_Comm #define MAX_MSG_LENGTH 20480 // Max length of a message #define MAX_PACK_BUFFER_SIZE 20480 // Max length of a packed message // Help structure for manipulators having one int& argument class NetStream; struct smanip1c // "const int" { NetStream& (*f)(NetStream&, const int); // The ONE argument function int i; // The argument smanip1c( NetStream&(*ff)(NetStream&,const int), int ii) : f(ff), i(ii) {} // Constuctor }; struct smanip1 // "int*" note: references do not work! "int&" { NetStream& (*f)(NetStream&, int*); // The ONE argument function int* i; // The argument smanip1( NetStream&(*ff)(NetStream&, int*), int* ii) : f(ff), i(ii) {} // Constuctor }; // Tags for the available streams const int any = MPI_ANY_TAG; // Tag value valid for any stream const int regular = REGULAR_STREAM_TAG; // Tag value for regular stream of data const int packed = PACKED_STREAM_TAG; // Tag value for packed stream of data class NetStream { public: NetStream (); // Default constructor // Constructor with source integer left unchanged NetStream (int, char **); // Init the communications ~NetStream (); // Default destructor static void init(int,char**); // Init the communication system. Invoke it only ONCE static void finalize(void); // Shutdown the communication system. Invoke it ONCE // GROUP management void set_communicator(NET_Comm comm); // Set the netstream to a new communicator NET_Comm get_communicator(void); // Get the present communicator in this netstream static NET_Comm create_group(NET_Comm comm, int color, int key); // Create a new group inside the present communicator // Create a bridge between local and remote MATCHING call static NET_Comm create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtrype); // BASIC INPUT SERVICES <comments> BASIC OUTPUT SERVICES // ============================================================================================================ NetStream& operator>> (bool& d); NetStream& operator<< (bool d); NetStream& operator>> (char& d); NetStream& operator<< (char d); NetStream& operator>> (short& d); NetStream& operator<< (short d); NetStream& operator>> (int& d); NetStream& operator<< (int d); NetStream& operator>> (long& d); NetStream& operator<< (long d); NetStream& operator>> (float& d); NetStream& operator<< (float d); NetStream& operator>> (double& d); NetStream& operator<< (double d); NetStream& operator>> (char* d); /*NULL terminated*/ NetStream& operator<< (char* d); NetStream& operator>> (void* d); /*NULL terminated*/ NetStream& operator<< (void* d); // Extended data types from version 1.5 on NetStream& operator>> (unsigned char& d); NetStream& operator<< (unsigned char d); NetStream& operator>> (unsigned short int& d); NetStream& operator<< (unsigned short int d); NetStream& operator>> (unsigned int& d); NetStream& operator<< (unsigned int d); NetStream& operator>> (unsigned long int& d); NetStream& operator<< (unsigned long int d); NetStream& operator>> (long double& d); NetStream& operator<< (long double d); int pnumber(void); // Returns the number of processes bool broadcast; // Determines whether the next sent message is for broadcasting // Input MANIPULATORS for modifying the behavior of the channel on the fly // NO ARGUMENTS NetStream& operator<< (NetStream& (*f)(NetStream& n)) { return f(*this); } // NO arguments NetStream& _barrier(void); // Sit and wait until all processes are in barrier NetStream& _pack_begin(void); // Marks the beginning of a packed information NetStream& _pack_end(void); // Marks the end of a packed and flush it to the net NetStream& _probe(const int stream_type, int& pending); // Check whether there are awaiting data NetStream& _broadcast(void); // Broadcast a message to all the processes // ONE ARGUMENT // "const int" NetStream& operator<< (smanip1c m) { return m.f((*this),m.i); }// ONE int& argument constant // "int*" NetStream& operator<< (smanip1 m) { return m.f((*this),m.i); }// ONE int& argument // BASIC CLASS METHODS FOR MANIPULATORS NetStream& _my_pid(int* pid); // Returns the process ID of the calling process NetStream& _wait(const int stream_type); // Wait for an incoming message in the specified stream NetStream& _set_target(const int p); // Establish "p" as the default receiver NetStream& _get_target(int* p); // Get into "p" the default receiver NetStream& _set_source(const int p); // Establish "p" as the default transmitter NetStream& _get_source(int* p); // Get into "p" the default transmitter // AUXILIAR PUBLIC METHODS FOR ALLOWING EASY MANAGEMENTS OF NETSTREAMS int my_pid(void); // Returns the process ID of the calling process private: int default_target, default_source; // Default process IDs to send-recv data to-from bool pack_in_progress; // Defines whether a packet is being defined with "pack_begin-pack_end" int packin_index; // Index to be used for extracting from a IN packed message - v1.6 int packout_index; // Index to be used for adding to an OUT packed message - v1.6 int pending_input_packet; // Is there a pending packet already read into the IN buffer? - v1.6 char* packin_buffer; // Buffer to temporary storage of the IN packed being defined - v1.6 char* packout_buffer; // Buffer to temporary storage of the OUT packed being defined - v1.6 bool pack_in, pack_out; // Define whether input-output packed message is being used void reset(void); // Reset member variables of this class NET_Comm my_communicator; // Communicator of this netstream void send(void* d, const int len, const NET_TYPE type, const int target); void rcv (void* d, const int len, const NET_TYPE type, const int source); }; // class NetStream // MANIPULATORS (must be static or non-member methods in C++ -mpiCC only allows non-member!-) // NO ARGUMENTS NetStream& barrier(NetStream& n); // Sit and wait until all processes are in barrier NetStream& broadcast(NetStream& n); // Broadcast a message to all the processes NetStream& pack_begin(NetStream& n); // Marks the beginning of a packed information NetStream& pack_end(NetStream& n); // Marks the end of a packed and flush it to the net // ONE ARGUMENT NetStream& __my_pid(NetStream& n, int* pid); // Returns the process ID of the calling process inline smanip1 my_pid(int* pid){ return smanip1(__my_pid,pid); } // manipulator NetStream& __wait(NetStream& n, const int stream_type);// Wait for an incoming message - helper inline smanip1c wait(const int stream_type){ return smanip1c(__wait,stream_type); } // manipulator NetStream& __set_target(NetStream& n, const int p); // Stablish "p" as the default receiver inline smanip1c set_target(const int p){ return smanip1c(__set_target,p); } // manipulator NetStream& __get_target(NetStream& n, int* p); // Get into "p" the default receiver inline smanip1 get_target(int* p){ return smanip1(__get_target,p); } // manipulator NetStream& __set_source(NetStream& n, const int p); // Stablish "p" as the default transmitter inline smanip1c set_source(const int p){ return smanip1c(__set_source,p); } // manipulator NetStream& __get_source(NetStream& n, int* p); // Get into "p" the default transmitter inline smanip1 get_source(int* p){ return smanip1(__get_source,p); } // manipulator // TWO ARGUMENTS - not used yet NetStream& probe(NetStream& n, const int stream_type, int& pending); // Check whether there are awaiting data #endif