001/* 002 * $Id: GroebnerBaseDistributedEC.java 4964 2014-10-17 19:43:31Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.io.IOException; 009import java.util.ArrayList; 010import java.util.Collections; 011import java.util.List; 012import java.util.ListIterator; 013import java.util.concurrent.Semaphore; 014 015import org.apache.log4j.Logger; 016 017import edu.jas.poly.ExpVector; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.PolyUtil; 021import edu.jas.structure.RingElem; 022import edu.jas.util.ChannelFactory; 023import edu.jas.util.DistHashTable; 024import edu.jas.util.DistHashTableServer; 025import edu.jas.util.DistThreadPool; 026import edu.jas.util.RemoteExecutable; 027import edu.jas.util.SocketChannel; 028import edu.jas.util.Terminator; 029import edu.jas.util.ThreadPool; 030 031 032/** 033 * Groebner Base distributed algorithm. Implements a distributed memory parallel 034 * version of Groebner bases with executable channels. Using pairlist class, 035 * distributed tasks do reduction, one communication channel per task. 036 * @param <C> coefficient type 037 * @author Heinz Kredel 038 */ 039 040public class GroebnerBaseDistributedEC<C extends RingElem<C>> extends GroebnerBaseAbstract<C> { 041 042 043 private static final Logger logger = Logger.getLogger(GroebnerBaseDistributedEC.class); 044 045 046 /** 047 * Number of threads to use. 048 */ 049 protected final int threads; 050 051 052 /** 053 * Default number of threads. 054 */ 055 protected static final int DEFAULT_THREADS = 2; 056 057 058 /** 059 * Pool of threads to use. <b>Note:</b> No ComputerThreads for one node 060 * tests 061 */ 062 protected transient final ThreadPool pool; 063 064 065 /** 066 * Default server port. 067 */ 068 protected static final int DEFAULT_PORT = 55711; 069 070 071 /** 072 * Default distributed hash table server port. 073 */ 074 protected final int DHT_PORT; 075 076 077 /** 078 * Server port to use. 079 */ 080 protected final int port; 081 082 083 /** 084 * machine file to use. 085 */ 086 protected final String mfile; 087 088 089 /** 090 * Distributed thread pool to use. 091 */ 092 private final transient DistThreadPool dtp; 093 094 095 /** 096 * Distributed hash table server to use. 097 */ 098 private final transient DistHashTableServer<Integer> dhts; 099 100 101 /** 102 * Constructor. 103 * @param mfile name of the machine file. 104 */ 105 public GroebnerBaseDistributedEC(String mfile) { 106 this(mfile, DEFAULT_THREADS, DEFAULT_PORT); 107 } 108 109 110 /** 111 * Constructor. 112 * @param mfile name of the machine file. 113 * @param threads number of threads to use. 114 */ 115 public GroebnerBaseDistributedEC(String mfile, int threads) { 116 this(mfile, threads, new ThreadPool(threads), DEFAULT_PORT); 117 } 118 119 120 /** 121 * Constructor. 122 * @param mfile name of the machine file. 123 * @param threads number of threads to use. 124 * @param port server port to use. 125 */ 126 public GroebnerBaseDistributedEC(String mfile, int threads, int port) { 127 this(mfile, threads, new ThreadPool(threads), port); 128 } 129 130 131 /** 132 * Constructor. 133 * @param mfile name of the machine file. 134 * @param threads number of threads to use. 135 * @param pool ThreadPool to use. 136 * @param port server port to use. 137 */ 138 public GroebnerBaseDistributedEC(String mfile, int threads, ThreadPool pool, int port) { 139 this(mfile, threads, pool, new OrderedPairlist<C>(), port); 140 } 141 142 143 /** 144 * Constructor. 145 * @param mfile name of the machine file. 146 * @param threads number of threads to use. 147 * @param pl pair selection strategy 148 * @param port server port to use. 149 */ 150 public GroebnerBaseDistributedEC(String mfile, int threads, PairList<C> pl, int port) { 151 this(mfile, threads, new ThreadPool(threads), pl, port); 152 } 153 154 155 /** 156 * Constructor. 157 * @param mfile name of the machine file. 158 * @param threads number of threads to use. 159 * @param pool ThreadPool to use. 160 * @param pl pair selection strategy 161 * @param port server port to use. 162 */ 163 public GroebnerBaseDistributedEC(String mfile, int threads, ThreadPool pool, PairList<C> pl, int port) { 164 super(new ReductionPar<C>(), pl); 165 this.threads = threads; 166 if (mfile == null || mfile.length() == 0) { 167 this.mfile = "../util/machines"; // contains localhost 168 } else { 169 this.mfile = mfile; 170 } 171 if (threads < 1) { 172 threads = 1; 173 } 174 if (pool == null) { 175 pool = new ThreadPool(threads); 176 } 177 this.pool = pool; 178 this.port = port; 179 logger.info("machine file " + mfile + ", port = " + port); 180 this.dtp = new DistThreadPool(this.threads, this.mfile); 181 logger.info("running " + dtp); 182 this.DHT_PORT = this.dtp.getEC().getMasterPort() + 100; 183 this.dhts = new DistHashTableServer<Integer>(this.DHT_PORT); 184 this.dhts.init(); 185 logger.info("running " + dhts); 186 } 187 188 189 /** 190 * Cleanup and terminate ThreadPool. 191 */ 192 @Override 193 public void terminate() { 194 terminate(true); 195 } 196 197 198 /** 199 * Terminates the distributed thread pools. 200 * @param shutDown true, if shut-down of the remote executable servers is 201 * requested, false, if remote executable servers stay alive. 202 */ 203 public void terminate(boolean shutDown) { 204 pool.terminate(); 205 dtp.terminate(shutDown); 206 logger.info("dhts.terminate()"); 207 dhts.terminate(); 208 } 209 210 211 /** 212 * Distributed Groebner base. 213 * @param modv number of module variables. 214 * @param F polynomial list. 215 * @return GB(F) a Groebner base of F or null, if a IOException occurs. 216 */ 217 public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) { 218 List<GenPolynomial<C>> Fp = normalizeZerosOnes(F); 219 Fp = PolyUtil.<C> monic(Fp); 220 if (Fp.size() <= 1) { 221 return Fp; 222 } 223 if (!Fp.get(0).ring.coFac.isField()) { 224 throw new IllegalArgumentException("coefficients not from a field"); 225 } 226 227 String master = dtp.getEC().getMasterHost(); 228 //int port = dtp.getEC().getMasterPort(); // wrong port 229 GBExerClient<C> gbc = new GBExerClient<C>(master, port, DHT_PORT); 230 for (int i = 0; i < threads; i++) { 231 // schedule remote clients 232 dtp.addJob(gbc); 233 } 234 // run master 235 List<GenPolynomial<C>> G = GBMaster(modv, Fp); 236 return G; 237 } 238 239 240 /** 241 * Distributed Groebner base. 242 * @param modv number of module variables. 243 * @param F non empty monic polynomial list. 244 * @return GB(F) a Groebner base of F or null, if a IOException occurs. 245 */ 246 List<GenPolynomial<C>> GBMaster(int modv, List<GenPolynomial<C>> F) { 247 ChannelFactory cf = new ChannelFactory(port); 248 cf.init(); 249 logger.info("GBMaster on " + cf); 250 251 List<GenPolynomial<C>> G = F; 252 if (G.isEmpty()) { 253 throw new IllegalArgumentException("empty polynomial list not allowed"); 254 } 255 GenPolynomialRing<C> ring = G.get(0).ring; 256 if (!ring.coFac.isField()) { 257 throw new IllegalArgumentException("coefficients not from a field"); 258 } 259 PairList<C> pairlist = strategy.create(modv, ring); 260 pairlist.put(G); 261 262 /* 263 GenPolynomial<C> p; 264 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); 265 PairList<C> pairlist = null; 266 boolean oneInGB = false; 267 int l = F.size(); 268 int unused; 269 ListIterator<GenPolynomial<C>> it = F.listIterator(); 270 while (it.hasNext()) { 271 p = it.next(); 272 if (p.length() > 0) { 273 p = p.monic(); 274 if (p.isONE()) { 275 oneInGB = true; 276 G.clear(); 277 G.add(p); 278 //return G; must signal termination to others 279 } 280 if (!oneInGB) { 281 G.add(p); 282 } 283 if (pairlist == null) { 284 //pairlist = new OrderedPairlist<C>(modv, p.ring); 285 pairlist = strategy.create(modv, p.ring); 286 if (!p.ring.coFac.isField()) { 287 throw new IllegalArgumentException("coefficients not from a field"); 288 } 289 } 290 // theList not updated here 291 if (p.isONE()) { 292 unused = pairlist.putOne(); 293 } else { 294 unused = pairlist.put(p); 295 } 296 } else { 297 l--; 298 } 299 } 300 logger.info("start " + pairlist); 301 //if (l <= 1) { 302 //return G; must signal termination to others 303 //} 304 */ 305 logger.debug("looking for clients"); 306 DistHashTable<Integer, GenPolynomial<C>> theList = new DistHashTable<Integer, GenPolynomial<C>>( 307 "localhost", DHT_PORT); 308 theList.init(); 309 List<GenPolynomial<C>> al = pairlist.getList(); 310 for (int i = 0; i < al.size(); i++) { 311 GenPolynomial<C> nn = theList.put(Integer.valueOf(i), al.get(i)); 312 if (nn != null) { 313 logger.info("double polynomials " + i + ", nn = " + nn + ", al(i) = " + al.get(i)); 314 } 315 } 316 // wait for arrival 317 while (theList.size() < al.size()) { 318 logger.info("#distributed list = " + theList.size() + " #pairlist list = " + al.size()); 319 @SuppressWarnings("unused") 320 GenPolynomial<C> nn = theList.getWait(al.size() - 1); 321 } 322 323 Terminator fin = new Terminator(threads); 324 ReducerServerEC<C> R; 325 for (int i = 0; i < threads; i++) { 326 R = new ReducerServerEC<C>(fin, cf, theList, pairlist); 327 pool.addJob(R); 328 } 329 logger.debug("main loop waiting"); 330 fin.waitDone(); 331 int ps = theList.size(); 332 logger.debug("#distributed list = " + ps); 333 // make sure all polynomials arrived: not needed in master 334 G = pairlist.getList(); 335 if (ps != G.size()) { 336 logger.warn("#distributed list = " + theList.size() + " #pairlist list = " + G.size()); 337 } 338 long time = System.currentTimeMillis(); 339 List<GenPolynomial<C>> Gp; 340 Gp = minimalGB(G); // not jet distributed but threaded 341 time = System.currentTimeMillis() - time; 342 logger.debug("parallel gbmi = " + time); 343 /* 344 time = System.currentTimeMillis(); 345 G = GroebnerBase.<C>GBmi(G); // sequential 346 time = System.currentTimeMillis() - time; 347 logger.info("sequential gbmi = " + time); 348 */ 349 G = Gp; 350 logger.debug("cf.terminate()"); 351 cf.terminate(); 352 logger.debug("theList.terminate()"); 353 theList.clear(); 354 theList.terminate(); 355 logger.info("" + pairlist); 356 return G; 357 } 358 359 360 /** 361 * GB distributed client part. 362 * @param host the server runs on. 363 * @param port the server runs. 364 * @param dhtport of the DHT server. 365 * @throws IOException 366 */ 367 public static <C extends RingElem<C>> void clientPart(String host, int port, int dhtport) 368 throws IOException { 369 ChannelFactory cf = new ChannelFactory(port + 10); // != port for localhost 370 cf.init(); 371 logger.info("clientPart connecting to " + host + ", port = " + port + ", dhtport = " + dhtport); 372 SocketChannel pairChannel = cf.getChannel(host, port); 373 374 DistHashTable<Integer, GenPolynomial<C>> theList = new DistHashTable<Integer, GenPolynomial<C>>(host, 375 dhtport); 376 theList.init(); 377 ReducerClientEC<C> R = new ReducerClientEC<C>(pairChannel, theList); 378 379 logger.info("clientPart running on " + host + ", pairChannel = " + pairChannel); 380 R.run(); 381 382 pairChannel.close(); 383 //master only: theList.clear(); 384 theList.terminate(); 385 cf.terminate(); 386 return; 387 } 388 389 390 /** 391 * Minimal ordered groebner basis. 392 * @param Fp a Groebner base. 393 * @return a reduced Groebner base of Fp. 394 */ 395 @Override 396 public List<GenPolynomial<C>> minimalGB(List<GenPolynomial<C>> Fp) { 397 GenPolynomial<C> a; 398 ArrayList<GenPolynomial<C>> G; 399 G = new ArrayList<GenPolynomial<C>>(Fp.size()); 400 ListIterator<GenPolynomial<C>> it = Fp.listIterator(); 401 while (it.hasNext()) { 402 a = it.next(); 403 if (a.length() != 0) { // always true 404 // already monic a = a.monic(); 405 G.add(a); 406 } 407 } 408 if (G.size() <= 1) { 409 return G; 410 } 411 412 ExpVector e; 413 ExpVector f; 414 GenPolynomial<C> p; 415 ArrayList<GenPolynomial<C>> F; 416 F = new ArrayList<GenPolynomial<C>>(G.size()); 417 boolean mt; 418 419 while (G.size() > 0) { 420 a = G.remove(0); 421 e = a.leadingExpVector(); 422 423 it = G.listIterator(); 424 mt = false; 425 while (it.hasNext() && !mt) { 426 p = it.next(); 427 f = p.leadingExpVector(); 428 mt = e.multipleOf(f); 429 } 430 it = F.listIterator(); 431 while (it.hasNext() && !mt) { 432 p = it.next(); 433 f = p.leadingExpVector(); 434 mt = e.multipleOf(f); 435 } 436 if (!mt) { 437 F.add(a); 438 } else { 439 // System.out.println("dropped " + a.length()); 440 } 441 } 442 G = F; 443 if (G.size() <= 1) { 444 return G; 445 } 446 Collections.reverse(G); // important for lex GB 447 448 @SuppressWarnings("cast") 449 MiReducerServerEC<C>[] mirs = (MiReducerServerEC<C>[]) new MiReducerServerEC[G.size()]; 450 int i = 0; 451 F = new ArrayList<GenPolynomial<C>>(G.size()); 452 while (G.size() > 0) { 453 a = G.remove(0); 454 // System.out.println("doing " + a.length()); 455 List<GenPolynomial<C>> R = new ArrayList<GenPolynomial<C>>(G.size() + F.size()); 456 R.addAll(G); 457 R.addAll(F); 458 mirs[i] = new MiReducerServerEC<C>(R, a); 459 pool.addJob(mirs[i]); 460 i++; 461 F.add(a); 462 } 463 G = F; 464 F = new ArrayList<GenPolynomial<C>>(G.size()); 465 for (i = 0; i < mirs.length; i++) { 466 a = mirs[i].getNF(); 467 F.add(a); 468 } 469 return F; 470 } 471 472} 473 474 475/** 476 * Distributed server reducing worker threads. 477 * @param <C> coefficient type 478 */ 479 480class ReducerServerEC<C extends RingElem<C>> implements Runnable { 481 482 483 private final Terminator pool; 484 485 486 private final ChannelFactory cf; 487 488 489 private SocketChannel pairChannel; 490 491 492 private final DistHashTable<Integer, GenPolynomial<C>> theList; 493 494 495 //private List<GenPolynomial<C>> G; 496 private final PairList<C> pairlist; 497 498 499 private static final Logger logger = Logger.getLogger(ReducerServerEC.class); 500 501 502 ReducerServerEC(Terminator fin, ChannelFactory cf, DistHashTable<Integer, GenPolynomial<C>> dl, 503 PairList<C> L) { 504 pool = fin; 505 this.cf = cf; 506 theList = dl; 507 //this.G = G; 508 pairlist = L; 509 } 510 511 512 public void run() { 513 logger.info("reducer server running with " + cf); 514 try { 515 pairChannel = cf.getChannel(); 516 } catch (InterruptedException e) { 517 logger.debug("get pair channel interrupted"); 518 e.printStackTrace(); 519 return; 520 } 521 if (logger.isDebugEnabled()) { 522 logger.debug("pairChannel = " + pairChannel); 523 } 524 Pair<C> pair; 525 //GenPolynomial<C> pi; 526 //GenPolynomial<C> pj; 527 //GenPolynomial<C> S; 528 GenPolynomial<C> H = null; 529 boolean set = false; 530 boolean goon = true; 531 int polIndex = -1; 532 int red = 0; 533 int sleeps = 0; 534 535 // while more requests 536 while (goon) { 537 // receive request 538 logger.info("receive request"); 539 Object req = null; 540 try { 541 req = pairChannel.receive(); 542 } catch (IOException e) { 543 goon = false; 544 e.printStackTrace(); 545 } catch (ClassNotFoundException e) { 546 goon = false; 547 e.printStackTrace(); 548 } 549 //logger.debug("received request, req = " + req); 550 if (req == null) { 551 goon = false; 552 break; 553 } 554 if (!(req instanceof GBTransportMessReq)) { 555 goon = false; 556 break; 557 } 558 559 // find pair 560 logger.debug("find pair"); 561 while (!pairlist.hasNext()) { // wait 562 if (!set) { 563 pool.beIdle(); 564 set = true; 565 } 566 if (!pool.hasJobs() && !pairlist.hasNext()) { 567 goon = false; 568 break; 569 } 570 try { 571 sleeps++; 572 if (sleeps % 10 == 0) { 573 logger.info("reducer is sleeping, pool = " + pool); 574 } 575 Thread.sleep(100); 576 } catch (InterruptedException e) { 577 goon = false; 578 break; 579 } 580 } 581 if (Thread.currentThread().isInterrupted()) { 582 goon = false; 583 break; 584 } 585 if (!pairlist.hasNext() && !pool.hasJobs()) { 586 goon = false; 587 break; //continue; //break? 588 } 589 if (set) { 590 set = false; 591 pool.notIdle(); 592 } 593 594 pair = pairlist.removeNext(); 595 /* 596 * send pair to client, receive H 597 */ 598 logger.debug("send pair = " + pair); 599 GBTransportMess msg = null; 600 if (pair != null) { 601 msg = new GBTransportMessPairIndex(pair); // ,pairlist.size()-1); // size-1 602 } else { 603 msg = new GBTransportMess(); // not End(); at this time 604 // goon ?= false; 605 } 606 try { 607 pairChannel.send(msg); 608 } catch (IOException e) { 609 e.printStackTrace(); 610 goon = false; 611 break; 612 } 613 logger.debug("#distributed list = " + theList.size()); 614 Object rh = null; 615 try { 616 rh = pairChannel.receive(); 617 } catch (IOException e) { 618 e.printStackTrace(); 619 goon = false; 620 break; 621 } catch (ClassNotFoundException e) { 622 e.printStackTrace(); 623 goon = false; 624 break; 625 } 626 //logger.debug("received H polynomial"); 627 if (rh == null) { 628 if (pair != null) { 629 pair.setZero(); 630 } 631 } else if (rh instanceof GBTransportMessPoly) { 632 // update pair list 633 red++; 634 H = ((GBTransportMessPoly<C>) rh).pol; 635 if (logger.isDebugEnabled()) { 636 logger.debug("H = " + H); 637 } 638 if (H == null) { 639 if (pair != null) { 640 pair.setZero(); 641 } 642 } else { 643 if (H.isZERO()) { 644 pair.setZero(); 645 } else { 646 if (H.isONE()) { 647 // pool.allIdle(); 648 polIndex = pairlist.putOne(); 649 theList.putWait(Integer.valueOf(polIndex), H); 650 goon = false; 651 break; 652 } 653 polIndex = pairlist.put(H); 654 // use putWait ? but still not all distributed 655 theList.putWait(Integer.valueOf(polIndex), H); 656 } 657 } 658 } 659 } 660 logger.info("terminated, done " + red + " reductions"); 661 662 /* 663 * send end mark to client 664 */ 665 logger.debug("send end"); 666 try { 667 pairChannel.send(new GBTransportMessEnd()); 668 } catch (IOException e) { 669 if (logger.isDebugEnabled()) { 670 e.printStackTrace(); 671 } 672 } 673 pool.beIdle(); 674 pairChannel.close(); 675 } 676 677} 678 679 680/** 681 * Distributed clients reducing worker threads. 682 */ 683 684class ReducerClientEC<C extends RingElem<C>> implements Runnable { 685 686 687 private final SocketChannel pairChannel; 688 689 690 private final DistHashTable<Integer, GenPolynomial<C>> theList; 691 692 693 private final ReductionPar<C> red; 694 695 696 private static final Logger logger = Logger.getLogger(ReducerClientEC.class); 697 698 699 ReducerClientEC(SocketChannel pc, DistHashTable<Integer, GenPolynomial<C>> dl) { 700 pairChannel = pc; 701 theList = dl; 702 red = new ReductionPar<C>(); 703 } 704 705 706 public void run() { 707 logger.debug("pairChannel = " + pairChannel + " reducer client running"); 708 Pair<C> pair = null; 709 GenPolynomial<C> pi, pj, ps; 710 GenPolynomial<C> S; 711 GenPolynomial<C> H = null; 712 //boolean set = false; 713 boolean goon = true; 714 int reduction = 0; 715 //int sleeps = 0; 716 Integer pix, pjx, psx; 717 718 while (goon) { 719 /* protocol: 720 * request pair, process pair, send result 721 */ 722 // pair = (Pair) pairlist.removeNext(); 723 Object req = new GBTransportMessReq(); 724 logger.debug("send request = " + req); 725 H = null; 726 try { 727 pairChannel.send(req); 728 } catch (IOException e) { 729 goon = false; 730 e.printStackTrace(); 731 break; 732 } 733 logger.debug("receive pair, goon = " + goon); 734 Object pp = null; 735 try { 736 pp = pairChannel.receive(); 737 } catch (IOException e) { 738 goon = false; 739 if (logger.isDebugEnabled()) { 740 e.printStackTrace(); 741 } 742 break; 743 } catch (ClassNotFoundException e) { 744 goon = false; 745 e.printStackTrace(); 746 } 747 if (logger.isDebugEnabled()) { 748 logger.debug("received pair = " + pp); 749 } 750 if (pp == null) { // should not happen 751 continue; 752 } 753 if (pp instanceof GBTransportMessEnd) { 754 goon = false; 755 continue; 756 } 757 if (pp instanceof GBTransportMessPair || pp instanceof GBTransportMessPairIndex) { 758 pi = pj = ps = null; 759 if (pp instanceof GBTransportMessPair) { // obsolete, for tests 760 GBTransportMessPair<C> tmp = (GBTransportMessPair<C>) pp; 761 pair = tmp.pair; 762 if (pair != null) { 763 pi = pair.pi; 764 pj = pair.pj; 765 //logger.debug("pair: pix = " + pair.i 766 // + ", pjx = " + pair.j); 767 } 768 } 769 if (pp instanceof GBTransportMessPairIndex) { 770 GBTransportMessPairIndex tmpi = (GBTransportMessPairIndex) pp; 771 pix = tmpi.i; 772 pjx = tmpi.j; 773 psx = tmpi.s; 774 pi = theList.getWait(pix); 775 pj = theList.getWait(pjx); 776 ps = theList.getWait(psx); 777 //logger.info("pix = " + pix + ", pjx = " + pjx + ", psx = " + psx); 778 } 779 780 if (pi != null && pj != null) { 781 S = red.SPolynomial(pi, pj); 782 //System.out.println("S = " + S); 783 if (S.isZERO()) { 784 // pair.setZero(); does not work in dist 785 } else { 786 if (logger.isDebugEnabled()) { 787 logger.debug("ht(S) = " + S.leadingExpVector()); 788 } 789 H = red.normalform(theList, S); 790 reduction++; 791 if (H.isZERO()) { 792 // pair.setZero(); does not work in dist 793 } else { 794 H = H.monic(); 795 if (logger.isInfoEnabled()) { 796 logger.info("ht(H) = " + H.leadingExpVector()); 797 } 798 } 799 } 800 } else { 801 logger.info("pi = " + pi + ", pj = " + pj + ", ps = " + ps); 802 } 803 } 804 805 // send H or must send null 806 if (logger.isDebugEnabled()) { 807 logger.debug("#distributed list = " + theList.size()); 808 logger.debug("send H polynomial = " + H); 809 } 810 try { 811 pairChannel.send(new GBTransportMessPoly<C>(H)); 812 } catch (IOException e) { 813 goon = false; 814 e.printStackTrace(); 815 } 816 } 817 logger.info("terminated, " + reduction + " reductions, " + theList.size() + " polynomials"); 818 pairChannel.close(); 819 } 820} 821 822 823/** 824 * Distributed server reducing worker threads for minimal GB Not jet distributed 825 * but threaded. 826 */ 827 828class MiReducerServerEC<C extends RingElem<C>> implements Runnable { 829 830 831 private final List<GenPolynomial<C>> G; 832 833 834 private GenPolynomial<C> H; 835 836 837 private final Semaphore done = new Semaphore(0); 838 839 840 private final Reduction<C> red; 841 842 843 private static final Logger logger = Logger.getLogger(MiReducerServerEC.class); 844 845 846 MiReducerServerEC(List<GenPolynomial<C>> G, GenPolynomial<C> p) { 847 this.G = G; 848 H = p; 849 red = new ReductionPar<C>(); 850 } 851 852 853 /** 854 * getNF. Blocks until the normal form is computed. 855 * @return the computed normal form. 856 */ 857 public GenPolynomial<C> getNF() { 858 try { 859 done.acquire(); //done.P(); 860 } catch (InterruptedException e) { 861 } 862 return H; 863 } 864 865 866 public void run() { 867 if (logger.isDebugEnabled()) { 868 logger.debug("ht(H) = " + H.leadingExpVector()); 869 } 870 H = red.normalform(G, H); //mod 871 done.release(); //done.V(); 872 if (logger.isDebugEnabled()) { 873 logger.debug("ht(H) = " + H.leadingExpVector()); 874 } 875 // H = H.monic(); 876 } 877} 878 879 880/** 881 * Distributed clients reducing worker threads for minimal GB. Not jet used. 882 */ 883 884class MiReducerClientEC<C extends RingElem<C>> implements Runnable { 885 886 887 private final List<GenPolynomial<C>> G; 888 889 890 private GenPolynomial<C> H; 891 892 893 private final Reduction<C> red; 894 895 896 private final Semaphore done = new Semaphore(0); 897 898 899 private static final Logger logger = Logger.getLogger(MiReducerClientEC.class); 900 901 902 MiReducerClientEC(List<GenPolynomial<C>> G, GenPolynomial<C> p) { 903 this.G = G; 904 H = p; 905 red = new ReductionPar<C>(); 906 } 907 908 909 /** 910 * getNF. Blocks until the normal form is computed. 911 * @return the computed normal form. 912 */ 913 public GenPolynomial<C> getNF() { 914 try { 915 done.acquire(); //done.P(); 916 } catch (InterruptedException u) { 917 Thread.currentThread().interrupt(); 918 } 919 return H; 920 } 921 922 923 public void run() { 924 if (logger.isDebugEnabled()) { 925 logger.debug("ht(S) = " + H.leadingExpVector()); 926 } 927 H = red.normalform(G, H); //mod 928 done.release(); //done.V(); 929 if (logger.isDebugEnabled()) { 930 logger.debug("ht(H) = " + H.leadingExpVector()); 931 } 932 // H = H.monic(); 933 } 934} 935 936 937/** 938 * Objects of this class are to be send to a ExecutableServer. 939 */ 940 941class GBExerClient<C extends RingElem<C>> implements RemoteExecutable { 942 943 944 String host; 945 946 947 int port; 948 949 950 int dhtport; 951 952 953 /** 954 * GBExerClient. 955 * @param host 956 * @param port 957 * @param dhtport 958 */ 959 public GBExerClient(String host, int port, int dhtport) { 960 this.host = host; 961 this.port = port; 962 this.dhtport = dhtport; 963 } 964 965 966 /** 967 * run. 968 */ 969 public void run() { 970 //System.out.println("running " + this); 971 try { 972 GroebnerBaseDistributedEC.<C> clientPart(host, port, dhtport); 973 } catch (Exception e) { 974 e.printStackTrace(); 975 } 976 } 977 978 979 /** 980 * String representation. 981 */ 982 @Override 983 public String toString() { 984 StringBuffer s = new StringBuffer("GBExerClient("); 985 s.append("host=" + host); 986 s.append(", port=" + port); 987 s.append(", dhtport=" + dhtport); 988 s.append(")"); 989 return s.toString(); 990 } 991 992}