Last active
January 23, 2017 13:17
-
-
Save bede/9948ec835aae44ae2c019c3223348cf5 to your computer and use it in GitHub Desktop.
Simple Python3 parallelism
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": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Blocking parallelism in Python 3\n", | |
"Dispatch parallel commands and block until the last of them completes à la GNU Parallel.\n", | |
"- Uses available logical CPUs\n", | |
"- Python 3.2+\n", | |
"- Functions and arguments must be pickleable" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 1) Parallelising functions\n", | |
"### Just run the functions" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1\n", | |
"3\n", | |
"2\n" | |
] | |
} | |
], | |
"source": [ | |
"import concurrent.futures\n", | |
"\n", | |
"def run(function, iterable):\n", | |
" with concurrent.futures.ProcessPoolExecutor() as x:\n", | |
" result = x.map(function, iterable)\n", | |
" \n", | |
"run(print, [1,2,3]) " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Return list of function return values" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[1, 2, 3]" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"import concurrent.futures\n", | |
"\n", | |
"def run(function, iterable):\n", | |
" with concurrent.futures.ProcessPoolExecutor() as x:\n", | |
" return [r for r in x.map(function, iterable)]\n", | |
" \n", | |
"run(abs, [-1,-2,-3])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Return dict associating input and return values" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{-3: 3, -2: 2, -1: 1}" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"import concurrent.futures\n", | |
"\n", | |
"def run(function, iterable):\n", | |
" with concurrent.futures.ProcessPoolExecutor() as x:\n", | |
" return {iterable:r for iterable, r in zip(iterable, x.map(function, iterable))}\n", | |
" \n", | |
"run(abs, [-1,-2,-3])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 2) Parallelising subprocesses\n", | |
"Returns a list of `CompletedProcess` instances with input arguments, stdout, stderr and return code." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"import functools\n", | |
"import subprocess\n", | |
"import concurrent.futures\n", | |
"\n", | |
"def run_cmds(cmds):\n", | |
" run = functools.partial(subprocess.run,\n", | |
" shell=True,\n", | |
" check=True, # Raise CalledProcessError with non zero exit code\n", | |
" universal_newlines=True,\n", | |
" stdout=subprocess.PIPE, # Capture stdout\n", | |
" stderr=subprocess.PIPE) # Capture stderr \n", | |
" with concurrent.futures.ProcessPoolExecutor() as x:\n", | |
" return [r for r in x.map(run, cmds)]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[CompletedProcess(args='sleep 4; echo sleep4', returncode=0, stdout='sleep4\\n', stderr=''),\n", | |
" CompletedProcess(args='sleep 5; echo sleep5', returncode=0, stdout='sleep5\\n', stderr=''),\n", | |
" CompletedProcess(args='sleep 3; echo sleep3', returncode=0, stdout='sleep3\\n', stderr=''),\n", | |
" CompletedProcess(args='sleep 2; echo sleep2', returncode=0, stdout='sleep2\\n', stderr='')]" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"cmds = ['sleep 4; echo sleep4',\n", | |
" 'sleep 5; echo sleep5',\n", | |
" 'sleep 3; echo sleep3',\n", | |
" 'sleep 2; echo sleep2']\n", | |
"\n", | |
"run_cmds(cmds)" | |
] | |
} | |
], | |
"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.6.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment