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