Last active
March 18, 2016 22:16
-
-
Save wasade/82e5e776dba14a84e8b8 to your computer and use it in GitHub Desktop.
Example of using joblib to run systemcalls in parallel complete with ipy magics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"import subprocess\n", | |
"import functools\n", | |
"from IPython.core.magic import line_magic, Magics, magics_class, line_cell_magic\n", | |
"import joblib\n", | |
"\n", | |
"\n", | |
"def systemcall(to_exec):\n", | |
" proc = subprocess.Popen(to_exec, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", | |
" stdout, stderr = proc.communicate()\n", | |
" retval = proc.returncode\n", | |
"\n", | |
" return(stdout, stderr, retval)\n", | |
"\n", | |
"\n", | |
"@magics_class\n", | |
"class JobManager(Magics):\n", | |
" jobs = []\n", | |
" ncpus = 2\n", | |
" \n", | |
" def __init__(self, shell, systemcaller):\n", | |
" super(JobManager, self).__init__(shell)\n", | |
" self.shell = shell\n", | |
" self.systemcall = systemcaller\n", | |
" \n", | |
" @line_magic\n", | |
" def stage(self, line):\n", | |
" self.jobs.append(line)\n", | |
" \n", | |
" @line_cell_magic\n", | |
" def execute(self, line, cell=None):\n", | |
" if cell is not None:\n", | |
" self.shell.run_cell(cell)\n", | |
" \n", | |
" to_run = self.jobs\n", | |
" self.jobs = []\n", | |
" \n", | |
" if to_run:\n", | |
" return joblib.Parallel(n_jobs=self.ncpus)(joblib.delayed(self.systemcall)(f) for f in to_run)\n", | |
" else:\n", | |
" return []\n", | |
" \n", | |
" \n", | |
"ip = get_ipython()\n", | |
"magics = JobManager(ip, systemcall)\n", | |
"ip.register_magics(magics)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Stage and run some commands in parallel. Displaying cell runtime as, with 2 processors, we expect 1 to be blocked with the delay, and the other processor to execute the remaining trivial tasks. As such, we expect walltime here to be approximately `==` to `delay`. Note that passing variables as works as with the `!` syntax." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"10.142510175704956\n" | |
] | |
} | |
], | |
"source": [ | |
"import time\n", | |
"start = time.time()\n", | |
"delay = 10\n", | |
"%stage sleep $delay\n", | |
"%stage hostname\n", | |
"%stage uptime\n", | |
"%stage foobar\n", | |
"%execute\n", | |
"print(time.time() - start)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We just executed in the prior cell, so there should be nothing to execute now." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[]" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%execute" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can also use a \"cell magic\" which will automagically run the staged commands in the cell." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[(b'sandbar.local\\n', b'', 0),\n", | |
" (b'15:11 up 23:02, 7 users, load averages: 1.68 1.59 1.57\\n', b'', 0),\n", | |
" (b'', b'', 0),\n", | |
" (b'', b'/bin/sh: foobar: command not found\\n', 127)]" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%%execute\n", | |
"delay = 2\n", | |
"%stage hostname\n", | |
"%stage uptime\n", | |
"%stage sleep $delay\n", | |
"%stage foobar" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"UsageError: %%execute is a cell magic, but the cell body is empty. Did you mean the line magic %execute (single %)?" | |
] | |
} | |
], | |
"source": [ | |
"%%execute" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.1" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment