Show More
@@ -20,6 +20,7 b' import warnings' | |||||
20 |
|
20 | |||
21 | import zmq |
|
21 | import zmq | |
22 |
|
22 | |||
|
23 | from IPython.config.configurable import MultipleInstanceError | |||
23 | from IPython.zmq import check_for_zmq |
|
24 | from IPython.zmq import check_for_zmq | |
24 |
|
25 | |||
25 | if os.name == 'nt': |
|
26 | if os.name == 'nt': | |
@@ -51,12 +52,23 b' def bind_kernel(**kwargs):' | |||||
51 |
|
52 | |||
52 | This function returns immediately. |
|
53 | This function returns immediately. | |
53 | """ |
|
54 | """ | |
|
55 | from IPython.zmq.ipkernel import IPKernelApp | |||
54 | from IPython.parallel.apps.ipengineapp import IPEngineApp |
|
56 | from IPython.parallel.apps.ipengineapp import IPEngineApp | |
|
57 | ||||
|
58 | # first check for IPKernelApp, in which case this should be a no-op | |||
|
59 | # because there is already a bound kernel | |||
|
60 | if IPKernelApp.initialized() and isinstance(IPKernelApp._instance, IPKernelApp): | |||
|
61 | return | |||
|
62 | ||||
55 | if IPEngineApp.initialized(): |
|
63 | if IPEngineApp.initialized(): | |
|
64 | try: | |||
56 | app = IPEngineApp.instance() |
|
65 | app = IPEngineApp.instance() | |
|
66 | except MultipleInstanceError: | |||
|
67 | pass | |||
57 | else: |
|
68 | else: | |
58 | raise RuntimeError("Must be called from an IPEngineApp instance") |
|
|||
59 |
|
||||
60 | return app.bind_kernel(**kwargs) |
|
69 | return app.bind_kernel(**kwargs) | |
61 |
|
70 | |||
|
71 | raise RuntimeError("bind_kernel be called from an IPEngineApp instance") | |||
|
72 | ||||
|
73 | ||||
62 |
|
74 |
@@ -420,6 +420,16 b' class KernelMagics(Magics):' | |||||
420 | Useful for connecting a qtconsole to running notebooks, for better |
|
420 | Useful for connecting a qtconsole to running notebooks, for better | |
421 | debugging. |
|
421 | debugging. | |
422 | """ |
|
422 | """ | |
|
423 | ||||
|
424 | # %qtconsole should imply bind_kernel for engines: | |||
|
425 | try: | |||
|
426 | from IPython.parallel import bind_kernel | |||
|
427 | except ImportError: | |||
|
428 | # technically possible, because parallel has higher pyzmq min-version | |||
|
429 | pass | |||
|
430 | else: | |||
|
431 | bind_kernel() | |||
|
432 | ||||
423 | try: |
|
433 | try: | |
424 | p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) |
|
434 | p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) | |
425 | except Exception as e: |
|
435 | except Exception as e: |
@@ -554,6 +554,64 b' on the engines until you do ``%autopx`` again.' | |||||
554 | Auto Parallel Disabled |
|
554 | Auto Parallel Disabled | |
555 |
|
555 | |||
556 |
|
556 | |||
|
557 | Engines as Kernels | |||
|
558 | ****************** | |||
|
559 | ||||
|
560 | Engines are really the same object as the Kernels used elsewhere in IPython, | |||
|
561 | with the minor exception that engines connect to a controller, while regular kernels | |||
|
562 | bind their sockets, listening for connections from a QtConsole or other frontends. | |||
|
563 | ||||
|
564 | Sometimes for debugging or inspection purposes, you would like a QtConsole connected | |||
|
565 | to an engine for more direct interaction. You can do this by first instructing | |||
|
566 | the Engine to *also* bind its kernel, to listen for connections: | |||
|
567 | ||||
|
568 | .. sourcecode:: ipython | |||
|
569 | ||||
|
570 | In [50]: %px from IPython.parallel import bind_kernel; bind_kernel() | |||
|
571 | ||||
|
572 | Then, if your engines are local, you can start a qtconsole right on the engine(s): | |||
|
573 | ||||
|
574 | .. sourcecode:: ipython | |||
|
575 | ||||
|
576 | In [51]: %px %qtconsole | |||
|
577 | ||||
|
578 | Careful with this one, because if your view is of 16 engines it will start 16 QtConsoles! | |||
|
579 | ||||
|
580 | Or you can view just the connection info, and work out the right way to connect to the engines, | |||
|
581 | depending on where they live and where you are: | |||
|
582 | ||||
|
583 | .. sourcecode:: ipython | |||
|
584 | ||||
|
585 | In [51]: %px %connect_info | |||
|
586 | Parallel execution on engine(s): [0, 1, 2, 3] | |||
|
587 | [stdout:0] | |||
|
588 | { | |||
|
589 | "stdin_port": 60387, | |||
|
590 | "ip": "127.0.0.1", | |||
|
591 | "hb_port": 50835, | |||
|
592 | "key": "eee2dd69-7dd3-4340-bf3e-7e2e22a62542", | |||
|
593 | "shell_port": 55328, | |||
|
594 | "iopub_port": 58264 | |||
|
595 | } | |||
|
596 | ||||
|
597 | Paste the above JSON into a file, and connect with: | |||
|
598 | $> ipython <app> --existing <file> | |||
|
599 | or, if you are local, you can connect with just: | |||
|
600 | $> ipython <app> --existing kernel-60125.json | |||
|
601 | or even just: | |||
|
602 | $> ipython <app> --existing | |||
|
603 | if this is the most recent IPython session you have started. | |||
|
604 | [stdout:1] | |||
|
605 | { | |||
|
606 | "stdin_port": 61869, | |||
|
607 | ... | |||
|
608 | ||||
|
609 | .. note:: | |||
|
610 | ||||
|
611 | ``%qtconsole`` will call :func:`bind_kernel` on an engine if it hasn't been done already, | |||
|
612 | so you can often skip that first step. | |||
|
613 | ||||
|
614 | ||||
557 | Moving Python objects around |
|
615 | Moving Python objects around | |
558 | ============================ |
|
616 | ============================ | |
559 |
|
617 |
General Comments 0
You need to be logged in to leave comments.
Login now