def initialize(self): names = [] for mod in self.modules: for var in mod.calculates(): if var in self.calculators: raise ValueError( "There exist at least two modules that want to calculate variable '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.calculators[var].__class__.__name__)) self.calculators[var] = mod for var in mod.updates(): if var in self.updaters: raise ValueError( "There exist at least two modules that want to update/change variable '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.updaters[var].__class__.__name__)) self.updaters[var] = mod for var in mod.params(): if var in self.updaters: raise ValueError( "There exist at least two modules that want to handle parameter '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.param_handlers[var].__class__.__name__)) self.param_handlers[var] = mod mod.initialize(self) names.append(type(mod).__name__) logger.info("Initialized modules: %s", ", ".join(names)) self.initialized = True
def initialize(self, system): self.system = system self.Ms = Field(system.mesh) self.Ms.fill(0.0) self.alpha = Field(system.mesh) self.alpha.fill(0.0) self.__valid_factors = False # Find other active modules self.field_terms = [] self.field_energies = [] self.llge_terms = [] for mod in system.modules: prop = mod.properties() if 'EFFECTIVE_FIELD_TERM' in prop.keys(): self.field_terms.append(prop['EFFECTIVE_FIELD_TERM']) if 'EFFECTIVE_FIELD_ENERGY' in prop.keys(): self.field_energies.append(prop['EFFECTIVE_FIELD_ENERGY']) if 'LLGE_TERM' in prop.keys(): self.llge_terms.append(prop['LLGE_TERM']) logger.info("LandauLifshitzGilbert module configuration:") logger.info(" - H_tot = %s", " + ".join(self.field_terms) or "0") logger.info(" - E_tot = %s", " + ".join(self.field_energies) or "0") logger.info(" - dM/dt = %s", " + ".join(["LLGE(M, H_tot)"] + self.llge_terms) or "0") if not self.__do_precess: logger.info(" - Precession term is disabled")
def initialize(self, system): logger.info("%s: Providing parameters %s" % (self.name(), ", ".join(self.params()))) A = VectorField(system.mesh) A.clear() setattr(self, self.__var_id, A)
def update(self, state, id, value): if id == "M": logger.info("Assigning new magnetic state M") module.assign(state.y, value) state.y.normalize(self.system.Ms) # XXX: Is this a good idea? (Solution: Use unit magnetization everywhere.) state.flush_cache() else: raise KeyError(id)
def initialize(self, argv = None): # Initialize magneto magneto.initialize(self.getCacheDirectory()) self.parseCommandLine(argv if argv is not None else sys.argv) # Register cleanup function atexit.register(MagnumConfig.cleanupBeforeExit, self) logger.info("CUDA GPU support: %s", "yes" if self.haveCudaSupport() else "no")
def initialize(self, argv=None): # Initialize magneto magneto.initialize(self.getCacheDirectory()) self.parseCommandLine(argv or sys.argv) # Register cleanup function atexit.register(MagnumConfig.cleanupBeforeExit, self) logger.info("CUDA GPU support: %s", "yes" if self.haveCudaSupport() else "no")
def update(self, state, id, value): if id == "M": logger.info("Assigning new magnetic state M") module.assign(state.y, value) state.y.normalize( state.Ms ) # XXX: Is this a good idea? (Solution: Use unit magnetization everywhere.) state.flush_cache() else: raise KeyError(id)
def __init__(self, mesh, method = "tensor", padding = TensorField.PADDING_ROUND_4): # are we periodic? peri, peri_repeat = mesh.periodic_bc peri_x = peri.find("x") != -1 peri_y = peri.find("y") != -1 peri_z = peri.find("z") != -1 # number of cells and cell sizes nx, ny, nz = mesh.num_nodes dx, dy, dz = mesh.delta if nx * ny * nz > 32: if not (nx < ny < nz): logger.info("Performance hint: The number of cells nx, ny, nz in each direction should satisfy nx >= ny >= nz.") if (nx == 1 or ny == 1) and nz != 1: logger.info("Performance hint: Meshes with 2-dimensional cell grids should span the xy-plane, i.e. the number of cells in z-direction should be 1.") # generate calculation function depending on user-selected method if method == "tensor": tensor = DemagTensorField(mesh, padding) tensor.setPeriodicBoundaries(peri_x, peri_y, peri_z, peri_repeat) # Determine if we should use the fast convolution (via FFT) or the simple convolution (using for-loops, CPU only). if cfg.isCudaEnabled(): use_fft = True else: # HACK: Our CPU implementation of fast convolution doesn't support these input dimensions. if nx == 1 and (ny != 1 or nz != 1): use_fft = False else: use_fft = (nx * ny * nz >= 32) # this is the break-even point for using FFT convolutions on my system. if use_fft: conv = magneto.SymmetricMatrixVectorConvolution_FFT(tensor.generate(), nx, ny, nz) else: conv = magneto.SymmetricMatrixVectorConvolution_Simple(tensor.generate(), nx, ny, nz) self.__calc = lambda M, H: conv.execute(M, H) elif method == "potential": assert not peri_x and not peri_y and not peri_z tensor = PhiTensorField(mesh, padding) tensor.setPeriodicBoundaries(peri_x, peri_y, peri_z, peri_repeat) conv = magneto.VectorVectorConvolution_FFT(tensor.generate(), nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: conv.execute(M, H) # experimental, don't use (and not implemented :) ) elif method == "single": assert not peri_x and not peri_y and not peri_z stray = magneto.StrayField_single(nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: stray.calculate(M, H) elif method == "multi": assert not peri_x and not peri_y and not peri_z stray = magneto.StrayField_multi(nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: stray.calculate(M, H) else: assert False
def __init__(self, mesh, method, stepsize_controller): super(RungeKutta, self).__init__(mesh) self.__tab = RungeKutta.TABLES[method]() self.__controller = stepsize_controller self.__y0 = VectorField(mesh) self.__y_err = VectorField(mesh) self.__y_tmp = VectorField(mesh) self.__k = [None] * self.__tab.getNumSteps() logger.info("Runge Kutta evolver: method is %s, step size controller is %s.", method, self.__controller)
def __init__(self, mesh, method, stepsize_controller): super(RungeKutta, self).__init__(mesh) self.tab = RungeKutta.TABLES[method]() self.controller = stepsize_controller self.y0 = VectorField(mesh) self.y_err = VectorField(mesh) self.y_tmp = VectorField(mesh) self.k = [None] * self.tab.getNumSteps() logger.info( "Runge Kutta evolver: method is %s, step size controller is %s.", method, self.controller)
def initialize(self): names = [] for mod in self.modules: for var in mod.calculates(): if var in self.calculators: raise ValueError("There exist at least two modules that want to calculate variable '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.calculators[var].__class__.__name__)) self.calculators[var] = mod for var in mod.updates(): if var in self.updaters: raise ValueError("There exist at least two modules that want to update/change variable '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.updaters[var].__class__.__name__)) self.updaters[var] = mod for var in mod.params(): if var in self.updaters: raise ValueError("There exist at least two modules that want to handle parameter '%s': Modules %s and %s." % (var, mod.__class__.__name__, self.param_handlers[var].__class__.__name__)) self.param_handlers[var] = mod mod.initialize(self) names.append(type(mod).__name__) logger.info("Initialized modules: %s", ", ".join(names)) self.initialized = True
def initialize(self, system): self.system = system self.Ms = Field(system.mesh); self.Ms.fill(0.0) self.alpha = Field(system.mesh); self.alpha.fill(0.0) self.__valid_factors = False # Find other active modules self.field_terms = [] self.field_energies = [] self.llge_terms = [] for mod in system.modules: prop = mod.properties() if 'EFFECTIVE_FIELD_TERM' in prop.keys(): self.field_terms.append(prop['EFFECTIVE_FIELD_TERM']) if 'EFFECTIVE_FIELD_ENERGY' in prop.keys(): self.field_energies.append(prop['EFFECTIVE_FIELD_ENERGY']) if 'LLGE_TERM' in prop.keys(): self.llge_terms.append(prop['LLGE_TERM']) logger.info("LandauLifshitzGilbert module configuration:") logger.info(" - H_tot = %s", " + ".join(self.field_terms) or "0") logger.info(" - E_tot = %s", " + ".join(self.field_energies) or "0") logger.info(" - dM/dt = %s", " + ".join(["LLGE(M, H_tot)"] + self.llge_terms) or "0") if not self.__do_precess: logger.info(" - Precession term is disabled")
def logCallMessage(self, idx, param): if len(param) == 1: (p, ) = param else: p = param logger.info( "==========================================================") logger.info("Controller: Calling simulation function (param set: %s)", idx) logger.info(" Parameters: %s", p)
def initializeFromWorld(self): logger.info("Initializing material parameters") def format_parameter_value(value): if isinstance(value, numbers.Number): if abs(value) >= 1e3 or abs(value) <= 1e-3: return "%g" % value return str(value) for body in self.world.bodies: mat = body.material cells = body.shape.getCellIndices(self.mesh) used_param_list = [] for param in self.all_params: if hasattr(mat, param): val = getattr(mat, param) self.set_param(param, val, mask=cells) used_param_list.append( "'%s=%s'" % (param, format_parameter_value(val))) logger.info( " body id='%s', volume=%s%%, params: %s", body.id, round(1000.0 * len(cells) / self.mesh.total_nodes) / 10, ", ".join(used_param_list) or "(none)")
def initializeFromWorld(self): logger.info("Initializing material parameters") def format_parameter_value(value): if isinstance(value, numbers.Number): if abs(value) >= 1e3 or abs(value) <= 1e-3: return "%g" % value return str(value) for body in self.world.bodies: mat = body.material cells = body.shape.getCellIndices(self.mesh) used_param_list = [] for param in self.all_params: if hasattr(mat, param): val = getattr(mat, param) self.set_param(param, val, mask=cells) used_param_list.append("'%s=%s'" % (param, format_parameter_value(val))) logger.info(" body id='%s', volume=%s%%, params: %s", body.id, round(1000.0 * len(cells) / self.mesh.total_nodes) / 10, ", ".join(used_param_list) or "(none)" )
def initialize(self, system): self.system = system logger.info("%s: Providing model variable %s, parameters are %s" % (self.name(), self.__var, ", ".join(self.params())))
def logCallMessage(self, idx, param): if len(param) == 1: (p,) = param else: p = param logger.info("==========================================================") logger.info("Controller: Calling simulation function (param set: %s)", idx) logger.info(" Parameters: %s", p)
def parseCommandLine(self, argv): import magnum parser = OptionParser(version="MicroMagnum " + magnum.__version__) hw_group = OptionGroup( parser, "Hardware options", "Options that control which hardware is used.", ) hw_group.add_option( "-g", type="string", help= "enable GPU processing (using 32-bit accuracy) on cuda device GPU_ID. The simulator will fall back to CPU mode if it was not compiled with CUDA support or when no CUDA capable graphics cards were detected.", metavar="GPU_ID", dest="gpu32", default=None) hw_group.add_option( "-G", type="string", help= "enable GPU processing (using 64-bit accuracy) on cuda device GPU_ID. TODO: Describe fallback behaviour.", metavar="GPU_ID", dest="gpu64", default=None) hw_group.add_option( "-t", "--threads", help= "enable CPU multithreading with NUM_THREADS (1..64) threads. This parameter instructs the fftw library to use NUM_THREADS threads for computing FFTs.", metavar="NUM_THREADS", dest="num_fftw_threads", type="int", default=1) parser.add_option_group(hw_group) log_group = OptionGroup( parser, "Logging options", "Options related to logging and benchmarking.") log_group.add_option( "--loglevel", "-l", type="int", help= "set log level (0:Debug, 1:Info, 2:Warn, 4:Error, 5:Critical), default is Debug (0).", metavar="LEVEL", dest="loglevel", default=1) log_group.add_option("--prof", help="Log profiling info at program exit.", dest="profiling_enabled", action="store_true", default=False) parser.add_option_group(log_group) def prange_callback(option, opt_str, value, parser, *args, **kwargs): # e.g.: ./script.py --prange=0,64 -> xrange(0,64) object match = re.match("^(\d+),(\d+)$", value) if match: p0, p1 = int(match.group(1)), int(match.group(2)) else: match = re.match("^(\d+)$", value) if match: p0 = int(match.group(1)) p1 = p0 + 1 else: raise OptionValueError( "Invalid --param-range / -p format.") if not p0 < p1: raise OptionValueError( "Invalid --param-range / -p specified: second value must be greater than first value" ) setattr(parser.values, "prange", range(p0, p1)) ctrl_group = OptionGroup( parser, "Parameter sweep options", "These options have only an effect when the simulation script uses a Controller object to sweep through a parameter range." ) ctrl_group.add_option( "--param-range", "-p", type="string", help= "select parameter set to run, e.g. --param-range=0,64 to run sets 0 to 63.", metavar="RANGE", action="callback", callback=prange_callback, default=None) ctrl_group.add_option( "--print-num-params", help="print number of sweep parameters to stdout and exit.", action="store_true", dest="print_num_params_requested", default=False) ctrl_group.add_option( "--print-all-params", action="store_true", help="print all sweep parameters to stdout and exit.", dest="print_all_params_requested", default=False, ) parser.add_option_group(ctrl_group) misc_group = OptionGroup(parser, "Miscellanous options") misc_group.add_option( "--on_io_error", type="int", help= "Specifies what to do when an i/o error occurs when writing an .omf/.vtk file. 0: Abort (default), 1: Retry a few times, then abort, 2: Retry a few times, then pause and ask for user intervention", metavar="MODE", dest="on_io_error", default=0) parser.add_option_group(misc_group) options, rest_args = parser.parse_args(argv) self.options = options ### Process the options ### # --loglevel, -l ll_map = [ logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR, logging.CRITICAL ] logger.setLevel(ll_map[options.loglevel]) logger.info( "----------------------------------------------------------------------" ) logger.info("MicroMagnum %s" % magnum.__version__) logger.info("Copyright (C) 2012 by the MicroMagnum team.") logger.info("This program comes with ABSOLUTELY NO WARRANTY.") logger.info( "This is free software, and you are welcome to redistribute it under" ) logger.info( "certain conditions; see the file COPYING in the distribution package." ) logger.info( "----------------------------------------------------------------------" ) # -g, -G if options.gpu32 and options.gpu64: logger.warn("Ignoring -g argument because -G was specified") def parse_gpu_id(arg): return -1 if arg == "auto" else int(arg) if options.gpu64: cuda_mode, cuda_dev = MagnumConfig.CUDA_64, parse_gpu_id( options.gpu64) elif options.gpu32: cuda_mode, cuda_dev = MagnumConfig.CUDA_32, parse_gpu_id( options.gpu32) else: cuda_mode, cuda_dev = MagnumConfig.CUDA_DISABLED, -1 self.enableCuda(cuda_mode, cuda_dev) # --prof if options.profiling_enabled: self.enableProfiling(True) # enable fftw threads... self.setFFTWThreads(options.num_fftw_threads)
def parseCommandLine(self, argv): from optparse import OptionParser, OptionValueError, OptionGroup parser = OptionParser(version="MagNum v.0.1") hw_group = OptionGroup(parser, "Hardware options", "Options that control which hardware is used.", ) hw_group.add_option("-g", type = "string", help = "enable GPU processing (using 32-bit accuracy) on cuda device GPU_ID. The simulator will fall back to CPU mode if it was not compiled with CUDA support or when no CUDA capable graphics cards were detected.", metavar = "GPU_ID", dest = "gpu32", default = None ) hw_group.add_option("-G", type = "string", help = "enable GPU processing (using 64-bit accuracy) on cuda device GPU_ID. TODO: Describe fallback behaviour.", metavar = "GPU_ID", dest = "gpu64", default = None ) hw_group.add_option("-t", "--threads", help = "enable CPU multithreading with NUM_THREADS (1..64) threads. This parameter instructs the fftw library to use NUM_THREADS threads for computing FFTs.", metavar = "NUM_THREADS", dest = "num_fftw_threads", type = "int", default = 1 ) #hw_group.add_option("-f", "--fftw-mode", # help = "set fftw plan creation mode (0:Estimate, 1:Measure, 2:Exhaustive), default is Measure (1).", # dest = "fftw_plan", # default = 1, # type = "int", # metavar = "FFTW_MODE" #) parser.add_option_group(hw_group) log_group = OptionGroup(parser, "Logging options", "Options related to logging and benchmarking." ) log_group.add_option("--loglevel", "-l", type = "int", help = "set log level (0:Debug, 1:Info, 2:Warn, 4:Error, 5:Critical), default is Debug (0).", metavar = "LEVEL", dest = "loglevel", default = 1 ) log_group.add_option("--prof", help = "Log profiling info at program exit.", dest = "profiling_enabled", action = "store_true", default = False ) parser.add_option_group(log_group) def prange_callback(option, opt_str, value, parser, *args, **kwargs): # e.g.: ./script.py --prange=0,64 -> xrange(0,64) object match = re.match("^(\d+),(\d+)$", value) if match: p0, p1 = int(match.group(1)), int(match.group(2)) else: match = re.match("^(\d+)$", value) if match: p0 = int(match.group(1)) p1 = p0 + 1 else: raise OptionValueError("Invalid --prange format.") if not p0 < p1: raise OptionValueError("Invalid --prange specified: second value must be greater than first value") setattr(parser.values, "prange", range(p0, p1)) ctrl_group = OptionGroup(parser, "Parameter sweep options", "These options have only an effect when the simulation script uses a Controller object to sweep through a parameter range." ) ctrl_group.add_option("--param-range", "-p", type = "string", help = "set parameter range to run, e.g. --prange=0,64. ", metavar = "RANGE", action = "callback", callback= prange_callback, default = None ) ctrl_group.add_option("--print-num-params", help = "print number of sweep parameters to stdout and exit.", action = "store_true", dest = "print_num_params_requested", default = False ) ctrl_group.add_option("--print-all-params", action = "store_true", help = "print all sweep parameters to stdout and exit.", dest = "print_all_params_requested", default = False, ) parser.add_option_group(ctrl_group) misc_group = OptionGroup(parser, "Miscellanous options" ) misc_group.add_option("--on_io_error", type = "int", help = "Specifies what to do when an i/o error occurs when writing an .omf/.vtk file. 0: Abort (default), 1: Retry a few times, then abort, 2: Retry a few times, then pause and ask for user intervention", metavar = "MODE", dest = "on_io_error", default = 0 ) parser.add_option_group(misc_group) options, rest_args = parser.parse_args(argv) self.options = options ### Process the options ### # --loglevel, -l import logging ll_map = [logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR, logging.CRITICAL] logger.setLevel(ll_map[options.loglevel]) logger.info("MicroMagnum 0.2 Copyright (C) 2012 by the MicroMagnum team.") logger.info("This program comes with ABSOLUTELY NO WARRANTY.") logger.info("This is free software, and you are welcome to redistribute it") logger.info("under certain conditions; see the file COPYING in the distribution package.") logger.info("----------") # -g, -G def parse_gpu_id(arg): if arg == "auto": return -1 return int(arg) cuda_mode = MagnumConfig.CUDA_DISABLED cuda_dev = -1 if options.gpu32 is not None: cuda_mode = MagnumConfig.CUDA_32 cuda_dev = parse_gpu_id(options.gpu32) if options.gpu64 is not None: if options.gpu32 is not None: logger.warn("Ignoring -g argument because -G was specified") cuda_mode = MagnumConfig.CUDA_64 cuda_dev = parse_gpu_id(options.gpu64) self.enableCuda(cuda_mode, cuda_dev) # --prof if options.profiling_enabled: self.enableProfiling(True) # enable fftw threads... self.setFFTWThreads(options.num_fftw_threads)
def enableProfiling(self, yes = True): magneto.enableProfiling(yes) if magneto.isProfilingEnabled(): logger.info("Profiling enabled") else: logger.info("Profiling disabled")
def __init__(self, mesh, method="tensor", padding=TensorField.PADDING_ROUND_4): # are we periodic? peri, peri_repeat = mesh.periodic_bc peri_x = peri.find("x") != -1 peri_y = peri.find("y") != -1 peri_z = peri.find("z") != -1 # number of cells and cell sizes nx, ny, nz = mesh.num_nodes dx, dy, dz = mesh.delta if nx * ny * nz > 32: if not (nx < ny < nz): logger.info( "Performance hint: The number of cells nx, ny, nz in each direction should satisfy nx >= ny >= nz." ) if (nx == 1 or ny == 1) and nz != 1: logger.info( "Performance hint: Meshes with 2-dimensional cell grids should span the xy-plane, i.e. the number of cells in z-direction should be 1." ) # generate calculation function depending on user-selected method if method == "tensor": tensor = DemagTensorField(mesh, padding) tensor.setPeriodicBoundaries(peri_x, peri_y, peri_z, peri_repeat) # Determine if we should use the fast convolution (via FFT) or the simple convolution (using for-loops, CPU only). if cfg.isCudaEnabled(): use_fft = True else: # HACK: Our CPU implementation of fast convolution doesn't support these input dimensions. if nx == 1 and (ny != 1 or nz != 1): use_fft = False else: use_fft = ( nx * ny * nz >= 32 ) # this is the break-even point for using FFT convolutions on my system. if use_fft: conv = magneto.SymmetricMatrixVectorConvolution_FFT( tensor.generate(), nx, ny, nz) else: conv = magneto.SymmetricMatrixVectorConvolution_Simple( tensor.generate(), nx, ny, nz) self.__calc = lambda M, H: conv.execute(M, H) elif method == "potential": assert not peri_x and not peri_y and not peri_z tensor = PhiTensorField(mesh, padding) tensor.setPeriodicBoundaries(peri_x, peri_y, peri_z, peri_repeat) conv = magneto.VectorVectorConvolution_FFT(tensor.generate(), nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: conv.execute(M, H) # experimental, don't use (and not implemented :) ) elif method == "single": assert not peri_x and not peri_y and not peri_z stray = magneto.StrayField_single(nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: stray.calculate(M, H) elif method == "multi": assert not peri_x and not peri_y and not peri_z stray = magneto.StrayField_multi(nx, ny, nz, dx, dy, dz) self.__calc = lambda M, H: stray.calculate(M, H) else: assert False
def enableProfiling(self, yes=True): magneto.enableProfiling(yes) if magneto.isProfilingEnabled(): logger.info("Profiling enabled") else: logger.info("Profiling disabled")