теперь работают с функцией Python multicore
в течение более часа, пытаясь распараллелить довольно сложную функцию обхода графика с помощью Process
и Manager
:
import networkx as nx
import csv
import time
from operator import itemgetter
import os
import multiprocessing as mp
cutoff = 1
exclusionlist = ["cpd:C00024"]
DG = nx.read_gml("KeggComplete.gml", relabel = True)
for exclusion in exclusionlist:
DG.remove_node(exclusion)
#checks if 'memorizedPaths exists, and if not, creates it
fn = os.path.join(os.path.dirname(__file__), 'memorizedPaths' + str(cutoff+1))
if not os.path.exists(fn):
os.makedirs(fn)
manager = mp.Manager()
memorizedPaths = manager.dict()
filepaths = manager.dict()
degreelist = sorted(DG.degree_iter(),key=itemgetter(1),reverse=True)
def _all_simple_paths_graph(item, DG, cutoff, memorizedPaths, filepaths):
source = item[0]
uniqueTreePaths = []
if cutoff < 1:
return
visited = [source]
stack = [iter(DG[source])]
while stack:
children = stack[-1]
child = next(children, None)
if child is None:
stack.pop()
visited.pop()
elif child in memorizedPaths:
for path in memorizedPaths[child]:
newPath = (tuple(visited) + tuple(path))
if (len(newPath) <= cutoff) and (len(set(visited) & set(path)) == 0):
uniqueTreePaths.append(newPath)
continue
elif len(visited) < cutoff:
if child not in visited:
visited.append(child)
stack.append(iter(DG[child]))
if visited not in uniqueTreePaths:
uniqueTreePaths.append(tuple(visited))
else: #len(visited) == cutoff:
if (visited not in uniqueTreePaths) and (child not in visited):
uniqueTreePaths.append(tuple(visited + [child]))
stack.pop()
visited.pop()
#writes the absolute path of the node path file into the hash table
filepaths[source] = str(fn) + "/" + str(source) +"path.txt"
with open (filepaths[source], "wb") as csvfile2:
writer = csv.writer(csvfile2, delimiter=' ', quotechar='|')
for path in uniqueTreePaths:
writer.writerow(path)
memorizedPaths[source] = uniqueTreePaths
############################################################################
start = time.clock()
if __name__ == '__main__':
for item in degreelist:
test = mp.Process(target=_all_simple_paths_graph, args=(DG, cutoff, item, memorizedPaths, filepaths))
test.start()
test.join()
end = time.clock()
print (end-start)
В настоящее время - хотя удача и магия - это работает (вроде). Моя проблема в том, что я использую только 12 из моих 24 ядер.
Может кто-нибудь объяснить, почему это может быть так? Возможно, мой код - не лучшее многопроцессорное решение, или это особенность моей архитектуры [Intel Xeon CPU E5-2640 @2.50GHz x18 работает на Ubuntu 13.04 x64]?
EDIT:
Мне удалось получить:
p = mp.Pool()
for item in degreelist:
p.apply_async(_all_simple_paths_graph, args=(DG, cutoff, item, memorizedPaths, filepaths))
p.close()
p.join()
Работая, однако, ОЧЕНЬ МЕДЛЕННО! Поэтому я предполагаю, что я использую неправильную функцию для работы. надеюсь, это поможет прояснить то, что я пытаюсь выполнить!
EDIT2: .map
попытка:
partialfunc = partial(_all_simple_paths_graph, DG=DG, cutoff=cutoff, memorizedPaths=memorizedPaths, filepaths=filepaths)
p = mp.Pool()
for item in processList:
processVar = p.map(partialfunc, xrange(len(processList)))
p.close()
p.join()
Работает медленнее, чем singlecore. Время для оптимизации!