如何在 Anaconda 中安装 SageMath 内核?

How to install SageMath kernel in Anaconda?

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

我首先创建了一个新环境 'ipykernel_py2',然后按照 here 中的说明安装了 Python 2。有了这个,我可以在 Anaconda 3 中同时拥有 Python 3 和 Python 3 以及 运行ning。

然后我去创建内核的文件夹(C:\Users\YOUR_USERNAME\AppData\Local\Continuum\anaconda3\envs\ipykernel_py2\share\jupyter\kernels)并粘贴Sage的内核(取自C:\Program Files\SageMath 8.2\runtime\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 文件。但是,图书馆仍然无法正常工作。该文件似乎 运行ning 像一个普通的 Python 2 文件。

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

Windows 的 Sage 在称为 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 脚本。至少你需要提供一个 Windows 路径到 Cygwin 附带的 bash 并将它传递给 UNIX sage 可执行文件的路径(与上面的相同)。如果没有登录 shell,大多数所需的环境变量也不会设置,因此您可能需要 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 内核的 class,有一个线程轮询内核的父进程(在本例中是笔记本服务器) ) 已经退出,因此如果父级关闭,它可以适当地关闭。这就是内核知道在您终止笔记本服务器时自动关闭的方式。

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

一个可能的解决方案看起来像这样:从 SageMath Shell 中执行:

$ cd "$SAGE_LOCAL"
$ mkdir -p ./share/jupyter/kernels/sagemath
$ cd ./share/jupyter/kernels/sagemath
$ cat <<_EOF_ > kernel-wrapper.sh
#!/bin/sh
here="$(dirname "[=12=]")"
connection_file="$(cygpath -u -a "")"
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", "/opt/sagemath-8.2/local/share/jupyter/kernels/sagemath/kernel-wrapper.sh", "{connection_file}"]}

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

确保将每个“8.2”更改为适合您的 Sage 安装的“X.Y”版本。

更新: 根据用户的反馈进行了一些更新,但我还没有测试这些更改,所以请确保而不是盲目 copy/pasting我的说明中的每个 file/directory 路径都存在并且看起来正确。

如您所见,这不是微不足道的,而且从来都不是设计使然的。但这是可以完成的。一旦内核本身启动并且 运行 它只是通过 TCP/IP 套接字与它交谈的问题,所以在那之后就没有太多的魔法了。我相信可以在 Jupyter 端和 Sage 端进行一些小的改进,这将在未来促进此类事情...