int PointLIFProbe::calcValues(double timevalue) { // TODO: Reduce duplicated code between PointProbe::calcValues and PointLIFProbe::calcValues. assert(this->getNumValues()==NUMBER_OF_VALUES); LIF * LIF_layer = dynamic_cast<LIF *>(getTargetLayer()); assert(LIF_layer != NULL); pvconductance_t const * G_E = LIF_layer->getConductance(CHANNEL_EXC) + batchLoc * LIF_layer->getNumNeurons(); pvconductance_t const * G_I = LIF_layer->getConductance(CHANNEL_INH) + batchLoc * LIF_layer->getNumNeurons(); pvconductance_t const * G_IB = LIF_layer->getConductance(CHANNEL_INHB) + batchLoc * LIF_layer->getNumNeurons(); pvdata_t const * V = getTargetLayer()->getV(); pvdata_t const * Vth = LIF_layer->getVth(); pvdata_t const * activity = getTargetLayer()->getLayerData(); assert(V && activity && G_E && G_I && G_IB && Vth); double * valuesBuffer = this->getValuesBuffer(); //We need to calculate which mpi process contains the target point, and send that info to the root process //Each process calculates local index const PVLayerLoc * loc = getTargetLayer()->getLayerLoc(); //Calculate local cords from global const int kx0 = loc->kx0; const int ky0 = loc->ky0; const int kb0 = loc->kb0; const int nx = loc->nx; const int ny = loc->ny; const int nf = loc->nf; const int nbatch = loc->nbatch; const int xLocLocal = xLoc - kx0; const int yLocLocal = yLoc - ky0; const int nbatchLocal = batchLoc - kb0; //if in bounds if( xLocLocal >= 0 && xLocLocal < nx && yLocLocal >= 0 && yLocLocal < ny && nbatchLocal >= 0 && nbatchLocal < nbatch){ const pvdata_t * V = getTargetLayer()->getV(); const pvdata_t * activity = getTargetLayer()->getLayerData(); //Send V and A to root const int k = kIndex(xLocLocal, yLocLocal, fLoc, nx, ny, nf); const int kbatch = k + nbatchLocal*getTargetLayer()->getNumNeurons(); valuesBuffer[0] = G_E[kbatch]; valuesBuffer[1] = G_I[kbatch]; valuesBuffer[2] = G_IB[kbatch]; valuesBuffer[3] = V[kbatch]; valuesBuffer[4] = Vth[kbatch]; const int kex = kIndexExtended(k, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up); valuesBuffer[5] = activity[kex + nbatchLocal * getTargetLayer()->getNumExtended()]; //If not in root process, send to root process if(parent->columnId()!=0){ MPI_Send(valuesBuffer, NUMBER_OF_VALUES, MPI_DOUBLE, 0, 0, parent->icCommunicator()->communicator()); } } //Root process if(parent->columnId()==0){ //Calculate which rank target neuron is //TODO we need to calculate rank from batch as well int xRank = xLoc/nx; int yRank = yLoc/ny; int srcRank = rankFromRowAndColumn(yRank, xRank, parent->icCommunicator()->numCommRows(), parent->icCommunicator()->numCommColumns()); //If srcRank is not root process, MPI_Recv from that rank if(srcRank != 0){ MPI_Recv(valuesBuffer, NUMBER_OF_VALUES, MPI_DOUBLE, srcRank, 0, parent->icCommunicator()->communicator(), MPI_STATUS_IGNORE); } } return PV_SUCCESS; }
int PointProbe::calcValues(double timevalue) { assert(this->getNumValues()==2); double * valuesBuffer = this->getValuesBuffer(); //We need to calculate which mpi process contains the target point, and send that info to the root process //Each process calculates local index const PVLayerLoc * loc = getTargetLayer()->getLayerLoc(); //Calculate local cords from global const int kx0 = loc->kx0; const int ky0 = loc->ky0; const int kb0 = loc->kb0; const int nx = loc->nx; const int ny = loc->ny; const int nf = loc->nf; const int nbatch = loc->nbatch; const int xLocLocal = xLoc - kx0; const int yLocLocal = yLoc - ky0; const int nbatchLocal = batchLoc - kb0; //if in bounds if( xLocLocal >= 0 && xLocLocal < nx && yLocLocal >= 0 && yLocLocal < ny && nbatchLocal >= 0 && nbatchLocal < nbatch){ const pvdata_t * V = getTargetLayer()->getV(); const pvdata_t * activity = getTargetLayer()->getLayerData(); //Send V and A to root const int k = kIndex(xLocLocal, yLocLocal, fLoc, nx, ny, nf); if(V){ valuesBuffer[0] = V[k + nbatchLocal*getTargetLayer()->getNumNeurons()]; } else { valuesBuffer[0] = 0.0; } if(activity){ const int kex = kIndexExtended(k, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up); valuesBuffer[1] = activity[kex + nbatchLocal * getTargetLayer()->getNumExtended()]; } else { valuesBuffer[1] = 0.0; } //If not in root process, send to root process if(parent->columnId()!=0){ MPI_Send(&valuesBuffer, 2, MPI_DOUBLE, 0, 0, parent->icCommunicator()->communicator()); } } //Root process if(parent->columnId()==0){ //Calculate which rank target neuron is //TODO we need to calculate rank from batch as well int xRank = xLoc/nx; int yRank = yLoc/ny; int srcRank = rankFromRowAndColumn(yRank, xRank, parent->icCommunicator()->numCommRows(), parent->icCommunicator()->numCommColumns()); //If srcRank is not root process, MPI_Recv from that rank if(srcRank != 0){ MPI_Recv(&valuesBuffer, 2, MPI_DOUBLE, srcRank, 0, parent->icCommunicator()->communicator(), MPI_STATUS_IGNORE); } } return PV_SUCCESS; }