Sandia Home Sandia Home
Main Page | Publications | Downloads | Configuration | Running the Code | Solver Parameters | FAQ | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

APPSPACK_GCI.cpp

Go to the documentation of this file.
00001 // $Id: APPSPACK_GCI.cpp,v 1.9 2005/08/10 19:13:00 tgkolda Exp $ 
00002 // $Source: /space/CVS-Acro/acro/packages/appspack/appspack/src/APPSPACK_GCI.cpp,v $ 
00003 
00004 //@HEADER
00005 // ************************************************************************
00006 // 
00007 //          APPSPACK: Asynchronous Parallel Pattern Search
00008 //                 Copyright (2003) Sandia Corporation
00009 // 
00010 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00011 // license for use of this work by or on behalf of the U.S. Government.
00012 // 
00013 // This library is free software; you can redistribute it and/or modify
00014 // it under the terms of the GNU Lesser General Public License as
00015 // published by the Free Software Foundation; either version 2.1 of the
00016 // License, or (at your option) any later version.
00017 //  
00018 // This library is distributed in the hope that it will be useful, but
00019 // WITHOUT ANY WARRANTY; without even the implied warranty of
00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021 // Lesser General Public License for more details.
00022 //                                                                                 
00023 // You should have received a copy of the GNU Lesser General Public
00024 // License along with this library; if not, write to the Free Software
00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00026 // USA.                                                                           .
00027 // 
00028 // Questions? Contact Tammy Kolda (tgkolda@sandia.gov) 
00029 // 
00030 // ************************************************************************
00031 //@HEADER
00032 
00038 #include "APPSPACK_GCI.hpp"
00039 
00040 using namespace APPSPACK;
00041 
00042 // ----------------------------------------------------------------------
00043 // Initialize
00044 // ----------------------------------------------------------------------
00045 
00046 #ifdef HAVE_PVM
00047 
00048 int GCI::lastBufferId = 0;
00049 struct pvmhostinfo* GCI::pvmHostInfo = NULL;
00050 int GCI::nHosts = 0;
00051 int GCI::nArch = 0;
00052 
00053 #elif defined HAVE_MPI
00054 
00055 char* GCI::sendBuffer = NULL;
00056 char* GCI::recvBuffer = NULL;
00057 int GCI::sendPosition = 0;
00058 int GCI::recvPosition = 0; 
00059 int GCI::msgSize = 0;
00060 MPI_Comm GCI::APPS_COMM = MPI_COMM_NULL;
00061 MPI_Status GCI::status;
00062 
00063 #endif
00064 
00065 // ----------------------------------------------------------------------
00066 // Functions
00067 // ----------------------------------------------------------------------
00068 
00069 // ----------------------------------------------------------------------
00070 // Initialize & Exit
00071 // ----------------------------------------------------------------------
00072 
00073 int GCI::init()
00074 {
00075   int argc = -1;
00076   char** argv = NULL;
00077   return GCI::init(argc, argv);
00078 }
00079 
00080 int GCI::init(int& argc, char**& argv) 
00081 { 
00082 
00083 #ifdef HAVE_PVM
00084 
00085   // PVM is initialized by calling any PVM command
00086   return GCI::getMyTid();
00087 
00088 #elif defined HAVE_MPI
00089 
00090   // This routine puts all processes in a communicator called
00091   // APPS_COMM.  Users who wish to divide the processes into more than
00092   // one communicator, in order to do multi-level parallelism for
00093   // instance, should add code to pare down worldgroup to just the set
00094   // of processes APPS should use. This function returns the process'
00095   // rank.
00096 
00097   if (argc == -1) 
00098   {
00099     cerr << "APPSPACK::GCI::init - must specify argc and argv when using MPI" << endl;
00100     throw "APPSPACK error";
00101   }
00102 
00103   MPI_Group worldGroup, appsGroup;
00104   int e;
00105   int groupSize;
00106   int* ranksInOldGroup;
00107 
00108   e = MPI_Init(&argc, &argv);
00109 
00110   if (e != MPI_SUCCESS) 
00111   {
00112     cerr << "APPSPACK::GCI::init - error initializing MPI." << endl;
00113     throw "APPSPACK error";
00114   }
00115   
00116   // Get the set of processes (group, in MPI lingo) associated with 
00117   // MPI_COMM_WORLD.
00118   e = MPI_Comm_group(MPI_COMM_WORLD, &worldGroup);
00119   if (e != MPI_SUCCESS) 
00120   {
00121     cerr << "APPSPACK::GCI::init - error calling MPI_Comm_group" << endl;
00122     throw "APPSPACK error";
00123   }
00124 
00125   // Find out how many process there are in the group.
00126   e = MPI_Group_size(worldGroup, &groupSize);
00127   if (e != MPI_SUCCESS) 
00128   {
00129     cerr << "APPSPACK::GCI::init - error calling MPI_Group_size" << endl;
00130     throw "APPSPACK error";
00131   }
00132 
00133   // Build an array of ranks to include in the new communicator.  
00134   // The process with rank ranksInOldGroup[0] will have rank 0 in the 
00135   // new groupd, ranksInOldGroup[1] will have rank 1, etc.
00136   // In this case, since we want the new group to be the same as the
00137   // old, we include all ranks in the original order.
00138   ranksInOldGroup = new int[groupSize];
00139   for (int i = 0; i < groupSize; i++)
00140     ranksInOldGroup[i] = i;
00141 
00142   // Create the new group.
00143   e = MPI_Group_incl(worldGroup, groupSize, ranksInOldGroup, &appsGroup);
00144   if (e != MPI_SUCCESS) 
00145   {
00146     cerr << "APPSPACK::GCI::init - error calling MPI_Group_incl" << endl;
00147     throw "APPSPACK error";
00148   }
00149 
00150   // Create a new communicator which has the processes in group
00151   // appsGroup, drawn from MPI_COMM_WORLD.
00152   e = MPI_Comm_create(MPI_COMM_WORLD, appsGroup, &APPS_COMM);
00153   if (e != MPI_SUCCESS) 
00154   {
00155     cerr << "APPSPACK::GCI::init - error calling MPI_Comm_create" << endl;
00156     throw "APPSPACK error";
00157   }
00158 
00159   delete[] ranksInOldGroup;
00160 
00161   return GCI::getMyTid();
00162 
00163 #else
00164 
00165   cerr << "APPSPACK::GCI::init - requires PVM or MPI" << endl; 
00166   throw "APPSPACK error";
00167 
00168 #endif
00169 }
00170 
00171 void GCI::catchOutput(bool flag)
00172 {
00173   // Set standard output to pipe through this process ONLY IF this
00174   // process HAS NOT been launched from the PVM console. If flag
00175   // (default true) is false, then disable output redirection.
00176 
00177 #ifdef HAVE_PVM
00178 
00179   if (flag) 
00180   {
00181     if (pvm_parent() == PvmParentNotSet) // running from PVM console
00182       return;
00183     pvm_catchout(stdout);
00184     pvm_setopt(PvmShowTids, 0);
00185   }
00186   else
00187     pvm_catchout(0);
00188 
00189 #else
00190 
00191   cerr << "Warning! APPSPACK::GCI::catchOutput requires PVM" << endl;
00192 
00193 #endif
00194 }
00195 
00196 int GCI::spawn(const string name, const string host, char* argv[])
00197 {
00198   // Spawn a SINGLE task with the given name on a specified host. If
00199   // the host name is unspecified (""), then the task is spawned on
00200   // any available machine. Default argv is NULL. Return 0 if the
00201   // spawn failed. Otherwise, return the taskid.
00202 
00203 #ifdef HAVE_PVM
00204 
00205   int taskId;
00206   int info;
00207 
00208   if (host == "") 
00209     info = pvm_spawn(const_cast<char*>(name.c_str()), argv, PvmTaskDefault, 
00210                      NULL, 1, &taskId);
00211   else 
00212     info = pvm_spawn(const_cast<char*>(name.c_str()), argv, PvmTaskHost, 
00213                      const_cast<char*>(host.c_str()), 1, &taskId);
00214 
00215   if (info == PvmBadParam) 
00216   {
00217     cerr << "APPSPACK::GCI::spawn - invalid parameter" << endl;
00218     throw "APPSPACK error";
00219   }
00220 
00221   if (info == PvmNoHost) 
00222   {
00223     cerr << "APPSPACK::GCI::spawn - requested host is not in virtual machine" << endl;
00224     throw "APPSPACK error";
00225   }
00226 
00227   if (info == PvmNoFile) 
00228   {
00229     cerr << "APPSPACK::GCI::spawn - executable cannot be found" << endl;
00230     return 0;
00231   }
00232 
00233   if (info == PvmNoMem) 
00234   {
00235     cerr << "APPSPACK::GCI::spawn - not enough memory on host" << endl;
00236     return 0;
00237   }
00238 
00239   if (info == PvmSysErr) 
00240   {
00241     cerr <<  "APPSPACK::GCI::spawn - pvmd not responding" << endl;
00242     return 0;
00243   }
00244 
00245   if (info == PvmOutOfRes) 
00246   {
00247     cerr <<  "APPSPACK::GCI::spawn - out of resources" << endl;
00248     return 0;
00249   }
00250 
00251   if (info < 0) 
00252   {
00253     cerr << "APPSPACK::GCI::spawn - unrecgonized error" << endl;
00254     throw "APPSPACK error";
00255   }
00256 
00257   if (info < 1)
00258     return 0;
00259 
00260   return taskId;
00261 
00262 #else
00263 
00264   cerr << "APPSPACK::GCI::spawn requires PVM" << endl;
00265   throw "APPSPACK error";
00266 
00267 #endif
00268 }
00269 
00270 void GCI::kill(int taskId)
00271 {
00272   // Kill the process with the given task id.
00273 
00274 #ifdef HAVE_PVM
00275 
00276   int info = pvm_kill(taskId);
00277 
00278   if (info == PvmSysErr) 
00279   {
00280     cerr << "APPSPACK::GCI::kill -  pvmd not responding" << endl;
00281     throw "APPSPACK error";
00282   }
00283   if (info == PvmBadParam) 
00284   {
00285     cerr << "APPSPACK::GCI::kill - invalid taskId" << endl;
00286     throw "APPSPACK error";
00287   }
00288   if (info < 0) 
00289   {
00290     cerr << "APPSPACK::GCI::kill - unrecognized PVM error" << endl;
00291     throw "APPSPACK error";
00292   }
00293 #else
00294 
00295   cerr << "Warning! APPSPACK::GCI::kill requires PVM" << endl;
00296 
00297 #endif
00298 }
00299 
00300 void GCI::exit()
00301 {
00302   // Exit communication interface.
00303 
00304 #ifdef HAVE_PVM
00305 
00306   // In PVM it's very important to call this before exiting.
00307 
00308   int info = pvm_exit();
00309 
00310   if (info == PvmSysErr) 
00311   {
00312     cerr << "APPSPACK::GCI::exit - pvmd not responding" << endl;
00313     throw "APPSPACK error";
00314   }
00315   if (info < 0) 
00316   {
00317     cerr << "APPSPACK::GCI::exit - unrecognized PVM error" << endl;
00318     throw "APPSPACK error";
00319   }
00320 
00321 #elif defined HAVE_MPI
00322 
00323   delete[] sendBuffer;
00324   delete[] recvBuffer;
00325 
00326   int e;
00327 
00328   // Wait for all processes to finish.
00329   e = MPI_Barrier(APPS_COMM);
00330   if (e != MPI_SUCCESS) 
00331   {
00332     cerr << "APPSPACK::GCI::exit - error in MPI barrier" << endl;
00333     throw "APPSPACK error";
00334   }
00335   // End MPI.
00336   e = MPI_Finalize();
00337   if (e != MPI_SUCCESS) 
00338   {
00339     cerr << "APPSPACK::GCI::exit - error in MPI finalize" << endl;
00340     throw "APPSPACK error";
00341   }
00342 #else
00343 
00344   cerr << "Warning! APPSPACK::GCI::exit requires PVM or MPI" << endl;
00345 
00346 #endif
00347 
00348 }
00349 
00350 // ----------------------------------------------------------------------
00351 // Status & Notify
00352 // ----------------------------------------------------------------------
00353 
00354 int GCI::getMyTid() 
00355 {
00356   // Return my taskId (or rank in MPI lingo).
00357 
00358 #ifdef HAVE_PVM
00359 
00360   int info = pvm_mytid();
00361 
00362   if (info == PvmSysErr) 
00363   {
00364     cerr << "APPSPACK::GCI::getMyTid - pvmd is not running" << endl;
00365     throw "APPSPACK error";
00366   }
00367   if (info < 0) 
00368   {
00369     cerr << "APPSPACK::GCI::mytid - unrecognized PVM error" << endl;
00370     throw "APPSPACK error";
00371   }
00372   return info;
00373 
00374 #elif defined HAVE_MPI
00375 
00376   int rank;
00377 
00378   int e = MPI_Comm_rank(APPS_COMM, &rank);
00379   if (e != MPI_SUCCESS) 
00380   {
00381     cerr << "APPSPACK::GCI::mytid - error getting MPI rank." << endl;
00382     throw "APPSPACK error";
00383   }
00384 
00385   return rank;
00386 
00387 #else
00388 
00389   cerr << "APPSPACK::GCI::mytid requires PVM" << endl;
00390   throw "APPSPACK error";
00391 
00392 #endif
00393 }
00394 
00395 int GCI::getNumProcs() 
00396 { 
00397   // Returns number of processes
00398 
00399 #ifdef HAVE_MPI
00400 
00401   int nProcs;
00402 
00403   int e = MPI_Comm_size(APPS_COMM, &nProcs);
00404   if (e != MPI_SUCCESS) 
00405   {
00406     cerr << "APPSPACK::GCI::getNumProcs - error getting number of processes." << endl;
00407     throw "APPSPACK error";
00408   }
00409         
00410   return nProcs;
00411 
00412 #else
00413 
00414    cerr << "APPSPACK::GCI::getNumProcs() requires MPI" << endl;
00415    throw "APPSPACK error";
00416 
00417 #endif
00418 }
00419 
00420 bool GCI::isOrphan()
00421 {
00422 #ifdef HAVE_PVM
00423 
00424   // Check if the process is an orphan, i.e., the process was spawned
00425   // from the command line or the PVM console.
00426 
00427   int info = pvm_parent();
00428 
00429   if (info == PvmSysErr) 
00430   {
00431     cerr << "APPSPACK::GCI::isorphan - pvmd not responding" << endl;
00432     throw "APPSPACK error";
00433   }
00434   if ((info < 0) && (info != PvmNoParent) && (info != PvmParentNotSet)) 
00435   {
00436     cerr << "APPSPACK::GCI::isorphan - unrecognized PVM error" << endl;
00437     throw "APPSPACK error";
00438   }
00439 
00440   return ((info == PvmNoParent) || (info == PvmParentNotSet));
00441 
00442 #else
00443 
00444   cerr << "APPSPACK::GCI::isorphan requires PVM" << endl;
00445   throw "APPSPACK error";
00446 
00447 #endif
00448 }
00449 
00450 int GCI::parent()
00451 {
00452 #ifdef HAVE_PVM
00453 
00454   // Return the task id for the parent task. This will throw an error
00455   // if there is not a parent, so call if necessary isOrphan() first
00456   // to check.
00457 
00458   int info = pvm_parent();
00459 
00460   if (info == PvmNoParent) 
00461   {
00462     cerr << "APPSPACK::GCI::parent - no PVM parent" << endl;
00463     throw "APPSPACK error";
00464   }
00465   if (info == PvmSysErr) 
00466   {
00467     cerr << "APPSPACK::GCI::parent - pvmd not responding" << endl;
00468     throw "APPSPACK error";
00469   }
00470   if (info < 0) 
00471   {
00472     cerr << "APPSPACK::GCI::parent - unrecognized PVM error" << endl;
00473     throw "APPSPACK error";
00474   }
00475 
00476   return info;
00477 
00478 #else
00479 
00480   cerr << "APPSPACK::GCI::parent requires PVM" << endl;
00481   throw "APPSPACK error";
00482 
00483 #endif
00484 }
00485 
00486 int GCI::tidToHost(int t)
00487 {
00488   // Find the host id for the given task.
00489 
00490 #ifdef HAVE_PVM
00491 
00492   int info = pvm_tidtohost(t);
00493 
00494   if (info == PvmBadParam) 
00495   {
00496     cerr << "APPSPACK::GCI::tidtohost - invalid task id" << endl;
00497     throw "APPSPACK error";
00498   }
00499   if (info < 0) 
00500   {
00501     cerr << "APPSPACK::GCI::tidtohost - unrecognized PVM error" << endl;
00502     throw "APPSPACK error";
00503   }
00504 
00505   return info;
00506 
00507 #else
00508 
00509    cerr << "APPSPACK::GCI::tidtohost requires PVM" << endl;
00510    throw "APPSPACK error";
00511 
00512 #endif
00513 }
00514 
00515 void GCI::notify(int msgtag, int taskId)
00516 {
00517   // Set notify for a SINGLE task 
00518 
00519 #ifdef HAVE_PVM
00520 
00521   int info = pvm_notify(PvmTaskExit, msgtag, 1, &taskId);
00522 
00523   if (info == PvmSysErr) 
00524   {
00525     cerr << "APPSPACK::GCI::notify - pvmd not responding" << endl;
00526     throw "APPSPACK error";
00527   }
00528   if (info == PvmBadParam) 
00529   {
00530     cerr << "APPSPACK::GCI::notify - invalid argument to pvm_notify" << endl;
00531     throw "APPSPACK error";
00532   }
00533   if (info < 0) 
00534   {
00535     cerr << "APPSPACK::GCI::notify - unrecognized PVM error" << endl;
00536     throw "APPSPACK error";
00537   }
00538 #else
00539 
00540    cerr << "APPSPACK::GCI::notify requires PVM" << endl;
00541    throw "APPSPACK error";
00542 
00543 #endif
00544 }
00545 
00546 void GCI::notify(int msgtag)
00547 {
00548   // Set notify for ALL host additions
00549 
00550 #ifdef HAVE_PVM
00551 
00552   int info = pvm_notify(PvmHostAdd, msgtag, -1, NULL);
00553 
00554   if (info == PvmSysErr) 
00555   {
00556     cerr << "APPSPACK::GCI::notify - pvmd not responding" << endl;
00557     throw "APPSPACK error";
00558   }
00559   if (info == PvmBadParam) 
00560   {
00561     cerr << "APPSPACK::GCI::notify - invalid argument to pvm_notify" << endl;
00562     throw "APPSPACK error";
00563   }
00564   if (info < 0) 
00565   {
00566     cerr << "APPSPACK::GCI::notify - unrecognized PVM error" << endl;
00567     throw "APPSPACK error";
00568   }
00569 
00570 #else
00571 
00572    cerr << "APPSPACK::GCI::notify requires PVM" << endl;
00573    throw "APPSPACK error";
00574 
00575 #endif
00576 }
00577 
00578 // ----------------------------------------------------------------------
00579 // Send, Recv, and Related Commands
00580 // ----------------------------------------------------------------------
00581 
00582 void GCI::initSend()
00583 {
00584   // Initialize send.
00585 
00586 #ifdef HAVE_PVM
00587 
00588   int info = pvm_initsend(PvmDataDefault); // XDR encoding
00589 
00590   if (info == PvmBadParam) 
00591   {
00592     cerr << "APPSPACK::GCI::initsend - invalid encoding value" << endl;
00593     throw "APPSPACK error";
00594   }
00595   if (info == PvmNoMem) 
00596   {
00597     cerr << "APPSPACK::GCI::initsend - out of memory" << endl;
00598     throw "APPSPACK error";
00599   }
00600   if (info < 0) 
00601   {
00602     cerr << "APPSPACK::GCI::initsend - unrecognized PVM error" << endl;
00603     throw "APPSPACK error";
00604   }
00605 
00606 #elif defined HAVE_MPI
00607 
00608   delete[] sendBuffer;
00609   sendBuffer = NULL;
00610   sendPosition = 0;
00611   sendPosition = 0;
00612 
00613 #else
00614 
00615    cerr << "APPSPACK::GCI::initsend requires PVM or MPI" << endl;
00616    throw "APPSPACK error";
00617 
00618 #endif
00619 }
00620 
00621 void GCI::send(int msgtag, int taskId)
00622 {
00623   // Send a message with the specified message tag to the given task
00624   // id.
00625 
00626 #ifdef HAVE_PVM
00627 
00628   int info = pvm_send(taskId, msgtag);
00629 
00630   if (info == PvmSysErr) 
00631   {
00632     cerr << "APPSPACK::GCI::send - pvmd not responding" << endl;
00633     throw "APPSPACK error";
00634   }
00635   if (info == PvmBadParam) 
00636   {
00637     cerr << "APPSPACK::GCI::send - invalid argument" << endl;
00638     throw "APPSPACK error";
00639   }
00640   if (info == PvmNoBuf) 
00641   {
00642     cerr << "APPSPACK::GCI::send - no active send buffer" << endl;
00643     throw "APPSPACK error";
00644   }
00645   if (info < 0) 
00646   {
00647     cerr << "APPSPACK::GCI::send - unrecognized PVM error" << endl;
00648     throw "APPSPACK error";
00649   }
00650 
00651 #elif defined HAVE_MPI
00652 
00653   int e = MPI_Send(sendBuffer, sendPosition, MPI_PACKED, taskId, msgtag, APPS_COMM);
00654   if (e != MPI_SUCCESS) 
00655   {
00656     cerr << "APPSPACK::GCI::send - error in MPI packed send" << endl;
00657     throw "APPSPACK error";
00658   }
00659 
00660 #else
00661 
00662    cerr << "APPSPACK::GCI::send requires PVM or MPI" << endl;
00663    throw "APPSPACK error";
00664 
00665 #endif
00666 }
00667 
00668 void GCI::broadcast (int msgtag, const vector<int>& taskId)
00669 {
00670   // Broadcast message in buffer using tag msgtag to the n tasks
00671   // listed in the taskId array.
00672 
00673 #ifdef HAVE_PVM
00674 
00675   // MAY WANT TO FIX THIS??
00676 
00677   int n = taskId.size();
00678   int* taskIdcpy = new int[n];
00679   for (int i = 0; i < n; i ++)
00680     taskIdcpy[i] = taskId[i];
00681 
00682 
00683   int info = pvm_mcast(taskIdcpy, n, msgtag);
00684 
00685   if (info == PvmSysErr) 
00686   {
00687     cerr << "APPSPACK::GCI::broadcast - pvmd not responding" << endl;
00688     throw "APPSPACK error";
00689   }
00690   if (info == PvmBadParam) 
00691   {
00692     cerr << "APPSPACK::GCI::broadcast -  msgtag < 0" << endl;
00693     throw "APPSPACK error";
00694   }
00695   if (info == PvmNoBuf) 
00696   {
00697     cerr << "APPSPACK::GCI::broadcast - no active send buffer" << endl;
00698     throw "APPSPACK error";
00699   }
00700   if (info < 0) 
00701   {
00702     cerr << "APPSPACK::GCI::broadcast - unrecognized PVM error" << endl;
00703     throw "APPSPACK error";
00704   }
00705 
00706   delete taskIdcpy;
00707 
00708 #else
00709 
00710    cerr << "APPSPACK::GCI::broadcast requires PVM" << endl;
00711    throw "APPSPACK error";
00712 
00713 #endif
00714 }
00715 
00716 bool GCI::recv(int msgtag, int msgtid)
00717 {
00718   // Blocking receive for a message with the given tag and task id.
00719   // The inputs msgtag and msgtid default to -1 (wildcard).  Returns
00720   // the buffer id of the message (PVM) or 1 (MPI), if any, and 0
00721   // otherwise.
00722 
00723 #ifdef HAVE_PVM
00724 
00725   int bufid = pvm_recv(msgtid, msgtag); 
00726 
00727   if (bufid == PvmBadParam) 
00728   {
00729     cerr << "APPSPACK::GCI::recv - invalid tid value or msgtag < -1" << endl;
00730     throw "APPSPACK error";
00731   }
00732   if (bufid == PvmSysErr) 
00733   {
00734     cerr << "APPSPACK::GCI::recv - pvmd not responding" << endl;
00735     throw "APPSPACK error";
00736   }
00737   if (bufid < 0) 
00738   {
00739     cerr << "APPSPACK::GCI::recv - unrecognized PVM error" << endl;
00740     throw "APPSPACK error";
00741   }
00742 
00743   lastBufferId = bufid;
00744   return (bufid != 0) ? true : false;
00745 
00746 #elif defined HAVE_MPI
00747 
00748   if (msgtid == -1) 
00749     msgtid = MPI_ANY_SOURCE;
00750   if (msgtag == -1) 
00751     msgtag = MPI_ANY_TAG;
00752 
00753   // First, do a probe to find out how big to make the receive buffer
00754   int e = MPI_Probe(msgtid, msgtag, APPS_COMM, &status);
00755   if (e != MPI_SUCCESS) 
00756   {
00757     cerr << "APPSPACK::GCI::recv - error calling probe" << endl;
00758     throw "APPSPACK error";
00759   }
00760   msgSize = mpiGetMsgSize(status, MPI_PACKED);
00761 
00762   // Create the buffer.
00763   delete[] recvBuffer;
00764   recvBuffer = new char[msgSize];
00765 
00766   // Receive the message
00767   MPI_Recv(recvBuffer, msgSize, MPI_PACKED, msgtid, msgtag, APPS_COMM, &status);
00768 
00769   // QUESTION: Should the value of status or some error code be
00770   // checked here?
00771 
00772   // The value recvPosition is incremented as the message is read via
00773   // calls to unpack. Set it to 0 so we can start reading at the
00774   // beginning of the message.
00775   recvPosition = 0;
00776 
00777   return true;
00778 
00779 #else
00780 
00781    cerr << "APPSPACK::GCI::recv requires PVM or MPI" << endl;
00782    throw "APPSPACK error";
00783 
00784 #endif
00785 }
00786 
00787 bool GCI::nrecv(int msgtag, int msgtid)
00788 {
00789   // Non-blocking receive for a message with the given tag and task
00790   // id.  The inputs msgtag and msgtid default to -1 (wildcard).
00791   // Returns the buffer id of the message, if any, and 0 otherwise.
00792 
00793 #ifdef HAVE_PVM
00794 
00795   int bufid = pvm_nrecv(msgtid, msgtag);
00796 
00797   if (bufid == PvmBadParam) 
00798   {
00799     cerr << "APPSPACK::GCI::nrecv - invalid parameter" << endl;
00800     throw "APPSPACK error";
00801   }
00802   if (bufid == PvmSysErr) 
00803   {
00804     cerr << "APPSPACK::GCI::nrecv - pvmd not responding" << endl;
00805     throw "APPSPACK error";
00806   }
00807   if (bufid < 0) 
00808   {
00809     cerr << "APPSPACK::GCI::nrecv - unrecognized PVM error" << endl;
00810     throw "APPSPACK error";
00811   }
00812  
00813   lastBufferId = bufid;
00814   return (bufid != 0) ? true : false;
00815 
00816 #else
00817 
00818    cerr << "APPSPACK::GCI::nrecv requires PVM" << endl;
00819    throw "APPSPACK error";
00820 
00821 #endif
00822 }
00823 
00824 bool GCI::probe(int msgtag, int msgtid)
00825 {
00826   // Non-blocking probe for a message with the specified message tag
00827   // and task id. Returns the buffer id of the message for PVM or 1
00828   // for MPI, if any, and 0 otherwise. The inputs msgtag and msgtid
00829   // default to -1 (wildcard).
00830 
00831 #ifdef HAVE_PVM
00832 
00833   int bufid = pvm_probe(msgtid, msgtag);
00834 
00835   if (bufid == PvmBadParam) 
00836   {
00837     cerr << "APPSPACK::GCI::probe - invalid msgtid or msgtag" << endl;
00838     throw "APPSPACK error";
00839   }
00840   if (bufid == PvmSysErr) 
00841   {
00842     cerr << "APPSPACK::GCI::probe - pvmd not responding" << endl;
00843     throw "APPSPACK error";
00844   }
00845   if (bufid < 0) 
00846   {
00847     cerr << "APPSPACK::GCI::probe - unrecognized PVM error" << endl;
00848     throw "APPSPACK error";
00849   }
00850   
00851   lastBufferId = bufid;
00852   return (bufid != 0) ? true : false;
00853 
00854 #elif defined HAVE_MPI
00855 
00856   int iflag;
00857 
00858   if (msgtid == -1) 
00859     msgtid = MPI_ANY_SOURCE;
00860   if (msgtag == -1)
00861     msgtag = MPI_ANY_TAG;
00862 
00863   // MPI sets iflag = 1 if there is a matching message, 0 if not.
00864   int e = MPI_Iprobe(msgtid, msgtag, APPS_COMM, &iflag, &status);
00865 
00866   if (e != MPI_SUCCESS) 
00867   {
00868     cerr << "APPSPACK::GCI::probe - error in MPI iprobe" << endl;
00869     throw "APPSPACK error";
00870   }
00871 
00872   return (iflag == 1) ? true : false;
00873 
00874 #else
00875 
00876    cerr << "APPSPACK::GCI::probe requires PVM or MPI" << endl;
00877    throw "APPSPACK error";
00878 
00879 #endif
00880 }
00881 
00882 void GCI::bprobe(int msgtag, int msgtid) 
00883 { 
00884   // Do a blocking probe for a message with tag msgtag and from
00885   // process msgtid. The default values of msgtag and msgtid are both
00886   // -1.
00887 
00888 #ifdef HAVE_MPI
00889 
00890   if (msgtid == -1) 
00891     msgtid = MPI_ANY_SOURCE;
00892   if (msgtag == -1) 
00893     msgtag = MPI_ANY_TAG;
00894 
00895   int e = MPI_Probe(msgtid, msgtag, APPS_COMM, &status);
00896   if (e != MPI_SUCCESS) 
00897   {
00898     cerr << "APPSPACK::GCI::bprobe - error in MPI probe" << endl;
00899     throw "APPSPACK error";
00900   }
00901 
00902 #else
00903 
00904    cerr << "APPSPACK::GCI::bprobe requires MPI" << endl;
00905    throw "APPSPACK error";
00906 
00907 #endif
00908 }
00909 
00910 void GCI::bufinfo(int& msgtag, int& msgtid)
00911 {
00912   // Determine the msgtag and msgtid for the most recently probed or
00913   // received message.
00914   
00915 #ifdef HAVE_PVM
00916 
00917   if (lastBufferId == 0) 
00918   {
00919     cerr << "APPSPACK::GCI::bufinfo called without first doing recv or probe" << endl;
00920     throw "APPSPACK error";
00921   }
00922 
00923   int bytes;
00924   int info = pvm_bufinfo(lastBufferId, &bytes, &msgtag, &msgtid);
00925   
00926   if (info == PvmNoSuchBuf) 
00927   {
00928     cerr << "APPSPACK::GCI::bufinfo - specified PVM buffer does not exist" << endl;
00929     throw "APPSPACK error";
00930   }
00931   if (info == PvmBadParam) 
00932   {
00933     cerr << "APPSPACK::GCI::bufinfo - invalid argument to pvm_bufinfo" << endl;
00934     throw "APPSPACK error";
00935   }
00936   if (info < 0) 
00937   {
00938     cerr << "APPSPACK::GCI::bufinfo - unrecognized PVM error" << endl;
00939     throw "APPSPACK error";
00940   }
00941 
00942 #elif defined HAVE_MPI
00943 
00944   msgtag = status.MPI_TAG;
00945   msgtid = status.MPI_SOURCE;
00946 
00947 #else
00948 
00949    cerr << "APPSPACK::GCI::bufinfo requires PVM or MPI" << endl;
00950    throw "APPSPACK error";
00951 
00952 #endif
00953 }
00954 
00955 // ----------------------------------------------------------------------
00956 // Pack & Unpack
00957 // ----------------------------------------------------------------------
00958 
00959 void GCI::pack(int i)
00960 {
00961  // Pack a single integer.
00962 
00963 #ifdef HAVE_PVM
00964 
00965   pvmPackCheck(pvm_pkint(&i, 1, 1));
00966 
00967 #elif defined HAVE_MPI
00968 
00969   int bufsize = sendPosition + sizeof(int);
00970   mpiStretchSendBuffer(bufsize);
00971   int e = MPI_Pack(&i, 1, MPI_INT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
00972   if (e != MPI_SUCCESS) 
00973   {
00974     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
00975     throw "APPSPACK error";
00976   }
00977 
00978 #else
00979 
00980    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
00981    throw "APPSPACK error";
00982 
00983 #endif
00984 }
00985 
00986 void GCI::pack(char i)
00987 {
00988  // Pack a single chareger.
00989 
00990 #ifdef HAVE_PVM
00991 
00992   pvmPackCheck(pvm_pkbyte(&i, 1, 1));
00993 
00994 #elif defined HAVE_MPI
00995 
00996   int bufsize = sendPosition + sizeof(char);
00997   mpiStretchSendBuffer(bufsize);
00998   int e = MPI_Pack(&i, 1, MPI_CHAR, sendBuffer, bufsize, &sendPosition, APPS_COMM);
00999   if (e != MPI_SUCCESS) 
01000   {
01001     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01002     throw "APPSPACK error";
01003   }
01004 
01005 #else
01006 
01007    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01008    throw "APPSPACK error";
01009 
01010 #endif
01011 }
01012 
01013 void GCI::pack(double d)
01014 {
01015   // Pack a single double.
01016 
01017 #ifdef HAVE_PVM
01018 
01019   pvmPackCheck(pvm_pkdouble(&d, 1, 1));
01020 
01021 #elif defined HAVE_MPI
01022 
01023   int bufsize = sendPosition + sizeof(double);
01024   mpiStretchSendBuffer(bufsize);
01025 
01026   int e = MPI_Pack(&d, 1, MPI_DOUBLE, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01027   if (e != MPI_SUCCESS) 
01028   {
01029     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01030     throw "APPSPACK error";
01031   }
01032 
01033 #else
01034    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01035    throw "APPSPACK error";
01036 
01037 #endif
01038 }
01039 
01040 void GCI::pack(float d)
01041 {
01042   // Pack a single float.
01043 
01044 #ifdef HAVE_PVM
01045 
01046   pvmPackCheck(pvm_pkfloat(&d, 1, 1));
01047 
01048 #elif defined HAVE_MPI
01049 
01050   int bufsize = sendPosition + sizeof(double);
01051   mpiStretchSendBuffer(bufsize);
01052 
01053   int e = MPI_Pack(&d, 1, MPI_FLOAT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01054   if (e != MPI_SUCCESS) 
01055   {
01056     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01057     throw "APPSPACK error";
01058   }
01059 
01060 #else
01061    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01062    throw "APPSPACK error";
01063 
01064 #endif
01065 }
01066 
01067 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01068 void GCI::pack(const char* s)
01069 {
01070   // Pack character array WITH its length first
01071 
01072 #ifdef HAVE_PVM
01073 
01074   pack((int)strlen(s));
01075   pvmPackCheck(pvm_pkstr(const_cast<char*>(s)));
01076 
01077 #elif defined HAVE_MPI
01078 
01079   // Calculate length of string including terminator '\O'
01080   int n = strlen(s) + 1;
01081 
01082   // Pack string length
01083   pack(n);
01084 
01085   // Pack the string itself
01086   int bufsize = sendPosition + sizeof(char) * n; 
01087   mpiStretchSendBuffer(bufsize);
01088 
01089   int e = MPI_Pack(const_cast<char*>(s), n, MPI_CHAR, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01090   if (e != MPI_SUCCESS) 
01091   {
01092     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01093     throw "APPSPACK error";
01094   }
01095 
01096 #else
01097 
01098    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01099    throw "APPSPACK error";
01100 
01101 #endif
01102 }
01103 #endif
01104 
01105 void GCI::pack(bool b)
01106 {
01107   // Pack a single bool. Bools are packed as ints because neither PVM
01108   // nor MPI can handle the bool datatype.
01109 
01110   int fakebool = (int) b;
01111 
01112 #ifdef HAVE_PVM
01113 
01114   pvmPackCheck(pvm_pkint(&fakebool, 1, 1));
01115 
01116 #elif defined HAVE_MPI
01117 
01118   pack(fakebool);
01119 
01120 #else
01121 
01122    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01123    throw "APPSPACK error";
01124 
01125 #endif
01126 }
01127 
01128 void GCI::pack(const string s)
01129 {
01130 
01131   // Pack a string.
01132 
01133 #if defined HAVE_PVM || defined HAVE_MPI
01134 
01135   pack(s.c_str());
01136 
01137 #else
01138 
01139    cerr << "APPSPACK::GCI::pack requires PVM or MPI" << endl;
01140    throw "APPSPACK error";
01141 
01142 #endif
01143 }
01144 
01145 void GCI::pack(const vector<int>& v)
01146 {
01147   int n = v.size();
01148   pack(n);
01149   for (int i = 0; i < n; i ++)
01150     pack(v[i]);
01151 }
01152 
01153 void GCI::pack(const Vector& v)
01154 {
01155   int n = v.size();
01156   pack(n);
01157   for (int i = 0; i < n; i ++)
01158     pack(v[i]);
01159 }
01160 
01161 void GCI::pack(const vector< Vector >& v)
01162 {
01163   int n = v.size();
01164   pack(n);
01165   for (int i = 0; i < n; i ++)
01166     pack(v[i]);
01167 }
01168 
01169 void GCI::pack(const vector<string>& v)
01170 {
01171   int n = v.size();
01172   pack(n);
01173   for (int i = 0; i < n; i ++)
01174     pack(v[i]);
01175 }
01176 
01177 void GCI::pack(const vector<bool>& v)
01178 {
01179   // Bool vectors must be handled specially because they are stored is
01180   // a compacted format.
01181   int n = v.size();
01182   pack(n);
01183   int tmp;
01184   for (int i = 0; i < n; i ++) 
01185   {
01186     tmp = (int) v[i];
01187     pack(tmp);
01188   }
01189 }    
01190 
01191 void GCI::pack(int length, const char* array)
01192 {
01193   // Pack array WITH its length first
01194 
01195 #ifdef HAVE_PVM
01196 
01197   pack(length);
01198   pvmPackCheck(pvm_pkbyte(const_cast<char*>(array), length, 1));
01199 
01200 #elif defined HAVE_MPI
01201 
01202   // Pack array length
01203   pack(length);
01204 
01205   // Pack the array itself
01206   int bufsize = sendPosition + sizeof(char) * length; 
01207   mpiStretchSendBuffer(bufsize);
01208 
01209   int e = MPI_Pack(const_cast<char*>(array), length, MPI_CHAR, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01210   if (e != MPI_SUCCESS) 
01211   {
01212     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01213     throw "APPSPACK error";
01214   }
01215 
01216 #else
01217 
01218    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01219    throw "APPSPACK error";
01220 
01221 #endif
01222 }
01223 
01224 void GCI::pack(int length, const int* array)
01225 {
01226   // Pack array WITH its length first
01227 
01228 #ifdef HAVE_PVM
01229 
01230   pack(length);
01231   pvmPackCheck(pvm_pkint(const_cast<int*>(array), length, 1));
01232 
01233 #elif defined HAVE_MPI
01234 
01235   // Pack array length
01236   pack(length);
01237 
01238   // Pack the array itself
01239   int bufsize = sendPosition + sizeof(int) * length; 
01240   mpiStretchSendBuffer(bufsize);
01241 
01242   int e = MPI_Pack((int*)array, length, MPI_INT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01243   if (e != MPI_SUCCESS) 
01244   {
01245     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01246     throw "APPSPACK error";
01247   }
01248 
01249 #else
01250 
01251    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01252    throw "APPSPACK error";
01253 
01254 #endif
01255 }
01256 
01257 void GCI::pack(int length, const double* array)
01258 {
01259   // Pack array WITH its length first
01260 
01261 #ifdef HAVE_PVM
01262 
01263   pack(length);
01264   pvmPackCheck(pvm_pkdouble((double*) array, length, 1));
01265 
01266 #elif defined HAVE_MPI
01267 
01268   // Pack array length
01269   pack(length);
01270 
01271   // Pack the array itself
01272   int bufsize = sendPosition + sizeof(double) * length; 
01273   mpiStretchSendBuffer(bufsize);
01274 
01275   int e = MPI_Pack((double*)array, length, MPI_DOUBLE, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01276   if (e != MPI_SUCCESS) 
01277   {
01278     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01279     throw "APPSPACK error";
01280   }
01281 
01282 #else
01283 
01284    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01285    throw "APPSPACK error";
01286 
01287 #endif
01288 }
01289 
01290 
01291 void GCI::pack(int length, const float* array)
01292 {
01293   // Pack array WITH its length first
01294 
01295 #ifdef HAVE_PVM
01296 
01297   pack(length);
01298   pvmPackCheck(pvm_pkfloat((float*) array, length, 1));
01299 
01300 #elif defined HAVE_MPI
01301 
01302   // Pack array length
01303   pack(length);
01304 
01305   // Pack the array itself
01306   int bufsize = sendPosition + sizeof(float) * length; 
01307   mpiStretchSendBuffer(bufsize);
01308 
01309   int e = MPI_Pack((float*)array, length, MPI_FLOAT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
01310   if (e != MPI_SUCCESS) 
01311   {
01312     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
01313     throw "APPSPACK error";
01314   }
01315 
01316 #else
01317 
01318    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
01319    throw "APPSPACK error";
01320 
01321 #endif
01322 }
01323 
01324 void GCI::unpack(int& i)
01325 {
01326   // Unpack a single integer
01327 
01328 #ifdef HAVE_PVM
01329 
01330   pvmUnpackCheck(pvm_upkint(&i, 1, 1));
01331 
01332 #elif defined HAVE_MPI
01333 
01334   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &i, 1, MPI_INT, APPS_COMM);
01335   if (e != MPI_SUCCESS) 
01336   {
01337     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01338     throw "APPSPACK error";
01339   }
01340 
01341 #else
01342 
01343    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01344    throw "APPSPACK error";
01345 
01346 #endif
01347 }
01348 
01349 void GCI::unpack(char& i)
01350 {
01351   // Unpack a single integer
01352 
01353 #ifdef HAVE_PVM
01354 
01355   pvmUnpackCheck(pvm_upkbyte(&i, 1, 1));
01356 
01357 #elif defined HAVE_MPI
01358 
01359   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &i, 1, MPI_CHAR, APPS_COMM);
01360   if (e != MPI_SUCCESS) 
01361   {
01362     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01363     throw "APPSPACK error";
01364   }
01365 
01366 #else
01367 
01368    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01369    throw "APPSPACK error";
01370 
01371 #endif
01372 }
01373 
01374 void GCI::unpack(double& d)
01375 {
01376   // Unpack a single double
01377 
01378 #ifdef HAVE_PVM
01379 
01380   pvmUnpackCheck(pvm_upkdouble(&d, 1, 1));
01381 
01382 #elif defined HAVE_MPI
01383 
01384   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &d, 1, MPI_DOUBLE, APPS_COMM);
01385   if (e != MPI_SUCCESS) 
01386   {
01387     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01388     throw "APPSPACK error";
01389   }
01390 
01391 #else
01392 
01393    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01394    throw "APPSPACK error";
01395 
01396 #endif
01397 }
01398 
01399 void GCI::unpack(float& d)
01400 {
01401   // Unpack a single float
01402 
01403 #ifdef HAVE_PVM
01404 
01405   pvmUnpackCheck(pvm_upkfloat(&d, 1, 1));
01406 
01407 #elif defined HAVE_MPI
01408 
01409   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &d, 1, MPI_FLOAT, APPS_COMM);
01410   if (e != MPI_SUCCESS) 
01411   {
01412     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01413     throw "APPSPACK error";
01414   }
01415 
01416 #else
01417 
01418    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01419    throw "APPSPACK error";
01420 
01421 #endif
01422 }
01423 
01424 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01425 void GCI::unpack(char*& s)
01426 {
01427   // Unpack char array s. If s is NULL, memory is allocated for it. If
01428   // not, the length of s is checked to be sure it's large enough.
01429 
01430   int len;
01431   unpack(len);
01432 
01433   if (!s) 
01434     s = new char[len];
01435   else if (((int)strlen(s)) < len) 
01436   {
01437     cerr << "APPSPACK::GCI::unpack - string is too small for unpack" << endl;
01438     throw "APPSPACK error";
01439   }
01440 
01441 #ifdef HAVE_PVM
01442 
01443   pvmUnpackCheck(pvm_upkstr(s));
01444 
01445 #elif defined HAVE_MPI
01446 
01447   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, s, len, MPI_CHAR, APPS_COMM);
01448   if (e != MPI_SUCCESS) 
01449   {
01450     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01451     throw "APPSPACK error";
01452   }
01453 
01454 #else
01455 
01456    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01457    throw "APPSPACK error";
01458 
01459 #endif
01460 }
01461 #endif
01462 
01463 void GCI::unpack(bool& b)
01464 {
01465   // Unpack a single boolean.
01466 
01467 #ifdef HAVE_PVM
01468 
01469   int bfake;
01470   pvmUnpackCheck(pvm_upkint(&bfake, 1, 1));
01471   b = (bool) bfake;
01472 
01473 #elif defined HAVE_MPI
01474 
01475   int bfake;
01476   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &bfake, 1, MPI_INT, APPS_COMM);
01477   if (e != MPI_SUCCESS) 
01478   {
01479     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01480     throw "APPSPACK error";
01481   }
01482 
01483   b = (bool) bfake;
01484 
01485 #else
01486 
01487    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01488    throw "APPSPACK error";
01489 
01490 #endif
01491 }
01492 
01493 void GCI::unpack(string& s)
01494 {
01495 
01496 #if defined HAVE_PVM || defined HAVE_MPI
01497 
01498 #ifdef DEBUG
01499   cout << "Unpacking a string" << endl;
01500 #endif
01501 
01502   char* tmp = NULL;
01503   unpack(tmp);
01504 
01505 #ifdef DEBUG
01506   cout << "Unpacking a string=" << tmp << endl;
01507 #endif
01508 
01509   s = tmp;
01510 
01511 #ifdef DEBUG
01512   cout << "Unpacking a string=" << s << endl;
01513 #endif
01514 
01515 
01516   try
01517   {
01518     delete [] tmp;
01519   }
01520   catch(...)
01521   {
01522   }
01523   
01524 #ifdef DEBUG
01525   cout << "Unpacking a string=" << s << endl;
01526 #endif
01527 
01528 #else
01529 
01530    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01531    throw "APPSPACK error";
01532 
01533 #endif
01534 }
01535 
01536 void GCI::unpack(vector<int>& v)
01537 {
01538   int n;
01539   unpack(n);
01540   v.resize(n);
01541   for (int i = 0; i < n; i ++)
01542     unpack(v[i]);
01543 }
01544 
01545 void GCI::unpack(Vector& v)
01546 {
01547   int n;
01548   unpack(n);
01549   v.resize(n);
01550   for (int i = 0; i < n; i ++)
01551     unpack(v[i]);
01552 }
01553 
01554 void GCI::unpack(vector< Vector >& v)
01555 {
01556   int n;
01557   unpack(n);
01558   v.resize(n);
01559   for (int i = 0; i < n; i ++)
01560     unpack(v[i]);
01561 }
01562 
01563 void GCI::unpack(vector<string>& v)
01564 {
01565   int n;
01566   unpack(n);
01567   v.resize(n);
01568   for (int i = 0; i < n; i ++)
01569     unpack(v[i]);
01570 }
01571 
01572 
01573 void GCI::unpack(vector<bool>& v)
01574 {
01575   // Bool vectors must be handled specially because they are stored is
01576   // a compacted format.
01577   int n;
01578   unpack(n);
01579   v.resize(n);
01580   int tmp;
01581   for (int i = 0; i < n; i ++) 
01582   {
01583     unpack(tmp);
01584     v[i] = (bool) tmp;
01585   }
01586 }    
01587 
01588 void GCI::unpack(int& length, char*& array)
01589 {
01590   // Unpack array s. If s is NULL, memory is allocated for it. If
01591   // not, the length of s is checked to be sure it's large enough.
01592 
01593   unpack(length);
01594   array = new char[length];
01595 
01596 #ifdef HAVE_PVM
01597 
01598   pvmUnpackCheck(pvm_upkbyte(array, length, 1));
01599 
01600 #elif defined HAVE_MPI
01601 
01602   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_CHAR, APPS_COMM);
01603   if (e != MPI_SUCCESS) 
01604   {
01605     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01606     throw "APPSPACK error";
01607   }
01608 
01609 #else
01610 
01611    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01612    throw "APPSPACK error";
01613 
01614 #endif
01615 }
01616 
01617 void GCI::unpack(int& length, int*& array)
01618 {
01619   // Unpack array s. If s is NULL, memory is allocated for it. If
01620   // not, the length of s is checked to be sure it's large enough.
01621 
01622   unpack(length);
01623   array = new int[length];
01624 
01625 #ifdef HAVE_PVM
01626 
01627   pvmUnpackCheck(pvm_upkint(array, length, 1));
01628 
01629 #elif defined HAVE_MPI
01630 
01631   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_INT, APPS_COMM);
01632   if (e != MPI_SUCCESS) 
01633   {
01634     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01635     throw "APPSPACK error";
01636   }
01637 
01638 #else
01639 
01640    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01641    throw "APPSPACK error";
01642 
01643 #endif
01644 }
01645 
01646 void GCI::unpack(int& length, double*& array)
01647 {
01648   // Unpack array s. If s is NULL, memory is allocated for it. If
01649   // not, the length of s is checked to be sure it's large enough.
01650 
01651   unpack(length);
01652   array = new double[length];
01653 
01654 #ifdef HAVE_PVM
01655 
01656   pvmUnpackCheck(pvm_upkdouble(array, length, 1));
01657 
01658 #elif defined HAVE_MPI
01659 
01660   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_DOUBLE, APPS_COMM);
01661   if (e != MPI_SUCCESS) 
01662   {
01663     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01664     throw "APPSPACK error";
01665   }
01666 
01667 #else
01668 
01669    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01670    throw "APPSPACK error";
01671 
01672 #endif
01673 }
01674 
01675 void GCI::unpack(int& length, float*& array)
01676 {
01677   // Unpack array s. If s is NULL, memory is allocated for it. If
01678   // not, the length of s is checked to be sure it's large enough.
01679 
01680   unpack(length);
01681   array = new float[length];
01682 
01683 #ifdef HAVE_PVM
01684 
01685   pvmUnpackCheck(pvm_upkfloat(array, length, 1));
01686 
01687 #elif defined HAVE_MPI
01688 
01689   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_FLOAT, APPS_COMM);
01690   if (e != MPI_SUCCESS) 
01691   {
01692     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
01693     throw "APPSPACK error";
01694   }
01695 
01696 #else
01697 
01698    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
01699    throw "APPSPACK error";
01700 
01701 #endif
01702 }
01703 
01704 // ----------------------------------------------------------------------
01705 // Host Info
01706 // ----------------------------------------------------------------------
01707 
01708 int GCI::resetHostInfo() 
01709 {
01710   // Reset host information by asking PVM to update pvmHostInfo - the data
01711   // structure that contains the host information. Return the number
01712   // of hosts.
01713 
01714 #ifdef HAVE_PVM
01715 
01716   pvmHostInfo = NULL;
01717 
01718   if ((pvm_config(&nHosts, &nArch, &pvmHostInfo)) < 0) 
01719   {
01720     cerr << "APPSPACK::GCI::resetHostInfo - error from pvm_config" << endl;
01721     throw "APPSPACK error";
01722   }
01723 
01724   return nHosts;
01725 
01726 #else
01727 
01728    cerr << "APPSPACK::GCI::resetHostInfo requires PVM" << endl;
01729    throw "APPSPACK error";
01730 
01731 #endif
01732 }
01733 
01734 int GCI::getHostTid(int i) 
01735 {
01736   // Get the host id of the ith host.
01737 
01738 #ifdef HAVE_PVM
01739 
01740   return pvmHostInfo[i].hi_tid;
01741 
01742 #else
01743 
01744    cerr << "APPSPACK::GCI::getHostTid requires PVM" << endl;
01745    throw "APPSPACK error";
01746 
01747 #endif
01748 }
01749 
01750 int GCI::getHostSpeed(int i) 
01751 {
01752   // Get the speed of the ith host.
01753 
01754 #ifdef HAVE_PVM
01755 
01756   return pvmHostInfo[i].hi_speed;
01757 
01758 #else
01759 
01760    cerr << "APPSPACK::GCI::getHostSpeed requires PVM" << endl;
01761    throw "APPSPACK error";
01762 
01763 #endif
01764 }
01765 
01766 char* GCI::getHostName(int i) 
01767 {
01768   // Get the name of the ith host.
01769 
01770 #ifdef HAVE_PVM
01771 
01772   return pvmHostInfo[i].hi_name;
01773 
01774 #else
01775 
01776    cerr << "APPSPACK::GCI::getHostName requires PVM" << endl;
01777    throw "APPSPACK error";
01778 
01779 #endif
01780 }
01781 
01782 // ----------------------------------------------------------------------
01783 // Helper functions for PVM
01784 // ----------------------------------------------------------------------
01785 
01786 #ifdef HAVE_PVM
01787 
01788 void GCI::pvmPackCheck(int info)        // PRIVATE
01789 {
01790   // Check return code from pvm_pack
01791 
01792   if (info == PvmNoMem) 
01793   {
01794     cerr << "APPSPACK::GCI::pack - out of memory" << endl;
01795     throw "APPSPACK error";
01796   }
01797   if (info == PvmNoBuf) 
01798   {
01799     cerr << "APPSPACK::GCI::pack - no active send buffer" << endl;
01800     throw "APPSPACK error";
01801   }
01802   if (info < 0) 
01803   {
01804     cerr << "APPSPACK::GCI::pack - unrecognized PVM error" << endl;
01805     throw "APPSPACK error";
01806   }
01807 }
01808 
01809 void GCI::pvmUnpackCheck(int info) // PRIVATE
01810 {
01811   // Check return code form pvm_unpack
01812 
01813   if (info == PvmNoData) 
01814   {
01815     cerr << "APPSPACK::GCI::unpack - reading past end of buffer" << endl;
01816     throw "APPSPACK error";
01817   }
01818   if (info == PvmBadMsg) 
01819   {
01820     cerr << "APPSPACK::GCI::unpack - incompatiable encoding" << endl;
01821     throw "APPSPACK error";
01822   }
01823   if (info == PvmNoBuf) 
01824   {
01825     cerr << "APPSPACK::GCI::unpack - no active receive buffer" << endl;
01826     throw "APPSPACK error";
01827   }
01828   if (info < 0) 
01829   {
01830     cerr << "APPSPACK::GCI::unpack - unrecognized PVM error" << endl;
01831     throw "APPSPACK error";
01832   }
01833 }
01834 
01835 #endif
01836 
01837 
01838 // ----------------------------------------------------------------------
01839 // Helper functions for MPI
01840 // ----------------------------------------------------------------------
01841 
01842 #ifdef HAVE_MPI
01843 
01844 int GCI::mpiGetMsgSize(MPI_Status localstatus, MPI_Datatype datatype)
01845 {
01846   // Returns the size of the message localstatus is associated with.
01847   // "localstatus" is so named to separate it from the global variable
01848   // "status."
01849 
01850   int count;
01851 
01852   // This MPI call sets count = the number of items of type datatype
01853   // in the message. 
01854   int e = MPI_Get_count(&localstatus, datatype, &count);
01855   if (e != MPI_SUCCESS) 
01856   {
01857     cerr << "APPSPACK::GCI::mpiGetMsgSize - error" << endl;
01858     throw "APPSPACK error";
01859   }
01860 
01861   return(count);
01862 }
01863 
01864 void GCI::mpiStretchSendBuffer(int bufsize)
01865 {
01866   // This is a helper function for the pack methods.  It makes the
01867   // size of the send buffer bufsize.
01868 
01869   // Create new buffer
01870   char* newbuffer = new char[bufsize];
01871   
01872   // Copy old buffer into new
01873   for(int i = 0; i < sendPosition; i++)
01874     newbuffer[i] = sendBuffer[i];
01875 
01876   // Delete old buffer and replace with new
01877   delete[] sendBuffer;
01878   sendBuffer = newbuffer;
01879 }
01880 
01881 #endif
01882 

 

© Sandia Corporation | Site Contact | Privacy and Security

Generated on Fri Feb 16 10:33:35 2007 for APPSPACK 5.0.1 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2002