Ejemplo n.º 1
0
    def _sig_gemv(self,
                  ops,
                  A_js_fn,
                  X_js_fn,
                  Y_fn,
                  Y_in_fn=None,
                  alpha=1.0,
                  beta=1.0,
                  gamma=0.0,
                  tag=None):
        if len(ops) == 0:
            return []

        all_data, sidx = self.all_data, self.sidx
        A_js = RaggedArray([[sidx[ss] for ss in A_js_fn(op)] for op in ops])
        X_js = RaggedArray([[sidx[ss] for ss in X_js_fn(op)] for op in ops])
        Y_sigs = [Y_fn(item) for item in ops]
        Y_in_sigs = [Y_in_fn(item) for item in ops] if Y_in_fn else Y_sigs
        Y = all_data[[sidx[sig] for sig in Y_sigs]]
        Y_in = all_data[[sidx[sig] for sig in Y_in_sigs]]
        if callable(beta):
            beta = RaggedArray([sidx[beta(o)] for o in ops], dtype=np.float32)

        rval = plan_block_gemv(self.queue,
                               alpha,
                               all_data,
                               A_js,
                               all_data,
                               X_js,
                               beta,
                               Y,
                               Y_in=Y_in,
                               gamma=gamma,
                               tag=tag)
        return rval.plans
Ejemplo n.º 2
0
 def _plan_LinearFilter(self, ops):
     steps = [
         op.process.make_step(op.input.shape,
                              op.output.shape,
                              self.model.dt,
                              rng=None) for op in ops
     ]
     A = self.RaggedArray([f.den for f in steps], dtype=np.float32)
     B = self.RaggedArray([f.num for f in steps], dtype=np.float32)
     X = self.all_data[[self.sidx[op.input] for op in ops]]
     Y = self.all_data[[self.sidx[op.output] for op in ops]]
     Xbuf0 = RaggedArray(
         [np.zeros(shape) for shape in zip(B.sizes, X.sizes)],
         dtype=np.float32)
     Ybuf0 = RaggedArray(
         [np.zeros(shape) for shape in zip(A.sizes, Y.sizes)],
         dtype=np.float32)
     Xbuf = CLRaggedArray(self.queue, Xbuf0)
     Ybuf = CLRaggedArray(self.queue, Ybuf0)
     self._raggedarrays_to_reset[Xbuf] = Xbuf0
     self._raggedarrays_to_reset[Ybuf] = Ybuf0
     return plan_linearfilter(self.queue, X, Y, A, B, Xbuf, Ybuf)
Ejemplo n.º 3
0
 def from_arrays(cls, queue, arrays, names=None, dtype=None, align=False):
     return cls(queue,
                RaggedArray(arrays, names=names, dtype=dtype, align=align))
Ejemplo n.º 4
0
    def __init__(self,
                 network,
                 dt=0.001,
                 seed=None,
                 model=None,
                 context=None,
                 n_prealloc_probes=32,
                 profiling=None,
                 if_python_code='none',
                 planner=greedy_planner,
                 progress_bar=True):
        # --- check version
        if nengo.version.version_info in bad_nengo_versions:
            raise ValueError(
                "This simulator does not support Nengo version %s. Upgrade "
                "with 'pip install --upgrade --no-deps nengo'." %
                nengo.__version__)
        elif nengo.version.version_info > latest_nengo_version_info:
            warnings.warn("This version of `nengo_ocl` has not been tested "
                          "with your `nengo` version (%s). The latest fully "
                          "supported version is %s" %
                          (nengo.__version__, latest_nengo_version))

        # --- create these first since they are used in __del__
        self.closed = False
        self.model = None

        # --- arguments/attributes
        if context is None and Simulator.some_context is None:
            print('No context argument was provided to nengo_ocl.Simulator')
            print("Calling pyopencl.create_some_context() for you now:")
            Simulator.some_context = cl.create_some_context()
        if profiling is None:
            profiling = int(os.getenv("NENGO_OCL_PROFILING", 0))
        self.context = Simulator.some_context if context is None else context
        self.profiling = profiling
        self.queue = cl.CommandQueue(
            self.context, properties=PROFILING_ENABLE if self.profiling else 0)

        if if_python_code not in ['none', 'warn', 'error']:
            raise ValueError("%r not a valid value for `if_python_code`" %
                             if_python_code)
        self.if_python_code = if_python_code
        self.n_prealloc_probes = n_prealloc_probes
        self.progress_bar = progress_bar

        # --- Nengo build
        with Timer() as nengo_timer:
            if model is None:
                self.model = Model(dt=float(dt),
                                   label="%s, dt=%f" % (network, dt),
                                   decoder_cache=get_default_decoder_cache())
            else:
                self.model = model

            if network is not None:
                # Build the network into the model
                self.model.build(network)

        logger.info("Nengo build in %0.3f s" % nengo_timer.duration)

        # --- operators
        with Timer() as planner_timer:
            operators = list(self.model.operators)

            # convert DotInc and Copy to MultiDotInc
            operators = list(map(MultiDotInc.convert_to, operators))
            operators = MultiDotInc.compress(operators)

            # plan the order of operations, combining where appropriate
            op_groups = planner(operators)
            assert len([typ for typ, _ in op_groups if typ is Reset
                        ]) < 2, ("All resets not planned together")

            self.operators = operators
            self.op_groups = op_groups

        logger.info("Planning in %0.3f s" % planner_timer.duration)

        with Timer() as signals_timer:
            # Initialize signals
            all_signals = stable_unique(sig for op in operators
                                        for sig in op.all_signals)
            all_bases = stable_unique(sig.base for sig in all_signals)

            sigdict = SignalDict()  # map from Signal.base -> ndarray
            for op in operators:
                op.init_signals(sigdict)

            # Add built states to the probe dictionary
            self._probe_outputs = dict(self.model.params)

            # Provide a nicer interface to probe outputs
            self.data = ProbeDict(self._probe_outputs)

            # Create data on host and add views
            self.all_data = RaggedArray(
                [sigdict[sb] for sb in all_bases],
                names=[getattr(sb, 'name', '') for sb in all_bases],
                dtype=np.float32)

            view_builder = ViewBuilder(all_bases, self.all_data)
            view_builder.setup_views(operators)
            for probe in self.model.probes:
                view_builder.append_view(self.model.sig[probe]['in'])
            view_builder.add_views_to(self.all_data)

            self.all_bases = all_bases
            self.sidx = {
                k: np.int32(v)
                for k, v in iteritems(view_builder.sidx)
            }
            self._A_views = view_builder._A_views
            self._X_views = view_builder._X_views
            self._YYB_views = view_builder._YYB_views
            del view_builder

            # Copy data to device
            self.all_data = CLRaggedArray(self.queue, self.all_data)

        logger.info("Signals in %0.3f s" % signals_timer.duration)

        # --- set seed
        self.seed = np.random.randint(npext.maxint) if seed is None else seed
        self.rng = np.random.RandomState(self.seed)

        # --- create list of plans
        self._raggedarrays_to_reset = {}
        self._cl_rngs = {}
        self._python_rngs = {}

        plans = []
        with Timer() as plans_timer:
            for op_type, op_list in op_groups:
                plans.extend(self.plan_op_group(op_type, op_list))
            plans.extend(self.plan_probes())

        logger.info("Plans in %0.3f s" % plans_timer.duration)

        # -- create object to execute list of plans
        self._plans = Plans(plans, self.profiling)

        self.rng = None  # all randomness set, should no longer be used
        self._reset_probes()  # clears probes from previous model builds
Ejemplo n.º 5
0
    def sig_gemv(self,
                 seq,
                 alpha,
                 A_js_fn,
                 X_js_fn,
                 beta,
                 Y_sig_fn,
                 Y_in_sig_fn=None,
                 gamma=None,
                 verbose=0,
                 tag=None):
        if len(seq) == 0:
            return []
        sidx = self.sidx

        if callable(beta):
            beta_sigs = list(map(beta, seq))
            beta = RaggedArray(list(map(sidx.__getitem__, beta_sigs)),
                               dtype=np.float32)

        Y_sigs = [Y_sig_fn(item) for item in seq]
        if Y_in_sig_fn is None:
            Y_in_sigs = Y_sigs
        else:
            Y_in_sigs = [Y_in_sig_fn(item) for item in seq]
        Y_idxs = [sidx[sig] for sig in Y_sigs]
        Y_in_idxs = [sidx[sig] for sig in Y_in_sigs]

        # -- The following lines illustrate what we'd *like* to see...
        #
        # A_js = RaggedArray(
        #   [[sidx[ss] for ss in A_js_fn(item)] for item in seq])
        # X_js = RaggedArray(
        #   [[sidx[ss] for ss in X_js_fn(item)] for item in seq])
        #
        # -- ... but the simulator supports broadcasting. So in fact whenever
        #    a signal in X_js has shape (N, 1), the corresponding A_js signal
        #    can have shape (M, N) or (1, 1).
        #    Fortunately, scalar multiplication of X by A can be seen as
        #    Matrix multiplication of A by X, so we can still use gemv,
        #    we just need to reorder and transpose.
        A_js = []
        X_js = []
        for ii, item in enumerate(seq):
            A_js_i = []
            X_js_i = []
            A_sigs_i = A_js_fn(item)
            X_sigs_i = X_js_fn(item)
            assert len(A_sigs_i) == len(X_sigs_i)
            for asig, xsig in zip(A_sigs_i, X_sigs_i):
                A_js_i.append(sidx[asig])
                X_js_i.append(sidx[xsig])
            A_js.append(A_js_i)
            X_js.append(X_js_i)

        if verbose:
            print("in sig_vemv")
            print("print A", A_js)
            print("print X", X_js)

        A_js = RaggedArray(A_js, dtype=np.int32)
        X_js = RaggedArray(X_js, dtype=np.int32)
        Y = self.all_data[Y_idxs]
        Y_in = self.all_data[Y_in_idxs]

        rval = self.plan_ragged_gather_gemv(
            alpha=alpha,
            A=self.all_data,
            A_js=A_js,
            X=self.all_data,
            X_js=X_js,
            beta=beta,
            Y=Y,
            Y_in=Y_in,
            tag=tag,
            seq=seq,
            gamma=gamma,
        )

        try:
            return rval.plans
        except AttributeError:
            return [rval]
Ejemplo n.º 6
0
    def __init__(self,
                 network,
                 dt=0.001,
                 seed=None,
                 model=None,
                 planner=greedy_planner):

        with Timer() as nengo_timer:
            if model is None:
                self.model = Model(dt=float(dt),
                                   label="%s, dt=%f" % (network, dt),
                                   decoder_cache=get_default_decoder_cache())
            else:
                self.model = model

            if network is not None:
                # Build the network into the model
                self.model.build(network)

        logger.info("Nengo build in %0.3f s" % nengo_timer.duration)

        # --- set seed
        seed = np.random.randint(npext.maxint) if seed is None else seed
        self.seed = seed
        self.rng = np.random.RandomState(self.seed)

        self._step = Signal(np.array(0.0, dtype=np.float64), name='step')
        self._time = Signal(np.array(0.0, dtype=np.float64), name='time')

        # --- operators
        with Timer() as planner_timer:
            operators = list(self.model.operators)

            # convert DotInc, Reset, Copy, and ProdUpdate to MultiProdUpdate
            operators = list(map(MultiProdUpdate.convert_to, operators))
            operators = MultiProdUpdate.compress(operators)

            # plan the order of operations, combining where appropriate
            op_groups = planner(operators)
            assert len([typ for typ, _ in op_groups if typ is Reset
                        ]) < 2, ("All resets not planned together")

            # add time operator after planning, to ensure it goes first
            time_op = TimeUpdate(self._step, self._time)
            operators.insert(0, time_op)
            op_groups.insert(0, (type(time_op), [time_op]))

            self.operators = operators
            self.op_groups = op_groups

        logger.info("Planning in %0.3f s" % planner_timer.duration)

        with Timer() as signals_timer:
            # Initialize signals
            all_signals = signals_from_operators(operators)
            all_bases = stable_unique([sig.base for sig in all_signals])

            sigdict = SignalDict()  # map from Signal.base -> ndarray
            for op in operators:
                op.init_signals(sigdict)

            # Add built states to the probe dictionary
            self._probe_outputs = self.model.params

            # Provide a nicer interface to probe outputs
            self.data = ProbeDict(self._probe_outputs)

            self.all_data = RaggedArray(
                [sigdict[sb] for sb in all_bases],
                [getattr(sb, 'name', '') for sb in all_bases],
                dtype=np.float32)

            builder = ViewBuilder(all_bases, self.all_data)
            self._AX_views = {}
            self._YYB_views = {}
            for op_type, op_list in op_groups:
                self.setup_views(builder, op_type, op_list)
            for probe in self.model.probes:
                builder.append_view(self.model.sig[probe]['in'])
            builder.add_views_to(self.all_data)

            self.all_bases = all_bases
            self.sidx = builder.sidx

            self._prep_all_data()

        logger.info("Signals in %0.3f s" % signals_timer.duration)

        # --- create list of plans
        with Timer() as plans_timer:
            self._plan = []
            for op_type, op_list in op_groups:
                self._plan.extend(self.plan_op_group(op_type, op_list))
            self._plan.extend(self.plan_probes())

        logger.info("Plans in %0.3f s" % plans_timer.duration)

        self.n_steps = 0
from nengo_ocl import raggedarray as ra
from nengo_ocl.clra_nonlinearities import (
    plan_copy,
    plan_elementwise_inc,
    plan_lif,
    plan_lif_rate,
    plan_linearfilter,
    plan_reset,
    plan_slicedcopy,
)
from nengo_ocl.clraggedarray import CLRaggedArray as CLRA
from nengo_ocl.clraggedarray import to_device
from nengo_ocl.raggedarray import RaggedArray

logger = logging.getLogger(__name__)
RA = lambda arrays, dtype=np.float32: RaggedArray(arrays, dtype=dtype)


def not_close(a, b, rtol=1e-3, atol=1e-3):
    return np.abs(a - b) > atol + rtol * np.abs(b)


@pytest.mark.parametrize("upsample", [1, 4])
def test_lif_step(ctx, upsample):
    """Test the lif nonlinearity, comparing one step with the Numpy version."""
    rng = np.random

    dt = 1e-3
    n_neurons = [12345, 23456, 34567]
    J = RA([rng.normal(scale=1.2, size=n) for n in n_neurons])
    V = RA([rng.uniform(low=0, high=1, size=n) for n in n_neurons])