472 lines
10 KiB
C++
472 lines
10 KiB
C++
// Block.cpp: implementation of the Block class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
#include <assert.h>
|
|
#include "Block.h"
|
|
|
|
using namespace std;
|
|
|
|
extern ofstream prot;
|
|
|
|
#if defined (_MSC_VER) || (defined (__GNUG__) && (__GNUC__ < 3))
|
|
/*template <class T>
|
|
T min(T a, T b)
|
|
{
|
|
return a < b ? a : b;
|
|
}*/
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
Block::Block(vector<LS> &v)
|
|
{
|
|
LSDim = v;
|
|
}
|
|
|
|
Block::Block()
|
|
{
|
|
|
|
}
|
|
|
|
Block::~Block()
|
|
{
|
|
// printf("Block::~Block()=%0X\n", this);
|
|
}
|
|
|
|
Block operator^ (Block &x, Block &y)
|
|
{
|
|
Block temp;
|
|
vector<LS> empty_Block(0);
|
|
long i;
|
|
|
|
if (x.empty() || y.empty())
|
|
return empty_Block;
|
|
|
|
if (x.GetRank() != y.GetRank())
|
|
{
|
|
prot << "Wrong call operator^" << endl;
|
|
exit(1);
|
|
}
|
|
|
|
temp.LSDim.reserve(x.GetRank());
|
|
|
|
for (i = 0; i < x.GetRank(); i++)
|
|
if ((x.LSDim[i] ^ y.LSDim[i]).IsEmpty() != true)
|
|
temp.LSDim.push_back(x.LSDim[i] ^ y.LSDim[i]);
|
|
else
|
|
{
|
|
temp.LSDim = empty_Block;
|
|
break;
|
|
};
|
|
return temp;
|
|
}
|
|
|
|
long Block::GetBlockSize()
|
|
{
|
|
int i;
|
|
long size = 1;
|
|
|
|
if (LSDim.empty())
|
|
return 0;
|
|
|
|
for (i = 0; i < LSDim.size(); i++)
|
|
size *= LSDim[i].GetLSSize();
|
|
//====
|
|
//printf("GETSIZE[%d] %d\n",i,size);
|
|
//=***
|
|
|
|
return size;
|
|
}
|
|
|
|
//grig
|
|
Block::Block(DArray * da, long ProcLI , int a)
|
|
{
|
|
int i;
|
|
long vmRank, vmDimSize, dimProcI;
|
|
long amRank, amDimSize, amAxis;
|
|
long daRank, daAxis;
|
|
long amLower, amUpper, BlockSize; // Param, Module;
|
|
bool IsBlockEmpty = false;
|
|
vector<long> ProcSI;
|
|
VM *vm;
|
|
AMView *am;
|
|
DistAxis dist;
|
|
AlignAxis align, alignParam;
|
|
LS ls;
|
|
|
|
am = da->AM_Dis;
|
|
amRank = am->Rank();
|
|
vm = am->VM_Dis;
|
|
vmRank = vm->Rank();
|
|
vm->GetSI(ProcLI, ProcSI);
|
|
|
|
daRank = da->Rank();
|
|
LSDim.reserve(daRank);
|
|
|
|
|
|
//grig
|
|
std::vector<double> avWeights;
|
|
int j;
|
|
long local_sum=0; // èíäåêñ ñ êîòîðîãî íà÷àíàþòñÿ âåñà äëÿ äàííîãî èçìåðåíèÿ VM
|
|
long jmax; // ðàçìåð òåêóùåãî èçìåðåíèÿ Vm
|
|
double vBlockSize,temp_w=0; //
|
|
double sum1=0;
|
|
//grig
|
|
|
|
/* LU deb
|
|
for(i=0;i<da->AlignRule.size();i++)
|
|
printf("Block %d %d %d %d ",da->AlignRule[i].A,da->AlignRule[i].B,da->AlignRule[i].Axis,da->AlignRule[i].TAxis);
|
|
printf("\n");
|
|
*/
|
|
|
|
// Ïðåäâàðèòåëüíàÿ èíèöèàëèçàöèÿ áëîêà (ðàâåí ìàññèâó)
|
|
for (i = 0; i < daRank; i++)
|
|
LSDim.push_back(LS(0, da->GetSize(i+1)-1));
|
|
|
|
for (i = 0; i < vmRank; i++)
|
|
{
|
|
dist = am->DistRule[amRank + i];
|
|
switch (dist.Attr)
|
|
{
|
|
case map_NORMVMAXIS :
|
|
amAxis = dist.Axis;
|
|
vmDimSize = vm->GetSize(i+1);
|
|
amDimSize = am->GetSize(amAxis);
|
|
dimProcI = ProcSI[i];
|
|
|
|
BlockSize = (amDimSize - 1) / vmDimSize + 1;
|
|
|
|
amLower = dimProcI * BlockSize;
|
|
|
|
amUpper = min(amDimSize, amLower+BlockSize) - 1;
|
|
|
|
|
|
// printf("amAxis=%d amDimSize=%d\n",amAxis,amDimSize);
|
|
// printf("Blocksize=%d %d %d\n",BlockSize,amLower,amUpper);
|
|
|
|
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;j<i;j++)
|
|
{
|
|
local_sum+=vm->GetSize(j+1);
|
|
}
|
|
for(j=0;j<jmax;j++)
|
|
{ if(j+local_sum>=am->weightEl.GetSize()) break;
|
|
temp_w+=am->weightEl.body[j+local_sum]; // íàõîäèì ñóììó âåñîâ
|
|
}
|
|
if(temp_w==0) temp_w=1; //====//
|
|
vBlockSize = amDimSize/temp_w; // ðàçìåð áëîêà
|
|
|
|
// lBlockSize=ceil((double)amDimSize/temp_w) > 0.5 ? amDimSize/temp_w+ 1 : amDimSize/temp_w; // ðàçìåð áëîêà
|
|
//====
|
|
if(am->BSize.size() > 0)
|
|
{
|
|
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;
|
|
}
|
|
//=***
|
|
/*
|
|
if(vBlockSize - ceil(vBlockSize)<0.5) // åñëè VBlocksize - celoe
|
|
{
|
|
lBlockSize=floor(vBlockSize);
|
|
}
|
|
else // íåò
|
|
lBlockSize= ceil(vBlockSize);
|
|
*/
|
|
// printf("Blocksize v=%f l=%d\n",vBlockSize, lBlockSize);
|
|
|
|
for(j=0;j<dimProcI;j++)
|
|
{ if(j+local_sum>=am->weightEl.GetSize()) break; //====//
|
|
sum1+=(vBlockSize*am->weightEl.body[j+local_sum]);
|
|
}
|
|
|
|
amLower=sum1;
|
|
amUpper=(double)sum1;
|
|
if(dimProcI+local_sum<am->weightEl.GetSize()) amUpper += vBlockSize*am->weightEl.body[dimProcI+local_sum]-1; //====//
|
|
if(amUpper+1>=amDimSize-1)
|
|
amUpper=amDimSize-1;
|
|
|
|
|
|
IsBlockEmpty = IsBlockEmpty || amLower > amUpper;
|
|
if (IsBlockEmpty)
|
|
break;
|
|
|
|
// printf("bBLOCK[%d] %d %d\n",ProcLI, amLower,amUpper);
|
|
|
|
align = da->AlignRule[daRank+amAxis-1];
|
|
|
|
|
|
switch (align.Attr) {
|
|
case align_NORMTAXIS :
|
|
daAxis = align.Axis;
|
|
assert(daAxis != 0);
|
|
alignParam = da->AlignRule[daAxis-1];
|
|
|
|
ls = LS(amLower, amUpper);
|
|
|
|
// printf("bBLOCK ls=%d %d daAxissize=%d\n",ls.GetLower(),ls.GetUpper(),da->GetSize(daAxis));
|
|
ls.transform(alignParam.A, alignParam.B, da->GetSize(daAxis));
|
|
// printf("eBLOCK ls=%d %d\n",ls.GetLower(),ls.GetUpper());
|
|
|
|
if (ls.IsEmpty()) {
|
|
IsBlockEmpty = true;
|
|
}
|
|
else
|
|
{
|
|
//xp_max
|
|
if(daAxis-1<LSDim.size())
|
|
LSDim[daAxis-1] = ls; // LSDim ñ íóëÿ
|
|
else
|
|
{
|
|
printf("PREDICTOR!!! seems as error in Block.cpp\n");
|
|
//exit(0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case align_BOUNDREPL :
|
|
ls = LS(amLower, amUpper);
|
|
ls.transform(align.A, align.B, align.Bound);
|
|
|
|
if (ls.IsEmpty())
|
|
IsBlockEmpty = true;
|
|
break;
|
|
|
|
case align_REPLICATE :
|
|
break;
|
|
|
|
case align_CONSTANT :
|
|
if (align.B < amLower || align.B > amUpper)
|
|
IsBlockEmpty = true;
|
|
break;
|
|
} // end switch
|
|
break;
|
|
|
|
case map_REPLICATE :
|
|
break;
|
|
} // end switch
|
|
if (IsBlockEmpty)
|
|
break;
|
|
} // end for
|
|
|
|
if (IsBlockEmpty)
|
|
{
|
|
LSDim = vector<LS>(0);
|
|
#ifdef _TIME_TRACE_
|
|
prot << LSDim.empty() << endl; // ïîòîì óáðàòü
|
|
#endif
|
|
}
|
|
}
|
|
//\grig
|
|
|
|
|
|
|
|
Block::Block(DArray * da, long ProcLI)
|
|
{
|
|
int i;
|
|
long vmRank, vmDimSize, dimProcI;
|
|
long amRank, amDimSize, amAxis;
|
|
long daRank, daAxis;
|
|
long amLower, amUpper, BlockSize; // Param, Module;
|
|
bool IsBlockEmpty = false;
|
|
vector<long> ProcSI;
|
|
VM *vm;
|
|
AMView *am;
|
|
DistAxis dist;
|
|
AlignAxis align, alignParam;
|
|
LS ls;
|
|
|
|
am = da->AM_Dis;
|
|
amRank = am->Rank();
|
|
vm = am->VM_Dis;
|
|
vmRank = vm->Rank();
|
|
vm->GetSI(ProcLI, ProcSI);
|
|
|
|
daRank = da->Rank();
|
|
LSDim.reserve(daRank);
|
|
|
|
// Ïðåäâàðèòåëüíàÿ èíèöèàëèçàöèÿ áëîêà (ðàâåí ìàññèâó)
|
|
for (i = 0; i < daRank; i++)
|
|
LSDim.push_back(LS(0, da->GetSize(i+1)-1));
|
|
|
|
for (i = 0; i < vmRank; i++)
|
|
{
|
|
dist = am->DistRule[amRank + i];
|
|
switch (dist.Attr)
|
|
{
|
|
case map_NORMVMAXIS :
|
|
amAxis = dist.Axis;
|
|
vmDimSize = vm->GetSize(i+1);
|
|
amDimSize = am->GetSize(amAxis);
|
|
dimProcI = ProcSI[i];
|
|
// Param = amDimSize / vmDimSize;
|
|
// Module = amDimSize % vmDimSize;
|
|
// amLower = dimProcI * Param;
|
|
BlockSize = (amDimSize - 1) / vmDimSize + 1;
|
|
amLower = dimProcI * BlockSize;
|
|
|
|
//if ((Module != 0) && (dimProcI < Module))
|
|
//{
|
|
// amLower += dimProcI;
|
|
// Param++;
|
|
//}
|
|
//else
|
|
// amLower += Module;
|
|
|
|
amUpper = min(amDimSize, amLower+BlockSize) - 1;
|
|
IsBlockEmpty = IsBlockEmpty || amLower > amUpper;
|
|
if (IsBlockEmpty)
|
|
break;
|
|
align = da->AlignRule[daRank+amAxis-1];
|
|
|
|
switch (align.Attr) {
|
|
case align_NORMTAXIS :
|
|
daAxis = align.Axis;
|
|
assert(daAxis != 0);
|
|
alignParam = da->AlignRule[daAxis-1];
|
|
|
|
ls = LS(amLower, amUpper);
|
|
ls.transform(alignParam.A, alignParam.B, da->GetSize(daAxis));
|
|
|
|
if (ls.IsEmpty()) {
|
|
IsBlockEmpty = true;
|
|
}
|
|
else
|
|
{
|
|
//xp_max
|
|
if(daAxis-1<LSDim.size())
|
|
LSDim[daAxis-1] = ls; // LSDim ñ íóëÿ
|
|
}
|
|
break;
|
|
|
|
case align_BOUNDREPL :
|
|
ls = LS(amLower, amUpper);
|
|
ls.transform(align.A, align.B, align.Bound);
|
|
|
|
if (ls.IsEmpty())
|
|
IsBlockEmpty = true;
|
|
break;
|
|
|
|
case align_REPLICATE :
|
|
break;
|
|
|
|
case align_CONSTANT :
|
|
if (align.B < amLower || align.B > amUpper)
|
|
IsBlockEmpty = true;
|
|
break;
|
|
} // end switch
|
|
break;
|
|
|
|
case map_REPLICATE :
|
|
break;
|
|
} // end switch
|
|
if (IsBlockEmpty)
|
|
break;
|
|
} // end for
|
|
|
|
if (IsBlockEmpty)
|
|
{
|
|
LSDim = vector<LS>(0);
|
|
#ifdef _TIME_TRACE_
|
|
prot << LSDim.empty() << endl; // ïîòîì óáðàòü
|
|
#endif
|
|
}
|
|
}
|
|
|
|
bool Block::empty()
|
|
{
|
|
return LSDim.empty();
|
|
}
|
|
|
|
long Block::GetRank()
|
|
{
|
|
return LSDim.size();
|
|
}
|
|
|
|
Block & Block::operator =(const Block & x)
|
|
{
|
|
this->LSDim = x.LSDim;
|
|
return *this;
|
|
}
|
|
|
|
bool Block::IsBoundIn(const vector<long>& ALeftBSizeArray,
|
|
const vector<long>& ARightBSizeArray)
|
|
{
|
|
long i;
|
|
for (i = 0; i < LSDim.size(); i++)
|
|
{
|
|
if (!LSDim[i].IsBoundIn(ALeftBSizeArray[i], ARightBSizeArray[i]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Block::IsLeft(long arrDim, long elem)
|
|
{
|
|
if (empty())
|
|
return false;
|
|
return LSDim[arrDim-1].IsLeft(elem);
|
|
}
|
|
|
|
bool Block::IsRight(long arrDim, long elem)
|
|
{
|
|
if (empty())
|
|
return false;
|
|
return LSDim[arrDim-1].IsRight(elem);
|
|
}
|
|
|
|
long Block::GetBlockSizeMult(long dim)
|
|
{
|
|
int i;
|
|
long size = 1;
|
|
|
|
if (LSDim.empty())
|
|
return 0;
|
|
|
|
for (i = 0; i < LSDim.size(); i++)
|
|
{
|
|
if (i == dim-1)
|
|
continue;
|
|
size *= LSDim[i].GetLSSize();
|
|
}
|
|
return size;
|
|
}
|
|
|
|
long Block::GetBlockSizeMult2(long dim1, long dim2)
|
|
{
|
|
int i;
|
|
long size = 1;
|
|
|
|
if (LSDim.empty())
|
|
return 0;
|
|
|
|
for (i = 0; i < LSDim.size(); i++)
|
|
{
|
|
if (i == dim1-1 || i == dim2-1)
|
|
continue;
|
|
size *= LSDim[i].GetLSSize();
|
|
}
|
|
return size;
|
|
}
|
|
|
|
//====
|
|
long Block::GetUpper(long i)
|
|
{ return LSDim[i].GetUpper();
|
|
}
|
|
|
|
long Block::GetLower(long i)
|
|
{ return LSDim[i].GetLower();
|
|
}
|
|
//=***
|
|
|
|
|