PaCO++
0.05
|
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