8 #include "PresynapticPerspectiveStochasticDelivery.hpp"     9 #include "columns/HyPerCol.hpp"    16 PresynapticPerspectiveStochasticDelivery::PresynapticPerspectiveStochasticDelivery(
    22 PresynapticPerspectiveStochasticDelivery::PresynapticPerspectiveStochasticDelivery() {}
    24 PresynapticPerspectiveStochasticDelivery::~PresynapticPerspectiveStochasticDelivery() {
    28 int PresynapticPerspectiveStochasticDelivery::initialize(
char const *name, HyPerCol *hc) {
    29    return BaseObject::initialize(name, hc);
    32 void PresynapticPerspectiveStochasticDelivery::setObjectType() {
    33    mObjectType = 
"PresynapticPerspectiveStochasticDelivery";
    45 Response::Status PresynapticPerspectiveStochasticDelivery::communicateInitInfo(
    46       std::shared_ptr<CommunicateInitInfoMessage const> message) {
    47    auto status = HyPerDelivery::communicateInitInfo(message);
    54    return Response::SUCCESS;
    57 Response::Status PresynapticPerspectiveStochasticDelivery::allocateDataStructures() {
    58    auto status = HyPerDelivery::allocateDataStructures();
    64    return Response::SUCCESS;
    67 void PresynapticPerspectiveStochasticDelivery::allocateThreadGSyn() {
    69    int const numThreads = parent->getNumThreads();
    71       mThreadGSyn.resize(numThreads);
    74       for (
auto &th : mThreadGSyn) {
    75          th.resize(mPostLayer->getNumNeurons());
    80 void PresynapticPerspectiveStochasticDelivery::allocateRandState() {
    81    mRandState = 
new Random(mPreLayer->getLayerLoc(), 
true );
    86    if (getChannelCode() == CHANNEL_NOUPDATE) {
    89    float *postChannel = mPostLayer->getChannel(getChannelCode());
    90    pvAssert(postChannel);
    92    PVLayerLoc const *preLoc  = mPreLayer->getLayerLoc();
    93    PVLayerLoc const *postLoc = mPostLayer->getLayerLoc();
    94    Weights *weights          = mWeightsPair->getPreWeights();
    96    int const nxPreExtended  = preLoc->nx + preLoc->halo.rt + preLoc->halo.rt;
    97    int const nyPreExtended  = preLoc->ny + preLoc->halo.dn + preLoc->halo.up;
    98    int const numPreExtended = nxPreExtended * nyPreExtended * preLoc->nf;
   100    int const numPostRestricted = postLoc->nx * postLoc->ny * postLoc->nf;
   102    int nbatch = preLoc->nbatch;
   103    pvAssert(nbatch == postLoc->nbatch);
   105    const int sy  = postLoc->nx * postLoc->nf; 
   106    const int syw = weights->
getGeometry()->getPatchStrideY(); 
   108    bool const preLayerIsSparse = mPreLayer->getSparseFlag();
   111    for (
int arbor = 0; arbor < numAxonalArbors; arbor++) {
   112       int delay                = mArborList->getDelay(arbor);
   115       for (
int b = 0; b < nbatch; b++) {
   116          size_t batchOffset                                 = b * numPreExtended;
   117          float *activityBatch                               = activityCube.data + batchOffset;
   118          float *gSynPatchHeadBatch                          = postChannel + b * numPostRestricted;
   120          if (preLayerIsSparse) {
   126                preLayerIsSparse ? activityCube.numActive[b] : mPreLayer->getNumExtended();
   128 #ifdef PV_USE_OPENMP_THREADS   130          if (!mThreadGSyn.empty()) {
   131 #pragma omp parallel for schedule(static)   132             for (
int ti = 0; ti < parent->getNumThreads(); ++ti) {
   133                for (
int ni = 0; ni < numPostRestricted; ++ni) {
   134                   mThreadGSyn[ti][ni] = 0.0;
   140          std::size_t 
const *gSynPatchStart = weights->
getGeometry()->getGSynPatchStart().data();
   141          if (!preLayerIsSparse) {
   143 #ifdef PV_USE_OPENMP_THREADS   144 #pragma omp parallel for schedule(guided)   146                for (
int idx = 0; idx < numNeurons; idx++) {
   152                   if (y >= patch->ny) {
   157                   float a = activityBatch[kPreExt];
   161                   a *= mDeltaTimeFactor;
   164                   float *gSynPatchHead = gSynPatchHeadBatch;
   166 #ifdef PV_USE_OPENMP_THREADS   167                   if (!mThreadGSyn.empty()) {
   168                      gSynPatchHead = mThreadGSyn[omp_get_thread_num()].data();
   170 #endif // PV_USE_OPENMP_THREADS   172                   float *postPatchStart = &gSynPatchHead[gSynPatchStart[kPreExt]];
   176                   float const *weightDataStart = &weightDataHead[patch->offset];
   177                   taus_uint4 *rng              = mRandState->getRNG(kPreExt);
   178                   long along                   = (long)((
double)a * cl_random_max());
   180                   float *v                  = postPatchStart + y * sy;
   181                   float const *weightValues = weightDataStart + y * syw;
   182                   for (
int k = 0; k < nk; k++) {
   183                      *rng = cl_random_get(*rng);
   184                      v[k] += (rng->s0 < along) * weightValues[k];
   191             for (
int y = 0; y < nyp; y++) {
   192 #ifdef PV_USE_OPENMP_THREADS   193 #pragma omp parallel for schedule(guided)   195                for (
int idx = 0; idx < numNeurons; idx++) {
   196                   int kPreExt = activeIndicesBatch[idx].index;
   201                   if (y >= patch->ny) {
   206                   float a = activeIndicesBatch[idx].value;
   210                   a *= mDeltaTimeFactor;
   213                   float *gSynPatchHead = gSynPatchHeadBatch;
   215 #ifdef PV_USE_OPENMP_THREADS   216                   if (!mThreadGSyn.empty()) {
   217                      gSynPatchHead = mThreadGSyn[omp_get_thread_num()].data();
   219 #endif // PV_USE_OPENMP_THREADS   221                   float *postPatchStart = &gSynPatchHead[gSynPatchStart[kPreExt]];
   225                   float const *weightDataStart = &weightDataHead[patch->offset];
   226                   taus_uint4 *rng              = mRandState->getRNG(kPreExt);
   227                   long along                   = (long)((
double)a * cl_random_max());
   229                   float *v                  = postPatchStart + y * sy;
   230                   float const *weightValues = weightDataStart + y * syw;
   231                   for (
int k = 0; k < nk; k++) {
   232                      *rng = cl_random_get(*rng);
   233                      v[k] += (rng->s0 < along) * weightValues[k];
   238 #ifdef PV_USE_OPENMP_THREADS   241          if (!mThreadGSyn.empty()) {
   242             float *gSynPatchHead = gSynPatchHeadBatch;
   243             int numNeurons       = mPostLayer->getNumNeurons();
   244             for (
int ti = 0; ti < parent->getNumThreads(); ti++) {
   245                float *onethread = mThreadGSyn[ti].data();
   247 #pragma omp parallel for   248                for (
int ni = 0; ni < numNeurons; ni++) {
   249                   gSynPatchHead[ni] += onethread[ni];
   253 #endif // PV_USE_OPENMP_THREADS   258    mPostLayer->setUpdatedDeviceGSynFlag(
true);
   259 #endif // PV_USE_CUDA   262 void PresynapticPerspectiveStochasticDelivery::deliverUnitInput(
float *recvBuffer) {
   263    PVLayerLoc const *preLoc  = mPreLayer->getLayerLoc();
   264    PVLayerLoc const *postLoc = mPostLayer->getLayerLoc();
   265    Weights *weights          = mWeightsPair->getPreWeights();
   267    int const numPostRestricted = postLoc->nx * postLoc->ny * postLoc->nf;
   269    int nbatch = postLoc->nbatch;
   271    const int sy  = postLoc->nx * postLoc->nf; 
   272    const int syw = weights->
getGeometry()->getPatchStrideY(); 
   275    for (
int arbor = 0; arbor < numAxonalArbors; arbor++) {
   276       int delay                = mArborList->getDelay(arbor);
   279       for (
int b = 0; b < nbatch; b++) {
   280          float *recvBatch = recvBuffer + b * numPostRestricted;
   281          int numNeurons   = mPreLayer->getNumExtended();
   283 #ifdef PV_USE_OPENMP_THREADS   285          if (!mThreadGSyn.empty()) {
   286 #pragma omp parallel for schedule(static)   287             for (
int ti = 0; ti < parent->getNumThreads(); ++ti) {
   288                for (
int ni = 0; ni < numPostRestricted; ++ni) {
   289                   mThreadGSyn[ti][ni] = 0.0;
   295          std::size_t 
const *gSynPatchStart = weights->
getGeometry()->getGSynPatchStart().data();
   297 #ifdef PV_USE_OPENMP_THREADS   298 #pragma omp parallel for schedule(guided)   300             for (
int idx = 0; idx < numNeurons; idx++) {
   306                if (y >= patch->ny) {
   311                float a = mDeltaTimeFactor;
   314                float *recvPatchHead = recvBatch;
   316 #ifdef PV_USE_OPENMP_THREADS   317                if (!mThreadGSyn.empty()) {
   318                   recvPatchHead = mThreadGSyn[omp_get_thread_num()].data();
   320 #endif // PV_USE_OPENMP_THREADS   322                float *postPatchStart = &recvPatchHead[gSynPatchStart[kPreExt]];
   326                float const *weightDataStart = &weightDataHead[patch->offset];
   327                taus_uint4 *rng              = mRandState->getRNG(kPreExt);
   328                long along                   = (long)cl_random_max();
   330                float *v                  = postPatchStart + y * sy;
   331                float const *weightValues = weightDataStart + y * syw;
   332                for (
int k = 0; k < nk; k++) {
   333                   *rng = cl_random_get(*rng);
   334                   v[k] += (rng->s0 < along) * weightValues[k];
   338 #ifdef PV_USE_OPENMP_THREADS   341          if (!mThreadGSyn.empty()) {
   342             float *recvPatchHead = recvBatch;
   343             int numNeurons       = mPostLayer->getNumNeurons();
   344             for (
int ti = 0; ti < parent->getNumThreads(); ti++) {
   345                float *onethread = mThreadGSyn[ti].data();
   347 #pragma omp parallel for   348                for (
int ni = 0; ni < numNeurons; ni++) {
   349                   recvPatchHead[ni] += onethread[ni];
   353 #endif // PV_USE_OPENMP_THREADS 
PVLayerCube createCube(int delay=0)
static bool completed(Status &a)
Patch const & getPatch(int patchIndex) const 
int getPatchSizeY() const 
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
std::shared_ptr< PatchGeometry > getGeometry() const 
int getNumAxonalArbors() const 
float * getDataFromPatchIndex(int arbor, int patchIndex)
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual void deliver() override
virtual void ioParam_receiveGpu(enum ParamsIOFlag ioFlag) override
receiveGpu: PresynapticPerspectiveStochasticDelivery always sets receiveGpu to false. The receiveGpu=true case is handled by the PresynapticPerspectiveGPUDelivery class. 
int getPatchSizeF() const 
bool getInitInfoCommunicatedFlag() const