1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#include "My_Functions.hpp"
#ifndef threadbool
#define threadbool 0
#ifdef THREAD
#include <boost/thread/thread.hpp>
#undef threadbool
#define threadbool 1
#endif
#endif
using namespace std;
// ===================================================================
class erode_class{
public:
erode_class(vector<void*> args_):ptrs_(args_){};
void Run(vector<void* > &truc){
cout<<"Parameters :"<<endl;
for(size_t i=0;i<ptrs_.size();++i){
cout<<"\t"<<*(static_cast<int *> (ptrs_[i]))<<endl;
}
cout<<"Additional parameters :"<<endl;
for(size_t i=0;i<truc.size();++i){
int *temp=static_cast<int *> (truc[i]);
cout<<"\t"<<(*temp)<<endl;
}
cout<<endl<<endl;
};
template<class T>
void thread_erode_b(vector<void *> &arguments_,vector<bool> &traites){
if(arguments_.size()!=5){cout<<"Erode arguments are incorrect"<<endl<<"End program"<<endl;exit(0);}
T *volume=static_cast<T *> (arguments_[0]);
T *volume2=static_cast<T *> (arguments_[1]);
int ordre=*(static_cast<int *> (arguments_[2]));
int planstart=*(static_cast<int *> (arguments_[3]));
int planstop=*(static_cast<int *> (arguments_[4]));
const int dim1=(*volume).dim1(),dim2=(*volume).dim2(),dim3=(*volume).dim3();
// Traitement proprement dit
}
private:
vector<void*> ptrs_;
};
typedef void (erode_class::*traitement)(vector<void *> &arguments_,vector<bool> &traites);
typedef void (erode_class::*Run_test)(vector<void *> &truc);
// =========================================================================
template <class T>
void GenericThreadedFunction_2Volumes(T &volume1,T &volume2,const size_t nb_threads,vector<void* > &args,erode_class &test,int &planstart,int &planstop,vector<bool> &traites, traitement fonction){
volume2.resize(volume1.dim1(),volume1.dim2(),volume1.dim3());
#if threadbool
boost::thread_group threads1;
size_t box_size=volume1.dim1();
for (std::size_t n=0; n<nb_threads; ++n){
size_t nb_plans=(int)((double)box_size/(double)nb_threads);
if(n<box_size%nb_threads)nb_plans++;
if(n>=box_size%nb_threads){
planstart=n*nb_plans+box_size%nb_threads;
}
else {
planstart=n*nb_plans;
}
planstop=planstart-1+nb_plans;
// I know this is not the optimal way to spread the work but I ll improve it later :)
args[3]=&planstart;
args[4]=&planstop;
cout<<n<<" : "<<*(static_cast<int*> (args[3]))<<" to "<<*(static_cast<int*> (args[4]))<<endl;
threads1.create_thread(boost::bind(fonction,boost::ref(test),boost::ref(args),boost::ref(traites)));
}
threads1.join_all();
#else
size_t planstart=0,planstop=volume1.dim1()-1;
fonction(volume1,volume2,ordre,planstart,planstop);
#endif
}
template<typename T>
void affiche_test(double i){
cout<<"Affiche_test = "<<T(i)<<endl;
}
template<typename T>
void test_thread(T j,void (*f)(T k)){
boost::thread_group threads1;
for(int i=0;i<2;++i){
threads1.create_thread(boost::bind(f,j));
sleep(1);}
threads1.join_all();
}
int main(int argc, char *argv[])
{
size_t nb_threads;
#if threadbool
nb_threads=boost::thread::hardware_concurrency();
#else
nb_threads=1;
#endif
slip::RegularVector3dField3d<double> volume1b;
read_slip_data(volume1b,"volume_lif_00005.abe");
slip::Volume<double> volume1(volume1b.dim1(),volume1b.dim2(),volume1b.dim3()),volume2;
slip::RegularVector3dField3d<double>::const_iterator iter1=volume1b.begin();
slip::Volume<double>::iterator iter2=volume1.begin();
for( ;
iter1!=volume1b.end()&&
iter2!=volume1.end();
++iter1,++iter2)
(*iter2)=(*iter1)[0];
vector<void*> args,tmp;
erode_class test(args);
int planstart=0,planstop=(int)volume1.dim1(),ordre=3;
// Creation of the vector containing parameters. I would like to avoid it ...
tmp.push_back(&volume1);
tmp.push_back(&volume2);
tmp.push_back(&ordre);
tmp.push_back(&planstart);
tmp.push_back(&planstop);
vector<bool> traites(volume1.dim1());
traitement f = &erode_class::thread_erode_b<slip::Volume<double> >;
GenericThreadedFunction_2Volumes(volume1,volume2,nb_threads,tmp,test,planstart,planstop,traites,f);
return 0;
}
|