00001
00006 #include "idxl.h"
00007
00008
00009
00010 IDXL_Rec::IDXL_Rec(int entity_) {
00011 entity=entity_;
00012 oldlength=0;
00013 }
00014 IDXL_Rec::~IDXL_Rec() {}
00015 void IDXL_Rec::pup(PUP::er &p)
00016 {
00017 p|entity;
00018 p|shares;
00019 }
00020 void IDXL_Rec::add(int chk,int idx)
00021 {
00022 int n=shares.size();
00023 #if CMK_ERROR_CHECKING
00024 if (chk<0 || chk>1000000)
00025 CkAbort("FEM IDXL_Rec::add> Tried to add absurd chunk number!\n");
00026 #endif
00027 if(n >= oldlength) {
00028 oldlength = 2*(n+1);
00029 shares.reserve(oldlength);
00030 }
00031 shares.push_back(IDXL_Share(chk,idx));
00032 }
00033
00034
00035
00036 IDXL_Map::IDXL_Map() {}
00037 IDXL_Map::~IDXL_Map() {
00038
00039 CkHashtableIterator *it=map.iterator();
00040 IDXL_Rec **rec;
00041 while (NULL!=(rec=(IDXL_Rec **)it->next()))
00042 delete *rec;
00043 delete it;
00044 }
00045
00046
00047 void IDXL_Map::add(int entity,int chk,int idx)
00048 {
00049 IDXL_Rec *rec;
00050 if (NULL!=(rec=map.get(entity)))
00051 {
00052 rec->add(chk,idx);
00053 }
00054 else
00055 {
00056 rec=new IDXL_Rec(entity);
00057 rec->add(chk,idx);
00058 map.put(entity)=rec;
00059 }
00060 }
00061
00062
00063 const IDXL_Rec *IDXL_Map::get(int entity) const
00064 {
00065 return map.get(entity);
00066 }
00067
00068 IDXL_List::IDXL_List()
00069 {
00070 chunk=-1;
00071 lock = false;
00072 }
00073 IDXL_List::IDXL_List(int otherchunk)
00074 {
00075 chunk=otherchunk;
00076 lock = false;
00077 }
00078 IDXL_List::~IDXL_List() {}
00079
00080 bool IDXL_List::lockIdxl(){
00081 if(!lock) {
00082 lock = true;
00083 return true;
00084 }
00085 return false;
00086 }
00087
00088 void IDXL_List::unlockIdxl(){
00089 lock = false;
00090 }
00091
00092 bool IDXL_List::isLocked() {
00093 return lock;
00094 }
00095
00096 int IDXL_List::push_back(int localIdx) {
00097 int ret=shared.size();
00098 shared.push_back(localIdx);
00099 return ret;
00100 }
00101
00102 bool IDXL_List::set(int localIdx, int sharedIdx) {
00103 int size = shared.size();
00104 if(sharedIdx<0 || sharedIdx > size+50) return false;
00105 if(sharedIdx < size) {
00106 shared[sharedIdx] = localIdx;
00107 }
00108 else {
00109 for(int i=size; i<sharedIdx; i++) {
00110 shared.push_back(-1);
00111 }
00112 shared.push_back(localIdx);
00113 }
00114 return true;
00115 }
00116
00117 bool IDXL_List::unset(int sharedIdx) {
00118 int size = shared.size();
00119 if(sharedIdx >= size || sharedIdx < 0) return false;
00120 shared[sharedIdx] = -1;
00121 return true;
00122 }
00123
00124 int IDXL_List::exists(int localIdx) {
00125 for(int i=0; i<shared.size(); i++) {
00126 if(shared[i]==localIdx) return i;
00127 }
00128 return -1;
00129 }
00130
00131 int IDXL_List::get(int sharedIdx) {
00132 int size = shared.size();
00133 if(sharedIdx >= size || sharedIdx < 0) return -1;
00134 return shared[sharedIdx];
00135 }
00136
00137 void IDXL_List::pup(PUP::er &p)
00138 {
00139 p|chunk;
00140 p|shared;
00141 }
00142
00143 bool doubleeq(double a,double b){
00144 if(a-b < 1e-100 && a-b > -1e-100){
00145 return true;
00146 }
00147 return false;
00148 }
00149
00150 void IDXL_List::sort2d(double *coord){
00151 double *dist = new double[shared.size()];
00152 int i;
00153 for(i=0;i<shared.size();i++){
00154 int idx = shared[i];
00155 dist[i] = coord[2*idx]*coord[2*idx]+coord[2*idx+1]*coord[2*idx+1];
00156 }
00157 for(i=0;i<shared.size();i++){
00158 for(int j=i;j<shared.size();j++){
00163 if(doubleeq(dist[i],dist[j])){
00164 int idxi = shared[i];
00165 int idxj = shared[j];
00166 if(coord[2*idxi] > coord[2*idxj]){
00167 int k = shared[j];
00168 double temp = dist[j];
00169 shared[j] = shared[i];
00170 dist[j] = dist[i];
00171 shared[i] = k;
00172 dist[i] = temp;
00173 }
00174 }
00175 if(dist[i] > dist[j]){
00176 int k = shared[j];
00177 double temp = dist[j];
00178 shared[j] = shared[i];
00179 dist[j] = dist[i];
00180 shared[i] = k;
00181 dist[i] = temp;
00182 }
00183 }
00184 }
00185 delete [] dist;
00186 }
00187
00188 void IDXL_List::sort3d(double *coord){
00189 double *dist = new double[shared.size()];
00190 int i;
00191 for(i=0;i<shared.size();i++){
00192 int idx = shared[i];
00193 dist[i] = coord[3*idx]*coord[3*idx]+coord[3*idx+1]*coord[3*idx+1]+coord[3*idx+2]*coord[3*idx+2];
00194 }
00195 for(i=0;i<shared.size();i++){
00196 for(int j=i;j<shared.size();j++){
00201 if(doubleeq(dist[i],dist[j])){
00202 int idxi = shared[i];
00203 int idxj = shared[j];
00204 if(coord[3*idxi] > coord[3*idxj]){
00205 int k = shared[j];
00206 double temp = dist[j];
00207 shared[j] = shared[i];
00208 dist[j] = dist[i];
00209 shared[i] = k;
00210 dist[i] = temp;
00211 }
00212 else if(coord[3*idxi] == coord[3*idxj]) {
00213 if(coord[3*idxi+1] > coord[3*idxj+1]){
00214 int k = shared[j];
00215 double temp = dist[j];
00216 shared[j] = shared[i];
00217 dist[j] = dist[i];
00218 shared[i] = k;
00219 dist[i] = temp;
00220 }
00221 }
00222 }
00223 if(dist[i] > dist[j]){
00224 int k = shared[j];
00225 double temp = dist[j];
00226 shared[j] = shared[i];
00227 dist[j] = dist[i];
00228 shared[i] = k;
00229 dist[i] = temp;
00230 }
00231 }
00232 }
00233 delete [] dist;
00234 }
00235
00236
00237
00238
00239 IDXL_Side::IDXL_Side(void) :cached_map(NULL)
00240 {}
00241 IDXL_Side::~IDXL_Side() {
00242 flushMap();
00243 }
00244
00245 void IDXL_Side::clear(){
00246 flushMap();
00247 comm.free();
00248 }
00249
00250 void IDXL_Side::pup(PUP::er &p)
00251 {
00252 comm.pup(p);
00253
00254 }
00255
00256 int IDXL_Side::total(void) const {
00257 int ret=0;
00258 for (int s=0;s<size();s++) ret+=comm[s]->size();
00259 return ret;
00260 }
00261
00262 IDXL_Map &IDXL_Side::getMap(void) {
00263 if (cached_map) return *cached_map;
00264
00265 cached_map=new IDXL_Map;
00266 IDXL_Map &map=*cached_map;
00267 for (int c=0;c<comm.size();c++)
00268 for (int idx=0;idx<comm[c]->size();idx++)
00269 map.add((*comm[c])[idx],comm[c]->getDest(),idx);
00270 return map;
00271 }
00272 void IDXL_Side::flushMap(void) {
00273 if (cached_map) {
00274 delete cached_map;
00275 cached_map=NULL;
00276 }
00277 }
00278
00279 const IDXL_Rec *IDXL_Side::getRec(int entity) const
00280 {
00281
00282 IDXL_Side *writable=(IDXL_Side *)this;
00283 return writable->getMap().get(entity);
00284 }
00285
00286 void IDXL_Side::add(int myChunk,int myLocalNo,
00287 int hisChunk,int hisLocalNo,IDXL_Side &his)
00288 {
00289 IDXL_List *myList=getListN(hisChunk);
00290 if (myList==NULL)
00291 {
00292
00293 myList=new IDXL_List(hisChunk);
00294 IDXL_List *hisList=new IDXL_List(myChunk);
00295 comm.push_back(myList);
00296 his.comm.push_back(hisList);
00297 }
00298 IDXL_List *hisList=his.getListN(myChunk);
00299
00300
00301 myList->push_back(myLocalNo);
00302 hisList->push_back(hisLocalNo);
00303 flushMap(); his.flushMap();
00304 }
00305
00307 int IDXL_Side::addNode(int localNo,int sharedWithChk) {
00308 int shdIdx = addList(sharedWithChk).push_back(localNo);
00309 flushMap();
00310 return shdIdx;
00311 }
00312
00313 int IDXL_Side::removeNode(int localNo, int sharedWithChk) {
00314 int local = findLocalList(sharedWithChk);
00315 int shdIdx = -1;
00316 for(int i=0; i<comm[local]->size(); i++) {
00317 if((*comm[local])[i] == localNo) {
00318
00319 (*comm[local])[i] = -1;
00320 shdIdx = i;
00321 }
00322 }
00323 flushMap();
00324 return shdIdx;
00325 }
00326
00327
00328
00329
00330
00331 bool IDXL_Side::setNode(int localNo, int sharedWithChk, int sharedIdx) {
00332 bool done = addList(sharedWithChk).set(localNo, sharedIdx);
00333 flushMap();
00334 return done;
00335 }
00336
00337 bool IDXL_Side::unsetNode(int sharedWithChk, int sharedIdx) {
00338 bool done = addList(sharedWithChk).unset(sharedIdx);
00339 flushMap();
00340 return done;
00341 }
00342
00343 int IDXL_Side::existsNode(int localNo, int sharedWithChk) {
00344 return addList(sharedWithChk).exists(localNo);
00345 }
00346
00347 int IDXL_Side::getNode(int sharedWithChk, int sharedIdx) {
00348 return addList(sharedWithChk).get(sharedIdx);
00349 }
00350
00351 class IDXL_Identity_Map : public IDXL_Print_Map {
00352 virtual void map(int srcIdx) const {
00353 CkPrintf("%d ",srcIdx);
00354 }
00355 };
00356
00357 void IDXL_Side::print(const IDXL_Print_Map *idxmap) const
00358 {
00359 IDXL_Identity_Map im;
00360 if (idxmap==NULL) idxmap=&im;
00361 CkPrintf("Communication list: %d chunks, %d total entries\n",size(),total());
00362 for (int p=0;p<size();p++) {
00363 const IDXL_List &l=getLocalList(p);
00364 CkPrintf(" With %d:",l.getDest(),l.size());
00365 for (int n=0;n<l.size();n++)
00366 idxmap->map(l[n]);
00367 CkPrintf("\n");
00368 }
00369 }
00370
00371 void IDXL_Side::sort2d(double *coord){
00372 for(int i=0;i<comm.size();i++){
00373 IDXL_List *l = comm[i];
00374 l->sort2d(coord);
00375 }
00376 flushMap();
00377 }
00378
00379 void IDXL_Side::sort3d(double *coord){
00380 for(int i=0;i<comm.size();i++){
00381 IDXL_List *l = comm[i];
00382 l->sort3d(coord);
00383 }
00384 flushMap();
00385 }
00386
00387
00388
00389
00390
00391
00392 void IDXL::sort2d(double *coord){
00393 IDXL_Side &side = getSend();
00394 side.sort2d(coord);
00395
00396 if(!isSingle()){
00397 IDXL_Side &recvSide = getRecv();
00398 recvSide.sort2d(coord);
00399 }
00400 }
00401
00402 void IDXL::sort3d(double *coord){
00403 IDXL_Side &side = getSend();
00404 side.sort3d(coord);
00405
00406 if(!isSingle()){
00407 IDXL_Side &recvSide = getRecv();
00408 recvSide.sort3d(coord);
00409 }
00410 }