001/*
002 * $Id$
003 */
004
005package edu.jas.fd;
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;
013import java.util.concurrent.TimeoutException;
014
015import org.apache.logging.log4j.Logger;
016import org.apache.logging.log4j.LogManager; 
017
018import edu.jas.kern.ComputerThreads;
019import edu.jas.kern.PreemptingException;
020import edu.jas.poly.GenPolynomial;
021import edu.jas.poly.GenSolvablePolynomial;
022import edu.jas.structure.GcdRingElem;
023import edu.jas.structure.RingFactory;
024
025
026/**
027 * Solvable greatest common divisor parallel proxy. Executes methods from two
028 * implementations in parallel and returns the result from the fastest run. Uses
029 * timeout on <code>invokeAny()</code> and return fake common divisor <it>1</it>
030 * in case of timeout.
031 * @author Heinz Kredel
032 */
033
034public class SGCDParallelProxy<C extends GcdRingElem<C>> extends GreatestCommonDivisorAbstract<C> {
035
036
037    private static final Logger logger = LogManager.getLogger(SGCDParallelProxy.class);
038
039
040    private static final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
041
042
043    /**
044     * GCD engines.
045     */
046    public final GreatestCommonDivisorAbstract<C> e0;
047
048
049    public final GreatestCommonDivisorAbstract<C> e1;
050
051
052    public final GreatestCommonDivisorAbstract<C> e2;
053
054
055    /**
056     * Thread pool.
057     */
058    protected transient ExecutorService pool;
059
060
061    /**
062     * ParallelProxy constructor.
063     * @param cf coefficient ring.
064     */
065    public SGCDParallelProxy(RingFactory<C> cf, GreatestCommonDivisorAbstract<C> e1,
066                    GreatestCommonDivisorAbstract<C> e2) {
067        super(cf);
068        this.e0 = new GreatestCommonDivisorFake<C>(cf);
069        this.e1 = e1;
070        this.e2 = e2;
071        pool = ComputerThreads.getPool();
072        //System.out.println("pool 2 = "+pool);
073    }
074
075
076    /**
077     * Get the String representation with gcd engines.
078     * @see java.lang.Object#toString()
079     */
080    @Override
081    public String toString() {
082        return "SGCDParallelProxy[ " + e1.getClass().getName() + ", " + e2.getClass().getName() + " ]";
083    }
084
085
086    /**
087     * Left univariate GenSolvablePolynomial greatest common divisor.
088     * @param P univariate GenSolvablePolynomial.
089     * @param S univariate GenSolvablePolynomial.
090     * @return gcd(P,S).
091     */
092    @Override
093    public GenSolvablePolynomial<C> leftBaseGcd(final GenSolvablePolynomial<C> P,
094                    final GenSolvablePolynomial<C> S) {
095        if (debug) {
096            if (ComputerThreads.NO_THREADS) {
097                throw new RuntimeException("this should not happen");
098            }
099        }
100        if (S == null || S.isZERO()) {
101            return P;
102        }
103        if (P == null || P.isZERO()) {
104            return S;
105        }
106        // parallel case
107        GenSolvablePolynomial<C> g = P.ring.getONE();
108        //Callable<GenSolvablePolynomial<C>> c0;
109        //Callable<GenSolvablePolynomial<C>> c1;
110        List<Callable<GenSolvablePolynomial<C>>> cs = new ArrayList<Callable<GenSolvablePolynomial<C>>>(2);
111        cs.add(new Callable<GenSolvablePolynomial<C>>() {
112
113
114            public GenSolvablePolynomial<C> call() {
115                try {
116                    //System.out.println("starting e1 " + e1.getClass().getName());
117                    GenSolvablePolynomial<C> g = e1.leftBaseGcd(P, S);
118                    if (debug) {
119                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
120                    }
121                    return g;
122                } catch (PreemptingException e) {
123                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
124                    //return P.ring.getONE();
125                } catch (Exception e) {
126                    //e.printStackTrace();
127                    logger.info("SGCDParallelProxy e1 {}", e);
128                    logger.info("SGCDParallelProxy P = {}", P);
129                    logger.info("SGCDParallelProxy S = {}", S);
130                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
131                    //return P.ring.getONE();
132                }
133            }
134        });
135        cs.add(new Callable<GenSolvablePolynomial<C>>() {
136
137
138            public GenSolvablePolynomial<C> call() {
139                try {
140                    //System.out.println("starting e2 " + e2.getClass().getName());
141                    GenSolvablePolynomial<C> g = e2.leftBaseGcd(P, S);
142                    if (debug) {
143                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
144                    }
145                    return g;
146                } catch (PreemptingException e) {
147                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
148                    //return P.ring.getONE();
149                } catch (Exception e) {
150                    //e.printStackTrace();
151                    logger.info("SGCDParallelProxy e2 {}", e);
152                    logger.info("SGCDParallelProxy P = {}", P);
153                    logger.info("SGCDParallelProxy S = {}", S);
154                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
155                    //return P.ring.getONE();
156                }
157            }
158        });
159        try {
160            if (ComputerThreads.getTimeout() < 0) {
161                g = pool.invokeAny(cs);
162            } else {
163                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
164            }
165        } catch (InterruptedException ignored) {
166            logger.info("InterruptedException {}", ignored);
167            Thread.currentThread().interrupt();
168        } catch (ExecutionException e) {
169            logger.info("ExecutionException {}", e);
170            Thread.currentThread().interrupt();
171        } catch (TimeoutException e) {
172            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
173                            ComputerThreads.getTimeUnit());
174            g = e0.leftBaseGcd(P, S); // fake returns 1
175        }
176        return g;
177    }
178
179
180    /**
181     * left univariate GenSolvablePolynomial recursive greatest common divisor.
182     * @param P univariate recursive GenSolvablePolynomial.
183     * @param S univariate recursive GenSolvablePolynomial.
184     * @return gcd(P,S).
185     */
186    @Override
187    public GenSolvablePolynomial<GenPolynomial<C>> leftRecursiveUnivariateGcd(
188                    final GenSolvablePolynomial<GenPolynomial<C>> P,
189                    final GenSolvablePolynomial<GenPolynomial<C>> S) {
190        if (debug) {
191            if (ComputerThreads.NO_THREADS) {
192                throw new RuntimeException("this should not happen");
193            }
194        }
195        if (S == null || S.isZERO()) {
196            return P;
197        }
198        if (P == null || P.isZERO()) {
199            return S;
200        }
201        // parallel case
202        GenSolvablePolynomial<GenPolynomial<C>> g = P.ring.getONE();
203        //Callable<GenSolvablePolynomial<GenPolynomial<C>>> c0;
204        //Callable<GenSolvablePolynomial<GenPolynomial<C>>> c1;
205        List<Callable<GenSolvablePolynomial<GenPolynomial<C>>>> cs = new ArrayList<Callable<GenSolvablePolynomial<GenPolynomial<C>>>>(
206                        2);
207        cs.add(new Callable<GenSolvablePolynomial<GenPolynomial<C>>>() {
208
209
210            public GenSolvablePolynomial<GenPolynomial<C>> call() {
211                try {
212                    GenSolvablePolynomial<GenPolynomial<C>> g = e1.leftRecursiveUnivariateGcd(P, S);
213                    if (debug) {
214                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
215                    }
216                    return g;
217                } catch (PreemptingException e) {
218                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
219                    //return P.ring.getONE();
220                } catch (Exception e) {
221                    //e.printStackTrace();
222                    logger.info("SGCDParallelProxy e1 {}", e);
223                    logger.info("SGCDParallelProxy P = {}", P);
224                    logger.info("SGCDParallelProxy S = {}", S);
225                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
226                    //return P.ring.getONE();
227                }
228            }
229        });
230        cs.add(new Callable<GenSolvablePolynomial<GenPolynomial<C>>>() {
231
232
233            public GenSolvablePolynomial<GenPolynomial<C>> call() {
234                try {
235                    GenSolvablePolynomial<GenPolynomial<C>> g = e2.leftRecursiveUnivariateGcd(P, S);
236                    if (debug) {
237                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
238                    }
239                    return g;
240                } catch (PreemptingException e) {
241                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
242                    //return P.ring.getONE();
243                } catch (Exception e) {
244                    //e.printStackTrace();
245                    logger.info("SGCDParallelProxy e2 {}", e);
246                    logger.info("SGCDParallelProxy P = {}", P);
247                    logger.info("SGCDParallelProxy S = {}", S);
248                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
249                    //return P.ring.getONE();
250                }
251            }
252        });
253        try {
254            if (ComputerThreads.getTimeout() < 0) {
255                g = pool.invokeAny(cs);
256            } else {
257                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
258            }
259        } catch (InterruptedException ignored) {
260            logger.info("InterruptedException {}", ignored);
261            Thread.currentThread().interrupt();
262        } catch (ExecutionException e) {
263            logger.info("ExecutionException {}", e);
264            Thread.currentThread().interrupt();
265        } catch (TimeoutException e) {
266            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
267                        ComputerThreads.getTimeUnit());
268            g = e0.leftRecursiveUnivariateGcd(P, S); // fake returns 1
269        }
270        return g;
271    }
272
273
274    /**
275     * Left GenSolvablePolynomial greatest common divisor.
276     * @param P GenSolvablePolynomial.
277     * @param S GenSolvablePolynomial.
278     * @return leftGcd(P,S).
279     */
280    @Override
281    public GenSolvablePolynomial<C> leftGcd(final GenSolvablePolynomial<C> P,
282                    final GenSolvablePolynomial<C> S) {
283        if (debug) {
284            if (ComputerThreads.NO_THREADS) {
285                throw new RuntimeException("this should not happen");
286            }
287        }
288        if (S == null || S.isZERO()) {
289            return P;
290        }
291        if (P == null || P.isZERO()) {
292            return S;
293        }
294        // parallel case
295        GenSolvablePolynomial<C> g = P.ring.getONE();
296        //Callable<GenSolvablePolynomial<C>> c0;
297        //Callable<GenSolvablePolynomial<C>> c1;
298        List<Callable<GenSolvablePolynomial<C>>> cs = new ArrayList<Callable<GenSolvablePolynomial<C>>>(2);
299        cs.add(new Callable<GenSolvablePolynomial<C>>() {
300
301
302            public GenSolvablePolynomial<C> call() {
303                try {
304                    //System.out.println("starting e1 " + e1.getClass().getName());
305                    GenSolvablePolynomial<C> g = e1.leftGcd(P, S);
306                    if (debug) {
307                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
308                    }
309                    return g;
310                } catch (PreemptingException e) {
311                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
312                    //return P.ring.getONE();
313                } catch (Exception e) {
314                    //e.printStackTrace();
315                    logger.info("SGCDParallelProxy e1 {}", e);
316                    logger.info("SGCDParallelProxy P = {}", P);
317                    logger.info("SGCDParallelProxy S = {}", S);
318                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
319                    //return P.ring.getONE();
320                }
321            }
322        });
323        cs.add(new Callable<GenSolvablePolynomial<C>>() {
324
325
326            public GenSolvablePolynomial<C> call() {
327                try {
328                    //System.out.println("starting e2 " + e2.getClass().getName());
329                    GenSolvablePolynomial<C> g = e2.leftGcd(P, S);
330                    if (debug) {
331                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
332                    }
333                    return g;
334                } catch (PreemptingException e) {
335                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
336                    //return P.ring.getONE();
337                } catch (Exception e) {
338                    //e.printStackTrace();
339                    logger.info("SGCDParallelProxy e2 {}", e);
340                    logger.info("SGCDParallelProxy P = {}", P);
341                    logger.info("SGCDParallelProxy S = {}", S);
342                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
343                    //return P.ring.getONE();
344                }
345            }
346        });
347        try {
348            if (ComputerThreads.getTimeout() < 0) {
349                g = pool.invokeAny(cs);
350            } else {
351                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
352            }
353        } catch (InterruptedException ignored) {
354            logger.info("InterruptedException {}", ignored);
355            Thread.currentThread().interrupt();
356        } catch (ExecutionException e) {
357            logger.info("ExecutionException {}", e);
358            Thread.currentThread().interrupt();
359        } catch (TimeoutException e) {
360            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
361                            ComputerThreads.getTimeUnit());
362            g = e0.leftGcd(P, S); // fake returns 1
363        }
364        return g;
365    }
366
367
368    /**
369     * Right univariate GenSolvablePolynomial greatest common divisor.
370     * @param P univariate GenSolvablePolynomial.
371     * @param S univariate GenSolvablePolynomial.
372     * @return gcd(P,S).
373     */
374    @Override
375    public GenSolvablePolynomial<C> rightBaseGcd(final GenSolvablePolynomial<C> P,
376                    final GenSolvablePolynomial<C> S) {
377        if (debug) {
378            if (ComputerThreads.NO_THREADS) {
379                throw new RuntimeException("this should not happen");
380            }
381        }
382        if (S == null || S.isZERO()) {
383            return P;
384        }
385        if (P == null || P.isZERO()) {
386            return S;
387        }
388        // parallel case
389        GenSolvablePolynomial<C> g = P.ring.getONE();
390        //Callable<GenSolvablePolynomial<C>> c0;
391        //Callable<GenSolvablePolynomial<C>> c1;
392        List<Callable<GenSolvablePolynomial<C>>> cs = new ArrayList<Callable<GenSolvablePolynomial<C>>>(2);
393        cs.add(new Callable<GenSolvablePolynomial<C>>() {
394
395
396            public GenSolvablePolynomial<C> call() {
397                try {
398                    //System.out.println("starting e1 " + e1.getClass().getName());
399                    GenSolvablePolynomial<C> g = e1.rightBaseGcd(P, S);
400                    if (debug) {
401                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
402                    }
403                    return g;
404                } catch (PreemptingException e) {
405                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
406                    //return P.ring.getONE();
407                } catch (Exception e) {
408                    //e.printStackTrace();
409                    logger.info("SGCDParallelProxy e1 {}", e);
410                    logger.info("SGCDParallelProxy P = {}", P);
411                    logger.info("SGCDParallelProxy S = {}", S);
412                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
413                    //return P.ring.getONE();
414                }
415            }
416        });
417        cs.add(new Callable<GenSolvablePolynomial<C>>() {
418
419
420            public GenSolvablePolynomial<C> call() {
421                try {
422                    //System.out.println("starting e2 " + e2.getClass().getName());
423                    GenSolvablePolynomial<C> g = e2.rightBaseGcd(P, S);
424                    if (debug) {
425                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
426                    }
427                    return g;
428                } catch (PreemptingException e) {
429                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
430                    //return P.ring.getONE();
431                } catch (Exception e) {
432                    //e.printStackTrace();
433                    logger.info("SGCDParallelProxy e2 {}", e);
434                    logger.info("SGCDParallelProxy P = {}", P);
435                    logger.info("SGCDParallelProxy S = {}", S);
436                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
437                    //return P.ring.getONE();
438                }
439            }
440        });
441        try {
442            if (ComputerThreads.getTimeout() < 0) {
443                g = pool.invokeAny(cs);
444            } else {
445                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
446            }
447        } catch (InterruptedException ignored) {
448            logger.info("InterruptedException {}", ignored);
449            Thread.currentThread().interrupt();
450        } catch (ExecutionException e) {
451            logger.info("ExecutionException {}", e);
452            Thread.currentThread().interrupt();
453        } catch (TimeoutException e) {
454            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
455                            ComputerThreads.getTimeUnit());
456            g = e0.rightBaseGcd(P, S); // fake returns 1
457        }
458        return g;
459    }
460
461
462    /**
463     * right univariate GenSolvablePolynomial recursive greatest common divisor.
464     * @param P univariate recursive GenSolvablePolynomial.
465     * @param S univariate recursive GenSolvablePolynomial.
466     * @return gcd(P,S).
467     */
468    @Override
469    public GenSolvablePolynomial<GenPolynomial<C>> rightRecursiveUnivariateGcd(
470                    final GenSolvablePolynomial<GenPolynomial<C>> P,
471                    final GenSolvablePolynomial<GenPolynomial<C>> S) {
472        if (debug) {
473            if (ComputerThreads.NO_THREADS) {
474                throw new RuntimeException("this should not happen");
475            }
476        }
477        if (S == null || S.isZERO()) {
478            return P;
479        }
480        if (P == null || P.isZERO()) {
481            return S;
482        }
483        // parallel case
484        GenSolvablePolynomial<GenPolynomial<C>> g = P.ring.getONE();
485        //Callable<GenSolvablePolynomial<GenPolynomial<C>>> c0;
486        //Callable<GenSolvablePolynomial<GenPolynomial<C>>> c1;
487        List<Callable<GenSolvablePolynomial<GenPolynomial<C>>>> cs = new ArrayList<Callable<GenSolvablePolynomial<GenPolynomial<C>>>>(
488                        2);
489        cs.add(new Callable<GenSolvablePolynomial<GenPolynomial<C>>>() {
490
491
492            public GenSolvablePolynomial<GenPolynomial<C>> call() {
493                try {
494                    GenSolvablePolynomial<GenPolynomial<C>> g = e1.rightRecursiveUnivariateGcd(P, S);
495                    if (debug) {
496                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
497                    }
498                    return g;
499                } catch (PreemptingException e) {
500                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
501                    //return P.ring.getONE();
502                } catch (Exception e) {
503                    //e.printStackTrace();
504                    logger.info("SGCDParallelProxy e1 {}", e);
505                    logger.info("SGCDParallelProxy P = {}", P);
506                    logger.info("SGCDParallelProxy S = {}", S);
507                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
508                    //return P.ring.getONE();
509                }
510            }
511        });
512        cs.add(new Callable<GenSolvablePolynomial<GenPolynomial<C>>>() {
513
514
515            public GenSolvablePolynomial<GenPolynomial<C>> call() {
516                try {
517                    GenSolvablePolynomial<GenPolynomial<C>> g = e2.rightRecursiveUnivariateGcd(P, S);
518                    if (debug) {
519                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
520                    }
521                    return g;
522                } catch (PreemptingException e) {
523                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
524                    //return P.ring.getONE();
525                } catch (Exception e) {
526                    //e.printStackTrace();
527                    logger.info("SGCDParallelProxy e2 {}", e);
528                    logger.info("SGCDParallelProxy P = {}", P);
529                    logger.info("SGCDParallelProxy S = {}", S);
530                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
531                    //return P.ring.getONE();
532                }
533            }
534        });
535        try {
536            if (ComputerThreads.getTimeout() < 0) {
537                g = pool.invokeAny(cs);
538            } else {
539                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
540            }
541        } catch (InterruptedException ignored) {
542            logger.info("InterruptedException {}", ignored);
543            Thread.currentThread().interrupt();
544        } catch (ExecutionException e) {
545            logger.info("ExecutionException {}", e);
546            Thread.currentThread().interrupt();
547        } catch (TimeoutException e) {
548            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
549                            ComputerThreads.getTimeUnit());
550            g = e0.rightRecursiveUnivariateGcd(P, S); // fake returns 1
551        }
552        return g;
553    }
554
555
556    /**
557     * Right GenSolvablePolynomial greatest common divisor.
558     * @param P GenSolvablePolynomial.
559     * @param S GenSolvablePolynomial.
560     * @return rightGcd(P,S).
561     */
562    @Override
563    public GenSolvablePolynomial<C> rightGcd(final GenSolvablePolynomial<C> P,
564                    final GenSolvablePolynomial<C> S) {
565        if (debug) {
566            if (ComputerThreads.NO_THREADS) {
567                throw new RuntimeException("this should not happen");
568            }
569        }
570        if (S == null || S.isZERO()) {
571            return P;
572        }
573        if (P == null || P.isZERO()) {
574            return S;
575        }
576        // parallel case
577        GenSolvablePolynomial<C> g = P.ring.getONE();
578        //Callable<GenSolvablePolynomial<C>> c0;
579        //Callable<GenSolvablePolynomial<C>> c1;
580        List<Callable<GenSolvablePolynomial<C>>> cs = new ArrayList<Callable<GenSolvablePolynomial<C>>>(2);
581        cs.add(new Callable<GenSolvablePolynomial<C>>() {
582
583
584            public GenSolvablePolynomial<C> call() {
585                try {
586                    //System.out.println("starting e1 " + e1.getClass().getName());
587                    GenSolvablePolynomial<C> g = e1.rightGcd(P, S);
588                    if (debug) {
589                        logger.info("SGCDParallelProxy done e1 {}", e1.getClass().getName());
590                    }
591                    return g;
592                } catch (PreemptingException e) {
593                    throw new RuntimeException("SGCDParallelProxy e1 pre " + e);
594                    //return P.ring.getONE();
595                } catch (Exception e) {
596                    //e.printStackTrace();
597                    logger.info("SGCDParallelProxy e1 {}", e);
598                    logger.info("SGCDParallelProxy P = {}", P);
599                    logger.info("SGCDParallelProxy S = {}", S);
600                    throw new RuntimeException("SGCDParallelProxy e1 " + e);
601                    //return P.ring.getONE();
602                }
603            }
604        });
605        cs.add(new Callable<GenSolvablePolynomial<C>>() {
606
607
608            public GenSolvablePolynomial<C> call() {
609                try {
610                    //System.out.println("starting e2 " + e2.getClass().getName());
611                    GenSolvablePolynomial<C> g = e2.rightGcd(P, S);
612                    if (debug) {
613                        logger.info("SGCDParallelProxy done e2 {}", e2.getClass().getName());
614                    }
615                    return g;
616                } catch (PreemptingException e) {
617                    throw new RuntimeException("SGCDParallelProxy e2 pre " + e);
618                    //return P.ring.getONE();
619                } catch (Exception e) {
620                    //e.printStackTrace();
621                    logger.info("SGCDParallelProxy e2 {}", e);
622                    logger.info("SGCDParallelProxy P = {}", P);
623                    logger.info("SGCDParallelProxy S = {}", S);
624                    throw new RuntimeException("SGCDParallelProxy e2 " + e);
625                    //return P.ring.getONE();
626                }
627            }
628        });
629        try {
630            if (ComputerThreads.getTimeout() < 0) {
631                g = pool.invokeAny(cs);
632            } else {
633                g = pool.invokeAny(cs, ComputerThreads.getTimeout(), ComputerThreads.getTimeUnit());
634            }
635        } catch (InterruptedException ignored) {
636            logger.info("InterruptedException {}", ignored);
637            Thread.currentThread().interrupt();
638        } catch (ExecutionException e) {
639            logger.info("ExecutionException {}", e);
640            Thread.currentThread().interrupt();
641        } catch (TimeoutException e) {
642            logger.info("TimeoutException after {} {}", ComputerThreads.getTimeout(),
643                            ComputerThreads.getTimeUnit());
644            g = e0.rightGcd(P, S); // fake returns 1
645        }
646        return g;
647    }
648
649}