Source code for miv_simulator.lpt

import heapq

from miv_simulator.utils import get_module_logger

# This logger will inherit its settings from the root logger, created in dentate.env
logger = get_module_logger(__name__)


## Code by Michael Hines from the discussion thread
## https://www.neuron.yale.edu/phpBB/viewtopic.php?f=31&t=3628
[docs]def lpt(cx, npart): """From the list of (cx, gid) return a npart length list with each partition being a total_cx followed by a list of (cx, gid).""" cx.sort(key=lambda x: x[0], reverse=True) # initialize a priority queue for fast determination of current # partition with least complexity. The priority queue always has # npart items in it. At this time we do not care which partition will # be associated with which rank so a partition on the heap is just # (totalcx, [list of (cx, gid)] h = [] for i in range(npart): heapq.heappush(h, (0.0, [])) # each cx item goes into the current least complex partition for c in cx: lp = heapq.heappop(h) # least partition lp[1].append(c) heapq.heappush(h, (lp[0] + c[0], lp[1])) parts = [heapq.heappop(h) for i in range(len(h))] return parts
def statistics(parts): npart = len(parts) total_cx = 0 max_part_cx = 0 ncx = 0 max_cx = 0 for part in parts: ncx += len(part[1]) total_cx += part[0] if part[0] > max_part_cx: max_part_cx = part[0] for cx in part[1]: if cx[0] > max_cx: max_cx = cx[0] avg_part_cx = total_cx / npart loadbal = 1.0 if max_part_cx > 0.0: loadbal = avg_part_cx / max_part_cx print( "*** loadbal=%g total_cx=%g npart=%d ncx=%d max_part_cx=%g max_cx=%g" % (loadbal, total_cx, npart, ncx, max_part_cx, max_cx) ) if __name__ == "__main__": for cx in ([(i, i) for i in range(10)], []): logger.info(f"{len(cx)} complexity items {cx}") pinfo = lpt(cx, 3) logger.info(f"{len(pinfo)} lpt partitions {str(pinfo)}") statistics(pinfo)