Mik*_*ike 9 python ipython jupyter
我想在一个ipython会话中打开几个内核,在这些内核上运行代码,然后收集结果.但我无法弄清楚如何收集结果,甚至看不到stdout/stderr.我怎么能做这些事情?
我已经管理了前两个步骤(打开内核并在其上运行代码),代码如下:
from jupyter_client import MultiKernelManager
kernelmanager = MultiKernelManager()
remote_id = kernelmanager.start_kernel('python3')
remote_kernel = kernelmanager.get_kernel(remote_id)
remote = remote_kernel.client()
sent_msg_id = remote.execute('2+2')
Run Code Online (Sandbox Code Playgroud)
[我欢迎任何有关如何改进或关闭这些内核和客户端的建议.]
这里,python3可以是我设置的任何内核的名称(可以在命令行中列出jupyter-kernelspec list).我似乎能够运行任何合理的代码来代替'2+2'.例如,我可以写入文件,并且该文件确实已创建.
现在,问题是如何获得结果.我可以得到一些看似相关的消息
reply = remote.get_shell_msg(sent_msg_id)
Run Code Online (Sandbox Code Playgroud)
那个回复是这样的字典:
{'buffers': [],
'content': {'execution_count': 2,
'payload': [],
'status': 'ok',
'user_expressions': {}},
'header': {'date': datetime.datetime(2015, 10, 19, 14, 34, 34, 378577),
'msg_id': '98e216b4-3251-4085-8eb1-bfceedbae3b0',
'msg_type': 'execute_reply',
'session': 'ca4d615d-82b7-487f-88ff-7076c2bdd109',
'username': 'me',
'version': '5.0'},
'metadata': {'dependencies_met': True,
'engine': '868de9dd-054b-4630-99b7-0face61915a6',
'started': '2015-10-19T14:34:34.265718',
'status': 'ok'},
'msg_id': '98e216b4-3251-4085-8eb1-bfceedbae3b0',
'msg_type': 'execute_reply',
'parent_header': {'date': datetime.datetime(2015, 10, 19, 14, 34, 34, 264508),
'msg_id': '2674c61a-c79a-48a6-b88a-1f2e8da68a80',
'msg_type': 'execute_request',
'session': '767ae562-38d6-41a3-a9dc-6faf37d83222',
'username': 'me',
'version': '5.0'}}
Run Code Online (Sandbox Code Playgroud)
这在Jupyter的Messaging中有记录.没有记录的是如何实际使用它 - 即,我使用哪些功能,何时何地找到消息等等.我已经看到了这个问题及其答案,其中包含有用的相关信息,但不是我帮我解答了.而这个答案没有得到任何有用的输出,无论是.
所以,例如,我试图msg_id在上面的结果中获得带有给定的msg ,但它只是挂起.我已经尝试了我能想到的一切,但无法弄清楚如何从内核中获取任何东西.我该怎么做?我可以用某种字符串从内核传回数据吗?我能看到它的标准和标准吗?
我正在写一个ipython魔术来在远程内核上运行代码片段.[编辑:这个现在存在并且可以在这里使用.]我的想法是,我的笔记本电脑上有一个笔记本电脑,只需要一个像这样的小魔术单元从几个远程服务器收集数据:
%%remote_exec -kernels server1,server2
2+2
! hostname
Run Code Online (Sandbox Code Playgroud)
我用来remote_ikernel轻松自动地连接到那些远程内核.这似乎工作得很好; 我已经得到了我的魔法命令,它的所有铃声和口哨都运行良好,打开这些远程内核,并运行代码.现在我想从远程发送回我的笔记本电脑的一些数据 - 大概是通过某种方式序列化它.目前,我认为pickle.dumps并且pickle.loads对于这一部分将是完美的; 我只需要将这些函数从一个内核创建并使用到另一个内核.我宁愿不使用实际文件进行酸洗,尽管这可能是可以接受的.
看起来像这样的一些怪物是可能的:
remote.get_shell_msg(remote.execute('import pickle'))
sent_msg_id = remote.execute('a=2+2', user_expressions={'output':'pickle.dumps({"a":a})'})
reply = remote.get_shell_msg(sent_msg_id)
output_bytes = reply['content']['user_expressions']['output']['data']['text/plain']
variable_dict = pickle.loads(eval(output_bytes))
Run Code Online (Sandbox Code Playgroud)
现在,variable_dict['a']只是4.但请注意,这output_bytes是一个表示这些字节的字符串,因此必须进行eval编辑.这看起来很荒谬(并且仍然没有显示我如何得到标准输出).有没有更好的办法?我怎么得到stdout?
虽然我对上面的hack不满意,但我已经成功地使用它来编写一个名为remote_exec托管在github上的小模块,如上所述.该模块给了我一些ipython魔术,我可以用来在一个或多个其他内核上远程运行代码.这是一个或多或少的自动过程,我绝对满意 - 除了对下面发生的事情的唠叨知识.
我的问题可能还不够清楚,但我的主要用例是在多台远程计算机(使用大规模并行代码计算数据的集群)上运行一些代码,以便我可以在远程存储的大型数据集上运行相当简单的命令,最小配置。对于这个目的来说,ipyparallel是行不通的。我基本上必须重写代码才能使用它。相反,我的模块remote_exec是完美的,允许我简单地添加集群的名称和工作目录,但在其他方面使用与我在本地使用的代码完全相同的代码。
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |