Parcourir la source

Add Cilk support

Jean Fromentin il y a 11 mois
Parent
commit
951cc0b313

+ 8 - 2
c++/Makefile

@@ -2,10 +2,14 @@ EXE_W		= wilf-worker
 EXE_S 		= wilf-server
 EXE_I 		= wilf-interface
 EXE_A   	= wilf-alone
-CPP 		= g++  -g
+EXE_C		= wilf-cilk
+CPP 		= g++-7  -g
+CPP_CILK	= g++-7 -g
 CFLAGS		= --std=c++11 -march=corei7 -O3 -DNDEBUG
 
-all: $(EXE_S) $(EXE_W) $(EXE_I) $(EXE_A)
+all: $(EXE_S) $(EXE_W) $(EXE_I) $(EXE_A) $(EXE_C)
+
+cilk: $(EXE_C)
 
 dist/message.o:dist/message.cpp dist/message.hpp
 	$(CPP) $(CFLAGS) -c $< -o $@
@@ -43,6 +47,8 @@ $(EXE_I):dist/message.o dist/client.o dist/interface.o src/main-interface.cpp
 $(EXE_A):src/semigroup.o src/treewalk.o src/main-alone.cpp
 	$(CPP) $(CFLAGS) $^ -o $@ $(LIBS)
 
+$(EXE_C): src/semigroup.o src/treewalk.o src/main-cilk.cpp src/results_cilk.cpp
+	$(CPP_CILK) -fcilkplus $(CFLAGS) $^ -o $@ $(LIBS) -lcilkrts
 
 clean:
 	$(RM) -rf $(EXE_W) $(EXE_S) $(EXE_I) $(EXE_A)  data/* dist/*.o dist/*~ src/*.o src/*~

+ 3 - 1
c++/src/config.hpp

@@ -10,6 +10,8 @@ using namespace std;
 #define MAX_CLIENTS 2048
 #define MAX_WORKERS 2048
 
-#define MAX_GENUS 50
+#define MAX_GENUS 40
+#define STACK_BOUND 10
+#define CILK_WORKERS "4"
 
 #endif

+ 1 - 1
c++/src/main-alone.cpp

@@ -8,7 +8,7 @@ using namespace std;
 int main(int argc,char** argv){
   Semigroup S;
   Results res;
-  clear_results(res);
+  res.clear();
   init_full_N(S);
   work_on(S,res);
   if(res.has_counter_example){

+ 38 - 0
c++/src/main-cilk.cpp

@@ -0,0 +1,38 @@
+#include <cilk/cilk.h>
+#include <cilk/cilk_api.h>
+
+#include <iostream>
+#include "work.hpp"
+#include "results_cilk.hpp"
+using namespace std;
+
+void cilk_walk(Semigroup S){
+  Semigroup temp;
+  if(S.genus<MAX_GENUS-STACK_BOUND){
+    treat(S,cilk_results.get_results());
+    auto it = generator_iter<CHILDREN>(S);
+    ind_t pos=0;
+    while (it.move_next()){
+      remove_generator(temp,S, it.get_gen(),pos++);
+      if(not cut(temp)){
+	cilk_spawn cilk_walk(temp);
+      }
+    }
+    //cilk_sync;
+  }
+  else
+    work_on(S,cilk_results.get_results());
+}
+
+int main(){
+  __cilkrts_set_param("nworkers", CILK_WORKERS);
+  cout<<"Cilk workers : "<<__cilkrts_get_nworkers()<<endl;
+  Semigroup N;
+  init_full_N(N);
+  cilk_walk(N);
+ 
+  for (size_t g=0; g<=MAX_GENUS; g++){
+    cout << g << " : " <<cilk_results.get_results().n[g] << endl;
+  }
+  return 0;
+};

+ 2 - 2
c++/src/main-server.cpp

@@ -38,7 +38,7 @@ void  init_parallelize(list<Semigroup>& forest,Results& res){
 
 int main(int argc,char** argv){
   Results res;
-  clear_results(res);
+  res.clear();
   list<Semigroup> forest;
   init_parallelize(forest,res);
   // Set tasks
@@ -85,7 +85,7 @@ int main(int argc,char** argv){
   for(size_t i=0;i<nb_tasks;++i){
     if(tasks[i].get_statut()==Task::Done){
       GTaskOutput& output=*((GTaskOutput*)tasks[i].get_output());
-      add_results(res,output.res);
+      res.add(output.res);
       if(res.has_counter_example){
 	cout<<"A counter example was found : "<<endl;
 	print_Semigroup_gen(res.S_counter_example);

+ 1 - 0
c++/src/main-worker.cpp

@@ -31,6 +31,7 @@ int main(int argc,char** argv){
     //cout<<"S is "<<endl;
     //print_Semigroup(S);
     GTaskOutput output;
+    output.res.clear();
     work_on(S,output.res);
     //test_conjecture(offset,output);
     task.set_output((char*)&output,sizeof(output));

+ 18 - 10
c++/src/results.hpp

@@ -1,30 +1,38 @@
 #ifndef RESULTS_HPP
 #define RESULTS_HPP
 
+#include <iostream>
 #include "semigroup.hpp"
 
-struct Results{
+using namespace std;
+
+class Results{
+public:
   size_t n[MAX_GENUS+1];
   bool has_counter_example;
   Semigroup S_counter_example;
+
+  void clear();
+  void add(const Results& res);
 };
 
-void clear_results(Results& R);
-void add_results(Results& Rdest,const Results& Rsrc);
 
-inline void clear_results(Results& R){
-  R.has_counter_example=false;
+inline
+void Results::clear(){
+  has_counter_example=false;
   for(size_t g=0;g<=MAX_GENUS;++g){
-    R.n[g]=0;
+    n[g]=0;
   }
 }
 
-inline void add_results(Results& Rdest,const Results& Rsrc){
-  if((not Rdest.has_counter_example) and Rsrc.has_counter_example){
-    Rdest.S_counter_example=Rsrc.S_counter_example;
+inline
+void Results::add(const Results& res){
+  if((not has_counter_example) and res.has_counter_example){
+    S_counter_example=res.S_counter_example;
   }
   for(size_t g=0;g<=MAX_GENUS;++g){
-    Rdest.n[g]+=Rsrc.n[g];
+    n[g]+=res.n[g];
   }
 }
+
 #endif

+ 3 - 0
c++/src/results_cilk.cpp

@@ -0,0 +1,3 @@
+#include "results_cilk.hpp"
+
+ResultsReducer cilk_results;

+ 49 - 0
c++/src/results_cilk.hpp

@@ -0,0 +1,49 @@
+#ifndef RESULTS_CILK
+#define RESULTS_CILK
+
+#include <cilk/cilk.h>
+#include <cilk/reducer.h>
+
+#include "results.hpp"
+
+class ResultsReducer{
+private:
+  struct Monoid:cilk::monoid_base<Results>{
+    static void reduce(Results* left,Results* right);
+  };
+
+  cilk::reducer<Monoid> imp_;
+public:
+  ResultsReducer();
+  size_t& n(size_t g);
+  void reset();
+  Results& get_results();
+};
+
+extern ResultsReducer cilk_results;
+
+inline
+ResultsReducer::ResultsReducer():imp_(){
+}
+inline void
+ResultsReducer::reset(){
+  imp_.view().clear();
+}
+
+inline void
+ResultsReducer::Monoid::reduce(Results* left,Results* right){
+  left->add(*right);
+}
+
+
+inline size_t&
+ResultsReducer::n(size_t g){
+  return imp_.view().n[g];
+}
+
+inline Results&
+ResultsReducer::get_results(){
+  return imp_.view();
+}
+#endif
+

+ 0 - 1
c++/src/semigroup.hpp

@@ -46,7 +46,6 @@ inline void remove_generator(Semigroup &__restrict__ dst,
 			     ind_t gen,ind_t pos);
 inline Semigroup remove_generator(const Semigroup &src, ind_t gen,ind_t pos);
 
-
 // typedef enum { ALL, CHILDREN } generator_type;
 class ALL {};
 class CHILDREN {};

+ 1 - 0
c++/src/treat.hpp

@@ -6,6 +6,7 @@
 void treat(const Semigroup& S,Results& res);
   
 inline void treat(const Semigroup& S,Results& res){
+  //cout<<&res<<endl;
   res.n[S.genus]++;
 }
 

+ 1 - 2
c++/src/work.hpp

@@ -8,8 +8,7 @@ using namespace std;
 
 void work_on(Semigroup& S,Results& res){
   Stack stack;
-  clear_results(res);
-  if(not cut(S)){
+   if(not cut(S)){
     treat(S,res);
     Semigroup* root=stack.pushed();
     *root=S;