source: issm/trunk-jpl/externalpackages/petsc-dev/src/config/PETSc/utilities/cacheDetails.py@ 11896

Last change on this file since 11896 was 11896, checked in by habbalf, 13 years ago

petsc-dev : Petsc development code in external packages. Mercurial updates

File size: 4.3 KB
Line 
1import config.base
2import os
3import sys
4import string
5
6class CacheAttribute(object):
7 def __init__(self, name, keyword, help, default=None, min=0, max=min(sys.maxint,2**31-1)):
8 self.name = name
9 self.help = help
10 self.keyword = keyword
11 self.default = default
12 self.min = min
13 self.max = max
14 def valid(self,val):
15 return self.min <= val <= self.max
16 def sanitize(self,val):
17 if self.valid(val):
18 return val
19 else:
20 return self.default
21 def enum(self):
22 return self.name.upper().replace('-','_')
23
24class Configure(config.base.Configure):
25 def __init__(self, framework):
26 config.base.Configure.__init__(self, framework)
27 self.headerPrefix = 'PETSC'
28 self.substPrefix = 'PETSC'
29 self.updated = 0
30 self.strmsg = ''
31 self.attrs = [CacheAttribute('level1-dcache-size', 'int', 'Size in bytes of Level 1 data cache', 32768, 16),
32 CacheAttribute('level1-dcache-linesize', 'int', 'Size in bytes of each line of the Level 1 data cache', 32, 16),
33 CacheAttribute('level1-dcache-assoc', 'int', 'Associativity of the Level 1 data cache, 0 for full associative', 2, 0)]
34 self.method = None
35 return
36
37 def __str__(self):
38 return self.strmsg
39
40 def setupHelp(self, help):
41 import nargs
42 for a in self.attrs:
43 help.addArgument('PETSc', '-known-'+a.name+'=<'+a.keyword+'>', nargs.ArgInt(None, None, a.help, min=a.min, max=a.max))
44 return
45
46 def setupDependencies(self, framework):
47 config.base.Configure.setupDependencies(self, framework)
48 self.compilers = framework.require('config.compilers', self)
49 self.headers = framework.require('config.headers', self)
50 return
51
52 def getconfFunction(self, a):
53 VAR = a.enum()
54 funcname = 'getconf_' + VAR
55 sanitize = '('+str(a.min)+' <= val && val <= '+str(a.max)+') ? val : '+str(a.default)
56 methods = [
57 # On some systems, maybe just with glibc, sysconf can provide this stuff
58 '#include <unistd.h>\nlong '+funcname+'() { long val = sysconf(_SC_'+VAR+'); return '+sanitize+'; }\n'
59 ,
60 # A total hack since this will compile with any C compiler, but only return useful results when the getconf program is available
61 '#include <stdio.h>\nlong '+funcname+'() { long val=-1; FILE *f = popen("getconf '+VAR+'","r"); fscanf(f,"%ld",&val); pclose(f); return '+sanitize+'; }\n'
62 ,
63 # Fallback that just returns the default, guaranteed to compile
64 'long '+funcname+'() { return '+str(a.default)+'; }\n'
65 ]
66 if self.method is None: # Determine which method of finding configuration variables, only runs the first time around
67 self.pushLanguage('C')
68 for m in range(len(methods)):
69 d = methods[m]
70 if self.checkCompile(d,''):
71 self.method = m
72 break
73 self.popLanguage()
74 if self.method is None:
75 raise RuntimeError("The C compiler does not work")
76 return (funcname,methods[self.method])
77
78 def configureCacheDetails(self):
79 '''Try to determine the size and associativity of the cache.'''
80 for a in self.attrs:
81 arg = 'known-' + a.name
82 (fname, source) = self.getconfFunction(a)
83 if arg in self.framework.argDB:
84 val = self.framework.argDB[arg]
85 elif self.framework.argDB['with-batch']:
86 body = 'freopen("/dev/null","w",stderr);\n' + 'fprintf(output," \'--'+arg+'=%ld\',\\n",'+fname+'());'
87 self.framework.addBatchInclude(source)
88 self.framework.addBatchBody(body)
89 val = a.default
90 else:
91 filename = 'conftestval'
92 includes = '#include <stdio.h>\n'
93 body = 'FILE *output = fopen("'+filename+'","w"); if (!output) return 1; fprintf(output,"%ld",'+fname+'()); fclose(output);'
94 self.pushLanguage('C')
95 if self.checkRun(includes+source, body) and os.path.exists(filename):
96 f = open(filename)
97 val = int(f.read())
98 if not a.valid(val):
99 self.framework.log.write('Cannot use value returned for '+str(a.enum())+': '+str(val)+'\n')
100 f.close()
101 else:
102 self.framework.log.write('Could not determine '+str(a.enum())+', using default '+str(a.default)+'\n')
103 val = a.default
104 self.popLanguage()
105 self.addDefine(a.enum(), a.sanitize(val))
106
107 def configure(self):
108 self.executeTest(self.configureCacheDetails)
109 return
Note: See TracBrowser for help on using the repository browser.