Main Page | Namespace List | Class Hierarchy | Alphabetical List | 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.6.2.1 2005/06/29 17:07:42 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 void GCI::pack(const char* s)
    01068 {
    01069   // Pack character array WITH its length first
    01070
    01071 #ifdef HAVE_PVM
    01072
    01073   pack((int)strlen(s));
    01074   pvmPackCheck(pvm_pkstr(const_cast<char*>(s)));
    01075
    01076 #elif defined HAVE_MPI
    01077
    01078   // Calculate length of string including terminator '\O'
    01079   int n = strlen(s) + 1;
    01080
    01081   // Pack string length
    01082   pack(n);
    01083
    01084   // Pack the string itself
    01085   int bufsize = sendPosition + sizeof(char) * n;
    01086   mpiStretchSendBuffer(bufsize);
    01087
    01088   int e = MPI_Pack(const_cast<char*>(s), n, MPI_CHAR, sendBuffer, bufsize, &sendPosition, APPS_COMM);
    01089   if (e != MPI_SUCCESS)
    01090   {
    01091     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
    01092     throw "APPSPACK error";
    01093   }
    01094
    01095 #else
    01096
    01097    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01098    throw "APPSPACK error";
    01099
    01100 #endif
    01101 }
    01102
    01103 void GCI::pack(bool b)
    01104 {
    01105   // Pack a single bool. Bools are packed as ints because neither PVM
    01106   // nor MPI can handle the bool datatype.
    01107
    01108   int fakebool = (int) b;
    01109
    01110 #ifdef HAVE_PVM
    01111
    01112   pvmPackCheck(pvm_pkint(&fakebool, 1, 1));
    01113
    01114 #elif defined HAVE_MPI
    01115
    01116   pack(fakebool);
    01117
    01118 #else
    01119
    01120    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01121    throw "APPSPACK error";
    01122
    01123 #endif
    01124 }
    01125
    01126 void GCI::pack(const string s)
    01127 {
    01128
    01129   // Pack a string.
    01130
    01131 #if defined HAVE_PVM || defined HAVE_MPI
    01132
    01133   pack(s.c_str());
    01134
    01135 #else
    01136
    01137    cerr << "APPSPACK::GCI::pack requires PVM or MPI" << endl;
    01138    throw "APPSPACK error";
    01139
    01140 #endif
    01141 }
    01142
    01143 void GCI::pack(const vector<int>& v)
    01144 {
    01145   int n = v.size();
    01146   pack(n);
    01147   for (int i = 0; i < n; i ++)
    01148     pack(v[i]);
    01149 }
    01150
    01151 void GCI::pack(const vector<double>& v)
    01152 {
    01153   int n = v.size();
    01154   pack(n);
    01155   for (int i = 0; i < n; i ++)
    01156     pack(v[i]);
    01157 }
    01158
    01159 void GCI::pack(const vector< vector<double> >& v)
    01160 {
    01161   int n = v.size();
    01162   pack(n);
    01163   for (int i = 0; i < n; i ++)
    01164     pack(v[i]);
    01165 }
    01166
    01167 void GCI::pack(const vector<string>& v)
    01168 {
    01169   int n = v.size();
    01170   pack(n);
    01171   for (int i = 0; i < n; i ++)
    01172     pack(v[i]);
    01173 }
    01174
    01175 void GCI::pack(const vector<bool>& v)
    01176 {
    01177   // Bool vectors must be handled specially because they are stored is
    01178   // a compacted format.
    01179   int n = v.size();
    01180   pack(n);
    01181   int tmp;
    01182   for (int i = 0; i < n; i ++)
    01183   {
    01184     tmp = (int) v[i];
    01185     pack(tmp);
    01186   }
    01187 }
    01188
    01189 void GCI::pack(int length, const char* array)
    01190 {
    01191   // Pack array WITH its length first
    01192
    01193 #ifdef HAVE_PVM
    01194
    01195   pack(length);
    01196   pvmPackCheck(pvm_pkbyte(const_cast<char*>(array), length, 1));
    01197
    01198 #elif defined HAVE_MPI
    01199
    01200   // Pack array length
    01201   pack(length);
    01202
    01203   // Pack the array itself
    01204   int bufsize = sendPosition + sizeof(char) * length;
    01205   mpiStretchSendBuffer(bufsize);
    01206
    01207   int e = MPI_Pack(const_cast<char*>(array), length, MPI_CHAR, sendBuffer, bufsize, &sendPosition, APPS_COMM);
    01208   if (e != MPI_SUCCESS)
    01209   {
    01210     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
    01211     throw "APPSPACK error";
    01212   }
    01213
    01214 #else
    01215
    01216    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01217    throw "APPSPACK error";
    01218
    01219 #endif
    01220 }
    01221
    01222 void GCI::pack(int length, const int* array)
    01223 {
    01224   // Pack array WITH its length first
    01225
    01226 #ifdef HAVE_PVM
    01227
    01228   pack(length);
    01229   pvmPackCheck(pvm_pkint(const_cast<int*>(array), length, 1));
    01230
    01231 #elif defined HAVE_MPI
    01232
    01233   // Pack array length
    01234   pack(length);
    01235
    01236   // Pack the array itself
    01237   int bufsize = sendPosition + sizeof(int) * length;
    01238   mpiStretchSendBuffer(bufsize);
    01239
    01240   int e = MPI_Pack((int*)array, length, MPI_INT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
    01241   if (e != MPI_SUCCESS)
    01242   {
    01243     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
    01244     throw "APPSPACK error";
    01245   }
    01246
    01247 #else
    01248
    01249    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01250    throw "APPSPACK error";
    01251
    01252 #endif
    01253 }
    01254
    01255 void GCI::pack(int length, const double* array)
    01256 {
    01257   // Pack array WITH its length first
    01258
    01259 #ifdef HAVE_PVM
    01260
    01261   pack(length);
    01262   pvmPackCheck(pvm_pkdouble((double*) array, length, 1));
    01263
    01264 #elif defined HAVE_MPI
    01265
    01266   // Pack array length
    01267   pack(length);
    01268
    01269   // Pack the array itself
    01270   int bufsize = sendPosition + sizeof(double) * length;
    01271   mpiStretchSendBuffer(bufsize);
    01272
    01273   int e = MPI_Pack((double*)array, length, MPI_DOUBLE, sendBuffer, bufsize, &sendPosition, APPS_COMM);
    01274   if (e != MPI_SUCCESS)
    01275   {
    01276     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
    01277     throw "APPSPACK error";
    01278   }
    01279
    01280 #else
    01281
    01282    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01283    throw "APPSPACK error";
    01284
    01285 #endif
    01286 }
    01287
    01288
    01289 void GCI::pack(int length, const float* array)
    01290 {
    01291   // Pack array WITH its length first
    01292
    01293 #ifdef HAVE_PVM
    01294
    01295   pack(length);
    01296   pvmPackCheck(pvm_pkfloat((float*) array, length, 1));
    01297
    01298 #elif defined HAVE_MPI
    01299
    01300   // Pack array length
    01301   pack(length);
    01302
    01303   // Pack the array itself
    01304   int bufsize = sendPosition + sizeof(float) * length;
    01305   mpiStretchSendBuffer(bufsize);
    01306
    01307   int e = MPI_Pack((float*)array, length, MPI_FLOAT, sendBuffer, bufsize, &sendPosition, APPS_COMM);
    01308   if (e != MPI_SUCCESS)
    01309   {
    01310     cerr << "APPSPACK::GCI::pack - error in MPI pack" << endl;
    01311     throw "APPSPACK error";
    01312   }
    01313
    01314 #else
    01315
    01316    cerr << "APPSPACK::GCI::pack requires PVM of MPI" << endl;
    01317    throw "APPSPACK error";
    01318
    01319 #endif
    01320 }
    01321
    01322 void GCI::unpack(int& i)
    01323 {
    01324   // Unpack a single integer
    01325
    01326 #ifdef HAVE_PVM
    01327
    01328   pvmUnpackCheck(pvm_upkint(&i, 1, 1));
    01329
    01330 #elif defined HAVE_MPI
    01331
    01332   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &i, 1, MPI_INT, APPS_COMM);
    01333   if (e != MPI_SUCCESS)
    01334   {
    01335     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01336     throw "APPSPACK error";
    01337   }
    01338
    01339 #else
    01340
    01341    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01342    throw "APPSPACK error";
    01343
    01344 #endif
    01345 }
    01346
    01347 void GCI::unpack(char& i)
    01348 {
    01349   // Unpack a single integer
    01350
    01351 #ifdef HAVE_PVM
    01352
    01353   pvmUnpackCheck(pvm_upkbyte(&i, 1, 1));
    01354
    01355 #elif defined HAVE_MPI
    01356
    01357   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &i, 1, MPI_CHAR, APPS_COMM);
    01358   if (e != MPI_SUCCESS)
    01359   {
    01360     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01361     throw "APPSPACK error";
    01362   }
    01363
    01364 #else
    01365
    01366    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01367    throw "APPSPACK error";
    01368
    01369 #endif
    01370 }
    01371
    01372 void GCI::unpack(double& d)
    01373 {
    01374   // Unpack a single double
    01375
    01376 #ifdef HAVE_PVM
    01377
    01378   pvmUnpackCheck(pvm_upkdouble(&d, 1, 1));
    01379
    01380 #elif defined HAVE_MPI
    01381
    01382   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &d, 1, MPI_DOUBLE, APPS_COMM);
    01383   if (e != MPI_SUCCESS)
    01384   {
    01385     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01386     throw "APPSPACK error";
    01387   }
    01388
    01389 #else
    01390
    01391    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01392    throw "APPSPACK error";
    01393
    01394 #endif
    01395 }
    01396
    01397 void GCI::unpack(float& d)
    01398 {
    01399   // Unpack a single float
    01400
    01401 #ifdef HAVE_PVM
    01402
    01403   pvmUnpackCheck(pvm_upkfloat(&d, 1, 1));
    01404
    01405 #elif defined HAVE_MPI
    01406
    01407   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &d, 1, MPI_FLOAT, APPS_COMM);
    01408   if (e != MPI_SUCCESS)
    01409   {
    01410     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01411     throw "APPSPACK error";
    01412   }
    01413
    01414 #else
    01415
    01416    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01417    throw "APPSPACK error";
    01418
    01419 #endif
    01420 }
    01421
    01422 void GCI::unpack(char*& s)
    01423 {
    01424   // Unpack char array s. If s is NULL, memory is allocated for it. If
    01425   // not, the length of s is checked to be sure it's large enough.
    01426
    01427   int len;
    01428   unpack(len);
    01429
    01430   if (!s)
    01431     s = new char[len];
    01432   else if (((int)strlen(s)) < len)
    01433   {
    01434     cerr << "APPSPACK::GCI::unpack - string is too small for unpack" << endl;
    01435     throw "APPSPACK error";
    01436   }
    01437
    01438 #ifdef HAVE_PVM
    01439
    01440   pvmUnpackCheck(pvm_upkstr(s));
    01441
    01442 #elif defined HAVE_MPI
    01443
    01444   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, s, len, MPI_CHAR, APPS_COMM);
    01445   if (e != MPI_SUCCESS)
    01446   {
    01447     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01448     throw "APPSPACK error";
    01449   }
    01450
    01451 #else
    01452
    01453    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01454    throw "APPSPACK error";
    01455
    01456 #endif
    01457 }
    01458
    01459 void GCI::unpack(bool& b)
    01460 {
    01461   // Unpack a single boolean.
    01462
    01463 #ifdef HAVE_PVM
    01464
    01465   int bfake;
    01466   pvmUnpackCheck(pvm_upkint(&bfake, 1, 1));
    01467   b = (bool) bfake;
    01468
    01469 #elif defined HAVE_MPI
    01470
    01471   int bfake;
    01472   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, &bfake, 1, MPI_INT, APPS_COMM);
    01473   if (e != MPI_SUCCESS)
    01474   {
    01475     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01476     throw "APPSPACK error";
    01477   }
    01478
    01479   b = (bool) bfake;
    01480
    01481 #else
    01482
    01483    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01484    throw "APPSPACK error";
    01485
    01486 #endif
    01487 }
    01488
    01489 void GCI::unpack(string& s)
    01490 {
    01491
    01492 #if defined HAVE_PVM || defined HAVE_MPI
    01493
    01494 #ifdef DEBUG
    01495   cout << "Unpacking a string" << endl;
    01496 #endif
    01497
    01498   char* tmp = NULL;
    01499   unpack(tmp);
    01500
    01501 #ifdef DEBUG
    01502   cout << "Unpacking a string=" << tmp << endl;
    01503 #endif
    01504
    01505   s = tmp;
    01506
    01507 #ifdef DEBUG
    01508   cout << "Unpacking a string=" << s << endl;
    01509 #endif
    01510
    01511
    01512   try
    01513   {
    01514     delete [] tmp;
    01515   }
    01516   catch(...)
    01517   {
    01518   }
    01519
    01520 #ifdef DEBUG
    01521   cout << "Unpacking a string=" << s << endl;
    01522 #endif
    01523
    01524 #else
    01525
    01526    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01527    throw "APPSPACK error";
    01528
    01529 #endif
    01530 }
    01531
    01532 void GCI::unpack(vector<int>& v)
    01533 {
    01534   int n;
    01535   unpack(n);
    01536   v.resize(n);
    01537   for (int i = 0; i < n; i ++)
    01538     unpack(v[i]);
    01539 }
    01540
    01541 void GCI::unpack(vector<double>& v)
    01542 {
    01543   int n;
    01544   unpack(n);
    01545   v.resize(n);
    01546   for (int i = 0; i < n; i ++)
    01547     unpack(v[i]);
    01548 }
    01549
    01550 void GCI::unpack(vector< vector<double> >& v)
    01551 {
    01552   int n;
    01553   unpack(n);
    01554   v.resize(n);
    01555   for (int i = 0; i < n; i ++)
    01556     unpack(v[i]);
    01557 }
    01558
    01559 void GCI::unpack(vector<string>& v)
    01560 {
    01561   int n;
    01562   unpack(n);
    01563   v.resize(n);
    01564   for (int i = 0; i < n; i ++)
    01565     unpack(v[i]);
    01566 }
    01567
    01568
    01569 void GCI::unpack(vector<bool>& v)
    01570 {
    01571   // Bool vectors must be handled specially because they are stored is
    01572   // a compacted format.
    01573   int n;
    01574   unpack(n);
    01575   v.resize(n);
    01576   int tmp;
    01577   for (int i = 0; i < n; i ++)
    01578   {
    01579     unpack(tmp);
    01580     v[i] = (bool) tmp;
    01581   }
    01582 }
    01583
    01584 void GCI::unpack(int& length, char*& array)
    01585 {
    01586   // Unpack array s. If s is NULL, memory is allocated for it. If
    01587   // not, the length of s is checked to be sure it's large enough.
    01588
    01589   unpack(length);
    01590   array = new char[length];
    01591
    01592 #ifdef HAVE_PVM
    01593
    01594   pvmUnpackCheck(pvm_upkbyte(array, length, 1));
    01595
    01596 #elif defined HAVE_MPI
    01597
    01598   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_CHAR, APPS_COMM);
    01599   if (e != MPI_SUCCESS)
    01600   {
    01601     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01602     throw "APPSPACK error";
    01603   }
    01604
    01605 #else
    01606
    01607    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01608    throw "APPSPACK error";
    01609
    01610 #endif
    01611 }
    01612
    01613 void GCI::unpack(int& length, int*& array)
    01614 {
    01615   // Unpack array s. If s is NULL, memory is allocated for it. If
    01616   // not, the length of s is checked to be sure it's large enough.
    01617
    01618   unpack(length);
    01619   array = new int[length];
    01620
    01621 #ifdef HAVE_PVM
    01622
    01623   pvmUnpackCheck(pvm_upkint(array, length, 1));
    01624
    01625 #elif defined HAVE_MPI
    01626
    01627   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_INT, APPS_COMM);
    01628   if (e != MPI_SUCCESS)
    01629   {
    01630     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01631     throw "APPSPACK error";
    01632   }
    01633
    01634 #else
    01635
    01636    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01637    throw "APPSPACK error";
    01638
    01639 #endif
    01640 }
    01641
    01642 void GCI::unpack(int& length, double*& array)
    01643 {
    01644   // Unpack array s. If s is NULL, memory is allocated for it. If
    01645   // not, the length of s is checked to be sure it's large enough.
    01646
    01647   unpack(length);
    01648   array = new double[length];
    01649
    01650 #ifdef HAVE_PVM
    01651
    01652   pvmUnpackCheck(pvm_upkdouble(array, length, 1));
    01653
    01654 #elif defined HAVE_MPI
    01655
    01656   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_DOUBLE, APPS_COMM);
    01657   if (e != MPI_SUCCESS)
    01658   {
    01659     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01660     throw "APPSPACK error";
    01661   }
    01662
    01663 #else
    01664
    01665    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01666    throw "APPSPACK error";
    01667
    01668 #endif
    01669 }
    01670
    01671 void GCI::unpack(int& length, float*& array)
    01672 {
    01673   // Unpack array s. If s is NULL, memory is allocated for it. If
    01674   // not, the length of s is checked to be sure it's large enough.
    01675
    01676   unpack(length);
    01677   array = new float[length];
    01678
    01679 #ifdef HAVE_PVM
    01680
    01681   pvmUnpackCheck(pvm_upkfloat(array, length, 1));
    01682
    01683 #elif defined HAVE_MPI
    01684
    01685   int e = MPI_Unpack(recvBuffer, msgSize, &recvPosition, array, length, MPI_FLOAT, APPS_COMM);
    01686   if (e != MPI_SUCCESS)
    01687   {
    01688     cerr << "APPSPACK::GCI::unpack - error in MPI unpack" << endl;
    01689     throw "APPSPACK error";
    01690   }
    01691
    01692 #else
    01693
    01694    cerr << "APPSPACK::GCI::unpack requires PVM of MPI" << endl;
    01695    throw "APPSPACK error";
    01696
    01697 #endif
    01698 }
    01699
    01700 // ----------------------------------------------------------------------
    01701 // Host Info
    01702 // ----------------------------------------------------------------------
    01703
    01704 int GCI::resetHostInfo()
    01705 {
    01706   // Reset host information by asking PVM to update pvmHostInfo - the data
    01707   // structure that contains the host information. Return the number
    01708   // of hosts.
    01709
    01710 #ifdef HAVE_PVM
    01711
    01712   pvmHostInfo = NULL;
    01713
    01714   if ((pvm_config(&nHosts, &nArch, &pvmHostInfo)) < 0)
    01715   {
    01716     cerr << "APPSPACK::GCI::resetHostInfo - error from pvm_config" << endl;
    01717     throw "APPSPACK error";
    01718   }
    01719
    01720   return nHosts;
    01721
    01722 #else
    01723
    01724    cerr << "APPSPACK::GCI::resetHostInfo requires PVM" << endl;
    01725    throw "APPSPACK error";
    01726
    01727 #endif
    01728 }
    01729
    01730 int GCI::getHostTid(int i)
    01731 {
    01732   // Get the host id of the ith host.
    01733
    01734 #ifdef HAVE_PVM
    01735
    01736   return pvmHostInfo[i].hi_tid;
    01737
    01738 #else
    01739
    01740    cerr << "APPSPACK::GCI::getHostTid requires PVM" << endl;
    01741    throw "APPSPACK error";
    01742
    01743 #endif
    01744 }
    01745
    01746 int GCI::getHostSpeed(int i)
    01747 {
    01748   // Get the speed of the ith host.
    01749
    01750 #ifdef HAVE_PVM
    01751
    01752   return pvmHostInfo[i].hi_speed;
    01753
    01754 #else
    01755
    01756    cerr << "APPSPACK::GCI::getHostSpeed requires PVM" << endl;
    01757    throw "APPSPACK error";
    01758
    01759 #endif
    01760 }
    01761
    01762 char* GCI::getHostName(int i)
    01763 {
    01764   // Get the name of the ith host.
    01765
    01766 #ifdef HAVE_PVM
    01767
    01768   return pvmHostInfo[i].hi_name;
    01769
    01770 #else
    01771
    01772    cerr << "APPSPACK::GCI::getHostName requires PVM" << endl;
    01773    throw "APPSPACK error";
    01774
    01775 #endif
    01776 }
    01777
    01778 // ----------------------------------------------------------------------
    01779 // Helper functions for PVM
    01780 // ----------------------------------------------------------------------
    01781
    01782 #ifdef HAVE_PVM
    01783
    01784 void GCI::pvmPackCheck(int info)        // PRIVATE
    01785 {
    01786   // Check return code from pvm_pack
    01787
    01788   if (info == PvmNoMem)
    01789   {
    01790     cerr << "APPSPACK::GCI::pack - out of memory" << endl;
    01791     throw "APPSPACK error";
    01792   }
    01793   if (info == PvmNoBuf)
    01794   {
    01795     cerr << "APPSPACK::GCI::pack - no active send buffer" << endl;
    01796     throw "APPSPACK error";
    01797   }
    01798   if (info < 0)
    01799   {
    01800     cerr << "APPSPACK::GCI::pack - unrecognized PVM error" << endl;
    01801     throw "APPSPACK error";
    01802   }
    01803 }
    01804
    01805 void GCI::pvmUnpackCheck(int info) // PRIVATE
    01806 {
    01807   // Check return code form pvm_unpack
    01808
    01809   if (info == PvmNoData)
    01810   {
    01811     cerr << "APPSPACK::GCI::unpack - reading past end of buffer" << endl;
    01812     throw "APPSPACK error";
    01813   }
    01814   if (info == PvmBadMsg)
    01815   {
    01816     cerr << "APPSPACK::GCI::unpack - incompatiable encoding" << endl;
    01817     throw "APPSPACK error";
    01818   }
    01819   if (info == PvmNoBuf)
    01820   {
    01821     cerr << "APPSPACK::GCI::unpack - no active receive buffer" << endl;
    01822     throw "APPSPACK error";
    01823   }
    01824   if (info < 0)
    01825   {
    01826     cerr << "APPSPACK::GCI::unpack - unrecognized PVM error" << endl;
    01827     throw "APPSPACK error";
    01828   }
    01829 }
    01830
    01831 #endif
    01832
    01833
    01834 // ----------------------------------------------------------------------
    01835 // Helper functions for MPI
    01836 // ----------------------------------------------------------------------
    01837
    01838 #ifdef HAVE_MPI
    01839
    01840 int GCI::mpiGetMsgSize(MPI_Status localstatus, MPI_Datatype datatype)
    01841 {
    01842   // Returns the size of the message localstatus is associated with.
    01843   // "localstatus" is so named to separate it from the global variable
    01844   // "status."
    01845
    01846   int count;
    01847
    01848   // This MPI call sets count = the number of items of type datatype
    01849   // in the message.
    01850   int e = MPI_Get_count(&localstatus, datatype, &count);
    01851   if (e != MPI_SUCCESS)
    01852   {
    01853     cerr << "APPSPACK::GCI::mpiGetMsgSize - error" << endl;
    01854     throw "APPSPACK error";
    01855   }
    01856
    01857   return(count);
    01858 }
    01859
    01860 void GCI::mpiStretchSendBuffer(int bufsize)
    01861 {
    01862   // This is a helper function for the pack methods.  It makes the
    01863   // size of the send buffer bufsize.
    01864
    01865   // Create new buffer
    01866   char* newbuffer = new char[bufsize];
    01867
    01868   // Copy old buffer into new
    01869   for(int i = 0; i < sendPosition; i++)
    01870     newbuffer[i] = sendBuffer[i];
    01871
    01872   // Delete old buffer and replace with new
    01873   delete[] sendBuffer;
    01874   sendBuffer = newbuffer;
    01875 }
    01876
    01877 #endif
    01878

© Sandia Corporation | Site Contact | Privacy and Security

Generated on Wed Dec 14 18:41:04 2005 for APPSPACK 4.0.2 by 1.3.8 written by Dimitri van Heesch, © 1997-2002