1be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbarimport os, sys
2be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
3be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef detectCPUs():
4be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    """
5be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    Detects the number of CPUs on a system. Cribbed from pp.
6be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    """
7be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Linux, Unix and MacOS:
8be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if hasattr(os, "sysconf"):
9be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
10be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            # Linux & Unix:
11be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
12be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            if isinstance(ncpus, int) and ncpus > 0:
13be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                return ncpus
14be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        else: # OSX:
152f494b6afc921369c4878ec54646b077e4a3e81eJordy Rose            return int(capture(['sysctl', '-n', 'hw.ncpu']))
16be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Windows:
17be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if os.environ.has_key("NUMBER_OF_PROCESSORS"):
18a7f1d72d09f174da56217c0776dcab74998e50b9Dan Gohman        ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
19be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        if ncpus > 0:
20be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            return ncpus
21be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    return 1 # Default
22be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
23be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef mkdir_p(path):
24be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    """mkdir_p(path) - Make the "path" directory, if it does not exist; this
25be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    will also make directories for any missing parent directories."""
26be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    import errno
27be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
28be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if not path or os.path.exists(path):
29be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        return
30be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
31be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    parent = os.path.dirname(path)
32be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if parent != path:
33be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        mkdir_p(parent)
34be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
35be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    try:
36be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        os.mkdir(path)
37be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    except OSError,e:
38be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        # Ignore EEXIST, which may occur during a race condition.
39be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        if e.errno != errno.EEXIST:
40be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            raise
41be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
428d280fb50a1c35a4b598bf722038b7f0d71e90d0Jeffrey Yasskindef capture(args, env=None):
43be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    import subprocess
44be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    """capture(command) - Run the given command (or argv list) in a shell and
45be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    return the standard output."""
468d280fb50a1c35a4b598bf722038b7f0d71e90d0Jeffrey Yasskin    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
478d280fb50a1c35a4b598bf722038b7f0d71e90d0Jeffrey Yasskin                         env=env)
48be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    out,_ = p.communicate()
49be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    return out
50be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
51be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef which(command, paths = None):
52be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    """which(command, [paths]) - Look up the given command in the paths string
53be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    (or the PATH environment variable, if unspecified)."""
54be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
55be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if paths is None:
56be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        paths = os.environ.get('PATH','')
57be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
58be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Check for absolute match first.
5946b4b112d23cdec5d27e2ebf70fc492be3786316NAKAMURA Takumi    if os.path.isfile(command):
60be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        return command
61be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
62be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Would be nice if Python had a lib function for this.
63be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if not paths:
64be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        paths = os.defpath
65be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
66be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Get suffixes to search.
67f5201bcd3b57e6b96ae3293b3a9c31ab49dd967cNAKAMURA Takumi    # On Cygwin, 'PATHEXT' may exist but it should not be used.
68f5201bcd3b57e6b96ae3293b3a9c31ab49dd967cNAKAMURA Takumi    if os.pathsep == ';':
69f5201bcd3b57e6b96ae3293b3a9c31ab49dd967cNAKAMURA Takumi        pathext = os.environ.get('PATHEXT', '').split(';')
70f5201bcd3b57e6b96ae3293b3a9c31ab49dd967cNAKAMURA Takumi    else:
71f5201bcd3b57e6b96ae3293b3a9c31ab49dd967cNAKAMURA Takumi        pathext = ['']
72be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
73be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Search the paths...
74be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    for path in paths.split(os.pathsep):
75be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        for ext in pathext:
76be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            p = os.path.join(path, command + ext)
77be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            if os.path.exists(p):
78be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                return p
79be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
80be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    return None
81be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
82df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumidef checkToolsPath(dir, tools):
83df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi    for tool in tools:
84df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi        if not os.path.exists(os.path.join(dir, tool)):
85df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi            return False;
86df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi    return True;
87df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi
88df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumidef whichTools(tools, paths):
89df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi    for path in paths.split(os.pathsep):
90df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi        if checkToolsPath(path, tools):
91df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi            return path
92df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi    return None
93df944f1f83420b44e3a41d379c361b797c827b42NAKAMURA Takumi
94be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef printHistogram(items, title = 'Items'):
95be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    import itertools, math
96be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
97be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    items.sort(key = lambda (_,v): v)
98be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
99be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    maxValue = max([v for _,v in items])
100be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
101be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    # Select first "nice" bar height that produces more than 10 bars.
102be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    power = int(math.ceil(math.log(maxValue, 10)))
103be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    for inc in itertools.cycle((5, 2, 2.5, 1)):
104be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        barH = inc * 10**power
105be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        N = int(math.ceil(maxValue / barH))
106be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        if N > 10:
107be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            break
108be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        elif inc == 1:
109be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar            power -= 1
110be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
111be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    histo = [set() for i in range(N)]
112be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    for name,v in items:
113be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        bin = min(int(N * v/maxValue), N-1)
114be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        histo[bin].add(name)
115be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
116be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    barW = 40
117be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    hr = '-' * (barW + 34)
118be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print '\nSlowest %s:' % title
119be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print hr
120be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    for name,value in items[-20:]:
121be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        print '%.2fs: %s' % (value, name)
122be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print '\n%s Times:' % title
123be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print hr
124be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    pDigits = int(math.ceil(math.log(maxValue, 10)))
125be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    pfDigits = max(0, 3-pDigits)
126be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    if pfDigits:
127be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        pDigits += pfDigits + 1
128be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    cDigits = int(math.ceil(math.log(len(items), 10)))
129be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print "[%s] :: [%s] :: [%s]" % ('Range'.center((pDigits+1)*2 + 3),
130be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                                    'Percentage'.center(barW),
131be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                                    'Count'.center(cDigits*2 + 1))
132be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    print hr
133be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar    for i,row in enumerate(histo):
134be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        pct = float(len(row)) / len(items)
135be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        w = int(barW * pct)
136be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        print "[%*.*fs,%*.*fs)" % (pDigits, pfDigits, i*barH,
137be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                                   pDigits, pfDigits, (i+1)*barH),
138be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar        print ":: [%s%s] :: [%*d/%*d]" % ('*'*w, ' '*(barW-w),
139be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                                          cDigits, len(row),
140be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar                                          cDigits, len(items))
141be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar
142