////////////////////////////////////////////////////////////////////// // // LoopBlock.cpp: implementation of the Block class. // ////////////////////////////////////////////////////////////////////// #include #include "LoopBlock.h" #ifndef _MSC_VER template T _MIN(T a, T b) { return a < b ? a : b; } template T _MAX(T a, T b) { return a >= b ? a : b; } #endif using namespace std; long LoopBlock::GetRank() { return LSDim.size(); } bool LoopBlock::empty() { return LSDim.empty(); } long LoopBlock::GetBlockSize() { unsigned int i; long size = 1; if (LSDim.empty()) return 0; for (i = 0; i < LSDim.size(); i++) { size *= LSDim[i].GetLoopLSSize(); } return size; } LoopBlock::LoopBlock() { LSDim = vector(0); } LoopBlock::~LoopBlock() { } /* LoopBlock::LoopBlock(ParLoop *pl, long ProcLI) { int i; long vmDimSize, dimProcI; long amDimSize, amAxis; long plAxis; long amLower, amUpper, BlockSize; // Param, Module; bool IsBlockEmpty = false; vector ProcSI; DistAxis dist; AlignAxis align, plAlign; LoopLS ls; AMView* am = pl->AM_Dis; assert(am != NULL); VM* vm = am->VM_Dis; assert(vm != NULL); long amRank = am->Rank(); long vmRank = vm->Rank(); long plRank = pl->Rank; vm->GetSI(ProcLI, ProcSI); LSDim.reserve(plRank); // Предварительная инициализация блока (равен циклу с шагом 1) for (i = 0; i < plRank; i++) LSDim.push_back(LoopLS(pl->LowerIndex[i], pl->HigherIndex[i], 1)); // Формирование локальной части без учета шага for (i = 0; i < vmRank; i++) { dist = am->DistRule[amRank + i]; switch (dist.Attr) { case map_NORMVMAXIS : amAxis = dist.Axis; amDimSize = am->GetSize(amAxis); dimProcI = ProcSI[i]; vmDimSize = vm->GetSize(i+1); BlockSize = (amDimSize - 1) / vmDimSize + 1; amLower = dimProcI * BlockSize; amUpper = _MIN(amDimSize, amLower+BlockSize) - 1; IsBlockEmpty = IsBlockEmpty || amLower > amUpper; if(IsBlockEmpty) break; align = pl->AlignRule[plRank+amAxis-1]; switch(align.Attr) { case align_NORMTAXIS : plAxis = align.Axis; plAlign = pl->AlignRule[plAxis-1]; ls = LoopLS(amLower, amUpper, 1); ls.transform(plAlign.A, plAlign.B, pl->GetSize(plAxis-1)); if (ls.empty()) IsBlockEmpty = true; else { ls.Lower = _MAX(ls.Lower, (long)0); ls.Upper = _MIN(ls.Upper, (long)(pl->GetSize(plAxis-1)-1)); LSDim[plAxis-1] = ls; // LSDim с нуля }; break; case align_BOUNDREPL : ls = LoopLS(amLower, amUpper, 1); ls.transform(align.A, align.B, align.Bound); if (ls.empty()) IsBlockEmpty = true; break; case align_REPLICATE : break; case align_CONSTANT : if (align.B < amLower || align.B > amUpper) IsBlockEmpty = true; break; } // end internal switch break; case map_REPLICATE : break; } // end main switch if (IsBlockEmpty) break; } // end for if (IsBlockEmpty) { // Локальный блок пуст даже без учета шага LSDim = vector(0); } else { // Формирование локальной части с учетом шага for(i=0; iLoopStep[i] * (long)ceil((double)LSDim[i].Lower/(double)pl->LoopStep[i]); LSDim[i].Upper = pl->LoopStep[i] * (LSDim[i].Upper / pl->LoopStep[i]); LSDim[i].Step = pl->LoopStep[i]; if(LSDim[i].Lower > LSDim[i].Upper) break; }; if(i==plRank) { // Коррекция индексов с учетом начальных значений for(i=0; iLowerIndex[i]; LSDim[i].Upper += pl->LowerIndex[i]; }; } else { // Локальный блок с учетом шага пуст LSDim = vector(0); }; } } */ LoopBlock::LoopBlock(ParLoop *pl, long ProcLI,int a) { int i; long vmDimSize, dimProcI; long amDimSize, amAxis; long plAxis; long amLower, amUpper, BlockSize; // Param, Module; bool IsBlockEmpty = false; vector ProcSI; DistAxis dist; AlignAxis align, plAlign; LoopLS ls; AMView* am = pl->AM_Dis; // printf("LOOPBLOCK AM=%lx am->weightEl.ID=%lx\n",am, am->weightEl.ID); assert(am != NULL); VM* vm = am->VM_Dis; assert(vm != NULL); long amRank = am->Rank(); long vmRank = vm->Rank(); long plRank = pl->Rank; vm->GetSI(ProcLI, ProcSI); //grig std::vector avWeights; int j; long local_sum=0; // индекс с которого начанаются веса для данного измерения VM long jmax; // размер текущего измерения Vm double vBlockSize,temp_w=0; // double sum1=0; //grig LSDim.reserve(plRank); // Предварительная инициализация блока (равен циклу с шагом 1) for (i = 0; i < plRank; i++) { // printf("1. INIT %d %d %d\n",pl->LowerIndex[i], pl->HigherIndex[i], 1); LSDim.push_back(LoopLS(pl->LowerIndex[i], pl->HigherIndex[i], 1)); } // Формирование локальной части без учета шага for (i = 0; i < vmRank; i++) { dist = am->DistRule[amRank + i]; switch (dist.Attr) { case map_NORMVMAXIS : amAxis = dist.Axis; amDimSize = am->GetSize(amAxis); dimProcI = ProcSI[i]; vmDimSize = vm->GetSize(i+1); BlockSize = (amDimSize - 1) / vmDimSize + 1; //grig am->weightEl.GetWeights(avWeights); local_sum=0; // индекс с которого начинаются веса для данного измерения VM jmax=vm->GetSize(i+1); // размер текущего измерения Vm vBlockSize,temp_w=0; // sum1=0; long lBlockSize; for(j=0;jGetSize(j+1); } // printf("size()=%d arr=%d %d %d %d %d %d\n",am->weightEl.body.size(),am->weightEl.body[0],am->weightEl.body[1],am->weightEl.body[2],am->weightEl.body[3],am->weightEl.body[4],am->weightEl.body[5]); if(am->weightEl.body.size() == 0) temp_w=1; else { for(j=0;jweightEl.body[j+local_sum]; // находим сумму весов } // printf("temp_w=%f\n",temp_w); vBlockSize = amDimSize/temp_w; // размер блока lBlockSize=ceil((double)amDimSize/temp_w) > 0.5 ? amDimSize/temp_w+ 1 : amDimSize/temp_w; // размер блока //==== if(am->BSize.size()>0) { // если не задан мультиблок, то будет считаться что блоки размером в 1 и не надо ничего пересчитывать // а вот если он задан, то пересчитаем, даже если там единицы if(amDimSize % am->BSize[i] !=0 ) { printf("Error: Dimension %d is not dividible by %d \n",amDimSize, am->BSize[i]); exit(0);} lBlockSize=(long)ceil(vBlockSize); if( ( lBlockSize % am->BSize[i]) > 0) lBlockSize = ( lBlockSize / am->BSize[i] + 1) * am->BSize[i]; vBlockSize=lBlockSize; } // printf("ok 66666\n"); //=*** /* if(vBlockSize - ceil(vBlockSize)<0.5) // если VBlocksize - celoe { lBlockSize=floor(vBlockSize); } else // нет lBlockSize= ceil(vBlockSize); */ for(j=0;jweightEl.body.size() != 0)? (vBlockSize*am->weightEl.body[j+local_sum]) : vBlockSize); } amLower=sum1; amUpper=(double)sum1 + ((am->weightEl.body.size() != 0)? (vBlockSize*am->weightEl.body[dimProcI+local_sum]-1) : vBlockSize - 1); // printf("ok 777\n"); //==== убрал // так как вызывала ошибку в случае когда на каждый проц по одному элементу // и предпоследний проц захватывал 2 элемента, а последний брал еще раз свой элемент // if(amUpper+1==amDimSize-1) // amUpper=amDimSize-1; //=*** IsBlockEmpty = IsBlockEmpty || amLower > amUpper; if(IsBlockEmpty) break; align = pl->AlignRule[plRank+amAxis-1]; switch(align.Attr) { case align_NORMTAXIS : plAxis = align.Axis; plAlign = pl->AlignRule[plAxis-1]; ls = LoopLS(amLower, amUpper, 1); ls.transform(plAlign.A, plAlign.B, (pl->HigherIndex[plAxis-1] - pl->LowerIndex[plAxis-1]+1 )); // for(j=0; jLowerIndex[j],pl->HigherIndex[j],pl->LoopStep[j]); // } //printf("LS[%d] %d %d %d\n",ProcLI, ls.Lower, ls.Upper, ls.Step); if (ls.empty()) { printf("EMPTY %d\n",IsBlockEmpty); IsBlockEmpty = true; } else { //====// ls.Lower = _MAX(ls.Lower, (long)0); //====// ls.Upper = _MIN(ls.Upper, (long)(pl->HigherIndex[plAxis-1] - pl->LowerIndex[plAxis-1])); //int ii; // printf("Proc current = %d\n",ProcLI); // for(ii=0;iiLSDim.size();ii++) // printf("LSDim %d %d %d\n",this->LSDim[ii].Lower,this->LSDim[ii].Upper,this->LSDim[ii].Step); LSDim[plAxis-1] = ls; // LSDim с нуля // printf("Proc current = %d\n",ProcLI); // for(ii=0;iiLSDim.size();ii++) // printf("LSDim %d %d %d\n",this->LSDim[ii].Lower,this->LSDim[ii].Upper,this->LSDim[ii].Step); }; //==== this block was moved from down // for(i=0; iLowerIndex[i]; // LSDim[i].Upper += pl->LowerIndex[i]; // } // LSDim[plAxis-1].Lower += pl->LowerIndex[plAxis-1]; // LSDim[plAxis-1].Upper += pl->LowerIndex[plAxis-1]; //printf("PlAxis=%d\n",plAxis); //=*** break; case align_BOUNDREPL : ls = LoopLS(amLower, amUpper, 1); ls.transform(align.A, align.B, align.Bound); if (ls.empty()) IsBlockEmpty = true; break; case align_REPLICATE : break; case align_CONSTANT : if (align.B < amLower || align.B > amUpper) IsBlockEmpty = true; break; } // end internal switch break; case map_REPLICATE : //==== /* printf("----%d-%d-%d-%d-",i,vm->GetSize(0),vm->GetSize(1),vm->GetSize(2)); LSDim[i-1].Upper -= pl->LowerIndex[i-1];; LSDim[i-1].Lower -= pl->LowerIndex[i-1];; { int ii; for(ii=0; iiLowerIndex[ii]); } */ //=*** break; } // end main switch if (IsBlockEmpty) break; } // end for if (IsBlockEmpty) { // Локальный блок пуст даже без учета шага LSDim = vector(0); } else { // Формирование локальной части с учетом шага for (i = 0; i < plRank; i++) { LSDim[i].Lower = pl->LoopStep[i] * (long)ceil((double)LSDim[i].Lower / (double)pl->LoopStep[i]); LSDim[i].Upper = pl->LoopStep[i] * (LSDim[i].Upper / pl->LoopStep[i]); LSDim[i].Step = pl->LoopStep[i]; //printf("LSDim[%d] %d %d %d\n",ProcLI, LSDim[i].Lower,LSDim[i].Upper,LSDim[i].Step); LSDim[i].Invers = pl->Invers[i]; if (LSDim[i].Lower > LSDim[i].Upper) break; }; // if(i==plRank) // { // Коррекция индексов с учетом начальных значений // printf("**%d*%d** ",maxAlign,plRank); // for(i=0; iLowerIndex[i]; // LSDim[i].Upper += pl->LowerIndex[i]; //=*** // printf("-LoopBlock %d %d %d ",LSDim[i].Lower,LSDim[i].Upper,pl->LowerIndex[i]); // }; // } if(i!=plRank) { // Локальный блок с учетом шага пуст LSDim = vector(0); }; } // printf("Proc number-%d\n",ProcLI); // for(i=0;iGetRank();i++) // printf("%d %d %d\n",this->LSDim[i].Lower,this->LSDim[i].Upper,this->LSDim[i].Step); } //xp /* LoopBlock::LoopBlock(ParLoop *pl, long ProcLI,int a) { int i,ii; long vmDimSize, dimProcI; long amDimSize, amAxis; long plAxis; long amLower, amUpper, BlockSize; // Param, Module; bool IsBlockEmpty = false; vector ProcSI; DistAxis dist; AlignAxis align, plAlign; LoopLS ls; AMView* am = pl->AM_Dis; // printf("LOOPBLOCK AM=%lx am->weightEl.ID=%lx\n",am, am->weightEl.ID); assert(am != NULL); VM* vm = am->VM_Dis; assert(vm != NULL); long amRank = am->Rank(); long vmRank = vm->Rank(); long plRank = pl->Rank; vm->GetSI(ProcLI, ProcSI); //grig std::vector avWeights; int j; long local_sum=0; // индекс с которого начанаются веса для данного измерения VM long jmax; // размер текущего измерения Vm double vBlockSize,temp_w=0; // double sum1=0; //grig LSDim.reserve(plRank); // Предварительная инициализация блока (равен циклу с шагом 1) for (i = 0; i < plRank; i++) { // printf("1. INIT %d %d %d\n",pl->LowerIndex[i], pl->HigherIndex[i], 1); LSDim.push_back(LoopLS(pl->LowerIndex[i], pl->HigherIndex[i], 1)); } printf("Proc current = %d\n",ProcLI); for(ii=0;iiLSDim.size();ii++) printf("LSDim %d %d %d\n",this->LSDim[ii].Lower,this->LSDim[ii].Upper,this->LSDim[ii].Step); // for(i=0;iLSDim.size();i++) // { // printf("INIT %d %d %d\n",this->LSDim[i].Lower,this->LSDim[i].Upper,this->LSDim[i].Step); // printf("INIT addr %d %d %d\n",&LSDim[i].Lower,&LSDim[i].Upper,&LSDim[i].Step); // } // Формирование локальной части без учета шага for (i = 0; i < vmRank; i++) { // printf(" i=%d\n",i); dist = am->DistRule[amRank + i]; switch (dist.Attr) { case map_NORMVMAXIS : amAxis = dist.Axis; amDimSize = am->GetSize(amAxis); dimProcI = ProcSI[i]; vmDimSize = vm->GetSize(i+1); BlockSize = (amDimSize - 1) / vmDimSize + 1; //grig am->weightEl.GetWeights(avWeights); local_sum=0; // индекс с которого начинаются веса для данного измерения VM jmax=vm->GetSize(i+1); // размер текущего измерения Vm vBlockSize,temp_w=0; // sum1=0; long lBlockSize; for(j=0;jGetSize(j+1); } // printf("size()=%d arr=%d %d %d %d %d %d\n",am->weightEl.body.size(),am->weightEl.body[0],am->weightEl.body[1],am->weightEl.body[2],am->weightEl.body[3],am->weightEl.body[4],am->weightEl.body[5]); if(am->weightEl.body.size() == 0) temp_w=1; else { for(j=0;jweightEl.body[j+local_sum]; // находим сумму весов } // printf("temp_w=%f\n",temp_w); vBlockSize = amDimSize/temp_w; // размер блока lBlockSize=ceil((double)amDimSize/temp_w) > 0.5 ? amDimSize/temp_w+ 1 : amDimSize/temp_w; // размер блока // printf(" Blocksize v=%.0f l=%d \n",vBlockSize, lBlockSize); //==== if(am->BSize.size()>0) { // если не задан мультиблок, то будет считаться что блоки размером в 1 и не надо ничего пересчитывать // а вот если он задан, то пересчитаем, даже если там единицы if(amDimSize % am->BSize[i] !=0 ) { printf("Error: Dimension %d is not dividible by %d \n",amDimSize, am->BSize[i]); exit(0);} lBlockSize=(long)ceil(vBlockSize); if( ( lBlockSize % am->BSize[i]) > 0) lBlockSize = ( lBlockSize / am->BSize[i] + 1) * am->BSize[i]; vBlockSize=lBlockSize; } // printf("ok 66666\n"); //=*** for(j=0;jweightEl.body.size() != 0)? (vBlockSize*am->weightEl.body[j+local_sum]) : vBlockSize); } amLower=sum1; amUpper=(double)sum1 + ((am->weightEl.body.size() != 0)? (vBlockSize*am->weightEl.body[dimProcI+local_sum]-1) : vBlockSize - 1); // printf(" amlower=%d amupper=%d\n",amLower,amUpper); // printf("ok 777\n"); //==== убрал // так как вызывала ошибку в случае когда на каждый проц по одному элементу // и предпоследний проц захватывал 2 элемента, а последний брал еще раз свой элемент // if(amUpper+1==amDimSize-1) // amUpper=amDimSize-1; //=*** IsBlockEmpty = IsBlockEmpty || amLower > amUpper; if(IsBlockEmpty) break; align = pl->AlignRule[plRank+amAxis-1]; //не понимаю как устроен AlignRule!!! /// // printf("ALIGN plRank=%d amAxis=%d \n",plRank,amAxis); // // printf("ALIGN rule \n"); // for(j=0;jAlignRule.size();j++) // { // printf("%d %d %d %d\n",pl->AlignRule[j].A, pl->AlignRule[j].B, pl->AlignRule[j].Axis, pl->AlignRule[j].TAxis); // } // printf("\n"); // switch(align.Attr) { case align_NORMTAXIS : plAxis = align.Axis; if(plAxis > pl->Rank) { printf("BREAK!!!!!!!!!!!!!!! plAxis=%d pl->Rank=%d \n", plAxis, pl->Rank); break; // нельзя ничего перевыравнивать мимо... // Неправильно - но временное решение, пока не разберемся как устроен AlignRule } // LU deb // printf("sz=%d\n",pl->AlignRule.size()); // // if(1||plAxis-1>=pl->AlignRule.size()) // { // int i; // for(i=0;iAlignRule.size();i++) // printf("%d %d %d %d ",pl->AlignRule[i].A,pl->AlignRule[i].B,pl->AlignRule[i].Axis,pl->AlignRule[i].TAxis); // printf("\n"); // } // plAlign = pl->AlignRule[plAxis-1]; ls = LoopLS(amLower, amUpper, 1); ls.transform(plAlign.A, plAlign.B, (pl->HigherIndex[plAxis-1] - pl->LowerIndex[plAxis-1]+1 )); // for(j=0; jLowerIndex[j],pl->HigherIndex[j],pl->LoopStep[j]); // } printf("LS[%d] %d %d %d\n",ProcLI, ls.Lower, ls.Upper, ls.Step); if (ls.empty()) { printf(" EMPTY %d\n",IsBlockEmpty); IsBlockEmpty = true; } else { //====// ls.Lower = _MAX(ls.Lower, (long)0); //====// ls.Upper = _MIN(ls.Upper, (long)(pl->HigherIndex[plAxis-1] - pl->LowerIndex[plAxis-1])); printf("Proc current = %d\n",ProcLI); for(ii=0;iiLSDim.size();ii++) printf("LSDim %d %d %d\n",this->LSDim[ii].Lower,this->LSDim[ii].Upper,this->LSDim[ii].Step); printf(" set to dim %d %d\n",plAxis-1, align.Axis); LSDim[plAxis-1] = ls; // LSDim с нуля printf("Proc current = %d\n",ProcLI); for(ii=0;iiLSDim.size();ii++) printf("LSDim %d %d %d\n",this->LSDim[ii].Lower,this->LSDim[ii].Upper,this->LSDim[ii].Step); } //==== this block was moved from down // for(i=0; iLowerIndex[i]; // LSDim[i].Upper += pl->LowerIndex[i]; // } // LSDim[plAxis-1].Lower += pl->LowerIndex[plAxis-1]; // LSDim[plAxis-1].Upper += pl->LowerIndex[plAxis-1]; //printf("PlAxis=%d\n",plAxis); //=*** break; case align_BOUNDREPL : printf(" bound replicated %d %d \n", amLower, amUpper); ls = LoopLS(amLower, amUpper, 1); ls.transform(align.A, align.B, align.Bound); if (ls.empty()) IsBlockEmpty = true; else //xp { // printf(" set to dim %d < %d\n", align.Axis,LSDim.size()); if(align.Axis < LSDim.size()) LSDim[align.Axis] = ls; //xp почему то нельзя align.Axis-1 } break; case align_REPLICATE : break; case align_CONSTANT : if (align.B < amLower || align.B > amUpper) IsBlockEmpty = true; break; } // end internal switch break; case map_REPLICATE : // printf(" replicated\n"); //==== // printf("----%d-%d-%d-%d-",i,vm->GetSize(0),vm->GetSize(1),vm->GetSize(2)); // LSDim[i-1].Upper -= pl->LowerIndex[i-1];; // LSDim[i-1].Lower -= pl->LowerIndex[i-1];; // // { int ii; // for(ii=0; iiLowerIndex[ii]); // } // //=*** break; } // end main switch if (IsBlockEmpty) break; } // end for if (IsBlockEmpty) { // Локальный блок пуст даже без учета шага LSDim = vector(0); } else { // Формирование локальной части с учетом шага for(i=0; iLoopStep[i]); // printf("LSDim[i].Lower = addr %d\n",&(LSDim[i].Lower)); LSDim[i].Lower = pl->LoopStep[i] * (long)ceil((double)LSDim[i].Lower/(double)pl->LoopStep[i]); LSDim[i].Upper = pl->LoopStep[i] * (LSDim[i].Upper / pl->LoopStep[i]); LSDim[i].Step = pl->LoopStep[i]; //printf("LSDim[%d] %d %d %d\n",ProcLI, LSDim[i].Lower,LSDim[i].Upper,LSDim[i].Step); LSDim[i].Invers = pl->Invers[i]; if(LSDim[i].Lower > LSDim[i].Upper) break; } // if(i==plRank) // { // Коррекция индексов с учетом начальных значений // printf("**%d*%d** ",maxAlign,plRank); // for(i=0; iLowerIndex[i]; // LSDim[i].Upper += pl->LowerIndex[i]; //=*** // printf("-LoopBlock %d %d %d ",LSDim[i].Lower,LSDim[i].Upper,pl->LowerIndex[i]); // }; // } if(i!=plRank) { // Локальный блок с учетом шага пуст LSDim = vector(0); } } // LU deb // printf("Proc current = %d\n",ProcLI); // printf("This Rank (what meen?!) = %d\n",this->GetRank()); // for(i=0;iLSDim.size();i++) // printf("LSDim %d %d %d\n",this->LSDim[i].Lower,this->LSDim[i].Upper,this->LSDim[i].Step); } */ bool operator==(LoopBlock& x, LoopBlock& y) { bool equal = (x.GetRank() == y.GetRank()); int i; if(equal) for (i = 0; i < x.GetRank(); i++) equal = equal && (x.LSDim[i] == y.LSDim[i]); return equal; } int intersection(LoopBlock& x,LoopBlock&y) { int temp; std::vector arr1,arr2; long i,j,k; int t=0; arr1.resize(0); arr2.resize(0); // printf("finding intersection of two arrays:\n"); // printf("array 1 :\n"); // for(i=0;i