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.GenSolvablePolynomial;
020import edu.jas.structure.GcdRingElem;
021
022
023/**
024 * Groebner bases parallel proxy.
025 * @author Heinz Kredel
026 */
027
028public class SGBProxy<C extends GcdRingElem<C>> extends SolvableGroebnerBaseAbstract<C> {
029
030
031    private static final Logger logger = LogManager.getLogger(SGBProxy.class);
032
033
034    private static final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
035
036
037    /**
038     * GB engines.
039     */
040    public final SolvableGroebnerBaseAbstract<C> e1;
041
042
043    public final SolvableGroebnerBaseAbstract<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 SGBProxy(SolvableGroebnerBaseAbstract<C> e1, SolvableGroebnerBaseAbstract<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 "SGBProxy[ " + 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<GenSolvablePolynomial<C>> leftGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
104        if (F == null || F.isEmpty()) {
105            return F;
106        }
107        // parallel case
108        List<GenSolvablePolynomial<C>> G = null;
109        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
110                        2);
111        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
112
113
114            public List<GenSolvablePolynomial<C>> call() {
115                try {
116                    //System.out.println("starting e1 " + e1.getClass().getName());
117                    List<GenSolvablePolynomial<C>> G = e1.leftGB(modv, F);
118                    if (debug) {
119                        logger.info("SGBProxy done e1 {}", e1.getClass().getName());
120                    }
121                    return G;
122                } catch (PreemptingException e) {
123                    throw new RuntimeException("SGBProxy e1 preempted " + e);
124                    //return P.ring.getONE();
125                } catch (Exception e) {
126                    //e.printStackTrace();
127                    logger.info("SGBProxy e1 {}", e);
128                    logger.info("Exception SGBProxy F = {}", F);
129                    throw new RuntimeException("SGBProxy e1 " + e);
130                    //return P.ring.getONE();
131                }
132            }
133        });
134        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
135
136
137            public List<GenSolvablePolynomial<C>> call() {
138                try {
139                    //System.out.println("starting e2 " + e2.getClass().getName());
140                    List<GenSolvablePolynomial<C>> G = e2.leftGB(modv, F);
141                    if (debug) {
142                        logger.info("SGBProxy done e2 {}", e2.getClass().getName());
143                    }
144                    return G;
145                } catch (PreemptingException e) {
146                    throw new RuntimeException("SGBProxy e2 preempted " + e);
147                    //return P.ring.getONE();
148                } catch (Exception e) {
149                    //e.printStackTrace();
150                    logger.info("SGBProxy e2 {}", e);
151                    logger.info("Exception SGBProxy F = {}", F);
152                    throw new RuntimeException("SGBProxy e2 " + e);
153                    //return P.ring.getONE();
154                }
155            }
156        });
157        try {
158            G = pool.invokeAny(cs);
159        } catch (InterruptedException ignored) {
160            logger.info("InterruptedException {}", ignored);
161            Thread.currentThread().interrupt();
162        } catch (ExecutionException e) {
163            logger.info("ExecutionException {}", e);
164            Thread.currentThread().interrupt();
165        }
166        return G;
167    }
168
169
170    /**
171     * Right Groebner base.
172     * @param modv module variable number.
173     * @param F polynomial list.
174     * @return rightGB(F) a Groebner base of F.
175     */
176    @Override
177    public List<GenSolvablePolynomial<C>> rightGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
178        if (F == null || F.isEmpty()) {
179            return F;
180        }
181        // parallel case
182        List<GenSolvablePolynomial<C>> G = null;
183        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
184                        2);
185        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
186
187
188            public List<GenSolvablePolynomial<C>> call() {
189                try {
190                    //System.out.println("starting e1 " + e1.getClass().getName());
191                    List<GenSolvablePolynomial<C>> G = e1.rightGB(modv, F);
192                    if (debug) {
193                        logger.info("SGBProxy done e1 {}", e1.getClass().getName());
194                    }
195                    return G;
196                } catch (PreemptingException e) {
197                    throw new RuntimeException("SGBProxy e1 preempted " + e);
198                    //return P.ring.getONE();
199                } catch (Exception e) {
200                    //e.printStackTrace();
201                    logger.info("SGBProxy e1 {}", e);
202                    logger.info("Exception SGBProxy F = {}", F);
203                    throw new RuntimeException("SGBProxy e1 " + e);
204                    //return P.ring.getONE();
205                }
206            }
207        });
208        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
209
210
211            public List<GenSolvablePolynomial<C>> call() {
212                try {
213                    //System.out.println("starting e2 " + e2.getClass().getName());
214                    List<GenSolvablePolynomial<C>> G = e2.rightGB(modv, F);
215                    if (debug) {
216                        logger.info("SGBProxy done e2 {}", e2.getClass().getName());
217                    }
218                    return G;
219                } catch (PreemptingException e) {
220                    throw new RuntimeException("SGBProxy e2 preempted " + e);
221                    //return P.ring.getONE();
222                } catch (Exception e) {
223                    //e.printStackTrace();
224                    logger.info("SGBProxy e2 {}", e);
225                    logger.info("Exception SGBProxy F = {}", F);
226                    throw new RuntimeException("SGBProxy e2 " + e);
227                    //return P.ring.getONE();
228                }
229            }
230        });
231        try {
232            G = pool.invokeAny(cs);
233        } catch (InterruptedException ignored) {
234            logger.info("InterruptedException {}", ignored);
235            Thread.currentThread().interrupt();
236        } catch (ExecutionException e) {
237            logger.info("ExecutionException {}", e);
238            Thread.currentThread().interrupt();
239        }
240        return G;
241    }
242
243
244    /**
245     * Groebner base.
246     * @param modv module variable number.
247     * @param F polynomial list.
248     * @return twosidedGB(F) a Groebner base of F.
249     */
250    @Override
251    public List<GenSolvablePolynomial<C>> twosidedGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
252        if (F == null || F.isEmpty()) {
253            return F;
254        }
255        // parallel case
256        List<GenSolvablePolynomial<C>> G = null;
257        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
258                        2);
259        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
260
261
262            public List<GenSolvablePolynomial<C>> call() {
263                try {
264                    //System.out.println("starting e1 " + e1.getClass().getName());
265                    List<GenSolvablePolynomial<C>> G = e1.twosidedGB(modv, F);
266                    if (debug) {
267                        logger.info("SGBProxy done e1 {}", e1.getClass().getName());
268                    }
269                    return G;
270                } catch (PreemptingException e) {
271                    throw new RuntimeException("SGBProxy e1 preempted " + e);
272                    //return P.ring.getONE();
273                } catch (Exception e) {
274                    //e.printStackTrace();
275                    logger.info("SGBProxy e1 {}", e);
276                    logger.info("Exception SGBProxy F = {}", F);
277                    throw new RuntimeException("SGBProxy e1 " + e);
278                    //return P.ring.getONE();
279                }
280            }
281        });
282        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
283
284
285            public List<GenSolvablePolynomial<C>> call() {
286                try {
287                    //System.out.println("starting e2 " + e2.getClass().getName());
288                    List<GenSolvablePolynomial<C>> G = e2.twosidedGB(modv, F);
289                    if (debug) {
290                        logger.info("SGBProxy done e2 {}", e2.getClass().getName());
291                    }
292                    return G;
293                } catch (PreemptingException e) {
294                    throw new RuntimeException("SGBProxy e2 preempted " + e);
295                    //return P.ring.getONE();
296                } catch (Exception e) {
297                    //e.printStackTrace();
298                    logger.info("SGBProxy e2 {}", e);
299                    logger.info("Exception SGBProxy F = {}", F);
300                    throw new RuntimeException("SGBProxy e2 " + e);
301                    //return P.ring.getONE();
302                }
303            }
304        });
305        try {
306            G = pool.invokeAny(cs);
307        } catch (InterruptedException ignored) {
308            logger.info("InterruptedException {}", ignored);
309            Thread.currentThread().interrupt();
310        } catch (ExecutionException e) {
311            logger.info("ExecutionException {}", e);
312            Thread.currentThread().interrupt();
313        }
314        return G;
315    }
316
317}