8 #include "PostsynapticPerspectiveStochasticDelivery.hpp" 9 #include "columns/HyPerCol.hpp" 13 PostsynapticPerspectiveStochasticDelivery::PostsynapticPerspectiveStochasticDelivery(
19 PostsynapticPerspectiveStochasticDelivery::PostsynapticPerspectiveStochasticDelivery() {}
21 PostsynapticPerspectiveStochasticDelivery::~PostsynapticPerspectiveStochasticDelivery() {
25 int PostsynapticPerspectiveStochasticDelivery::initialize(
char const *name, HyPerCol *hc) {
26 return BaseObject::initialize(name, hc);
29 void PostsynapticPerspectiveStochasticDelivery::setObjectType() {
30 mObjectType =
"PostsynapticPerspectiveStochasticDelivery";
42 Response::Status PostsynapticPerspectiveStochasticDelivery::communicateInitInfo(
43 std::shared_ptr<CommunicateInitInfoMessage const> message) {
44 auto status = HyPerDelivery::communicateInitInfo(message);
51 return Response::POSTPONE;
54 return Response::SUCCESS;
57 Response::Status PostsynapticPerspectiveStochasticDelivery::allocateDataStructures() {
58 auto status = HyPerDelivery::allocateDataStructures();
62 mRandState =
new Random(mPostLayer->getLayerLoc(),
false );
63 return Response::SUCCESS;
68 if (getChannelCode() == CHANNEL_NOUPDATE) {
71 float *postChannel = mPostLayer->getChannel(getChannelCode());
72 pvAssert(postChannel);
75 for (
int arbor = 0; arbor < numAxonalArbors; arbor++) {
76 int delay = mArborList->getDelay(arbor);
80 const int numPostRestricted = mPostLayer->getNumNeurons();
82 const PVLayerLoc *sourceLoc = mPreLayer->getLayerLoc();
83 const PVLayerLoc *targetLoc = mPostLayer->getLayerLoc();
85 const int sourceNx = sourceLoc->nx;
86 const int sourceNy = sourceLoc->ny;
87 const int sourceNf = sourceLoc->nf;
88 const int targetNx = targetLoc->nx;
89 const int targetNy = targetLoc->ny;
90 const int targetNf = targetLoc->nf;
91 const int nbatch = targetLoc->nbatch;
93 const PVHalo *sourceHalo = &sourceLoc->halo;
94 const PVHalo *targetHalo = &targetLoc->halo;
97 int sy = (sourceNx + sourceHalo->lt + sourceHalo->rt) * sourceNf;
100 float *gSynPatchHead = mPostLayer->getChannel(getChannelCode());
103 Weights *postWeights = mWeightsPair->getPostWeights();
107 int neuronIndexStride = targetNf < 4 ? 1 : targetNf / 4;
109 for (
int b = 0; b < nbatch; b++) {
110 int sourceNxExt = sourceNx + sourceHalo->rt + sourceHalo->lt;
111 int sourceNyExt = sourceNy + sourceHalo->dn + sourceHalo->up;
112 int sourceNumExtended = sourceNxExt * sourceNyExt * sourceNf;
114 float *activityBatch = activityCube.data + b * sourceNumExtended;
115 float *gSynPatchHeadBatch = gSynPatchHead + b * numPostRestricted;
118 for (
int ky = 0; ky < yPatchSize; ky++) {
121 #ifdef PV_USE_OPENMP_THREADS 122 #pragma omp parallel for schedule(static) 124 for (
int feature = 0; feature < neuronIndexStride; feature++) {
125 for (
int idx = feature; idx < numPostRestricted; idx += neuronIndexStride) {
126 float *gSyn = gSynPatchHeadBatch + idx;
129 int idxExtended = kIndexExtended(
138 int startSourceExt = postWeights->
getGeometry()->getUnshrunkenStart(idxExtended);
139 float *a = activityBatch + startSourceExt + ky * sy;
141 int kTargetExt = kIndexExtended(
151 float *weightValues = weightBuf + ky * syp;
154 for (
int k = 0; k < numPerStride; ++k) {
155 *rng = cl_random_get(*rng);
156 double p = (double)rng->s0 / cl_random_max();
157 dv += (p < (double)(a[k] * mDeltaTimeFactor)) * weightValues[k];
167 mPostLayer->setUpdatedDeviceGSynFlag(
true);
168 #endif // PV_USE_CUDA 171 void PostsynapticPerspectiveStochasticDelivery::deliverUnitInput(
float *recvBuffer) {
173 const int numPostRestricted = mPostLayer->getNumNeurons();
175 const PVLayerLoc *targetLoc = mPostLayer->getLayerLoc();
177 const int targetNx = targetLoc->nx;
178 const int targetNy = targetLoc->ny;
179 const int targetNf = targetLoc->nf;
180 const int nbatch = targetLoc->nbatch;
182 const PVHalo *targetHalo = &targetLoc->halo;
185 Weights *postWeights = mWeightsPair->getPostWeights();
189 int neuronIndexStride = targetNf < 4 ? 1 : targetNf / 4;
192 for (
int arbor = 0; arbor < numAxonalArbors; arbor++) {
193 for (
int b = 0; b < nbatch; b++) {
194 float *recvBatch = recvBuffer + b * numPostRestricted;
197 for (
int ky = 0; ky < yPatchSize; ky++) {
200 #ifdef PV_USE_OPENMP_THREADS 201 #pragma omp parallel for schedule(static) 203 for (
int feature = 0; feature < neuronIndexStride; feature++) {
204 for (
int idx = feature; idx < numPostRestricted; idx += neuronIndexStride) {
205 float *recvLocation = recvBatch + idx;
208 int kTargetExt = kIndexExtended(
218 float *weightValues = weightBuf + ky * syp;
221 for (
int k = 0; k < numPerStride; ++k) {
222 *rng = cl_random_get(*rng);
223 double p = (double)rng->s0 / cl_random_max();
224 dv += (p < (double)mDeltaTimeFactor) * weightValues[k];
226 *recvLocation += mDeltaTimeFactor * dv;
int getPatchSizeX() const
PVLayerCube createCube(int delay=0)
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
static bool completed(Status &a)
virtual void deliver() override
int getPatchSizeY() const
std::shared_ptr< PatchGeometry > getGeometry() const
int getPatchStrideY() const
int getNumAxonalArbors() const
virtual void ioParam_receiveGpu(enum ParamsIOFlag ioFlag) override
receiveGpu: PostsynapticPerspectiveStochasticDelivery always sets receiveGpu to false. The receiveGpu=true case is handled by the PostsynapticPerspectiveGPUDelivery class.
float * getDataFromPatchIndex(int arbor, int patchIndex)
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
int getPatchSizeF() const
bool getInitInfoCommunicatedFlag() const