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