| /*****************************************************************************/ |
| /* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */ |
| /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */ |
| /* */ |
| /* This program is free software; you can redistribute it and/or modify */ |
| /* it under the terms of the GNU General Public License as published by */ |
| /* the Free Software Foundation. You should have received a copy of the */ |
| /* GNU General Public License along with this program; if not, write to the */ |
| /* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ |
| /* */ |
| /* * PVM.c ---- PVM calls source */ |
| /*****************************************************************************/ |
| #include "netpipe.h" |
| #include <pvm3.h> |
| |
| /**********************************************************************/ |
| /* Set up the communcations system. */ |
| /* In pvm, this means to join the parallel machine */ |
| /**********************************************************************/ |
| int Setup(ArgStruct * p) |
| { |
| p->prot.mytid = pvm_mytid(); |
| #ifdef DEBUG |
| printf("My task id is %d \n", p->prot.mytid); |
| #endif |
| } |
| |
| /**********************************************************************/ |
| /* Establish a link with the other processor */ |
| /* In pvm, this means to send a simple message, but to keep the */ |
| /* communication line open. Since the assumption is that we are */ |
| /* starting it by hand on the other machine, we don't know what */ |
| /* the other task id is. */ |
| /**********************************************************************/ |
| int Establish(ArgStruct * p) |
| { |
| /* Task information for the entire parallel machine (if trans) */ |
| int tasks_status; |
| struct pvmtaskinfo *taskp; |
| int ntasks; |
| |
| /* Received buffer (if receiver) */ |
| int buffer_id; |
| |
| /* |
| If we are the transmitting side, go find the other one and send |
| it a message containing our tid. If we are the receiving side, |
| just wait for a message. |
| */ |
| if (p->tr) { |
| #ifdef DEBUG |
| printf("this is the transmitter\n"); |
| #endif |
| tasks_status = pvm_tasks(0, &ntasks, &taskp); |
| if (ntasks != 2) { |
| printf |
| ("Error, too many processes in parallel machine \n"); |
| printf("Start a clean machine. n=%d\n", ntasks); |
| exit(-1); |
| } |
| |
| /* Since there are two tasks, one is ours the other is the receiver */ |
| p->prot.othertid = -1; |
| if (taskp[0].ti_tid == p->prot.mytid) { |
| p->prot.othertid = taskp[1].ti_tid; |
| } |
| if (taskp[1].ti_tid == p->prot.mytid) { |
| p->prot.othertid = taskp[0].ti_tid; |
| } |
| if (p->prot.othertid == -1) { |
| printf("Error, cannot find other (receiving) task \n"); |
| printf("Id's: %d %d \n", taskp[0].ti_tid, |
| taskp[1].ti_tid); |
| } |
| |
| /* Send the receiver a message. Tell pvm to keep the channel open */ |
| |
| #ifdef DEBUG |
| printf("The receiver tid is %d \n", p->prot.othertid); |
| #endif |
| pvm_setopt(PvmRoute, PvmRouteDirect); |
| pvm_initsend(PVMDATA); |
| pvm_pkint(&p->prot.mytid, 1, 1); |
| pvm_send(p->prot.othertid, 1); |
| } else { |
| #ifdef DEBUG |
| printf("This is the receiver \n"); |
| #endif |
| |
| /* Receive any message from any task */ |
| buffer_id = pvm_recv(-1, -1); |
| |
| if (buffer_id < 0) { |
| printf("Error on receive in receiver\n"); |
| exit(-1); |
| } |
| pvm_upkint(&p->prot.othertid, 1, 1); |
| } |
| } |
| |
| /**********************************************************************/ |
| /* Prepare to receive */ |
| /* In pvm, you cannot set up a reception buffer ahead of time */ |
| /**********************************************************************/ |
| void PrepareToReceive(ArgStruct * p) |
| { |
| } |
| |
| /**********************************************************************/ |
| /* Synchronize */ |
| /* In pvm, this is not necessary */ |
| /**********************************************************************/ |
| void Sync(ArgStruct * p) |
| { |
| } |
| |
| /**********************************************************************/ |
| /* Send a buffer full of information */ |
| /* In pvm, we use pvm_pkbyte and then send it. */ |
| /**********************************************************************/ |
| void SendData(ArgStruct * p) |
| { |
| #ifdef DEBUG |
| printf(" In send \n"); |
| #endif |
| pvm_initsend(PVMDATA); |
| pvm_pkbyte(p->buff, p->bufflen, 1); |
| pvm_send(p->prot.othertid, 1); |
| #ifdef DEBUG |
| printf(" message sent. Size=%d\n", p->bufflen); |
| #endif |
| } |
| |
| /**********************************************************************/ |
| /* Receive a buffer full of information */ |
| /**********************************************************************/ |
| void RecvData(ArgStruct * p) |
| { |
| #ifdef DEBUG |
| printf(" In receive \n"); |
| #endif |
| pvm_recv(-1, -1); |
| pvm_upkbyte(p->buff, p->bufflen, 1); |
| #ifdef DEBUG |
| printf(" message received . Size=%d \n", p->bufflen); |
| #endif |
| } |
| |
| /**********************************************************************/ |
| /* Send elapsed time to the other process */ |
| /**********************************************************************/ |
| void SendTime(ArgStruct * p, double *t) |
| { |
| pvm_initsend(PVMDATA); |
| pvm_pkdouble(t, 1, 1); |
| pvm_send(p->prot.othertid, 1); |
| } |
| |
| /**********************************************************************/ |
| /* Receive elapsed time from the other process */ |
| /**********************************************************************/ |
| void RecvTime(ArgStruct * p, double *t) |
| { |
| pvm_recv(-1, -1); |
| pvm_upkdouble(t, 1, 1); |
| } |
| |
| /**********************************************************************/ |
| /* Send repeat count to the other process */ |
| /**********************************************************************/ |
| void SendRepeat(ArgStruct * p, int rpt) |
| { |
| pvm_initsend(PVMDATA); |
| pvm_pkint(&rpt, 1, 1); |
| pvm_send(p->prot.othertid, 1); |
| } |
| |
| /**********************************************************************/ |
| /* Receiver repeat count from other process */ |
| /**********************************************************************/ |
| void RecvRepeat(ArgStruct * p, int *rpt) |
| { |
| pvm_recv(-1, -1); |
| pvm_upkint(rpt, 1, 1); |
| } |
| |
| /**********************************************************************/ |
| /* Close down the connection. |
| /**********************************************************************/ |
| int CleanUp(ArgStruct * p) |
| { |
| } |