00001 """
00002 Singleton class that contains all of the global variables
00003 """
00004
00005 __copyright__ = """
00006 Copyright 2008 Sean Ross-Ross
00007 """
00008 __license__ = """
00009 This file is part of SLIMpy .
00010
00011 SLIMpy is free software: you can redistribute it and/or modify
00012 it under the terms of the GNU Lesser General Public License as published by
00013 the Free Software Foundation, either version 3 of the License, or
00014 (at your option) any later version.
00015
00016 SLIMpy is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 GNU Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public License
00022 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00023 """
00024
00025 from slimpy_base.setup.DEFAULTS import DEFAULTS
00026 from pdb import set_trace
00027
00028 from os.path import abspath
00029 from slimpy_base.Environment.Singleton import Singleton
00030 from os import environ
00031
00032
00033 class GlobalVars( Singleton ):
00034 """
00035 Singleton class used by slimpy to store global
00036 variables
00037 """
00038
00039
00040 def _get_slim_global(self):
00041
00042 return self._slim_globals
00043
00044 def _set_slim_global(self,val):
00045
00046 self._slim_globals = val
00047
00048 slimGlobals = property( _get_slim_global, _set_slim_global )
00049
00050
00051 def __new_instance__( self, name ):
00052 Singleton.__new_instance__(self, name)
00053 self.slimGlobals = { }
00054
00055
00056
00057 self.PATHS = ["datapath", 'localtmpdir', 'globaltmpdir']
00058 self.INTS = ["memsize", "verbose", 'ispipe', "eps"]
00059 self.BOOLS = ['ispipe']
00060 self.EVALS = ['nwin']
00061
00062 self.slimdoc = {
00063
00064 "datapath": "path where perminant data files will be built",
00065
00066
00067 'localtmpdir': 'mpi - temp header files will be built (local to each node) ',
00068 'globaltmpdir': 'mpi - temp header files will be built (global for every node) ',
00069
00070 "memsize": 'set the memory available to each program',
00071 "verbose": 'set the verbosity from 1 to 10',
00072 "eps" : 'Domain decomposition overlap',
00073 'nwin' : 'dimentions to split the data into - mpi',
00074
00075 'MPIRUN': 'executable for mpi, used with MPIFLAGS' ,
00076 'NODEFILE': 'file containing list of node names for mpi',
00077 "MPIFLAGS": "defaults to '${MPIRUN} -np=${np} ${NODEFILE}'",
00078 'NODELIST': 'python list containing node names for mpi',
00079 'abridge': 'abridge output with abridge-map',
00080 'check_path': 'bool - check if all executable paths exist',
00081 'debug': 'print extra info to logfile eg. print >> log(10,"foo") will print if debug=foo',
00082 'logfile': 'file to print to',
00083 'mpi': 'bool - force running mpi or not',
00084 'np': 'number of processors running in mpi',
00085 'runtype': '"normal" or "dryrun" ',
00086 'strict_check' :'0,1 or 2. On 0 no domain/range checking. 1 checking. 2 no void Spaces will be accepted',
00087 'test_devel': 'run developer tests, usualy known bugs',
00088
00089 'abridgeMap': "dictionary of strings to call 'output.replace(key,val)' before printing",
00090 'no_del': "bool, if true SLIMpy will not delete data until the end",
00091 'walltime':'amount of time a command is allowed to take',
00092 'rsh':'distributed mode: command used to talk with nodes [default "ssh"]',
00093
00094 'sync_disk_om_rm':'calls $SYNC_CMD before removing data on disk'
00095
00096 }
00097
00098 self.update( **DEFAULTS )
00099
00100 def get(self, key, *val):
00101 '''
00102 get method, see dict.get
00103 '''
00104
00105 return self._slim_globals.get( key, *val)
00106
00107
00108 def update(self, **kw):
00109 'see: dict.update'
00110 self.setglobal( **kw )
00111
00112 def setglobal( self, **kargs ):
00113 """
00114 Sets the global parameters accessed by the rest of the module
00115 if the entry is None then the variable will be none
00116 """
00117 self.setpath( kargs, *self.PATHS )
00118 self.applyFunc( kargs, int, *self.INTS )
00119 self.applyFunc( kargs, bool, *self.BOOLS )
00120 self.applyFunc( kargs, eval, *self.EVALS )
00121
00122 self._slim_globals.update( kargs )
00123
00124
00125
00126
00127 return
00128
00129 def __contains__( self, key ):
00130 return self._slim_globals.has_key( key )
00131
00132 def __getitem__( self, item ):
00133 return self._slim_globals[item]
00134
00135 def __setitem__( self, key, val ):
00136
00137 if isinstance( val, tuple ):
00138 assert len( val ) == 2, "value must be a 2-tupel of (value,doc) "
00139 value = val[0]
00140 doc = val[1]
00141
00142 else:
00143 value = val
00144 doc = None
00145
00146 self.set(key, value, doc)
00147
00148
00149 def set( self, key, value, doc=None ):
00150 'set item with optional documentation param'
00151
00152 if doc:
00153 self.slimdoc[key] = doc
00154
00155 if isinstance(value, str) and key in self.PATHS:
00156 value = abspath( value )
00157
00158 self._slim_globals[key] = value
00159
00160 def applyFunc( self, dict, func, *keylist ):
00161 """
00162 apply a function on a values of dict
00163 specified by keylist
00164 """
00165 for key in keylist:
00166 if dict.has_key( key ):
00167 value = dict[key]
00168 if isinstance(value, str ):
00169 dict[key] = func( dict[key] )
00170
00171 def keys(self):
00172 "see: dict.keys"
00173 return self._slim_globals.keys()
00174
00175 def setpath( self, dict, *arglist ):
00176 """
00177 change values in dict specified by arglist
00178 to its absolute path
00179 """
00180 for arg in arglist:
00181 if dict.has_key( arg ):
00182 try:
00183 dict[arg] = abspath( dict[arg] )
00184 except:
00185 print arg, dict[arg]
00186 raise
00187
00188 def updateAbridgeMap( self, *d, **k ):
00189 """
00190 same as dict.update for self['abridgeMap']
00191 """
00192 self['abridgeMap'].update( *d, **k )
00193
00194
00195 def setworkingdir( self, path ):
00196 """
00197 sets the working directory for all out of core operations
00198 """
00199 self.setglobal( tmpdir=path )
00200 environ['DATAPATH'] = path
00201
00202 def printGlobals( self , paths=True ):
00203 """
00204 pretty printing of the globals
00205 """
00206 if paths:
00207 print " -- Paths --"
00208 print '='*35
00209 keys = self.PATHS
00210 keys.sort()
00211 for key in keys:
00212 print "%13s --| %s" % ( key, self[key] )
00213 doc = self.slimdoc.get( key, "" )
00214 if doc:
00215 print ' '*18, "%s" % doc
00216
00217 print '-- Vars --'
00218 print '='*35
00219 keys = self._slim_globals.keys()
00220 keys.sort()
00221 if 'abridgeMap' in keys:
00222 keys.remove( 'abridgeMap' )
00223 keys = [key for key in keys if key not in self.PATHS]
00224 for key in keys:
00225 print "%13s --| %13s -|- %s" % ( key, self[key], self.slimdoc.get( key, "" ) )
00226
00227 def get_node_map(self):
00228 ntype = self['nodemap_type']
00229
00230 NODELIST = None
00231 if self['NODEFILE']:
00232 NODELIST= [ node.strip() for node in open( self['NODEFILE'] ).read().split() ]
00233 elif self['NODELIST']:
00234 NODELIST = self['NODELIST']
00235
00236 nmap = []
00237 if NODELIST:
00238 sorted_list = list(NODELIST)
00239 if ntype == 'lin':
00240 sorted_list=sorted_list
00241 elif ntype == 'sort':
00242 sorted_list.sort()
00243
00244 else:
00245 raise Exception( 'unknowm value for nodemap_type' )
00246
00247 for rank,node in enumerate(sorted_list):
00248
00249 nmap.append((node,rank))
00250 else:
00251 for rank in range(self['np']):
00252 node = 'localhost'
00253 nmap.append((node,rank))
00254
00255 return nmap
00256
00257