PetaVision  Alpha
RescaleDelivery.cpp
1 /*
2  * RescaleDelivery.cpp
3  *
4  * Created on: Aug 24, 2017
5  * Author: Pete Schultz
6  */
7 
8 #include "RescaleDelivery.hpp"
9 #include "columns/HyPerCol.hpp"
10 
11 namespace PV {
12 
13 RescaleDelivery::RescaleDelivery(char const *name, HyPerCol *hc) { initialize(name, hc); }
14 
15 int RescaleDelivery::initialize(char const *name, HyPerCol *hc) {
16  return IdentDelivery::initialize(name, hc);
17 }
18 
19 void RescaleDelivery::setObjectType() { mObjectType = "RescaleDelivery"; }
20 
21 int RescaleDelivery::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
22  int status = IdentDelivery::ioParamsFillGroup(ioFlag);
23  ioParam_scale(ioFlag);
24  return status;
25 }
26 
27 void RescaleDelivery::ioParam_scale(enum ParamsIOFlag ioFlag) {
28  parent->parameters()->ioParamValue(
29  ioFlag, name, "scale", &mScale, mScale /*default*/, true /*warn if absent*/);
30 }
31 
32 // Delivers a scalar multiple of the identity from presynaptic activity to postsynaptic GSyn.
33 // Rescale::deliver() is largely a duplicate of IdentDelivery::deliver(), except
34 // for two lines inside for-loops with large numbers of iterations.
35 // We're discussing ways to eliminate code duplication like this without
36 // incurring added computational costs.
37 void RescaleDelivery::deliver() {
38  if (mChannelCode == CHANNEL_NOUPDATE) {
39  return;
40  }
41 
42  int delay = mSingleArbor->getDelay(0);
43  PVLayerCube const preActivityCube = mPreLayer->getPublisher()->createCube(delay);
44  PVLayerLoc const &preLoc = preActivityCube.loc;
45  PVLayerLoc const &postLoc = *mPostLayer->getLayerLoc();
46 
47  int const nx = preLoc.nx;
48  int const ny = preLoc.ny;
49  int const nf = preLoc.nf;
50  int nxPreExtended = nx + preLoc.halo.lt + preLoc.halo.rt;
51  int nyPreExtended = ny + preLoc.halo.dn + preLoc.halo.up;
52  int numPreExtended = nxPreExtended * nyPreExtended * nf;
53  pvAssert(numPreExtended * preLoc.nbatch == preActivityCube.numItems);
54  int numPostRestricted = nx * ny * nf;
55 
56  float *postChannel = mPostLayer->getChannel(mChannelCode);
57  for (int b = 0; b < parent->getNBatch(); b++) {
58  float const *preActivityBuffer = preActivityCube.data + b * numPreExtended;
59  float *postGSynBuffer = postChannel + b * numPostRestricted;
60  if (preActivityCube.isSparse) {
61  SparseList<float>::Entry const *activeIndices =
62  (SparseList<float>::Entry *)preActivityCube.activeIndices + b * numPreExtended;
63  int numActive = preActivityCube.numActive[b];
64 #ifdef PV_USE_OPENMP_THREADS
65 #pragma omp parallel for
66 #endif
67  for (int loopIndex = 0; loopIndex < numActive; loopIndex++) {
68  int kPre = activeIndices[loopIndex].index;
69  int kx = kxPos(kPre, nxPreExtended, nyPreExtended, nf) - preLoc.halo.lt;
70  int ky = kyPos(kPre, nxPreExtended, nyPreExtended, nf) - preLoc.halo.up;
71  if (kx < 0 or kx >= nx or ky < 0 or ky >= ny) {
72  continue;
73  }
74  int kf = featureIndex(kPre, nxPreExtended, nyPreExtended, nf);
75  int kPost = kIndex(kx, ky, kf, nx, ny, nf);
76  pvAssert(kPost >= 0 and kPost < numPostRestricted);
77  float a = activeIndices[loopIndex].value;
78  postGSynBuffer[kPost] += mScale * a;
79  }
80  }
81  else {
82  int const nk = postLoc.nx * postLoc.nf;
83 #ifdef PV_USE_OPENMP_THREADS
84 #pragma omp parallel for
85 #endif
86  for (int y = 0; y < ny; y++) {
87  int preLineIndex =
88  kIndex(preLoc.halo.lt, y + preLoc.halo.up, 0, nxPreExtended, nyPreExtended, nf);
89 
90  float const *preActivityLine = &preActivityBuffer[preLineIndex];
91  int postLineIndex = kIndex(0, y, 0, postLoc.nx, ny, postLoc.nf);
92  float *postGSynLine = &postGSynBuffer[postLineIndex];
93  for (int k = 0; k < nk; k++) {
94  postGSynLine[k] += mScale * preActivityLine[k];
95  }
96  }
97  }
98  }
99 #ifdef PV_USE_CUDA
100  mPostLayer->setUpdatedDeviceGSynFlag(!mReceiveGpu);
101 #endif // PV_USE_CUDA
102 }
103 
104 void RescaleDelivery::deliverUnitInput(float *recvBuffer) {
105  const int numNeuronsPost = mPostLayer->getNumNeuronsAllBatches();
106 #ifdef PV_USE_OPENMP_THREADS
107 #pragma omp parallel for
108 #endif
109  for (int k = 0; k < numNeuronsPost; k++) {
110  recvBuffer[k] += mScale;
111  }
112 }
113 
114 } // end namespace PV
115 
116 #include <cstring>
void ioParam_scale(enum ParamsIOFlag ioFlag)
PVLayerCube createCube(int delay=0)
Definition: Publisher.cpp:60
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override