如何在Anaconda中安装SageMath内核?

4
我正在尝试在Anaconda 3中使用Sage,但似乎库没有被导入。首先我创建了一个新的环境'ipykernel_py2',然后按照这里的说明安装了Python 2。这样,我可以在Anaconda 3中同时运行Python 3和Python 2。接下来,我进入内核文件夹(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提示符,并键入:
activate ipykernel_py2
python -m ipykernel install --user --name sagemath --display-name "SageMath 8.2"

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

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

1个回答

4
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脚本。至少需要提供一个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}"]}
< p > < em >可能有效。 我不确定的一件事是{connection_file}参数是否会被正确处理。我还没有测试过。

更新:事实上,上述方法部分有效,但存在一些问题:传递的{connection_file}参数是文件的绝对Windows路径。虽然Cygwin通常可以透明地将Windows路径转换为相应的UNIX路径,但这存在一个已知问题,即Cygwin上的Python的os.path模块无法很好地处理Windows风格的路径,这会导致问题。

我遇到的另一个主要问题是IPKernelApp,这个类驱动通用的Jupyter内核,有一个线程来轮询内核的父进程(在本例中为笔记本服务器)是否已退出,以便在父进程关闭时适当地关闭内核。这就是内核如何知道在您关闭笔记本服务器时自动关闭的方式。
这是根据平台的不同方式完成的--Windows与UNIX-like。由于Sage的内核在Cygwin中运行,它选择了UNIX-like的轮询程序。然而,如果笔记本服务器恰好是本机Windows进程,比如在Windows本机Jupyter中运行Sage内核时,这是错误的。令人惊讶的是,Windows的父级轮询程序 可以 在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 "$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_

现在编辑 share\jupyter\kernels\sagemath 下的 kernel.json 文件,使其内容如下:
{"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”版本。

更新:根据用户反馈进行了一些更新,但我还没有测试这些更改,因此请确保不要盲目复制/粘贴我的说明中的每个文件/目录路径都存在并且正确。

正如您所看到的,这并不是微不足道的,也不是通过设计意图可能实现的。但它可以完成。一旦内核本身启动并运行,就只需要通过TCP / IP套接字与其通信,因此在此之后没有太多魔法。我相信在Jupyter端和Sage端都可以进行一些小的改进,以促进将来这种事情的实现...


出于好奇,我试了一下,它几乎可以工作,除了我担心的{connection_file}没有被正确传递。让我看看是否能想到一个解决方法... - Iguananaut
我能够在整个过程周围放置一个包装脚本,以处理映射连接文件的文件名,这似乎有效。然而,现在似乎又出现了另一个问题,即笔记本似乎认为内核已经死亡,即使它并没有死亡。这很有趣,因为如果我直接运行内核(使用手动连接文件名),然后通过jupyter run传递命令给它,它就可以工作。所以也许还存在其他关于进程管理的混淆问题... - Iguananaut
感谢@Iguananaut提供详细的答案。不幸的是,我担心我无法实现它,因为我只是一个基本的Python用户,我的编程技能有限。像你所解释的那样,似乎有一种方法可以做到这一点,但对于基本用户来说过于繁琐。我将继续像以前一样使用我的SageMath shell。 - J. Serra
我建议你还是试一试。我已经几乎给出了要运行的命令,如果你这样做,它应该可以正常工作。注意,Sage也带有笔记本... - Iguananaut
@Iguananaut,希望你还在。我正在尝试按照你上面说的来帮助一位学生。不幸的是,我自己并不习惯这些,因为我个人不使用Windows。当我尝试创建“kernel-wrapper.sh”时,我遇到了一个错误“cygpath无法转换空路径”,实际上,文件中的那一行是 connection_file="" 你知道我需要在这里做什么吗?我猜我需要设置一些路径,但是哪些路径以及如何设置呢? - MWL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接