Files
SAPFOR/Sapfor/_src/Predictor/Lib/ParLoop.cpp
2025-03-25 20:39:29 +03:00

249 lines
7.5 KiB
C++

// ParLoop.cpp: implementation of the LoopLS class.
//
//////////////////////////////////////////////////////////////////////
#include "ParLoop.h"
extern int mode;
using namespace std;
extern ofstream prot;
ParLoop::ParLoop(long ARank)
{
Rank = ARank;
AlignRule = vector<AlignAxis>(0);
LowerIndex = vector<long>(Rank);
HigherIndex = vector<long>(Rank);
LoopStep = vector<long>(Rank);
Invers = vector<long>(Rank);
AM_Dis = 0;
//====
AcrossFlag=0;
AcrossCost=0;
//=***
}
ParLoop::~ParLoop()
{
}
//====
void ParLoop::Across(CommCost *BoundCost,int type_size)
{ AcrossFlag=type_size;
AcrossCost=BoundCost;
}
//=***
long ParLoop::GetLoopSize()
{ int i;
long size=1;
for(i=0;i<Rank;i++)
size=size*GetSize(i);
return size;
};
long ParLoop::GetSize(long plDim)
{ if(plDim<Rank)
return (HigherIndex[plDim] - LowerIndex[plDim] + LoopStep[plDim])/LoopStep[plDim];
return 0;
};
void ParLoop::SaveLoopParams(const vector<long>& AInInitIndex,
const vector<long>& AInLastIndex, const vector<long>& AInLoopStep)
{
int i; long lv;
// çàïîìèíàíèå ïàðàìåòðîâ öèêëà
LowerIndex.clear();
HigherIndex.clear();
LoopStep.clear();
Invers.clear();
for (i = 0; i < Rank; i++)
{
if(AInLoopStep[i]>=0) {
LowerIndex.push_back(AInInitIndex[i]);
HigherIndex.push_back(AInLastIndex[i]);
LoopStep.push_back(AInLoopStep[i]);
Invers.push_back(0);
} else {
lv=(AInInitIndex[i]-AInLastIndex[i]) % AInLoopStep[i];
if(lv)
LowerIndex.push_back((AInLastIndex[i]+AInLoopStep[i]-lv));
else
LowerIndex.push_back(AInLastIndex[i]);
HigherIndex.push_back(AInInitIndex[i]);
LoopStep.push_back(-AInLoopStep[i]);
Invers.push_back(1);
}
if (mode) printf("Save %d %d %d\n",LowerIndex[i],HigherIndex[i],LoopStep[i]);
}
}
void ParLoop::PrepareAlign(long& TempRank, const vector<long>& AAxisArray,
const vector<long>& ACoeffArray, const vector<long>& AConstArray,
vector<AlignAxis>& IniRule)
{
int i;
long IRSize = Rank + TempRank;
IniRule.reserve(IRSize);
// Ïðåäâàðèòåëüíàÿ èíèöèàëèçàöèÿ
for (i = 0; i < Rank; i++)
IniRule.push_back(AlignAxis(align_COLLAPSE, i+1, 0));
for (i = Rank; i < IRSize; i++)
IniRule.push_back(AlignAxis(align_NORMTAXIS, 0, i-Rank+1));
// Çàïîëíåíèå DistRule â ñîîòâåòñòâèè ñ ïàðàìåòðàìè
for (i = 0; i < TempRank; i++)
{
// prot << "i=" << i << ", AAxisArray[i]=" << AAxisArray[i] << endl;
if (mode)
printf("Rank=%d IRSize=%d i= %d AAxisArray[i]=%d \n",Rank, IRSize, i, AAxisArray[i]);
if (AAxisArray[i] == -1)
IniRule[i+Rank] = AlignAxis(align_REPLICATE, 0, i+1);
else if (ACoeffArray[i] == 0)
IniRule[i+Rank] = AlignAxis(align_CONSTANT, 0, i+1, 0, AConstArray[i]);
else {
IniRule[i+Rank] = AlignAxis(align_NORMTAXIS, AAxisArray[i], i+1, ACoeffArray[i],
AConstArray[i]+ACoeffArray[i]*LowerIndex[AAxisArray[i]-1]);
IniRule[AAxisArray[i]-1] = AlignAxis(align_NORMAL, AAxisArray[i], i+1, ACoeffArray[i],
AConstArray[i]+ACoeffArray[i]*LowerIndex[AAxisArray[i]-1]);
}
}
}
void ParLoop::MapPL(AMView *APattern, const vector<long>& AAxisArray,
const vector<long>& ACoeffArray, const vector<long>& AConstArray,
const vector<long>& AInInitIndex, const vector<long>& AInLastIndex,
const vector<long>& AInLoopStep)
{
if (!APattern->IsDistribute()) {
prot << "Wrong call MapPL" << endl;
abort();
}
long TempRank = APattern->Rank();
vector<AlignAxis> IniRule;
// çàïîìèíàíèå à/ì, íà ê-ðóþ â èòîãå âûðàâíèâàåì
AM_Dis = APattern;
// çàïîìèíàíèå ïàðàìåòðîâ öèêëà
SaveLoopParams(AInInitIndex, AInLastIndex, AInLoopStep);
// èíèöèàëèçàöèÿ AlignRule
PrepareAlign(TempRank, AAxisArray, ACoeffArray, AConstArray, IniRule);
AlignRule = IniRule;
}
void ParLoop::MapPL(DArray *APattern, const vector<long>& AAxisArray,
const vector<long>& ACoeffArray, const vector<long>& AConstArray,
const vector<long>& AInInitIndex, const vector<long>& AInLastIndex,
const vector<long>& AInLoopStep)
{
if (!APattern->IsAlign()) {
prot << "Wrong call MapPL" << endl;
abort();
}
long TempRank = APattern->Rank();
long ALSize;
int i;
vector<AlignAxis> TAlign,
IniRule;
AlignAxis aAl, tAl;
// çàïîìèíàíèå à/ì, íà ê-ðóþ â èòîãå âûðàâíèâàåì
AM_Dis = APattern->AM_Dis;
// çàïîìèíàíèå ïàðàìåòðîâ öèêëà
SaveLoopParams(AInInitIndex,AInLastIndex,AInLoopStep);
// íà÷àëüíàÿ èíèöèàëèçàöèÿ AlignRule
PrepareAlign(TempRank, AAxisArray, ACoeffArray, AConstArray, IniRule);
// Ôîðìèðîâàíèå ñóïåðïîçèöèè îòîáðàæåíèé
ALSize = Rank + AM_Dis->Rank();
TAlign = APattern->AlignRule;
AlignRule = vector<AlignAxis>(ALSize);
// íà÷àëüíàÿ èíèö. 2-îé ÷àñòè ïðàâèëà
// âûðàâíèâàíèÿ (åñëè øàáëîí ðàçìíîæåí, òî è ìàññèâ òåì áîëåå)
for (i = 0; i < AM_Dis->Rank(); i++)
AlignRule[i+Rank]=TAlign[i+TempRank];
/* LU deb
printf("rank=%d tempRank=%d\n",Rank,TempRank);
for(i=0;i<AlignRule.size();i++)
printf("map %d %d %d %d ",AlignRule[i].A, AlignRule[i].B, AlignRule[i].Axis, AlignRule[i].TAxis);
printf("\n");
*/
for (i = 0; i < Rank; i++)
{ aAl = IniRule[i];
if (aAl.Attr == align_NORMAL)
{ tAl = TAlign[aAl.TAxis - 1];
switch (tAl.Attr)
{ case align_NORMAL : aAl.TAxis = tAl.TAxis;
aAl.A *= tAl.A;
aAl.B = aAl.B * tAl.A + tAl.B;
AlignRule[i] = aAl;
AlignRule[Rank+aAl.TAxis-1].Axis = i+1;
AlignRule[Rank+aAl.TAxis-1].A = aAl.A;
AlignRule[Rank+aAl.TAxis-1].B = aAl.B;
break;
case align_COLLAPSE : aAl.TAxis = 0;
aAl.Attr = align_COLLAPSE;
AlignRule[i] = aAl;
break;
};
};
};
/* LU deb
for(i=0;i<AlignRule.size();i++)
printf("map %d %d %d %d ",AlignRule[i].A, AlignRule[i].B, AlignRule[i].Axis, AlignRule[i].TAxis);
printf("\n");
*/
for (i = 0; i < TempRank; i++)
{ aAl = IniRule[i+Rank];
switch (aAl.Attr)
{ case align_CONSTANT : tAl = TAlign[aAl.TAxis-1];
if (tAl.Attr == align_NORMAL)
{ aAl.TAxis = tAl.TAxis;
aAl.B = tAl.A * aAl.B + tAl.B;
AlignRule[Rank+tAl.TAxis-1] = aAl;
};
break;
case align_REPLICATE : tAl = TAlign[aAl.TAxis-1];
if (tAl.Attr == align_NORMAL)
{ aAl.Attr = align_BOUNDREPL;
aAl.TAxis = tAl.TAxis;
aAl.A = tAl.A;
aAl.B = tAl.B;
aAl.Bound = APattern->GetSize(tAl.TAxis);
AlignRule[Rank+tAl.TAxis-1] = aAl;
};
break;
};
};
/* LU deb
for(i=0;i<AlignRule.size();i++)
printf("map %d %d %d %d ",AlignRule[i].A, AlignRule[i].B, AlignRule[i].Axis, AlignRule[i].TAxis);
printf("\n");
*/
};