PaCO++  0.05
ClientSide.cc
Go to the documentation of this file.
00001 /* Padico Advanced Examples
00002  * author: Christian Pérez
00003  */
00004 
00005 #include <stdio.h>
00006 #include <mpi.h>
00007 
00008 #include "Schedule.h"
00009 #include "DistributionBloc.h"
00010 #include "Internal.h"
00011 
00012 #include <vector>
00013 #include <iostream>
00014 
00015 using namespace std;
00016 
00017 //#define NO_COM
00018 
00019 #undef STANDALONE_FILE
00020 
00021 #undef DEBUG_INTERNAL
00022 #undef DEBUG_COMM
00023 
00027 
00028 // Compute client-side redistribution on the client
00029 void computeSendDataBlock1DClient(const GlobalData_t& gd, const LocalData_t &sd, const ParisBlock_param_t* param,
00030               const Topology_t &stopo, const Topology_t &dtopo,
00031               vAbstrait& vdarray, vector<unsigned>& destid, void* comm)
00032 {
00033 
00034 #ifdef DEBUG_INTERNAL
00035   cerr << "In computeSendDataBlock1DClient...\n";
00036 #endif
00037 
00038   vector<LocalData_t> sched_send;
00039   vector<LocalData_t> sched_recv;
00040 
00041   sched_send.clear();
00042   sched_recv.clear();
00043 
00047   // Compute what to send
00049 #ifdef DEBUG_INTERNAL
00050   cerr << "In computeSendDataBlock1DClient...computing what to send\n";
00051 #endif
00052   computeSendBlock1D(gd, sd, stopo, dtopo, param, sched_send);
00053 
00057   // Compute what to receive
00059 #ifdef DEBUG_INTERNAL
00060   cerr << "In computeSendDataBlock1DClient...computing what to receive\n";
00061 #endif
00062 
00063   // compute how many dest local data this node has to handle
00064   unsigned int nvdarray  = dtopo.total/stopo.total;
00065   unsigned int remaining = (nvdarray*stopo.total + sd.rank < dtopo.total)?1:0;
00066   nvdarray += remaining;
00067 
00068   // Preparing also CORBA stuff
00069   vdarray.clear();
00070   vdarray.resize(nvdarray);
00071   destid.clear();
00072   destid.resize(nvdarray);
00073 
00074   // so, we simulate node from rank, rank+stopo.total ,... only if nvdarray>0
00075   unsigned dlbsz = blockSize(gd.len, dtopo.total, param); // blocsize on dest nodes
00076   // useless  unsigned dtbsz = NumberOfBlockProc(gd.len, dtopo.total , dlbsz, dtopo.total-1); // step on dest nodes
00077   
00078   //  cerr << "DBSZ: " << dbsz << endl;
00079   for (unsigned it=0; it<nvdarray; it++) {
00080 
00081 #ifdef DEBUG_INTERNAL
00082     cerr << "computeSendDataBlock1DClient: it = " << it << endl;
00083 #endif
00084 
00085     Abstrait* out = vdarray[it];
00086 
00087     out->topo().total   = dtopo.total;
00088     out->gd()           = gd;  // copy all global data struct
00089 
00090     // add for mode informations
00091     out->mode() = PaCO::ClientSide;
00092 
00093     out->dist().length(1);
00094     out->setSeqLength(1);
00095 
00096     PaCO::PacoLocalData_t& pld = out->dist()[0];
00097     LocalData_t dd;
00098     pld.rank  = dd.rank  = sd.rank + it * stopo.total;
00099     pld.start = dd.start = computeBlockBoundInf(dlbsz, dd.rank, dtopo.total, 0);
00100     pld.len   = dd.len   = TotalNumberOfElementProc(gd.len, dd.rank, dtopo.total, dlbsz);
00101 
00102 #ifdef DEBUG_INTERNAL
00103     fprintf(stderr, "dd loop %d: r:%d gl:%ld ll:%d start:%d dt:%ld\n", it,
00104        dd.rank, gd.len, dd.len, dd.start, dtopo.total);
00105 #endif
00106 
00107     destid[it] = dd.rank;
00108 
00111     // Allocating memory
00112 
00113 #ifdef DEBUG_INTERNAL
00114     cerr << "Allocating a sequence of length " << pld.len << endl;
00115 #endif
00116     out->setDataLength(0, pld.len);
00117     if (pld.len > 0 )
00118       dd.base = out->getDataBuffer(0, false);
00119     else
00120       dd.base = (char*) 1; /* hum, ... debug ;( */
00121 
00122     if (dd.base==0) {
00123       cerr << "Cannot allocate memory for #elements" << pld.len  << endl;
00124     } else {
00125 #ifdef DEBUG_INTERNAL
00126       fprintf(stderr, "dd.base = %p\n", dd.base);
00127 #endif
00128     }
00129 
00130     computeReceiveBlock1D(gd, dd, stopo, dtopo, param, sched_recv);
00131   }
00132 
00136   // Doing local communication
00138   //fprintf(stderr, "In computeSendDataBlock1DClient...Doing local communications with ctopo: %ld\n", dtopo.total);
00139   doSchedule(gd, sd, stopo, sched_send, sched_recv, comm); 
00140 
00141 #ifdef DEBUG_INTERNAL
00142   cerr << "In computeSendDataBlock1DClient...ok\n";
00143 #endif
00144 }
00145 
00149 
00150 // Compute server-side redistribution on the client -> almost nothing to do
00151 
00152 // simply send data from source i to dest i % dtopo.total
00153 // if less sources than destination: dest j <  source j % stopo.total
00154 
00155 // Client Side function
00156 void computeSendDataBlock1DServer(const GlobalData_t& gd, const LocalData_t &sd, 
00157               const Topology_t &stopo, const Topology_t &dtopo,
00158               vAbstrait& vdarray, vector<unsigned>& destid)
00159 {
00160 
00161 
00162   // Easy: node i send data to node i%dtopo.total
00163   // It has to send an empty message to nodes i+stopo.total, i+2*stopo.total ... < dtopo.total
00164 
00165   // How messages to send ?
00166   unsigned int nvdarray  = dtopo.total/stopo.total;
00167   unsigned int remaining = (nvdarray*stopo.total + sd.rank < dtopo.total)?1:0;
00168   nvdarray += remaining;
00169 
00170   // alwaays something to send
00171   if ( nvdarray == 0 ) nvdarray=1;
00172 
00173   // Preparing  CORBA stuff
00174   vdarray.clear();
00175   vdarray.resize(nvdarray);
00176   destid.clear();
00177   destid.resize(nvdarray);
00178 
00179   for (unsigned it=0; it<nvdarray; it++) {
00180 
00181     Abstrait* out = vdarray[it];
00182 
00183     out->topo().total = stopo.total;
00184     out->gd()         = gd;
00185     
00186     // add for mode information
00187     out->mode() = PaCO::ServerSide;
00188 
00189     if ( it == 0 ) { // always data to send
00190       out->dist().length(1);
00191       out->setSeqLength(1);
00192 
00193       out->dist()[0].rank  = sd.rank;
00194       out->dist()[0].start = sd.start;
00195       out->dist()[0].len   = sd.len;
00196       out->DataReplace(0, sd.len, sd.base, false);
00197     } else { // always nothing to send
00198       out->dist().length(0);
00199       out->setSeqLength(0);
00200     }
00201     destid[it] = ( sd.rank + it * stopo.total ) % dtopo.total;
00202   }
00203 }
00204 
00207 
00208 void computeSendDataBlock1DComm() {
00209 }
00210 
00213 
00214 // vOut represents what localData/stopo have to send to nodes of dtopo (vOut[].rank is in dtopo space)
00215 void computeSendDataBlock1D(const GlobalData_t& gd, const LocalData_t &sd, 
00216              const Topology_t &stopo, const Topology_t &dtopo, const ParisBlock_param_t* param,
00217              vAbstrait& vdarray, vector<unsigned>& destid,
00218              const PaCO::distLoc_t& mode, void* comm) {
00219 
00220   switch(mode) {
00221   case PaCO::none: cerr << "INTERNAL ERROR: " << __FILE__ << " " << __FUNCTION__ << endl;
00222   case PaCO::ClientSide: computeSendDataBlock1DClient(gd, sd, param, stopo, dtopo, vdarray, destid, comm); break;
00223   case PaCO::ServerSide: computeSendDataBlock1DServer(gd, sd, stopo, dtopo, vdarray, destid); break;
00224   case PaCO::CommSide:   computeSendDataBlock1DComm  (); break;   
00225   }
00226   
00227 }
00228