如何在Anaconda中安装SageMath内核?

时间:2018-07-12 08:12:21

标签: python anaconda jupyter sage jupyter-kernel

我正在尝试在Anaconda 3中使用Sage,但看起来库未导入。

我首先创建了一个新环境'ipykernel_py2',然后按照here中的说明安装了Python 2。这样,我就可以在Anaconda 3中启动并运行Python 3和Python 3。

然后我转到创建的内核文件夹(C:\ Users \ YOUR_USERNAME \ AppData \ Local \ Continuum \ anaconda3 \ envs \ ipykernel_py2 \ share \ jupyter \ kernels)并粘贴Sage的内核(取自C:\ Program Files \ SageMath 8.2 \运行时\ opt \ sagemath-8.2 \ local \ share \ jupyter \ kernels)。这允许在Jupyter中创建新的SageMath文件,但是内核已死。 要激活内核,我使用了Anaconda Prompt并输入:

activate ipykernel_py2
python -m ipykernel install --user --name sagemath --display-name "SageMath 8.2"

因此,内核现已激活,我可以创建和运行Sage文件。但是,这些库仍无法正常工作。该文件似乎像普通的Python 2文件一样​​运行。

有人知道如何解决此问题吗?我需要创建一个单独的环境吗?

1 个答案:

答案 0 :(得分:2)

Sage for Windows在称为Cygwin的UNIX仿真环境下运行。查看其中的sagemath/kernel.json

{"display_name": "SageMath 8.2", "argv": ["/opt/sagemath-8.2/local/bin/sage", "--python", "-m", "sage.repl.ipython_kernel", "-f", "{connection_file}"]}

您可以在此处看到它具有一个sage可执行文件的UNIX样式的路径。此路径仅对在Sage的Cygwin环境下运行的其他程序有意义,对本机Windows程序没有意义。简单地将其转换为等效的Windows路径也不起作用,因为bin/sage实际上是一个shell脚本。至少您需要提供Cygwin随附的bash Windows 路径,并将 UNIX 路径传递给sage可执行文件(与上面的相同)。如果没有登录外壳,则大多数环境变量也不会设置,因此您可能需要bash -l

所以,像这样:

{"display_name": "SageMath 8.2", "argv": ["C:\\Program Files\\SageMath 8.2\\runtime\\bin\\bash.exe", "-l", "/opt/sagemath-8.2/local/bin/sage", "--python", "-m", "sage.repl.ipython_kernel", "-f", "{connection_file}"]}

可能起作用。我不确定的一件事是{connection_file}参数是否会被正确处理。我还没有测试。

更新:确实,以上内容部分起作用,但是存在一些问题:{connection_file}参数作为Windows绝对路径传递给文件。虽然Cygwin通常可以从Windows路径透明地转换为相应的UNIX路径,但是known issue上Cygwin上的Python os.path模块不能很好地处理Windows样式的路径,这会导致问题。

我遇到的另一个主要问题是IPKernelApp这个驱动通用Jupyter内核的类具有一个线程,该线程进行轮询以查看内核的父进程(在本例中为笔记本服务器)是否已退出,因此它如果家长关闭,可以适当关闭。这是内核知道在杀死笔记本服务器时自动关闭的方式。

如何完成此操作因平台而异-Windows与类似UNIX的平台不同。由于Sage的内核在Cygwin中运行,因此它选择了类似UNIX的轮询器。但是,如果笔记本服务器恰好是本地Windows进程,则这是错误的,就像在Windows本地Jupyter中运行Sage内核时一样。值得注意的是,parent poller for Windows 在Cygwin上也可以正常工作,因为它通过ctypes访问Windows API。因此,可以通过为IPKernelApp提供一个包装程序来强制使用ParentPollerWindows来解决此问题。

然后可能的解决方案如下所示:从SageMath Shell中执行:

$ cd ~
$ mkdir -p ./local/share/jupyter/kernels/sagemath
$ cd ./local/share/jupyter/kernels/sagemath
$ cat <<_EOF_ > kernel-wrapper.sh
#!/bin/sh
here="$(dirname "$0")"
connection_file="$(cygpath -u -a "$1")"
exec /opt/sagemath-8.2/local/bin/sage --python "${here}/kernel-wrapper.py" -f "${connection_file}"
_EOF_
$ cat <<_EOF_ > kernel-wrapper.py
from ipykernel.kernelapp import IPKernelApp as OrigIPKernelApp
from ipykernel.parentpoller import ParentPollerWindows
from sage.repl.ipython_kernel.kernel import SageKernel


class IPKernelApp(OrigIPKernelApp):
    """
    Although this kernel runs under Cygwin, its parent is a native Windows
    process, so we force use of the ParentPollerWindows.
    """

    def init_poller(self):
        if self.interrupt or self.parent_handle:
            self.poller = ParentPollerWindows(self.interrupt,
                                              self.parent_handle)


IPKernelApp.launch_instance(kernel_class=SageKernel)
_EOF_

现在编辑kernel.json(在share\jupyter\kernels\sagemath下的现有位置)以读取:

{"display_name": "SageMath 8.2", "argv": ["C:\\Program Files\\SageMath 8.2\\runtime\\bin\\bash.exe", "-l", ".local/share/jupyter/kernels/sagemath/kernel-wrapper.sh", "{connection_file}"]}

此命令运行kernel-wrapper.sh,而后者依次运行kernel-wrapper.py。 (我可以做一些简化,以完全摆脱对kernel-wrapper.sh的需求,但这在包含PyCygwin的SageMath 8.3中会更容易。)

如您所见,这并非微不足道,而且绝不是故意设计的。但这是可以完成的。内核本身启动并运行后,只需通过TCP / IP套接字与之对话即可,因此在此之后不会涉及太多魔术。我相信在Jupyter方面和Sage方面都可以进行一些小的改进,这些改进将来会促进这种事情的发生。