Commit 430c4c9b authored by Sylvain Thery's avatar Sylvain Thery

cleaning of parallel_foreach (non template func in cpp) & resolve some include problems

parent 99598040
...@@ -32,9 +32,7 @@ ...@@ -32,9 +32,7 @@
#include "Algo/Render/GL2/topo3Render.h" #include "Algo/Render/GL2/topo3Render.h"
#include "Algo/Render/SVG/mapSVGRender.h" #include "Algo/Render/SVG/mapSVGRender.h"
//#include "Topology/generic/traversor3.h" #include "Topology/generic/traversorFactory.h"
//#include "Topology/generic/traversor3.h"
#include "Topology/generic/traversorGen.h"
#include "Algo/Render/GL2/drawerCells.h" #include "Algo/Render/GL2/drawerCells.h"
...@@ -214,7 +212,7 @@ void MyQT::traverse2() ...@@ -214,7 +212,7 @@ void MyQT::traverse2()
{ {
Algo::Render::drawerCell<PFP>(VERTEX+m_second2, m_drawer, myMap, m_selected, position, m_expl); Algo::Render::drawerCell<PFP>(VERTEX+m_second2, m_drawer, myMap, m_selected, position, m_expl);
m_drawer.color3f(1.0f,0.0f,0.0f); m_drawer.color3f(1.0f,0.0f,0.0f);
Traversor<PFP::MAP>* tra = Traversor<PFP::MAP>::createIncident(myMap, m_selected, 2, VERTEX+m_second2, VERTEX+m_first2); Traversor<PFP::MAP>* tra = TraversorFactory<PFP::MAP>::createIncident(myMap, m_selected, 2, VERTEX+m_second2, VERTEX+m_first2);
for (Dart d=tra->begin(); d != tra->end(); d= tra->next()) for (Dart d=tra->begin(); d != tra->end(); d= tra->next())
m_affDarts.push_back(d); m_affDarts.push_back(d);
Algo::Render::drawerCells<PFP>(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl); Algo::Render::drawerCells<PFP>(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl);
...@@ -223,7 +221,7 @@ void MyQT::traverse2() ...@@ -223,7 +221,7 @@ void MyQT::traverse2()
{ {
Algo::Render::drawerCell<PFP>(VERTEX+m_first2, m_drawer, myMap, m_selected, position, m_expl); Algo::Render::drawerCell<PFP>(VERTEX+m_first2, m_drawer, myMap, m_selected, position, m_expl);
m_drawer.color3f(1.0f,0.0f,0.0f); m_drawer.color3f(1.0f,0.0f,0.0f);
Traversor<PFP::MAP>* tra = Traversor<PFP::MAP>::createAdjacent(myMap, m_selected, 2, VERTEX+m_first2, VERTEX+m_second2); Traversor<PFP::MAP>* tra = TraversorFactory<PFP::MAP>::createAdjacent(myMap, m_selected, 2, VERTEX+m_first2, VERTEX+m_second2);
for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) for (Dart d = tra->begin(); d != tra->end(); d = tra->next())
m_affDarts.push_back(d); m_affDarts.push_back(d);
Algo::Render::drawerCells<PFP>(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl); Algo::Render::drawerCells<PFP>(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl);
...@@ -286,7 +284,7 @@ void MyQT::traverse3() ...@@ -286,7 +284,7 @@ void MyQT::traverse3()
dynamicMarkOrbit(VERTEX+m_second3); dynamicMarkOrbit(VERTEX+m_second3);
m_drawer.color3f(1.0f,0.0f,0.0f); m_drawer.color3f(1.0f,0.0f,0.0f);
Traversor<PFP::MAP>* tra = Traversor<PFP::MAP>::createIncident(myMap,m_selected, 3, VERTEX+m_second3, VERTEX+m_first3); Traversor<PFP::MAP>* tra = TraversorFactory<PFP::MAP>::createIncident(myMap,m_selected, 3, VERTEX+m_second3, VERTEX+m_first3);
for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) for (Dart d = tra->begin(); d != tra->end(); d = tra->next())
{ {
m_affDarts.push_back(d); m_affDarts.push_back(d);
...@@ -306,7 +304,7 @@ void MyQT::traverse3() ...@@ -306,7 +304,7 @@ void MyQT::traverse3()
dynamicMarkOrbit(VERTEX+m_first3); dynamicMarkOrbit(VERTEX+m_first3);
m_drawer.color3f(1.0f,0.0f,0.0f); m_drawer.color3f(1.0f,0.0f,0.0f);
Traversor<PFP::MAP>* tra = Traversor<PFP::MAP>::createAdjacent(myMap,m_selected, 3, VERTEX+m_first3, VERTEX+m_second3); Traversor<PFP::MAP>* tra = TraversorFactory<PFP::MAP>::createAdjacent(myMap,m_selected, 3, VERTEX+m_first3, VERTEX+m_second3);
for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) for (Dart d = tra->begin(); d != tra->end(); d = tra->next())
{ {
m_affDarts.push_back(d); m_affDarts.push_back(d);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "Algo/Render/SVG/mapSVGRender.h" #include "Algo/Render/SVG/mapSVGRender.h"
#include "Algo/Import/import.h" #include "Algo/Import/import.h"
#include "Topology/generic/traversorFactory.h"
MAP myMap; MAP myMap;
VertexAttribute<VEC3> position ; VertexAttribute<VEC3> position ;
...@@ -66,7 +67,7 @@ void MyQT::orbit_list(int x) ...@@ -66,7 +67,7 @@ void MyQT::orbit_list(int x)
m_selected.clear(); m_selected.clear();
// easy way to traverse darts of orbit // easy way to traverse darts of orbit
Traversor<MAP>* tra = Traversor<MAP>::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); Traversor<MAP>* tra = TraversorFactory<MAP>::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]);
for (Dart e = tra->begin(); e != tra->end(); e = tra->next()) for (Dart e = tra->begin(); e != tra->end(); e = tra->next())
m_selected.push_back(e); m_selected.push_back(e);
} }
...@@ -174,7 +175,7 @@ void MyQT::cb_mousePress(int button, int x, int y) ...@@ -174,7 +175,7 @@ void MyQT::cb_mousePress(int button, int x, int y)
m_selected.clear(); m_selected.clear();
// easy way to traverse darts of orbit // easy way to traverse darts of orbit
Traversor<MAP>* tra = Traversor<MAP>::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); Traversor<MAP>* tra = TraversorFactory<MAP>::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]);
for (Dart e = tra->begin(); e != tra->end(); e = tra->next()) for (Dart e = tra->begin(); e != tra->end(); e = tra->next())
m_selected.push_back(e); m_selected.push_back(e);
} }
......
...@@ -22,11 +22,12 @@ ...@@ -22,11 +22,12 @@
* * * *
*******************************************************************************/ *******************************************************************************/
#include "Topology/generic/functor.h"
#ifndef __PARALLEL_FOREACH__ #ifndef __PARALLEL_FOREACH__
#define __PARALLEL_FOREACH__ #define __PARALLEL_FOREACH__
#include "Topology/generic/functor.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -36,6 +37,11 @@ namespace Algo ...@@ -36,6 +37,11 @@ namespace Algo
namespace Parallel namespace Parallel
{ {
static unsigned int NBCORES=0;
/// enum for optimalNbThreads parameter
enum NbParam {NB_HIGHMEMORY, NB_HIGHCOMPUTE, NB_VERYHIGHMEMORY};
/// size of buffers to store darts or indexes in each threads /// size of buffers to store darts or indexes in each threads
const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise
...@@ -45,9 +51,15 @@ const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise ...@@ -45,9 +51,15 @@ const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise
inline unsigned int nbThreads(); inline unsigned int nbThreads();
/** /**
* @param p can be NB_HIGHMEMORY (default) or NB_HIGHCOMPUTE or NB_VERYHIGHMEMORY
* @return Number of core in fact (work only with quad core with/without hyper threading) * @return Number of core in fact (work only with quad core with/without hyper threading)
*/ */
inline unsigned int optimalNbThreads(); unsigned int optimalNbThreads( NbParam p=NB_HIGHMEMORY);
/**
* impossible to automatically determine the number of cores so ...
*/
void setNbCore(unsigned int nb);
/** /**
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <boost/thread/barrier.hpp> #include <boost/thread/barrier.hpp>
#include <vector> #include <vector>
namespace CGoGN namespace CGoGN
{ {
...@@ -34,6 +35,7 @@ namespace Algo ...@@ -34,6 +35,7 @@ namespace Algo
namespace Parallel namespace Parallel
{ {
/// internal functor for boost call
class ThreadFunctionAttrib class ThreadFunctionAttrib
{ {
protected: protected:
...@@ -66,11 +68,7 @@ public: ...@@ -66,11 +68,7 @@ public:
}; };
/// internal functor for boost call
/**
*
*/
template<typename MAP> template<typename MAP>
class ThreadFunction class ThreadFunction
{ {
...@@ -109,17 +107,25 @@ inline unsigned int nbThreads() ...@@ -109,17 +107,25 @@ inline unsigned int nbThreads()
} }
inline unsigned int optimalNbThreads(NbParam p)
inline unsigned int optimalNbThreads()
{ {
if (p==NB_HIGHCOMPUTE)
return nbThreads();
if (p==NB_VERYHIGHMEMORY)
return 2;
// NB_HIGHMEMORY
if (NBCORES != 0)
return NBCORES;
unsigned int nb = nbThreads(); unsigned int nb = nbThreads();
if (nb>4) if (nb>4)
return nb/2 ; return nb/2 ;
return nb; return nb;
} }
template <typename MAP, unsigned int ORBIT> template <typename MAP, unsigned int ORBIT>
void foreach_cell(MAP& map, FunctorMapThreaded<MAP>& func, unsigned int nbth, bool needMarkers, const FunctorSelect& good, unsigned int currentThread) void foreach_cell(MAP& map, FunctorMapThreaded<MAP>& func, unsigned int nbth, bool needMarkers, const FunctorSelect& good, unsigned int currentThread)
{ {
...@@ -144,7 +150,6 @@ void foreach_cell(MAP& map, FunctorMapThreaded<MAP>& func, unsigned int nbth, bo ...@@ -144,7 +150,6 @@ void foreach_cell(MAP& map, FunctorMapThreaded<MAP>& func, unsigned int nbth, bo
funcs.push_back(func.duplicate()); funcs.push_back(func.duplicate());
} }
foreach_cell<MAP,ORBIT>(map,funcs,nbth,needMarkers,good,currentThread); foreach_cell<MAP,ORBIT>(map,funcs,nbth,needMarkers,good,currentThread);
if (!shared) if (!shared)
...@@ -164,7 +169,6 @@ void foreach_cell(MAP& map, std::vector<FunctorMapThreaded<MAP>*>& funcs, unsign ...@@ -164,7 +169,6 @@ void foreach_cell(MAP& map, std::vector<FunctorMapThreaded<MAP>*>& funcs, unsign
for (unsigned int i = 0; i < nbth; ++i) for (unsigned int i = 0; i < nbth; ++i)
vd[i].reserve(SIZE_BUFFER_THREAD); vd[i].reserve(SIZE_BUFFER_THREAD);
AttributeContainer* cont = NULL; AttributeContainer* cont = NULL;
DartMarker* dmark = NULL; DartMarker* dmark = NULL;
CellMarker<ORBIT>* cmark = NULL; CellMarker<ORBIT>* cmark = NULL;
...@@ -413,7 +417,6 @@ void foreach_dart(MAP& map, std::vector<FunctorMapThreaded<MAP>*> funcs, unsigne ...@@ -413,7 +417,6 @@ void foreach_dart(MAP& map, std::vector<FunctorMapThreaded<MAP>*> funcs, unsigne
for (unsigned int i = 0; i < nbth; ++i) for (unsigned int i = 0; i < nbth; ++i)
{ {
// funcs[i]->setThreadID(1+i);
threads[i] = new boost::thread(ThreadFunction<MAP>(funcs[i], vd[i],sync1,sync2, finished,1+i)); threads[i] = new boost::thread(ThreadFunction<MAP>(funcs[i], vd[i],sync1,sync2, finished,1+i));
} }
...@@ -461,103 +464,6 @@ void foreach_dart(MAP& map, std::vector<FunctorMapThreaded<MAP>*> funcs, unsigne ...@@ -461,103 +464,6 @@ void foreach_dart(MAP& map, std::vector<FunctorMapThreaded<MAP>*> funcs, unsigne
} }
inline void foreach_attrib(AttributeContainer& attr_cont, FunctorAttribThreaded& func, unsigned int nbth)
{
if (nbth == 0)
nbth = optimalNbThreads();
std::vector<FunctorAttribThreaded*> funcs;
funcs.reserve(nbth);
FunctorAttribThreaded* ptr = func.duplicate();
bool shared = (ptr == NULL);
if (shared)
{
for (unsigned int i = 0; i < nbth; ++i)
funcs.push_back(&func);
}
else
{
funcs.push_back(ptr);
for (unsigned int i = 1; i < nbth; ++i)
funcs.push_back(func.duplicate());
}
foreach_attrib(attr_cont,funcs,nbth);
if (!shared)
for (unsigned int i = 0; i < nbth; ++i)
delete funcs[i];
}
inline void foreach_attrib(AttributeContainer& attr_cont, std::vector<FunctorAttribThreaded*> funcs, unsigned int nbth)
{
assert(funcs.size() == nbth);
std::vector<unsigned int >* vid = new std::vector<unsigned int>[2*nbth];
boost::thread** threads = new boost::thread*[nbth];
for (unsigned int i = 0; i < 2*nbth; ++i)
vid[i].reserve(SIZE_BUFFER_THREAD);
// fill each vid buffers with 4096 id
unsigned int id = attr_cont.begin();
unsigned int nb = 0;
unsigned int nbm = nbth*SIZE_BUFFER_THREAD;
while ((id != attr_cont.end()) && (nb < nbm))
{
vid[nb%nbth].push_back(id);
nb++;
attr_cont.next(id);
}
boost::barrier sync1(nbth+1);
boost::barrier sync2(nbth+1);
bool finished=false;
// lauch threads
for (unsigned int i = 0; i < nbth; ++i)
threads[i] = new boost::thread(ThreadFunctionAttrib(funcs[i], vid[i],sync1,sync2, finished,1+i));
while (id != attr_cont.end())
{
for (unsigned int i = nbth; i < 2*nbth; ++i)
vid[i].clear();
unsigned int nb = 0;
while ((id != attr_cont.end()) && (nb < nbm))
{
vid[nbth + nb%nbth].push_back(id);
nb++;
attr_cont.next(id);
}
sync1.wait();
for (unsigned int i = 0; i < nbth; ++i)
vid[i].swap(vid[nbth+i]);
sync2.wait();
}
sync1.wait();
finished = true;
sync2.wait();
//wait for all theads to be finished
for (unsigned int i = 0; i < nbth; ++i)
{
threads[i]->join();
delete threads[i];
}
delete[] threads;
delete[] vid;
}
// TODO same modification for transparent usage of dart marker / cell marker / quick traversal // TODO same modification for transparent usage of dart marker / cell marker / quick traversal
template <typename MAP, unsigned int CELL> template <typename MAP, unsigned int CELL>
......
...@@ -21,14 +21,15 @@ ...@@ -21,14 +21,15 @@
* Contact information: cgogn@unistra.fr * * Contact information: cgogn@unistra.fr *
* * * *
*******************************************************************************/ *******************************************************************************/
#include "Topology/generic/traversorGen.h"
#ifndef __TRAVERSOR3_H__ #ifndef __TRAVERSOR3_H__
#define __TRAVERSOR3_H__ #define __TRAVERSOR3_H__
#include "Topology/generic/dart.h"
#include "Topology/generic/traversorCell.h" #include "Topology/generic/traversorCell.h"
#include "Topology/generic/traversorGen.h"
#include "Topology/generic/traversorDoO.h"
#include "Topology/generic/dart.h"
#include "Topology/generic/cellmarker.h"
namespace CGoGN namespace CGoGN
{ {
......
...@@ -22,14 +22,13 @@ ...@@ -22,14 +22,13 @@
* * * *
*******************************************************************************/ *******************************************************************************/
#include "Topology/generic/traversorGen.h"
#ifndef __TRAVERSOR_CELL_H__ #ifndef __TRAVERSOR_CELL_H__
#define __TRAVERSOR_CELL_H__ #define __TRAVERSOR_CELL_H__
#include "Topology/generic/dart.h" #include "Topology/generic/dart.h"
#include "Topology/generic/dartmarker.h" #include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h" #include "Topology/generic/cellmarker.h"
#include "Topology/generic/traversorGen.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -98,24 +97,6 @@ public: ...@@ -98,24 +97,6 @@ public:
{} {}
}; };
template <typename MAP, unsigned int ORBIT>
class TraversorDartsOfOrbit : public Traversor<MAP>
{
private:
std::vector<Dart>::iterator m_current ;
std::vector<Dart> m_vd ;
public:
TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread = 0) ;
Dart begin() ;
Dart end() ;
Dart next() ;
} ;
} // namespace CGoGN } // namespace CGoGN
#include "Topology/generic/traversorCell.hpp" #include "Topology/generic/traversorCell.hpp"
......
...@@ -153,35 +153,35 @@ void TraversorCell<MAP, ORBIT>::skip(Dart d) ...@@ -153,35 +153,35 @@ void TraversorCell<MAP, ORBIT>::skip(Dart d)
cmark->mark(d) ; cmark->mark(d) ;
} }
//
template <typename MAP, unsigned int ORBIT> //template <typename MAP, unsigned int ORBIT>
TraversorDartsOfOrbit<MAP, ORBIT>::TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread) //TraversorDartsOfOrbit<MAP, ORBIT>::TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread)
{ //{
m_vd.reserve(16); // m_vd.reserve(16);
FunctorStoreNotBoundary<MAP> fs(map, m_vd); // FunctorStoreNotBoundary<MAP> fs(map, m_vd);
map.template foreach_dart_of_orbit<ORBIT>(d, fs, thread); // map.template foreach_dart_of_orbit<ORBIT>(d, fs, thread);
m_vd.push_back(NIL); // m_vd.push_back(NIL);
} //}
//
template <typename MAP, unsigned int ORBIT> //template <typename MAP, unsigned int ORBIT>
Dart TraversorDartsOfOrbit<MAP, ORBIT>::begin() //Dart TraversorDartsOfOrbit<MAP, ORBIT>::begin()
{ //{
m_current = m_vd.begin(); // m_current = m_vd.begin();
return *m_current; // return *m_current;
} //}
//
template <typename MAP, unsigned int ORBIT> //template <typename MAP, unsigned int ORBIT>
Dart TraversorDartsOfOrbit<MAP, ORBIT>::end() //Dart TraversorDartsOfOrbit<MAP, ORBIT>::end()
{ //{
return NIL; // return NIL;
} //}
//
template <typename MAP, unsigned int ORBIT> //template <typename MAP, unsigned int ORBIT>
Dart TraversorDartsOfOrbit<MAP, ORBIT>::next() //Dart TraversorDartsOfOrbit<MAP, ORBIT>::next()
{ //{
if (*m_current != NIL) // if (*m_current != NIL)
m_current++; // m_current++;
return *m_current; // return *m_current;
} //}
} // namespace CGoGN } // namespace CGoGN
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __TRAVERSORFACTORY_H__
#define __TRAVERSORGEN_H__
#include "Topology/generic/traversorGen.h"
namespace CGoGN
{
template <typename MAP>
class TraversorFactory
{
public:
/**
* Factory of incident traversors creation
* @param map the map in which we work
* @param dart the initial dart of traversal
* @param dim the dimension of traversal (2 or 3)
* @param orbX incident from cell
* @param orbY incident to cell
* @return a ptr on Generic Traversor
*/
static Traversor<MAP>* createIncident(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY);
/**
* Factory of adjacent traversors creation
* @param map the map in which we work
* @param dart the initial dart of traversal
* @param dim the dimension of traversal (2 or 3)
* @param orbX incident from cell
* @param orbY incident to cell
* @return a ptr on Generic Traversor
*/
static Traversor<MAP>* createAdjacent(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY);
/**