/home/coin/SVN-release/OS-2.1.1/Bcp/src/Member/BCP_message_mpi.cpp

Go to the documentation of this file.
00001 // BCP_message_mpi.cpp is a declaration of BCP_message_mpi
00002 // Sonya Marcarelli & Igor Vasil'ev (vil@icc.ru)
00003 // All Rights Reserved.
00004 
00005 #include "BcpConfig.h"
00006 #if defined(COIN_HAS_MPI)
00007 
00008 #include <cstdio>
00009 #include <cmath>
00010 
00011 #define MPICH_SKIP_MPICXX
00012 #include <mpi.h>
00013 
00014 #include "BCP_error.hpp"
00015 #include "BCP_process.hpp"
00016 #include "BCP_buffer.hpp"
00017 #include "BCP_vector.hpp"
00018 #include "BCP_message_mpi.hpp"
00019 
00020 bool BCP_mpi_environment::mpi_init_called = false;
00021 int BCP_mpi_environment::num_proc = 0;
00022 int BCP_mpi_environment::seqproc = 0;
00023 
00024 //#############################################################################
00025 
00026 int BCP_mpi_environment::is_mpi(int argc, char *argv[])
00027 {
00028     int pid;
00029     if (! mpi_init_called) {
00030         MPI_Init(&argc, &argv);
00031         // MPI_Init may or may not have succeeded. In any case check if we can
00032         // get the number of procs
00033         if (MPI_Comm_size(MPI_COMM_WORLD, &num_proc) != MPI_SUCCESS) {
00034             // Now it's certain. Not an MPI environment
00035             return -1;
00036         }
00037         mpi_init_called = true;
00038     }
00039     MPI_Comm_rank(MPI_COMM_WORLD, &pid);
00040     return pid;
00041 }
00042 
00043 //#############################################################################
00044 
00045 
00046 BCP_mpi_environment::BCP_mpi_environment(int argc, char *argv[])
00047 {
00048     /* Initialize the MPI environment. */
00049     is_mpi(argc, argv);
00050 }
00051 
00052 //-----------------------------------------------------------------------------
00053 
00054 BCP_mpi_environment::~BCP_mpi_environment()
00055 {
00056     MPI_Finalize();
00057     mpi_init_called = false;
00058 }
00059 
00060 //-----------------------------------------------------------------------------
00061 
00062 void
00063 BCP_mpi_environment::check_error(const int code, const char* str) const
00064 {
00065     if (code != MPI_SUCCESS){
00066         printf("%s returned error code %i.\n", str, code);
00067         throw BCP_fatal_error(" ERROR in mpi -- exiting.\n");
00068     }
00069 }
00070 
00071 //-----------------------------------------------------------------------------
00072 
00073 int
00074 BCP_mpi_environment::register_process(USER_initialize* user_init)
00075 {
00076     int pid;
00077     MPI_Comm_rank(MPI_COMM_WORLD, &pid);
00078     setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00079     return pid;
00080 }
00081 
00082 int
00083 BCP_mpi_environment::parent_process()
00084 {
00085     int pid;
00086     MPI_Comm_rank(MPI_COMM_WORLD, &pid);
00087     if (pid == 0)
00088         //I am the master and I have no parent
00089         return -1;
00090     //The master process has got always pid=0
00091     return 0;
00092 }
00093 
00094 bool
00095 BCP_mpi_environment::alive(const int pid)
00096 {
00097     //In Mpi is not possible check if a process is alive
00098     /* FIXME */
00099     return true;
00100 }
00101 
00102 const int*
00103 BCP_mpi_environment::alive(int num, const int* pids)
00104 {
00105   //In Mpi is not possible check if a process is alive
00106   return NULL;
00107 }
00108 
00109 //-----------------------------------------------------------------------------
00110 
00111 void
00112 BCP_mpi_environment::send(const int target, const BCP_message_tag tag)
00113 {
00114     //create an empty buffer and send it with the tag
00115     void * buf = NULL;
00116     check_error(MPI_Send(&buf, 0, MPI_CHAR,
00117                          target, tag, MPI_COMM_WORLD),"MPI_Send");
00118 }
00119 
00120 void
00121 BCP_mpi_environment::send(const int target,
00122                           const BCP_message_tag tag, const BCP_buffer& buf)
00123 {
00124     check_error(MPI_Send(const_cast<char*>(buf.data()), buf.size(), MPI_CHAR,
00125                          target, tag, MPI_COMM_WORLD),"MPI_Send");
00126 }
00127 
00128 //-----------------------------------------------------------------------------
00129 
00130 void
00131 BCP_mpi_environment::multicast(int num, const int* targets,
00132                                const BCP_message_tag tag)
00133 {
00134     void * buf = NULL;
00135     for (int i = 0; i < num; ++i) {
00136         check_error(MPI_Send(&buf, 0, MPI_CHAR,
00137                              targets[i], tag, MPI_COMM_WORLD),"MPI_Send");
00138     }
00139 }
00140 
00141 void
00142 BCP_mpi_environment::multicast(int num, const int* targets,
00143                                const BCP_message_tag tag,
00144                                const BCP_buffer& buf)
00145 {
00146     for (int i = 0; i < num; ++i) {
00147         check_error(MPI_Send(const_cast<char*>(buf.data()), buf.size(),
00148                              MPI_CHAR, targets[i], tag, MPI_COMM_WORLD),
00149                     "MPI_Send");
00150     }
00151 }
00152 
00153 //-----------------------------------------------------------------------------
00154 
00155 void
00156 BCP_mpi_environment::receive(const int source,
00157                              const BCP_message_tag tag, BCP_buffer& buf,
00158                              const double timeout)
00159 {
00160     buf.clear();
00161     buf._sender = -1;
00162     int pid = (source == BCP_AnyProcess ? MPI_ANY_SOURCE : source);
00163     int msgtag = (tag == BCP_Msg_AnyMessage ? MPI_ANY_TAG : tag);
00164     int flag = 0;
00165     MPI_Status status;
00166 
00167     if (timeout < 0) {
00168         check_error(MPI_Probe(pid, msgtag, MPI_COMM_WORLD, &status),
00169                     "MPI_Probe");
00170         flag = 1;
00171     } else {
00172         check_error(MPI_Iprobe(pid, msgtag, MPI_COMM_WORLD, &flag, &status),
00173                     "MPI_Iprobe");
00174     }
00175     //There is no message
00176     if (!flag) {
00177         buf._msgtag = BCP_Msg_NoMessage;
00178         return;
00179     }
00180 
00181     int bytes;
00182     //Get the size of message
00183     check_error(MPI_Get_count( &status, MPI_CHAR, &bytes ),"MPI_Get_Count");
00184     buf.make_fit(bytes);
00185     buf._msgtag = static_cast<BCP_message_tag>(status.MPI_TAG);
00186     buf._sender = status.MPI_SOURCE;
00187     buf._size = bytes;
00188 
00189     //Receive the content of the message
00190     check_error(MPI_Recv(buf._data, bytes, MPI_CHAR,
00191                          pid, msgtag, MPI_COMM_WORLD, &status),"MPI_Recv");
00192 }
00193 
00194 
00195 
00196 //-----------------------------------------------------------------------------
00197 
00198 bool
00199 BCP_mpi_environment::probe(const int source, const BCP_message_tag tag)
00200 {
00201     MPI_Status  status;
00202     // MPI_Request request;
00203     int  flag = 0;
00204     int pid = (source == BCP_AnyProcess ? MPI_ANY_SOURCE : source);
00205     int msgtag = (tag == BCP_Msg_AnyMessage ? MPI_ANY_TAG : tag);
00206     check_error(MPI_Iprobe(pid, msgtag, MPI_COMM_WORLD, &flag, &status),
00207                 "MPI_Iprobe");
00208     return flag > 0;
00209 }
00210 
00211 //-----------------------------------------------------------------------------
00212 
00213 int
00214 BCP_mpi_environment::start_process(const BCP_string& exe, const bool debug)
00215 {
00216 #ifdef COIN_HAS_MPI2
00217     // FIXME: implement MPI2 proces spawning
00218     printf("Sorry, MPI2 process spawning is not supported yet...\n");
00219     abort();
00220 #else
00221     // Fake it...
00222     return ++seqproc;
00223 #endif
00224 }
00225 
00226 int
00227 BCP_mpi_environment::start_process(const BCP_string& exe,
00228                                    const BCP_string& machine,
00229                                    const bool debug)
00230 {
00231 #ifdef COIN_HAS_MPI2
00232     // FIXME: implement MPI2 proces spawning
00233     printf("Sorry, MPI2 process spawning is not supported yet...\n");
00234     abort();
00235 #else
00236     // Fake it...
00237     return ++seqproc;
00238 #endif
00239 }
00240 
00241 bool
00242 BCP_mpi_environment::start_processes(const BCP_string& exe,
00243                                      const int proc_num,
00244                                      const bool debug,
00245                          int* ids)
00246 {
00247 #ifdef COIN_HAS_MPI2
00248     // FIXME: implement MPI2 proces spawning
00249     printf("Sorry, MPI2 process spawning is not supported yet...\n");
00250     abort();
00251 #else
00252     // Fake it...
00253     for (int i = 0; i < proc_num; ++i) {
00254       ids[i] = ++seqproc;
00255     }
00256     return true;
00257 #endif
00258 }
00259 
00260 bool
00261 BCP_mpi_environment::start_processes(const BCP_string& exe,
00262                                      const int proc_num,
00263                                      const BCP_vec<BCP_string>& machines,
00264                                      const bool debug,
00265                          int* ids)
00266 {
00267 #ifdef COIN_HAS_MPI2
00268     // FIXME: implement MPI2 proces spawning
00269     printf("Sorry, MPI2 process spawning is not supported yet...\n");
00270     abort();
00271 #else
00272     // Fake it...
00273     for (int i = 0; i < proc_num; ++i) {
00274         ids[i] = ++seqproc;
00275     }
00276     return true;
00277 #endif
00278 }
00279 
00280 int BCP_mpi_environment::num_procs() {
00281     return num_proc;
00282 }
00283 
00284 //#define MPID_DEV_REQUEST_DECL
00285 #if 0
00286 struct MPIDI_BGLTS_Request {
00287     MPIDI_Message_match match;     /* enough information to to MPI matching */
00288     MPI_Datatype        datatype;  /* data type of message */
00289     struct MPID_Datatype *datatype_ptr;
00290     int ca; /* completion action */
00291     char *userbuf;  /* user buffer for messages */
00292     unsigned userbufcount; /* count (not size) of userbuf */
00293     char *uebuf; /* unexpected buffer */
00294     unsigned uebuflen; /* length (bytes) of unexpected buffer */
00295     MPID_Segment segment; /* segment used for non-contigouous buffers */
00296     MPIDI_BGLTS_REQUEST_STATE state; /* state of request */
00297     int type; /* type of request, used by gettype and settype */
00298               /* one of send, rsend, recv, irecv. etc. */
00299     int msgtype; /* type of associated message */
00300                  /* one of self, eager, etc. */
00301     BGLML_Message msgdata;
00302     char slack[300];
00303     struct MPID_Request *next;    /* link to next request */
00304     int cancel_pending; /* Cancel State */
00305     int dest_rank;
00306     int dest_tag;
00307     int dest_context_id;
00308 } bglts;
00309 #endif
00310 
00311 #ifdef MPID_DEV_REQUEST_DECL
00312 int MPIDI_BGLTS_get_num_messages()
00313 {
00314     register MPID_Request * rreq = MPIDI_Process.recv_posted_head;
00315     register int cnt = 0;
00316     while (rreq != NULL) {
00317         ++cnt;
00318         rreq = rreq->bglts.next;
00319     }
00320     rreq = MPIDI_Process.recv_unexpected_head;
00321     while (rreq != NULL) {
00322         ++cnt;
00323         rreq = rreq->bglts.next;
00324     }
00325     return cnt;
00326 }
00327 #else
00328 int MPIDI_BGLTS_get_num_messages()
00329 {
00330     return -1;
00331 }
00332 #endif
00333 
00334 #endif /* COIN_HAS_MPI */

Generated on Mon May 3 03:05:12 2010 by  doxygen 1.4.7