/** Main method. */ public void run() { logger.debug("reducer server running: "); // + rank); // try { // pairChannel = new MPIChannel(engine, rank); // } catch (IOException e) { // e.printStackTrace(); // return; // } catch (MPIException e) { // e.printStackTrace(); // return; // } if (logger.isInfoEnabled()) { logger.info("reducer server running: pairChannel = " + pairChannel); } Pair<C> pair; GenPolynomial<C> H = null; boolean set = false; boolean goon = true; int polIndex = -1; int red = 0; int sleeps = 0; // while more requests while (goon) { // receive request logger.debug("receive request"); Object req = null; try { req = pairChannel.receive(); } catch (IOException e) { goon = false; e.printStackTrace(); } catch (MPIException e) { goon = false; e.printStackTrace(); } catch (ClassNotFoundException e) { goon = false; e.printStackTrace(); } // logger.debug("received request, req = " + req); if (req == null) { goon = false; break; } if (!(req instanceof GBTransportMessReq)) { goon = false; break; } // find pair logger.debug("find pair"); while (!pairlist.hasNext()) { // wait if (!set) { finaler.beIdle(); set = true; } if (!finaler.hasJobs() && !pairlist.hasNext()) { goon = false; break; } try { sleeps++; if (sleeps % 10 == 0) { logger.info(" reducer is sleeping"); } Thread.sleep(100); } catch (InterruptedException e) { goon = false; break; } } if (!pairlist.hasNext() && !finaler.hasJobs()) { goon = false; break; // continue; //break? } if (set) { set = false; finaler.notIdle(); } pair = pairlist.removeNext(); /* * send pair to client, receive H */ logger.debug("send pair = " + pair); GBTransportMess msg = null; if (pair != null) { msg = new GBTransportMessPairIndex(pair); } else { msg = new GBTransportMess(); // End(); // goon ?= false; } try { pairChannel.send(msg); } catch (IOException e) { e.printStackTrace(); goon = false; break; } catch (MPIException e) { e.printStackTrace(); goon = false; break; } logger.debug("#distributed list = " + theList.size()); Object rh = null; try { rh = pairChannel.receive(); } catch (IOException e) { e.printStackTrace(); goon = false; break; } catch (MPIException e) { e.printStackTrace(); goon = false; break; } catch (ClassNotFoundException e) { e.printStackTrace(); goon = false; break; } // logger.debug("received H polynomial"); if (rh == null) { if (pair != null) { pair.setZero(); } } else if (rh instanceof GBTransportMessPoly) { // update pair list red++; H = ((GBTransportMessPoly<C>) rh).pol; if (logger.isDebugEnabled()) { logger.debug("H = " + H); } if (H == null) { if (pair != null) { pair.setZero(); } } else { if (H.isZERO()) { pair.setZero(); } else { if (H.isONE()) { polIndex = pairlist.putOne(); // GenPolynomial<C> nn = theList.putWait(Integer.valueOf(polIndex), H); goon = false; break; } polIndex = pairlist.put(H); // use putWait ? but still not all distributed // GenPolynomial<C> nn = theList.putWait(Integer.valueOf(polIndex), H); } } } } logger.info("terminated, done " + red + " reductions"); /* * send end mark to client */ logger.debug("send end"); try { pairChannel.send(new GBTransportMessEnd()); } catch (IOException e) { if (logger.isDebugEnabled()) { e.printStackTrace(); } } catch (MPIException e) { if (logger.isDebugEnabled()) { e.printStackTrace(); } } finaler.beIdle(); pairChannel.close(); }
/** * Distributed Groebner base, part for MPI master. * * @param modv number of module variables. * @param F polynomial list. * @return GB(F) a Groebner base of F or null, if a IOException occurs. */ public List<GenPolynomial<C>> GBmaster(int modv, List<GenPolynomial<C>> F) throws MPIException, IOException { List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); GenPolynomial<C> p; PairList<C> pairlist = null; boolean oneInGB = false; // int l = F.size(); int unused = 0; ListIterator<GenPolynomial<C>> it = F.listIterator(); while (it.hasNext()) { p = it.next(); if (p.length() > 0) { p = p.monic(); if (p.isONE()) { oneInGB = true; G.clear(); G.add(p); // return G; must signal termination to others } if (!oneInGB) { G.add(p); } if (pairlist == null) { pairlist = strategy.create(modv, p.ring); if (!p.ring.coFac.isField()) { throw new IllegalArgumentException("coefficients not from a field"); } } // theList not updated here if (p.isONE()) { unused = pairlist.putOne(); } else { unused = pairlist.put(p); } } else { // l--; } } // if (l <= 1) { // return G; must signal termination to others // } logger.info("done pairlist, initialize DHT: " + unused); DistHashTableMPI<Integer, GenPolynomial<C>> theList = new DistHashTableMPI<Integer, GenPolynomial<C>>(engine); theList.init(); // logger.info("done DHT: " + theList); List<GenPolynomial<C>> al = pairlist.getList(); for (int i = 0; i < al.size(); i++) { // no wait required GenPolynomial<C> nn = theList.put(Integer.valueOf(i), al.get(i)); if (nn != null) { logger.info("double polynomials " + i + ", nn = " + nn + ", al(i) = " + al.get(i)); } } Terminator fin = new Terminator(threads - 1); MPIReducerServer<C> R; for (int i = 1; i < threads; i++) { logger.debug("addJob " + i + " of " + threads); MPIChannel chan = new MPIChannel(engine, i); // closed in server R = new MPIReducerServer<C>(i, fin, chan, theList, pairlist); pool.addJob(R); } logger.debug("main loop waiting"); fin.waitDone(); int ps = theList.size(); logger.info("#distributed list = " + ps); // make sure all polynomials arrived: not needed in master // G = (ArrayList)theList.values(); G = pairlist.getList(); if (ps != G.size()) { logger.info("#distributed list = " + theList.size() + " #pairlist list = " + G.size()); } long time = System.currentTimeMillis(); List<GenPolynomial<C>> Gp = minimalGB(G); // not jet distributed but threaded time = System.currentTimeMillis() - time; logger.debug("parallel gbmi = " + time); G = Gp; logger.info("theList.terminate()"); theList.terminate(); logger.info("end" + pairlist); return G; }