Commit b1fed762 authored by Martin Khannouz's avatar Martin Khannouz Committed by Berenger Bramas
Browse files

use taskname in simgrid.

Add a few more information to the ones simgrid use.
Put the same taskname in the explicit mpi.
Add source code to compare dag.
Add script to compile and run tests.
parent afb13093
......@@ -5,79 +5,180 @@
#include <vector>
#include <regex>
#include <thread>
#include <deque>
#include <unordered_set>
using namespace std;
#include "../../Src/Utils/FGlobal.hpp"
#include "../../Src/Utils/FMath.hpp"
#include "../../Src/Utils/FParameters.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
enum TaskType {P2M = 0, M2M, M2L, M2L_OUT, L2L, L2P, P2P, P2P_OUT};
string taskNames[] = {"P2M", "M2M", "M2L", "M2L_out", "L2L", "L2P", "P2P", "P2P_out"};
struct Task
{
TaskType type;
long long int uniqueId;
vector<long long int> id;
int mpiNode;
int level;
bool operator==(const Task & other) const
{
if(type != other.type || id.size() != other.id.size())
return false;
for(size_t i = 0; i < id.size(); ++i)
if(id[i] != other.id[i])
return false;
return true;
}
bool operator!=(const Task & other) const
{
return !((*this)==other);
}
void print(void)
{
cout << taskNames[type];
for(size_t i = 0; i < id.size(); ++i)
cout << ", " << id[i];
cout << endl;
}
};
//Spécialisation de hash pour le type Task
namespace std {
template <> struct hash<Task>
{
size_t operator()(const Task & x) const
{
return x.uniqueId;
}
};
}
struct DagData
{
unordered_set<Task> allTask;
};
void parseLine(DagData & dagData, string& line)
bool parseLine(DagData & dagData, deque<string> & lineElements)
{
std::regex regexAct("^([a-z0-9]+)_");
std::regex regexArgP2M("^[a-z0-9]+_([0-9]+)_([0-9]+)_([0-9])$");
std::regex regexArgM2M("^[a-z0-9]+_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$");
std::regex regexArgP2P("^[a-z0-9]+_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$");
std::smatch matches;
if(std::regex_search (line,matches,regexAct))
{
if(matches[1] == "p2m")
{
std::regex_search (line,matches,regexArgP2M);
int startMorton = stoi(matches[1], nullptr,10);
int endMorton = stoi(matches[2], nullptr,10);
int node = stoi(matches[3], nullptr,10);
}
else if(matches[1] == "m2m")
{
std::regex_search (line,matches,regexArgM2M);
int level = stoi(matches[1], nullptr,10);
int startMorton = stoi(matches[2], nullptr,10);
int endMorton = stoi(matches[3], nullptr,10);
int startMorton2 = stoi(matches[4], nullptr,10);
int endMorton2 = stoi(matches[5], nullptr,10);
int node = stoi(matches[6], nullptr,10);
}
else if(matches[1] == "m2l")
{
std::regex_search (line,matches,regexArgM2M);
int level = stoi(matches[1], nullptr,10);
int startMorton = stoi(matches[2], nullptr,10);
int endMorton = stoi(matches[3], nullptr,10);
int startMorton2 = stoi(matches[4], nullptr,10);
int endMorton2 = stoi(matches[5], nullptr,10);
int node = stoi(matches[6], nullptr,10);
}
else if(matches[1] == "l2l")
{
std::regex_search (line,matches,regexArgM2M);
int level = stoi(matches[1], nullptr,10);
int startMorton = stoi(matches[2], nullptr,10);
int endMorton = stoi(matches[3], nullptr,10);
int startMorton2 = stoi(matches[4], nullptr,10);
int endMorton2 = stoi(matches[5], nullptr,10);
int node = stoi(matches[6], nullptr,10);
}
else if(matches[1] == "l2p")
{
std::regex_search (line,matches,regexArgP2M);
int startMorton = stoi(matches[1], nullptr,10);
int endMorton = stoi(matches[2], nullptr,10);
int node = stoi(matches[3], nullptr,10);
}
else if(matches[1] == "p2p")
{
std::regex_search (line,matches,regexArgP2P);
int startMorton = stoi(matches[1], nullptr,10);
int endMorton = stoi(matches[2], nullptr,10);
int startMorton2 = stoi(matches[3], nullptr,10);
int endMorton2 = stoi(matches[4], nullptr,10);
int node = stoi(matches[5], nullptr,10);
}
if(lineElements.size() < 1)
return false;
Task task;
if(lineElements.size() >= 14 && lineElements[0] == "P2P_out")
{
task.type = P2P_OUT;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(4);
task.id[0] = stoll(lineElements[9]);
task.id[1] = stoll(lineElements[10]);
task.id[2] = stoll(lineElements[11]);
task.id[3] = stoll(lineElements[12]);
task.mpiNode = stoi(lineElements[13]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 10 && lineElements[0] == "P2P")
{
task.type = P2P;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(4);
task.id[0] = stoll(lineElements[5]);
task.id[1] = stoll(lineElements[6]);
task.id[2] = stoll(lineElements[7]);
task.id[3] = stoll(lineElements[8]);
if(task.id[0] == 0 && task.id[1] == 0 && task.id[2] == 0 && task.id[3] == 0)
cout << "Suricate" << endl;
task.mpiNode = stoi(lineElements[9]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 10 && lineElements[0] == "M2L" )
{
task.type = M2L;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(5);
task.id[0] = stoll(lineElements[2]);
task.id[1] = stoll(lineElements[5]);
task.id[2] = stoll(lineElements[6]);
task.id[3] = stoll(lineElements[7]);
task.id[4] = stoll(lineElements[8]);
task.mpiNode = stoi(lineElements[9]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 13 && lineElements[0] == "M2L_out")
{
task.type = M2L_OUT;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(5);
task.id[0] = stoll(lineElements[2]);
task.id[1] = stoll(lineElements[8]);
task.id[2] = stoll(lineElements[9]);
task.id[3] = stoll(lineElements[10]);
task.id[4] = stoll(lineElements[11]);
task.mpiNode = stoi(lineElements[12]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 13 && lineElements[0] == "M2M")
{
task.type = M2M;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(5);
task.id[0] = stoll(lineElements[2]);
task.id[1] = stoll(lineElements[8]);
task.id[2] = stoll(lineElements[9]);
task.id[3] = stoll(lineElements[10]);
task.id[4] = stoll(lineElements[11]);
task.mpiNode = stoi(lineElements[12]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 13 && lineElements[0] == "L2L")
{
task.type = L2L;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(5);
task.id[0] = stoll(lineElements[2]);
task.id[1] = stoll(lineElements[8]);
task.id[2] = stoll(lineElements[9]);
task.id[3] = stoll(lineElements[10]);
task.id[4] = stoll(lineElements[11]);
task.mpiNode = stoi(lineElements[12]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 8 && lineElements[0] == "L2P")
{
task.type = L2P;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(2);
task.id[0] = stoll(lineElements[5]);
task.id[1] = stoll(lineElements[6]);
task.mpiNode = stoi(lineElements[7]);
dagData.allTask.insert(task);
}
else if(lineElements.size() >= 8 && lineElements[0] == "P2M")
{
task.type = L2P;
task.uniqueId = stoll(lineElements[1]);
task.id.resize(2);
task.id[0] = stoll(lineElements[5]);
task.id[1] = stoll(lineElements[6]);
task.mpiNode = stoi(lineElements[7]);
dagData.allTask.insert(task);
}
else
{
cout << "No match for " << lineElements[0] << " - " << lineElements.size() << endl;
return false;
}
return true;
}
void split(string& line, string const& delim, deque<string> &result)
{
size_t prevPos = 0;
size_t pos = 0;
while((pos = line.find(delim, prevPos)) != string::npos)
{
result.push_back(line.substr(prevPos, pos-prevPos));
prevPos = pos+delim.size();
}
if(prevPos < line.size())
result.push_back(line.substr(prevPos));
}
bool fillDagData(const char* const filename, DagData & dagData)
{
......@@ -89,21 +190,53 @@ bool fillDagData(const char* const filename, DagData & dagData)
return false;
}
string line;
string delim(", ");
deque<string> splitLine;
int count = 0;
while(!fichier.eof())
{
++count;
getline(fichier, line);
if(line.size() > 3 && line[0] == 'N')
{
line = line.substr(3);
parseLine(dagData, line);
}
splitLine.clear();
split(line, delim, splitLine);
parseLine(dagData, splitLine);
}
cout << (count-1) << " lines in " << filename << endl;
// instructions
fichier.close(); // on ferme le fichier
return true;
}
void compareDag(DagData& dag1, DagData& dag2)
void compareDag(DagData& dag1, DagData& dag2, int treeHeight)
{
long long int notFoundCount[treeHeight] = {0};
bool notFound[treeHeight] = {false};
for(Task task : dag1.allTask)
{
bool found = false;
if(task.type == P2P || task.type == P2P_OUT || task.type == P2M || task.type == L2P)
notFound[treeHeight-1] = true;
else if(task.id[0] < treeHeight)
++notFound[task.id[0]] = true;
for(Task task2 : dag2.allTask)
{
if(task == task2)
{
found = true;
break;
}
}
if(found == false)
{
task.print();
if(task.type == P2P || task.type == P2P_OUT || task.type == P2M || task.type == L2P)
++notFoundCount[treeHeight-1];
else
++notFoundCount[task.id[0]];
}
}
for(int i = 0; i < treeHeight; ++i)
if(notFound[i] == true)
cout << "Diff lvl " << i << " -> " << notFoundCount[i] << endl;
}
int main(int argc, char* argv[]){
const FParameterNames Explicit {
......@@ -114,23 +247,32 @@ int main(int argc, char* argv[]){
{"-i"} ,
"Trace from implicit mpi"
};
FHelpDescribeAndExit(argc, argv, "Compare DAG mapping", Explicit, Implicit);
const FParameterNames TreeHeight {
{"-h"},
"Height of the tree"
};
FHelpDescribeAndExit(argc, argv, "Compare DAG mapping", Explicit, Implicit, TreeHeight);
// Get params
const char* const explicitFilename = FParameters::getStr(argc,argv,Explicit.options, "explicit.rec");
const char* const implicitFilename = FParameters::getStr(argc,argv,Implicit.options, "implicit.rec");
const int treeHeight = FParameters::getValue(argc,argv,TreeHeight.options, 5);
DagData implicitData, explicitData;
bool implicitGood, explicitGood;
std::thread implicitThread([&](){
std::thread explicitThread([&](){
explicitGood = fillDagData(explicitFilename, explicitData);
});
std::thread explicitThread([&](){
explicitThread.join();
std::thread implicitThread([&](){
implicitGood = fillDagData(implicitFilename, implicitData);
});
implicitThread.join();
explicitThread.join();
if(implicitGood && explicitGood)
compareDag(implicitData, explicitData);
{
cout << explicitData.allTask.size() << " tasks in explicit." << endl;
cout << implicitData.allTask.size() << " tasks in implicit." << endl;
compareDag(explicitData, implicitData, treeHeight);
}
return 0;
}
......@@ -139,7 +139,7 @@ int main(int argc, char* argv[]){
int rank = groupalgo.getRank();
for(int i = 0; i < groupedTree.getHeight(); ++i)
{
if(groupedTree.getNbCellGroupAtLevel(i) < groupalgo.getNProc())
if(groupedTree.getNbCellGroupAtLevel(i) < groupalgo.getNProc() && rank == 0)
std::cout << "Error at level " << i << std::endl;
}
return 0;
......
......@@ -72,7 +72,7 @@ int main(int argc, char* argv[]){
// Get params
const int NbLevels = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5);
const FSize NbParticles = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, FSize(20));
const int groupSize = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 250);
const int groupSize = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 8);
const FSize totalNbParticles = (NbParticles*mpiComm.global().processCount());
// Load the particles
......@@ -90,7 +90,8 @@ int main(int argc, char* argv[]){
std::unique_ptr<TestParticle[]> particles(new TestParticle[loader.getNumberOfParticles()]);
memset(particles.get(), 0, sizeof(TestParticle) * loader.getNumberOfParticles());
for(FSize idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
loader.fillParticle(&particles[idxPart].position);
loader.fillParticleAtMortonIndex(&(particles[idxPart].position), mpiComm.global().processId()*NbParticles + idxPart,NbLevels);
//loader.fillParticle(&(particles[idxPart].position));
}
// Sort in parallel
FVector<TestParticle> myParticles;
......@@ -129,10 +130,16 @@ int main(int argc, char* argv[]){
}
FLOG(std::cout << "My last index is " << leftLimite << "\n");
FLOG(std::cout << "My left limite is " << myLeftLimite << "\n");
std::cout << "My last index is (" << mpiComm.global().processId() << ") " << leftLimite << "\n";
std::cout << "My left limite is (" << mpiComm.global().processId() << ") " << myLeftLimite << "\n";
std::cout << "Size (" << mpiComm.global().processId() << ") " << allParticles.getNbParticles() << "\n";
for(int i = 0; i < mpiComm.global().processCount(); ++i)
{
if(i == mpiComm.global().processId())
{
std::cout << "My last index is (" << mpiComm.global().processId() << ") " << leftLimite << "\n";
std::cout << "My left limite is (" << mpiComm.global().processId() << ") " << myLeftLimite << "\n";
std::cout << "Size (" << mpiComm.global().processId() << ") " << allParticles.getNbParticles() << "\n";
}
mpiComm.global().barrier();
}
// Put the data into the tree
GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize,
......@@ -142,7 +149,7 @@ int main(int argc, char* argv[]){
// Run the algorithm
GroupKernelClass groupkernel;
GroupAlgorithm groupalgo(mpiComm.global(), &groupedTree,&groupkernel);
groupalgo.execute(FFmmP2P | FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P);
groupalgo.execute();
std::cout << "Wait Others... " << std::endl;
mpiComm.global().barrier();
......@@ -173,7 +180,8 @@ int main(int argc, char* argv[]){
FRandomLoader<FReal> loaderAll(NbParticles, 1.0, FPoint<FReal>(0,0,0), idxProc);
for(FSize idxPart = 0 ; idxPart < loaderAll.getNumberOfParticles() ; ++idxPart){
FPoint<FReal> pos;
loaderAll.fillParticle(&pos);
//loaderAll.fillParticle(&pos);
loaderAll.fillParticleAtMortonIndex(&pos, idxProc*NbParticles + idxPart,NbLevels);
tree.insert(pos);
}
}
......
#!/bin/sh
export SCALFMM_SIMGRIDOUT='scalfmm.out'
make testBlockedImplicitAlgorithm generateMapping testBlockedMpiAlgorithm compareDAGmapping -j16
if [ $? -ne 0 ]; then
exit
fi
mpiexec -n 8 ./Tests/Release/testBlockedMpiAlgorithm -nb 8 -bs 8 -h 3
if [ $? -ne 0 ]; then
exit
fi
a=`ls $SCALFMM_SIMGRIDOUT\_*`
rm -f $SCALFMM_SIMGRIDOUT
echo $a
for i in $a; do
echo $i
cat $i >> $SCALFMM_SIMGRIDOUT
done
cp -f $SCALFMM_SIMGRIDOUT scalfmm_explicit.out
mpiexec -n 8 ./Tests/Release/generateMapping -nb 8 -bs 8 -h 3
mpiexec -n 8 ./Tests/Release/testBlockedImplicitAlgorithm -map mapping -f canard.fma -bs 8 -h 3
if [ $? -ne 0 ]; then
exit
fi
cp -f scalfmm.out_0 scalfmm_implicit.out
./Tests/Release/compareDAGmapping -e scalfmm_explicit.out -i scalfmm_implicit.out -h 3 > output
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment