From 6ade4ef8100c03df1479666a52182c3efbdb9884 Mon Sep 17 00:00:00 2001 From: Stefan Brass <stefan.brass@informatik.uni-halle.de> Date: Tue, 25 Sep 2018 11:08:48 +0200 Subject: [PATCH] Neue Job-Klasse fuer parallele Ausfuehrung --- opt/opt.cpp | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 3 deletions(-) diff --git a/opt/opt.cpp b/opt/opt.cpp index c0a0351..c8ebab3 100755 --- a/opt/opt.cpp +++ b/opt/opt.cpp @@ -26,6 +26,13 @@ // #define DO_CHECKS 0 #define DO_CHECKS 1 +//============================================================================= +// How many parallel jobs? +//============================================================================= + +#define NUM_JOBS 2 + + //============================================================================= // Type for Large Integers (64 Bit): //============================================================================= @@ -1162,6 +1169,165 @@ int optimize_simple(par_t best_par, sys_t sys, return best_hits; } +//============================================================================= +// Class for Optimization Job (Can be executed in a thread): +//============================================================================= + +class job_c { + + public: + + //--------------------------------------------------------------------- + // Default Constructor (needed to declare array of jobs): + //--------------------------------------------------------------------- + + job_c() : + MinPar(), MaxPar(), IncPar(), BestPar() + { + Sys = nullptr; + JobNo = 0; + BestHits = -1; + } + + //--------------------------------------------------------------------- + // This does the real initialization: + //--------------------------------------------------------------------- + + void init(sys_t job_sys, const par_c& job_min_par, + const par_c& job_max_par, const par_c& job_inc_par, + int split_dimen, int split_jobs, int job_no) + { + // Store given data: + Sys = job_sys; + MinPar = job_min_par; + MaxPar = job_max_par; + IncPar = job_inc_par; + JobNo = job_no; + BestHits = -1; + + // Check splitting parameters: +#if DO_CHECK + if(split_jobs < 1) { + std::cerr << "Invalid number of jobs: " << + split_jobs << "\n"; + exit(6); + } + if(job_no < 0 || job_no >= split_jobs) { + std::cerr << "Invalid job no: " << job_no << "\n"; + exit(6); + } +#endif + + // Split parameter range in given dimension (for parallel exec): + if(split_dimen == par_c::DIMEN_NULL || split_jobs <= 1) + return; + long min = MinPar.get(split_dimen); + long max = MaxPar.get(split_dimen); + long inc = IncPar.get(split_dimen); + long diff = max - min; + long steps = IDIV_CEILING((diff+1), inc); + if(steps < split_jobs) { + std::cerr << split_jobs << " jobs requested, " << + "but only " << steps << " steps " << + "in dimension " << split_dimen << ".\n"; + exit(7); + } + long steps_per_job = steps / split_jobs; + MinPar.set(split_dimen, min + job_no * steps_per_job * inc); + MaxPar.set(split_dimen, + min + (job_no+1) * steps_per_job * inc - 1); + if(job_no == split_jobs - 1) + MaxPar.set(split_dimen, max); +std::cout << "Job " << JobNo << ": Min= " << MinPar.get(split_dimen) << + ", Max = " << MaxPar.get(split_dimen) << "\n"; + } + + //--------------------------------------------------------------------- + // Do Optimization (without relative optimization): + //--------------------------------------------------------------------- + + int optimize_simple() + { + int max_hits = 0; + + // Compute total number of steps: + bigint_t total_steps = 1; + for(int d = par_c::DIMEN_FIRST; d <= par_c::DIMEN_LAST; d++) { + long diff = MaxPar.get(d) - MinPar.get(d); + total_steps *= IDIV_CEILING((diff+1), IncPar.get(d)); + } + +std::cout << "Job: " << JobNo << "\n"; +std::cout << "Min: "; MinPar.print_short(); +std::cout << "Max: "; MaxPar.print_short(); +std::cout << "Inc: "; IncPar.print_short(); +std::cout << "Steps: " << total_steps << std::endl; + + // For output of progress: + bigint_t one_percent = IDIV_CEILING(total_steps, 100); + bigint_t countdown = 1; + int pct = 0; + + // Optimization: + par_c par = MinPar; + while(1) { + // Print control output: + if(--countdown <= 0) { + std::cout << "[Job: " << JobNo << ", done: " << + pct << "%]" << std::endl; + countdown = one_percent; + pct++; + } + + //par.print_short(); + + int hits = check_formula(&par, Sys); + if(hits > max_hits) { + BestPar = par; + max_hits = hits; + } + + // Determine next parameter value: + int dimen = par_c::DIMEN_LAST; + while(dimen >= par_c::DIMEN_FIRST) { + par.add(dimen, IncPar.get(dimen)); + if(par.get(dimen) <= MaxPar.get(dimen)) + break; + par.set(dimen, MinPar.get(dimen)); + dimen--; + + } + if(dimen < par_c::DIMEN_FIRST) + break; + } + + BestHits = max_hits; + return max_hits; + } + + //--------------------------------------------------------------------- + // Attribute Accessor Functions: + //--------------------------------------------------------------------- + + inline const par_c *best_par() const { return &BestPar; } + + inline int best_hits() const { return BestHits; } + + //--------------------------------------------------------------------- + // Attributes: + //--------------------------------------------------------------------- + + private: + + sys_t Sys; + par_c MinPar; + par_c MaxPar; + par_c IncPar; + par_c BestPar; + int BestHits; + int JobNo; +}; + //============================================================================= // The main Function (Does the Optimization): //============================================================================= @@ -1218,7 +1384,14 @@ int main(int argc, str_t argv[]) // Small test search: // |Startup| Load| Rule| Result|DataVal| - par_c steps( 500, 500, 1000, 1000, 500); + par_c steps( 10, 50, 100, 50, 50); + + // Very Large Search: + // |Startup| Load| Rule| Result|DataVal| + //par_c steps( 100, 500, 1000, 500, 500); + // 12.500.000.000.000 So 11 Stunden CPU-Zeit (40.000s) fuer 1-2%. + + // How many parameter tuples will be considered in total? std::cout << "Number of parameter tuples: " << steps.prod() << "\n"; std::cout << "\n"; @@ -1254,10 +1427,26 @@ int main(int argc, str_t argv[]) std::cout << "---------\n"; inc_par.print("\t"); + // Optimization Jobs: + job_c jobs[NUM_JOBS]; + for(int i = 0; i < NUM_JOBS; i++) { + jobs[i].init(sys, min_par, max_par, inc_par, + par_c::DIMEN_STARTUP, NUM_JOBS, i); + } // Do optimization: - best_hits = optimize_simple(&best_par, sys, - &min_par, &max_par, &inc_par); + //best_hits = optimize_simple(&best_par, sys, + // &min_par, &max_par, &inc_par); + for(int i = 0; i < NUM_JOBS; i++) + jobs[i].optimize_simple(); + + // Find the best solution among the job results: + best_par = *(jobs[0].best_par()); + best_hits = jobs[0].best_hits(); + for(int i = 1; i < NUM_JOBS; i++) { + if(jobs[i].best_hits() > best_hits) + best_par = *(jobs[i].best_par()); + } // Local Optimization form good starting points: // Start Load RuleApp Result -- GitLab