Source code for topo.gpu.sheet

import param
import numpy as np

from topo.sheet import SettlingCFSheet
from topo.base.cf import CFSheet

try:
    import pycuda.gpuarray as gpuarray
    import pycuda.driver as cuda
    import pycuda.autoinit               # pyflakes:ignore (API import)
    import scikits.cuda.cusparse as cusparse

    cusparse.init()
except:
    pass


def compute_sparse_gpu_joint_norm_totals(projlist,active_units_mask=True):
    assert len(projlist)>=1

    joint_sum = gpuarray.zeros((projlist[0].weights_gpu.shape[0], ), np.float32)
    for p in projlist:
        if not p.has_norm_total:
            p.norm_total_gpu = p.weights_gpu.mv(p.norm_ones_gpu, autosync=True)
            p.has_norm_total = True
        joint_sum += p.norm_total_gpu
    for p in projlist:
        p.norm_total_gpu = joint_sum.copy()


[docs]class GPUSettlingCFSheet(SettlingCFSheet): """ A SettlingCFSheet that makes it possible to calculate projection activities and learning in concurrent GPU streams. This is done by placing barriers before the 'activate' and 'learn' methods of the sheet that synchronize GPU streams. Otherwise, behaves exactly the same as SettlingCFSheet. """ joint_norm_fn = param.Callable(default=compute_sparse_gpu_joint_norm_totals,doc=""" Function to use to compute the norm_total for each CF in each gpu projection from a group to be normalized jointly.""") def __init__(self, **params): super(GPUSettlingCFSheet, self).__init__(**params)
[docs] def process_current_time(self): """ Pass the accumulated stimulation through self.output_fns and send it out on the default output port. We need to synchronize before processing the projection activities or their weights, since they might be still running on the GPU. """ if self.new_input: self.new_input = False if self.activation_count == self.mask_init_time: cuda.Context.synchronize() self.mask.calculate() if self.tsettle == 0: # Special case: behave just like a CFSheet cuda.Context.synchronize() self.activate() self.learn() elif self.activation_count == self.tsettle: # Once we have been activated the required number of times # (determined by tsettle), reset various counters, learn # if appropriate, and avoid further activation until an # external event arrives. for f in self.end_of_iteration: f() self.activation_count = 0 self.new_iteration = True # used by input_event when it is called if (self.plastic and not self.continuous_learning): self.learn() else: cuda.Context.synchronize() self.activate() self.activation_count += 1 if (self.plastic and self.continuous_learning): self.learn()
class GPUCFSheet(CFSheet): def __init__(self, **params): super(GPUCFSheet, self).__init__(**params) def process_current_time(self): """ Called by the simulation after all the events are processed for the current time but before time advances. Allows the event processor to send any events that must be sent before time advances to drive the simulation. GPUCFSheet is meant to be used with GPU projections that are called asynchronously and might not have computed the activation. Therefore, we synchronize. """ if self.new_input: cuda.Context.synchronize() self.activate() self.new_input = False if self.plastic: self.learn()