def dimensions(self, num_dim): """Set a number of dimensions and check if it is allowed.""" if not self.allowed_dimension(num_dim): msg = "%d-D %s is not supported." msg = msg % (num_dim, self.__class__.__name__) raise XenticaException(msg) self._dimensions = num_dim
def __init__(self, val=None, name="var"): """Initialize base class features.""" super(Variable, self).__init__() self.fallback_name = name self.base_class = Variable if val is None: raise XenticaException("Variable should have an initial value.") self._init_val = DeferredExpression(str(val))
def _define_constants_once(self): """Define field size constants in the C code.""" num_dimensions = self.bsca.topology.dimensions for i in range(num_dimensions): if not hasattr(self.bsca, "size") or i >= len(self.bsca.size): msg = "Wrong field's dimensionality ({} instead of {})." msg = msg.format(len(self.bsca.size), num_dimensions) raise XenticaException(msg) size = self.bsca.size[i] constant = Constant("%s%d" % (self.width_prefix, i), size) self.bsca.define_constant(constant)
def op_func(self_var, value): """Implement augmented assign operator.""" if type(self_var).__name__ == "DeferredExpression": msg = "Can't assign to DeferredExpression" raise XenticaException(msg) self_var.declare_once() code = "%s %s= %s;\n" % (self_var.var_name, oper, value) self_var.bsca.append_code(code) has_fallback = hasattr(self_var, "fallback_name") if has_fallback and self_var.fallback_name == "var": self_var.fallback_name = self.var_name return self_var
def is_born(self, num_neighbors): """ Determine if a cell could be born. :param num_neighbors: The number of neighbors to test over. :returns: ``DeferredExpression`` to calculate the bool value. """ if not self._outer: msg = "Can not get a born flag from the pure totalistic rule." raise XenticaException(msg) return ((self & self._genome_mask) >> num_neighbors) & 1
def _prepare_topology(cls, attrs): """Prepare the topology for future use.""" if hasattr(cls, 'Topology'): attrs['Topology'] = cls.Topology cls.topology = attrs.get('Topology') if cls.topology is None: raise XenticaException("No Topology class declared.") for field in cls.mandatory_fields: if not hasattr(cls.topology, field): msg = "No %s declared in Topology class." % field raise XenticaException(msg) cls.topology.lattice = deepcopy(cls.topology.lattice) cls.topology.neighborhood = deepcopy(cls.topology.neighborhood) cls.topology.border = deepcopy(cls.topology.border) cls.topology.lattice.dimensions = cls.topology.dimensions cls.topology.neighborhood.dimensions = cls.topology.dimensions cls.topology.border.dimensions = cls.topology.dimensions cls.topology.neighborhood.topology = cls.topology cls.topology.border.topology = cls.topology
def is_sustained(self, num_neighbors): """ Determine if a cell is living or intended to death. :param num_neighbors: The number of neighbors to test over. :returns: ``DeferredExpression`` to calculate the bool value. """ if not self._outer: msg = "Can not get a sustained flag from the pure totalistic rule." raise XenticaException(msg) mask = (self._genome_mask << (self._num_neighbors + 1)) return ((self & mask) >> (num_neighbors + self._num_neighbors + 1)) & 1
def bsca(self): """ Get a :class:`CellularAutomaton` instance holding current class. The objects tree is scanned up to the top and the first instance found is returned. """ frame = inspect.currentframe() while frame is not None: for local in frame.f_locals.values(): if hasattr(local, "__get__"): continue if isinstance(local, xentica.core.base.CellularAutomaton): return local frame = frame.f_back raise XenticaException("BSCA not detected")
def render(self): """ Render the field at the current timestep. You must call :meth:`set_viewport` before do any rendering. :returns: NumPy array of ``np.uint8`` values, ``width * height * 3`` size. The RGB values are consecutive. """ # pylint: disable=protected-access # This is "hack" to get block/grid sizes, it's vital to us. # No way to get it correctly with PyCuda right now. if self.gpu.arrays.img is None: msg = "Viewport is not set, call set_viewport() before rendering." raise XenticaException(msg) block, grid = self.gpu.arrays.img._block, self.gpu.arrays.img._grid with self._lock: args = self.renderer.get_args_vals(self) args += [param.dtype(param.value) for param in self._render_params] args.append(np.int32(self.width * self.height)) self.gpu.kernels.render(*args, block=block, grid=grid) return self.gpu.arrays.img.get().astype(np.uint8)