From b2fd8ff3f9594e7b7aa1d30e7269c4e08fc45854 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <PitelVonSacek@gmail.com>
Date: Wed, 9 Dec 2015 14:28:50 +0100
Subject: [PATCH] Parallelize generateSubdivisions()
---
.gitignore | 2 ++
Makefile | 2 +-
groupConnectivity.pyx | 16 +++++++++++++---
parmap.py | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 52 insertions(+), 4 deletions(-)
create mode 100644 parmap.py
diff --git a/.gitignore b/.gitignore
index eab1f01..35e4cba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
.*.swp
groupConnectivity.so
+parmap.pyc
+
diff --git a/Makefile b/Makefile
index c870548..572cac9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
default: groupConnectivity.so clean_obj
-groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h
+groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h parmap.py
python setup.py build_ext
cp build/lib*/groupConnectivity.so .
diff --git a/groupConnectivity.pyx b/groupConnectivity.pyx
index 2cb2506..7e30885 100644
--- a/groupConnectivity.pyx
+++ b/groupConnectivity.pyx
@@ -2,6 +2,7 @@ from libcpp.vector cimport vector
from libcpp cimport bool
from libcpp.utility cimport pair
from sage.graphs.graph import Graph
+from parmap import parmap
cdef extern from "group-connectivity.h" namespace "Ring":
cdef cppclass Z4[T]:
@@ -87,12 +88,21 @@ def subdivisionIterator(G, edges = None):
for L in subdivisionIterator(H, edges[1:]):
yield L
-def generateSubdivisions(file, G, edges = None, function = lambda H: H.graph6_string()):
+
+def generateSubdivisions(file, G, edges = None,
+ function = lambda H: H.graph6_string(),
+ parallel = 1):
f = open(file, 'w+')
f.write("# Subdivisions of edges '%s' of graph '%s' (%s)\n" %
(edges, G.graph6_string(), G))
- for H in subdivisionIterator(G, edges):
- f.write(function(H))
+
+ if parallel == 1:
+ iterator = map(function, subdivisionIterator(G, edges))
+ else:
+ iterator = parmap(function, subdivisionIterator(G, edges), parallel)
+
+ for line in iterator:
+ f.write(line)
f.write("\n")
f.close()
diff --git a/parmap.py b/parmap.py
new file mode 100644
index 0000000..411820d
--- /dev/null
+++ b/parmap.py
@@ -0,0 +1,36 @@
+# modified version of code written by klaus se from
+# http://stackoverflow.com/a/16071616
+
+import multiprocessing
+
+def fun(f, q_in, q_out):
+ while True:
+ i,x = q_in.get()
+ if i is None:
+ break
+ q_out.put((i, f(x)))
+
+def parmap(f, X, nprocs = None):
+ if nprocs is None:
+ nprocs = multiprocessing.cpu_count()
+
+ q_in = multiprocessing.Queue(100)
+ q_out = multiprocessing.Queue()
+
+ proc = [multiprocessing.Process(target=fun,args=(f,q_in,q_out)) for _ in range(nprocs)]
+ for p in proc:
+ p.daemon = True
+ p.start()
+
+ sent = [q_in.put((i,x)) for i,x in enumerate(X)]
+ [q_in.put((None,None)) for _ in range(nprocs)]
+
+ ret = {}
+ for _ in range(len(sent)):
+ i, val = q_out.get()
+ ret[i] = val
+
+ [ p.join() for p in proc ]
+
+ return [ ret[i] for i in range(len(sent)) ]
+
--
GitLab