3

Recently, I have been trying to parallelize some Sage (Sage 9.4 on a MacBook Pro running OSX 11.2.3) code using Dask. The problem I run into is that while I can run Dask inside Sage, it will break whenever I include any code that isn't "pure python." In particular, it keeps throwing an ImportError. Here is a basic example of what I am running into

import time
from dask import delayed
from dask.distributed import Client
from time import sleep

client = Client(n_workers=4)

def Hello():
    1+1 #this line breaks things by adding a sage operation
    #if I remove it the code runs fine
    return 'Hello World'

z = delayed(Hello)()
z.compute()

This code throws the following error

Traceback

ImportError                               Traceback (most recent call last)
<timed eval> in <module>

~/.sage/local/lib/python3.9/site-packages/dask/base.py in compute(self, **kwargs)
    284         dask.base.compute
    285         """
--> 286         (result,) = compute(self, traverse=False, **kwargs)
    287         return result
    288 

~/.sage/local/lib/python3.9/site-packages/dask/base.py in compute(*args, **kwargs)
    566         postcomputes.append(x.__dask_postcompute__())
    567 
--> 568     results = schedule(dsk, keys, **kwargs)
    569     return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])
    570 

~/.sage/local/lib/python3.9/site-packages/distributed/client.py in get(self, dsk, keys, workers, allow_other_workers, resources, sync, asynchronous, direct, retries, priority, fifo_timeout, actors, **kwargs)
   2669                     should_rejoin = False
   2670             try:
-> 2671                 results = self.gather(packed, asynchronous=asynchronous, direct=direct)
   2672             finally:
   2673                 for f in futures.values():

~/.sage/local/lib/python3.9/site-packages/distributed/client.py in gather(self, futures, errors, direct, asynchronous)
   1946             else:
   1947                 local_worker = None
-> 1948             return self.sync(
   1949                 self._gather,
   1950                 futures,

~/.sage/local/lib/python3.9/site-packages/distributed/client.py in sync(self, func, asynchronous, callback_timeout, *args, **kwargs)
    843             return future
    844         else:
--> 845             return sync(
    846                 self.loop, func, *args, callback_timeout=callback_timeout, **kwargs
    847             )

~/.sage/local/lib/python3.9/site-packages/distributed/utils.py in sync(loop, func, callback_timeout, *args, **kwargs)
    324     if error[0]:
    325         typ, exc, tb = error[0]
--> 326         raise exc.with_traceback(tb)
    327     else:
    328         return result[0]

~/.sage/local/lib/python3.9/site-packages/distributed/utils.py in f()
    307             if callback_timeout is not None:
    308                 future = asyncio.wait_for(future, callback_timeout)
--> 309             result[0] = yield future
    310         except Exception:
    311             error[0] = sys.exc_info()

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/tornado/gen.py in run(self)
    733 
    734                     try:
--> 735                         value = future.result()
    736                     except Exception:
    737                         exc_info = sys.exc_info()

~/.sage/local/lib/python3.9/site-packages/distributed/client.py in _gather(self, futures, errors, direct, local_worker)
   1811                             exc = CancelledError(key)
   1812                         else:
-> 1813                             raise exception.with_traceback(traceback)
   1814                         raise exc
   1815                     if errors == "skip":

~/.sage/local/lib/python3.9/site-packages/distributed/protocol/pickle.py in loads()
     73             return pickle.loads(x, buffers=buffers)
     74         else:
---> 75             return pickle.loads(x)
     76     except Exception:
     77         logger.info("Failed to deserialize %s", x[:10000], exc_info=True)

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/rings/integer.pyx in init sage.rings.integer (build/cythonized/sage/rings/integer.c:54201)()
----> 1 r"""
      2 Elements of the ring `\ZZ` of integers
      3 
      4 Sage has highly optimized and extensive functionality for arithmetic with integers
      5 and the ring of integers.

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/rings/rational.pyx in init sage.rings.rational (build/cythonized/sage/rings/rational.cpp:40442)()
     98 
     99 
--> 100 import sage.rings.real_mpfr
    101 import sage.rings.real_double
    102 from libc.stdint cimport uint64_t

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/rings/real_mpfr.pyx in init sage.rings.real_mpfr (build/cythonized/sage/rings/real_mpfr.c:46795)()
----> 1 r"""
      2 Arbitrary Precision Real Numbers
      3 
      4 AUTHORS:
      5 

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/libs/mpmath/utils.pyx in init sage.libs.mpmath.utils (build/cythonized/sage/libs/mpmath/utils.c:9062)()
----> 1 """
      2 Utilities for Sage-mpmath interaction
      3 
      4 Also patches some mpmath functions for speed
      5 """

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/rings/complex_mpfr.pyx in init sage.rings.complex_mpfr (build/cythonized/sage/rings/complex_mpfr.c:34594)()
----> 1 """
      2 Arbitrary Precision Floating Point Complex Numbers
      3 
      4 AUTHORS:
      5 

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/rings/complex_double.pyx in init sage.rings.complex_double (build/cythonized/sage/rings/complex_double.c:25284)()
     96 from cypari2.convert cimport new_gen_from_double, new_t_COMPLEX_from_double
     97 
---> 98 from . import complex_mpfr
     99 
    100 from .complex_mpfr import ComplexField

ImportError: cannot import name complex_mpfr


The only other time I have seen an ImportError like this is when I have been running sage inside python and did not include a from sage.all import *, so I am wondering if what is happening is that Dask is trying to run my code in python. I'm also not sure whether this qualifies as a Sage or a Dask problem. Any help would be greatly appreciated!

Sam Ballas
  • 53
  • 5
  • I really wanted to like SageMath, but it is a disaster. What are you trying to do with it? – Igor Rivin Aug 27 '21 at 18:42
  • @IgorRivin In general, I'm pretty happy with Sage. I'm a trying to take total (higher order) derivatives of a multivariable (25ish variables) polynomial with coefficients in a number field. Once I get up to 5 or 6th derivatives, this involves computing millions of partial derivatives, which seems very parallelizable. In case you are curious, the application I have in mind has to do with geometric structures on 3-manifolds – Sam Ballas Aug 27 '21 at 18:54
  • :) Last time I tried sage was in conjunction with snappy, and it did not make me happy. How are you trying to parallelize it? (it might be easier if you just emailed me at the Temple address instead of communicating here through comments...) – Igor Rivin Aug 27 '21 at 18:58
  • 1
    I'm not familar with SAGE but have worked with dask+Octave and other languages before, and I would say that if you're trying to scale SAGE operations using dask I would guess that your best bet is to call dask from python, then within the function you're sending to the dask client, import the [python sage bindings](https://doc.sagemath.org/html/en/faq/faq-usage.html#how-do-i-import-sage-into-a-python-script) and run SAGE through the python API, rather than trying to spin up a dask cluster from within sage. hope that's helpful? – Michael Delgado Aug 27 '21 at 19:37
  • Sage has its own parallelization structures: https://doc.sagemath.org/html/en/reference/parallel/index.html. Have you tried using those? – John Palmieri Aug 27 '21 at 22:24
  • @MichaelDelgado, I have also tried to run my code in python as you suggested, and I still get the same error whenever my code involves actual SAGE – Sam Ballas Aug 27 '21 at 22:51
  • @JohnPalmieri, I did come across the sage parallelization you mentioned, but I was having a hard time working through the documentation/examples there. Perhaps I will give it another look though. Do you have any advice on using sage parallelization for parallelizing simple loops? – Sam Ballas Aug 27 '21 at 22:58
  • I'm sorry, I have almost no experience using Sage's parallelization. You could also try adding some import statements to see if that helps. – John Palmieri Aug 27 '21 at 23:01
  • @IgorRivin: saying that SageMath "is a disaster" is not constructive. Please provide details. – John Palmieri Aug 27 '21 at 23:02
  • 1
    @SamBallas if you post another question trying to call sage from python within dask I'd be happy to check it out. I don't know how you could have gotten the same error outside a SAGE environment since 1+1 would certainly not error in a pure python environment :) – Michael Delgado Aug 28 '21 at 00:01
  • SamBallas or @JohnPalmieri - is there a way to invoke sage from python (NOT from a sage environment) using an API? All I can see are docs on sage itself. I'm looking for something analagous to these docs pages for [the matlab python bindings](https://www.mathworks.com/help/matlab/matlab_external/call-matlab-functions-from-python.html), [r2py for calling R](https://rpy2.github.io/), or [oct2py for calling Octave](https://pypi.org/project/oct2py/) – Michael Delgado Aug 28 '21 at 00:28
  • @MichaelDelgado: I don't know, and this is not the best website for Sage questions. The Google group sage-support is the most active, and ask.sagemath.org is pretty good. – John Palmieri Aug 28 '21 at 04:03
  • @MichaelDelgado: I posted [another question](https://stackoverflow.com/questions/68964884/using-dask-throws-importerror-when-sagemath-code-is-run-in-python) where I get the same error when I run the code from within python. You are right that in python 1+1 is fine, but if I tell python they are sage integers then I get the error – Sam Ballas Aug 28 '21 at 13:39
  • Does this answer your question? [Using Dask throws ImportError when SageMath code is run in python](https://stackoverflow.com/questions/68964884/using-dask-throws-importerror-when-sagemath-code-is-run-in-python) – mdurant Aug 31 '21 at 01:46

0 Answers0