Jean Fromentin il y a 10 mois
commit
b0163966ce
19 fichiers modifiés avec 923 ajouts et 0 suppressions
  1. BIN
      perf.data
  2. 44 0
      run.py
  3. 11 0
      run_all.sh
  4. 24 0
      src/Makefile
  5. 17 0
      src/config.hpp
  6. 14 0
      src/init_files.cpp
  7. 93 0
      src/main.cpp
  8. 61 0
      src/results.hpp
  9. 27 0
      src/run_walk.cpp
  10. 142 0
      src/semigroup.cpp
  11. 152 0
      src/semigroup.hpp
  12. 15 0
      src/show_res.cpp
  13. 144 0
      src/simd.hpp
  14. 27 0
      src/stack.cpp
  15. 43 0
      src/stack.hpp
  16. 15 0
      src/treat.hpp
  17. 22 0
      src/trim.hpp
  18. 60 0
      src/walk.cpp
  19. 12 0
      src/walk.hpp

BIN
perf.data


+ 44 - 0
run.py

@@ -0,0 +1,44 @@
+import os
+import sys
+
+def make(gmax):
+    os.chdir("src")
+    os.system("make clean > /dev/null")
+    os.system("make GMAX="+repr(gmax)+" > /dev/null")
+    os.chdir("../")
+
+def init():
+    os.system("./init_files > /dev/null")
+    todo=os.listdir("todo")
+    print("There is",len(todo),"files to treat");
+
+def filter():
+    todo=os.listdir("todo")
+    print("=> Filter <=")
+    print("in :",len(todo))
+    todo_flat=' '.join(todo)
+    cmd="parallel ./run_walk ::: "+todo_flat+" ::: 1 > /dev/null"
+    os.system(cmd)
+    todo2=os.listdir("todo")
+    rem=set(todo).intersection(todo2)
+    print("rem :",len(rem))
+    print("done :",len(todo)-len(rem))
+    print("new :",len(todo2)-len(rem))
+
+def run():
+    
+if __name__=="__main__":
+    if(len(sys.argv)!=2):
+        print("Argument error")
+        exit(-1)
+    gmax=int(sys.argv[1])
+    print("gmax =",gmax)
+    make(gmax)
+    init()
+    filter()
+
+    #run(timeout)
+    
+    
+    
+    

+ 11 - 0
run_all.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+
+cd input
+inputs=`ls *`
+cd ..
+
+for i in $inputs
+do
+    ./run_walk $i
+done
+	     

+ 24 - 0
src/Makefile

@@ -0,0 +1,24 @@
+DEFAULT_GMAX = 40
+GMAX = $(DEFAULT_GMAX)
+CPP = g++ -DGMAX=$(GMAX) -g -mavx2 -march=native -mtune=corei7 -O3
+
+all: ../init_files ../run_walk ../show_res
+
+%.o:%.cpp %.hpp
+	$(CPP) -c $< -o $@
+
+../init_files: semigroup.o init_files.cpp 
+	$(CPP) $^ -o $@
+
+../run_walk: semigroup.o stack.o walk.o run_walk.cpp 
+	$(CPP) $^ -o $@
+
+../show_res: semigroup.o show_res.cpp 
+	$(CPP) $^ -o $@	
+
+clean:
+	$(RM) ../init_files ../run_walk ../show_res
+	$(RM) *.o
+	$(RM) ../todo/* ../lock/* ../done/* ../output/* ../counter_example/*
+	$(RM) *~
+	$(RM) vgcore*

+ 17 - 0
src/config.hpp

@@ -0,0 +1,17 @@
+#ifndef CONFIG_HPP
+#define CONFIG_HPP
+
+#include <iostream>
+
+using namespace std;
+
+//#ifndef GMAX
+static const size_t g_max=60;
+//#else
+//static const size_t g_max=GMAX;
+//#endif
+
+//static const double min_cost_to_split=20;
+//static const double min_cost_to_consider=10;
+
+#endif

+ 14 - 0
src/init_files.cpp

@@ -0,0 +1,14 @@
+#include "walk.hpp"
+
+int main(){
+  cout<<"****************************************"<<endl;
+  cout<<"* Create files for ordinary semigroups *"<<endl;
+  cout<<"****************************************"<<endl;
+  Semigroup O;
+  O.init_N();
+  int m=1;
+  do{
+    O.to_file("todo/"+to_string(m));
+      O.son(O,m++,0);
+  }while(O.g<g_max);
+}

+ 93 - 0
src/main.cpp

@@ -0,0 +1,93 @@
+#include <sstream>
+#include <fstream>
+#include <list>
+#include <deque>
+#include <cmath>
+#include <vector>
+#include "walk.hpp"
+struct{
+  bool operator()(const Semigroup& l, const Semigroup& r) const { return l.cost > r.cost; }
+} customLess;
+
+void compute_cost(Semigroup& S){
+  if(S.g>=g_max-10) S.cost=0;
+  else{
+    Stack stack;
+    stack.next()->copy(S);
+    stack.push();
+    Results results;
+    results.clear();
+    walk(stack,results,min(g_max,S.g+4));
+    double r=pow((double)results.n,0.25);
+    S.cost=pow(r,log(double(g_max-S.g)));
+  }
+}
+
+bool must_split(const Semigroup& S){
+  return (S.g<g_max) and ((S.left<4 and S.cost>=min_cost_to_split and true) or (S.left==1));
+}
+
+void split(const Semigroup& S,deque<Semigroup>& to_explore){
+  list<Semigroup> res; 
+  auto it=SonIterator(&S);
+  size_t irr_pos=0;
+  while(it.move_next()){
+    Semigroup& son=to_explore.emplace_back();
+    son.son(S,it.get_gen(),irr_pos++);
+  }
+}
+
+void set_tasks(vector<Semigroup>& tasks){
+  deque<Semigroup> to_explore;
+  Semigroup& root=to_explore.emplace_back();
+  root.init_N();
+  while(not to_explore.empty()){
+    Semigroup S=to_explore.front();
+    compute_cost(S);
+    //cout<<S.cost<<endl;
+    to_explore.pop_front();
+    if(must_split(S)){
+      split(S,to_explore);
+    }
+    else{
+      tasks.push_back(S);
+    }       
+  }
+}
+
+using namespace std;
+int main(){
+  cout<<"g_max = "<<g_max<<endl;
+
+  vector<Semigroup> tasks;
+  set_tasks(tasks);
+  size_t nb_tasks=tasks.size();
+  cout<<"Number of tasks : "<<nb_tasks<<endl;
+
+  
+  Results results;
+  results.clear();
+  Stack stack;
+  size_t temp=0;
+  for(size_t i=0;i<nb_tasks;++i){
+    results.clear();
+    Semigroup& S=tasks[i];
+    treat(S,results);
+    //stack.next()->copy(S);
+    //stack.push();
+    //walk(stack,results);
+    if(S.cost>=10) ++temp;
+    /*if(S.g < g_max-10 and results.n>=10){
+      cout<<S.cost<<" "<<results.n<<endl;
+      }*/
+  }
+  cout<<temp<<endl;
+
+  /*size_t m_max=0;
+  for(int m=0;m<=g_max;++m){
+    cout<<m<<" "<<results.n2[m]<<endl;
+    }*/
+
+  
+			  
+}

+ 61 - 0
src/results.hpp

@@ -0,0 +1,61 @@
+#ifndef RESULTS_HPP
+#define RESULTS_HPP
+
+#include <iostream>
+#include "semigroup.hpp"
+
+
+using namespace std;
+
+class Results{
+public:
+  
+ 
+  size_t ng[g_max+1];
+  bool has_counter_example;
+  Semigroup S_counter_example;
+  void clear();
+  void add(const Results& res);
+  void to_file(string filename) const;
+  void from_file(string filename);
+
+};
+
+
+inline
+void Results::clear(){
+  has_counter_example=false;
+  for(size_t g=0;g<=g_max;++g){
+    ng[g]=0;
+  }
+}
+
+inline
+void Results::add(const Results& res){
+  if((not has_counter_example) and res.has_counter_example){
+    S_counter_example=res.S_counter_example;
+    has_counter_example=true;
+  }
+  for(size_t g=0;g<=g_max;++g){
+    ng[g]+=res.ng[g];
+  }
+}
+
+inline
+void Results::to_file(string filename) const{
+  fstream file;
+  file.open((filename).c_str(),ios::out|ios::binary|ios::trunc);
+  file.write((char*)ng,sizeof(size_t)*(g_max+1));
+  file.close();
+}
+
+
+inline
+void Results::from_file(string filename){
+  fstream file;
+  file.open((filename).c_str(),ios::in|ios::binary);
+  file.read((char*)ng,sizeof(size_t)*(g_max+1));
+  file.close();
+}
+
+#endif

+ 27 - 0
src/run_walk.cpp

@@ -0,0 +1,27 @@
+
+#include "walk.hpp"
+
+int main(int argc,char* argv[]){
+  if(argc!=3){
+    cerr<<"[run_walk] Argument error."<<endl;
+    exit(-1);
+  }
+  string filename=argv[1];
+  int timeout=stoi(argv[2]);
+  cout<<"Input filename : "<<filename<<endl;
+  cout<<"Timeout : "<<timeout<<" seconds"<<endl;
+  Stack stack;
+  Semigroup* S=stack.next();
+  rename(("todo/"+filename).c_str(),("lock/"+filename).c_str());
+  S->from_file("lock/"+filename);
+  stack.push();
+  Results results;
+  results.clear();
+  walk(stack,results,filename,timeout);
+  if(results.has_counter_example){
+    cout<<"*******************"<<endl;
+    cout<<"* Counter example *"<<endl;
+    cout<<"*******************"<<endl;
+    results.S_counter_example.display();
+  }
+}

+ 142 - 0
src/semigroup.cpp

@@ -0,0 +1,142 @@
+#include "semigroup.hpp"
+
+void
+Semigroup::init_N(){
+  c=1;
+  g=0;
+  m=1;
+  e=1;
+  e_left=0;
+  left=1;
+  for(size_t x=0;x<size;++x){
+    delta[x]=1+x/2;
+  }
+  for(size_t x=0;x<nin;++x){
+    in64[x]=18446744073709551615UL;
+  }
+}
+
+void
+Semigroup::son(const Semigroup& S,size_t  x,size_t pos){
+  c=x+1;
+  g=S.g+1;
+  int e_delta;
+  if(x>S.m){
+    m=S.m;
+    e_delta=(S.delta[x+S.m]==2)?0:-1;
+  }
+  else{
+    m=S.m+1;
+    e_delta=1;
+  }
+  e=S.e+e_delta;
+  e_left=S.e_left+pos;
+  left=S.left+x-S.c;
+  copy_delta(S);
+  copy_in(S);
+
+  size_t sx=x%32;
+  size_t bz=0;
+  v8x8 z;
+  z.v64=0;
+  epu64 w;
+ 
+  for(size_t bx=x/32;bx<navx;++bx){
+    uint64_t temp=in32[bz];
+    z.v64+=(temp<<sx);
+    w.data[0]=load_mask[z.v8[0]];
+    w.data[1]=load_mask[z.v8[1]];
+    w.data[2]=load_mask[z.v8[2]];
+    w.data[3]=load_mask[z.v8[3]];
+    
+    avx[bx]=_mm256_sub_epi8(avx[bx],w.avx);
+    z.v32[0]=z.v32[1];
+    z.v32[1]=0;
+    ++bz;       
+  }
+
+  in64[x/64]^=(1UL<<(x%64));  
+}
+
+void
+Semigroup::display() const{
+  bool flag=false;
+  cout<<'<';
+  for(size_t x=1;x<size;++x){
+    if(delta[x]==1){
+      if(flag) cout<<',';
+      flag=true;
+      cout<<x;
+    }
+  }
+  cout<<"> m = "<<m<<" g = "<<g<<" c = "<<c<<endl;;
+  /*for(size_t x=0;x<80;++x){
+    if(x<10) cout<<' ';
+    cout<<(int)x<<'|';
+  }
+  cout<<endl;
+  for(size_t x=0;x<80;++x){
+    cout<<"--|";
+  }
+  cout<<endl;
+  for(size_t x=0;x<80;++x){
+    if(delta[x]<10) cout<<' ';
+    cout<<(int)delta[x]<<'|';
+  }
+  cout<<endl;
+  for(uint64_t x=0;x<80;++x){
+    //    cout<<x<<" "<<x/64<<" and "<<(1UL<<(x%64))<<endl;
+    if((in64[x/64U]&(1UL<<(x%(64))))==0){
+      cout<<" n|";
+    }
+    else{
+      cout<<" y|";
+    }
+  }
+  cout<<endl;*/
+  
+}
+
+void
+Semigroup::copy(const Semigroup& S){
+  c=S.c;
+  m=S.m;
+  g=S.g;
+  e=S.e;
+  e_left=S.e_left;
+  left=S.left;
+  copy_delta(S);
+  copy_in(S);
+  
+}
+
+void
+Semigroup::to_file(string filename) const{
+  fstream file;
+  file.open(filename.c_str(),ios::out|ios::binary|ios::trunc);
+  file.write((char*)delta,size);
+  file.write((char*)in64,nin*8);
+  file.write((char*)&c,sizeof(size_t));
+  file.write((char*)&m,sizeof(size_t));
+  file.write((char*)&g,sizeof(size_t));
+  file.write((char*)&e,sizeof(size_t));
+  file.write((char*)&e_left,sizeof(size_t));
+  file.write((char*)&left,sizeof(size_t));
+  file.close();
+}
+			 
+void
+Semigroup::from_file(string filename){
+  fstream file;
+  file.open(filename.c_str(),ios::in|ios::binary);
+  file.read((char*)delta,size);
+  file.read((char*)in64,nin*8);
+  file.read((char*)&c,sizeof(size_t));
+  file.read((char*)&m,sizeof(size_t));
+  file.read((char*)&g,sizeof(size_t));
+  file.read((char*)&e,sizeof(size_t));
+  file.read((char*)&e_left,sizeof(size_t));
+  file.read((char*)&left,sizeof(size_t));
+  file.close();
+}
+			 

+ 152 - 0
src/semigroup.hpp

@@ -0,0 +1,152 @@
+#ifndef SEMIGROUP_HPP
+#define SEMIGROUP_HPP
+
+
+#include <cstring>
+#include <cstdint>
+#include <cassert>
+#include <immintrin.h>
+#include <fstream>
+
+#include "config.hpp"
+#include "simd.hpp"
+
+union v8x8{
+  uint64_t v64;
+  uint32_t v32[2];
+  uint8_t v8[8];
+};
+  static const size_t m1_32=((1UL<<32)-1);
+class Semigroup{
+public:
+  static const size_t _size=3*(g_max-1);
+  static const size_t navx=((_size+31)/32);
+  static const size_t nin=((_size+63)/64);
+  static const size_t size=navx*32;
+
+  union{
+    __m256i avx[navx];
+    uint8_t delta[size];
+  };
+  union{
+    uint64_t in64[nin];
+    uint32_t in32[2*nin];
+  };    
+  size_t c,m,g,e,e_left,left;
+
+  Semigroup();
+  void init_N();
+  void copy_delta(const Semigroup& S);
+  void copy_in(const Semigroup& S);
+  
+  void son(const Semigroup& S,size_t x,size_t pos);
+  void display() const;
+  void copy(const Semigroup& S);
+  ~Semigroup();
+  void to_file(string filename) const;
+  void from_file(string filename);
+};
+
+class SonIterator{
+public:
+  const Semigroup *S;
+  size_t  mask;   // movemask_epi8 returns a 32 bits values
+  size_t iblock, gen, bound;
+public:
+  SonIterator(const Semigroup *S);
+  bool move_next();
+  uint8_t count();
+  inline size_t get_gen() const {return gen;};
+};
+
+inline SonIterator::SonIterator(const Semigroup* _S)
+  : S(_S), bound(min(Semigroup::navx-1,(_S->c+_S->m+31) >> 5)){
+  iblock = S->c >> 5;
+  size_t imask = (S->c&0x1F);
+  __m256i a=S->avx[iblock];
+  __m256i b=mask32[imask];
+  __m256i block = _mm256_and_si256(a,b);
+  mask  =  _mm256_movemask_epi8(_mm256_cmpeq_epi8(block,avx1))&m1_32;
+  gen = (iblock << 5) - 1;
+};
+
+inline bool
+SonIterator::move_next(){
+  while (not mask){
+    iblock++;
+    if (iblock > bound) return false;
+    gen = (iblock << 5) - 1;
+    mask  = _mm256_movemask_epi8(_mm256_cmpeq_epi8(S->avx[iblock],avx1))&m1_32;
+  }
+  //unsigned char shift = __bsfq (mask) +1;
+   uint64_t shift;
+  asm("bsfq %1,%0" : "=r" (shift)  :"r" (mask));
+  ++shift;
+
+  gen += shift;
+  mask >>= shift;
+  return true;
+};
+
+inline
+Semigroup::Semigroup(){
+ 
+  
+}
+
+#define copy_delta_unroll(i) case (i): \
+  avx[(i-1)]=S.avx[(i-1)];
+
+inline void 
+Semigroup::copy_delta(const Semigroup& S){
+  switch(navx){
+    copy_delta_unroll(16);
+    copy_delta_unroll(15);
+    copy_delta_unroll(14);
+    copy_delta_unroll(13);
+    copy_delta_unroll(12);
+    copy_delta_unroll(11);
+    copy_delta_unroll(10);
+    copy_delta_unroll(9);
+    copy_delta_unroll(8);
+    copy_delta_unroll(7);
+    copy_delta_unroll(6);
+    copy_delta_unroll(5);
+    copy_delta_unroll(4);
+    copy_delta_unroll(3);
+    copy_delta_unroll(2);
+  case 1:
+    avx[0]=S.avx[0];
+    break;
+  default:
+    assert(false);
+  };
+}
+
+#define copy_in_unroll(i) case (i): \
+  in64[(i-1)]=S.in64[(i-1)];
+
+inline void 
+Semigroup::copy_in(const Semigroup& S){
+  switch(nin){
+    copy_in_unroll(8);
+    copy_in_unroll(7);
+    copy_in_unroll(6);
+    copy_in_unroll(5);
+    copy_in_unroll(4);
+    copy_in_unroll(3);
+    copy_in_unroll(2);
+  case 1:
+    in64[0]=S.in64[0];
+    break;
+  default:
+    assert(false);
+    break;
+  };
+}
+
+inline
+Semigroup::~Semigroup(){
+}
+
+#endif

+ 15 - 0
src/show_res.cpp

@@ -0,0 +1,15 @@
+#include "results.hpp"
+
+int main(int argc,char* argv[]){
+  if(argc!=2){
+    cerr<<"[show_res] Argument error"<<endl;
+    exit(-1);
+  }
+  Results results;
+  results.from_file(argv[1]);
+
+  for(size_t g=0;g<=g_max;++g){
+    cout<<g<<"\t"<<results.ng[g]<<endl;
+  }
+  exit(0);
+}

Fichier diff supprimé car celui-ci est trop grand
+ 144 - 0
src/simd.hpp


+ 27 - 0
src/stack.cpp

@@ -0,0 +1,27 @@
+#include "stack.hpp"
+
+Stack::Stack(){
+  data=new Semigroup*[capacity];
+  for(size_t i=0;i<capacity;++i){
+    data[i]=new Semigroup;
+  }
+  size=0;
+}
+
+
+Stack::~Stack(){
+  for(size_t i=0;i<capacity;++i){
+    delete data[i];
+  }
+  delete[] data;
+}
+
+void
+Stack::display(){
+  cout<<"---- Stack -----"<<endl;
+  for(size_t i=0;i<size;++i){
+    cout<<i<<"\t"<<data[i]<<endl;
+  }
+  cout<<"next \t"<<data[size]<<endl;
+  cout<<"----------------"<<endl;
+}

+ 43 - 0
src/stack.hpp

@@ -0,0 +1,43 @@
+#ifndef STACK_HPP
+#define STACK_HPP
+
+#include "semigroup.hpp"
+
+class Stack{
+public:
+  static const size_t capacity=g_max*(g_max+1)/2;
+  size_t size;
+  Semigroup** data;
+  Stack();
+  void pop(Semigroup** S);
+  void push();
+  Semigroup* next();
+  bool is_empty();
+  void display();
+  ~Stack();
+};
+
+inline void
+Stack::push(){
+  size++;
+}
+
+inline Semigroup*
+Stack::next(){
+  return data[size];
+}
+
+
+inline void
+Stack::pop(Semigroup** S){
+  swap(*S,data[--size]);
+}
+
+inline bool
+Stack::is_empty(){
+  return size==0;
+}
+
+
+
+#endif

+ 15 - 0
src/treat.hpp

@@ -0,0 +1,15 @@
+#ifndef TREAT_HPP
+#define TREAT_HPP
+
+#include "results.hpp"
+
+void treat(const Semigroup& S,Results &results);
+
+inline
+void treat(const Semigroup& S,Results &results){
+  assert(S.g<=g_max);
+  results.ng[S.g]++;
+}
+
+
+#endif

+ 22 - 0
src/trim.hpp

@@ -0,0 +1,22 @@
+#ifndef TRIM_HPP
+#define TRIM_HPP
+
+static const size_t k=3;
+
+inline bool
+trim_wilf1(Semigroup& S){
+
+  return k*S.e_left>=S.m;
+}
+
+inline bool
+trim_wilf2(Semigroup& S){
+  return (k*S.e)>=S.m+k*(g_max-S.g);
+}
+
+inline bool
+trim(Semigroup& S){
+  return S.m==S.c;// or trim_wilf1(S) or trim_wilf2(S);
+}
+
+#endif

+ 60 - 0
src/walk.cpp

@@ -0,0 +1,60 @@
+#include "walk.hpp"
+
+void walk(Stack& stack,Results &results,string filename,int timeout){
+  const auto start = time(nullptr);
+  size_t numbers=0;
+  Semigroup* father=new Semigroup;
+  while(not stack.is_empty()){
+    ++numbers;
+    if(numbers%10000000==0){
+      const auto now = time(nullptr);
+      auto duration=now-start;
+      if(duration>timeout){
+	cout<<"Timeout"<<endl;
+	cout<<"Stack size : "<<stack.size<<endl;
+	if(timeout>60){
+	  for(size_t i=0;i<stack.size;++i){
+	    cout<<i<<" : ";
+	    string filename2=filename+"_"+to_string(i);
+	    cout<<filename2<<endl;
+	    stack.data[i]->to_file("todo/"+filename2);
+	  }
+	  results.to_file("output/"+filename);
+	  if(results.has_counter_example){
+	    results.S_counter_example.to_file("counter_example/"+filename);
+	  }
+	  rename(("lock/"+filename).c_str(),("done/"+filename).c_str());
+	}
+	else{
+	  rename(("lock/"+filename).c_str(),("todo/"+filename).c_str());
+	}
+	return;
+      }
+    }
+    stack.pop(&father);
+    auto it=SonIterator(father);
+    size_t irr_pos=0;
+    size_t g=father->g;
+    if(g<g_max-1){
+      while(it.move_next()){
+	Semigroup* son=stack.next();
+	son->son(*father,it.get_gen(),irr_pos++);
+	if(not trim(*son)){
+	  stack.push();
+	  treat(*son,results);
+	}
+      }
+    }
+    else{
+      while(it.move_next()){
+	Semigroup* son=stack.next();
+	son->son(*father,it.get_gen(),irr_pos++);
+	if(not trim(*son)){
+	  treat(*son,results);
+	}
+	
+      }
+    }     
+  }
+  delete father;
+}

+ 12 - 0
src/walk.hpp

@@ -0,0 +1,12 @@
+#ifndef WALK_HPP
+#define WALK_HPP
+
+#include <time.h>
+#include "stack.hpp"
+#include "trim.hpp"
+#include "treat.hpp"
+#include "results.hpp"
+
+void walk(Stack& stack,Results &results,string filename,int timeout);
+
+#endif