001/*
002 * $Id$
003 */
004
005package edu.jas.gb;
006
007
008import java.util.ArrayList;
009import java.util.List;
010import java.util.concurrent.Callable;
011import java.util.concurrent.ExecutionException;
012import java.util.concurrent.ExecutorService;
013
014import org.apache.logging.log4j.Logger;
015import org.apache.logging.log4j.LogManager; 
016
017import edu.jas.kern.ComputerThreads;
018import edu.jas.kern.PreemptingException;
019import edu.jas.poly.GenPolynomial;
020import edu.jas.structure.GcdRingElem;
021
022
023/**
024 * Groebner bases parallel proxy.
025 * @author Heinz Kredel
026 */
027
028public class GBProxy<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<C> {
029
030
031    private static final Logger logger = LogManager.getLogger(GBProxy.class);
032
033
034    private static final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
035
036
037    /**
038     * GB engines.
039     */
040    public final GroebnerBaseAbstract<C> e1;
041
042
043    public final GroebnerBaseAbstract<C> e2;
044
045
046    /**
047     * Thread pool.
048     */
049    protected transient ExecutorService pool;
050
051
052    /**
053     * Proxy constructor.
054     * @param e1 Groebner base engine.
055     * @param e2 Groebner base engine.
056     */
057    public GBProxy(GroebnerBaseAbstract<C> e1, GroebnerBaseAbstract<C> e2) {
058        this.e1 = e1;
059        this.e2 = e2;
060        pool = ComputerThreads.getPool();
061        //System.out.println("pool 2 = "+pool);
062    }
063
064
065    /**
066     * Get the String representation with GB engines.
067     * @see java.lang.Object#toString()
068     */
069    @Override
070    public String toString() {
071        return "GBProxy[ " + e1.toString() + ", " + e2.toString() + " ]";
072    }
073
074
075    /**
076     * Cleanup and terminate ThreadPool.
077     */
078    @Override
079    public void terminate() {
080        e1.terminate();
081        e2.terminate();
082    }
083
084
085    /**
086     * Cancel ThreadPool.
087     */
088    @Override
089    public int cancel() {
090        int s = e1.cancel();
091        s += e2.cancel();
092        return s;
093    }
094
095
096    /**
097     * Groebner base.
098     * @param modv module variable number.
099     * @param F polynomial list.
100     * @return GB(F) a Groebner base of F.
101     */
102    @Override
103    public List<GenPolynomial<C>> GB(final int modv, final List<GenPolynomial<C>> F) {
104        if (F == null || F.isEmpty()) {
105            return F;
106        }
107        // parallel case
108        List<GenPolynomial<C>> G = null;
109        List<Callable<List<GenPolynomial<C>>>> cs = new ArrayList<Callable<List<GenPolynomial<C>>>>(2);
110        cs.add(new Callable<List<GenPolynomial<C>>>() {
111
112
113            public List<GenPolynomial<C>> call() {
114                try {
115                    //System.out.println("starting e1 " + e1.getClass().getName());
116                    List<GenPolynomial<C>> G = e1.GB(modv, F);
117                    if (debug) {
118                        logger.info("GBProxy done e1 {}", e1.getClass().getName());
119                    }
120                    return G;
121                } catch (PreemptingException e) {
122                    throw new RuntimeException("GBProxy e1 preempted " + e);
123                    //return P.ring.getONE();
124                } catch (Exception e) {
125                    //e.printStackTrace();
126                    logger.info("GBProxy e1 {}", e);
127                    logger.info("Exception GBProxy F = {}", F);
128                    throw new RuntimeException("GBProxy e1 " + e);
129                    //return P.ring.getONE();
130                }
131            }
132        });
133        cs.add(new Callable<List<GenPolynomial<C>>>() {
134
135
136            public List<GenPolynomial<C>> call() {
137                try {
138                    //System.out.println("starting e2 " + e2.getClass().getName());
139                    List<GenPolynomial<C>> G = e2.GB(modv, F);
140                    if (debug) {
141                        logger.info("GBProxy done e2 {}", e2.getClass().getName());
142                    }
143                    return G;
144                } catch (PreemptingException e) {
145                    throw new RuntimeException("GBProxy e2 preempted " + e);
146                    //return P.ring.getONE();
147                } catch (Exception e) {
148                    //e.printStackTrace();
149                    logger.info("GBProxy e2 {}", e);
150                    logger.info("Exception GBProxy F = {}", F);
151                    throw new RuntimeException("GBProxy e2 " + e);
152                    //return P.ring.getONE();
153                }
154            }
155        });
156        try {
157            G = pool.invokeAny(cs);
158        } catch (InterruptedException ignored) {
159            logger.info("InterruptedException {}", ignored);
160            Thread.currentThread().interrupt();
161        } catch (ExecutionException e) {
162            logger.info("ExecutionException {}", e);
163            Thread.currentThread().interrupt();
164        }
165        return G;
166    }
167
168}