///////////////////////////////////////////////////////// // processImage // ///////////////////////////////////////////////////////// void pix_tIIRf :: processImage(imageStruct &image) { int j; size_t imagesize = imgSize(&image); unsigned char *dest; if(!imgCompare(image, m_image)) { // LATER only reallocate if really needed deallocate(); allocate(image); m_set=CLEAR; } switch(m_set) { case SET: set(&image); break; case CLEAR: set(); break; default: break; } m_set=NONE; dest=m_image.data; // do the filtering // feed-back // w[n] = x[n]*ff0 + w[n-1]*ff1 + ... + w[n-N]*ffN // w[n] = x[n]*ff0 img2buf(&image, m_buffer[m_counter], m_fb[0]); j=m_fbnum; for(j=1; j<m_fbnum; j++) { // w[n] += w[n-J]*ffJ const unsigned int index=getIndex(m_counter, -j, m_bufnum-1); weightAdd(m_buffer[index], m_buffer[m_counter], m_fb[j], imagesize); } // feed-forward // y[n] = ff0*w[n] + ff1*w[n-1] + ... + ffM*w[n-M] weightSet(m_buffer[m_counter], m_buffer[m_bufnum-1], m_ff[0], imagesize); for(j=1; j<m_ffnum; j++) { const unsigned int index=getIndex(m_counter, -j, m_bufnum-1); weightAdd(m_buffer[index], m_buffer[m_bufnum-1], m_ff[j], imagesize); } buf2img(m_buffer[m_bufnum-1], &image); m_counter = getIndex(m_counter, 1, m_bufnum-1); }
/// - Assumes an MPI_WORLD distribution /// - Assumes ordered distribution of units in a population /// Also, only legitimate to use in cases where we have recurrent connectivity /// Quite specifically made for the random Projections atm. void Connectivity::MakeProjectionsSymmetric(vector<vector<long> >* preCache, vector<long>* postCache, ProjectionFixed* conn) { // send version // only gather all data send to node vector<int> nrPreRateUnits = ((PopulationColumns*)m_pre)->GetStructure(); vector<long> postsToAdd; vector<vector<long> > presToAdd; vector<vector<float> > weightsToAdd; vector<vector<float> > delaysToAdd; vector<int> procsUsed = conn->PreLayer()->MPIGetProcessesUsed(); MPI_Comm *comm = m_post->MPI()->MPIGetCommLayer(); bool cont = false; if(procsUsed.size() == 0) cont = true; else if(binary_search(procsUsed.begin(),procsUsed.end(),this->network()->MPIGetNodeId())) cont = true; if(cont == true) // only continue if this process takes part in the population { // assumes an ordered distribution long startId = ((PopulationColumns*)m_post)->GetUnits()[0]->GetUnitId(); long endId = ((PopulationColumns*)m_post)->GetUnits()[((PopulationColumns*)m_post)->GetUnits().size()-1]->GetUnitId(); // assumes that it is int totNr = procsUsed.size(); if(procsUsed.size()==0) totNr = this->network()->MPIGetNrProcs(); for(int i=0;i<totNr;i++)//this->network()->MPIGetNrProcs();i++) { vector<long> tempPost; vector<long> tempPostLocal; vector<vector<long> > tempPre; vector<vector<float> > weights; vector<vector<float> > delays; int mpiRank; if(procsUsed.size() == 0) mpiRank = i; else mpiRank = procsUsed[i]; if(procsUsed.size() == 1 || totNr == 1) // whole population on one process { tempPost = *postCache; tempPre = *preCache; int nrPosts = (*postCache).size(); for(int j=0;j<nrPosts;j++) { int nrPre = (*preCache)[j].size(); vector<float> w(nrPre); vector<float> d(nrPre); for(int m=0;m<nrPre;m++) { w[m] = this->network()->GetWeight((*preCache)[j][m],(*postCache)[j]); d[m] = this->network()->GetDelay((*preCache)[j][m],(*postCache)[j]); } weights.push_back(w); delays.push_back(d); } } else // broadcast the Projections and weights to other processes involved in this population { if(mpiRank == this->network()->MPIGetNodeId()) { tempPost = *postCache; tempPre = *preCache; // send locally corresponding part int nrPosts = (*postCache).size(); MPI_Bcast(&nrPosts,1,MPI_INT,mpiRank,*comm);//NETWORK_COMM_WORLD); if(nrPosts>0) { MPI_Bcast(&(*postCache)[0],nrPosts,MPI_LONG,mpiRank,*comm);//NETWORK_COMM_WORLD); for(int j=0;j<nrPosts;j++) { int nrPre = (*preCache)[j].size(); MPI_Bcast(&nrPre,1,MPI_INT,mpiRank,*comm);//NETWORK_COMM_WORLD); vector<float> w(nrPre); vector<float> d(nrPre); for(int m=0;m<nrPre;m++) { w[m] = this->network()->GetWeight((*preCache)[j][m],(*postCache)[j]); d[m] = this->network()->GetDelay((*preCache)[j][m],(*postCache)[j]); } weights.push_back(w); delays.push_back(d); if(nrPre>0) { MPI_Bcast(&(*preCache)[j][0],nrPre,MPI_LONG,mpiRank,*comm);//,NETWORK_COMM_WORLD); MPI_Bcast(&w[0],nrPre,MPI_FLOAT,mpiRank,*comm);//,NETWORK_COMM_WORLD); MPI_Bcast(&d[0],nrPre,MPI_FLOAT,mpiRank,*comm);//,NETWORK_COMM_WORLD); } } } } else { // retrieve int nrPosts; MPI_Bcast(&nrPosts,1,MPI_INT,mpiRank,*comm);//,NETWORK_COMM_WORLD); if(nrPosts>0) { tempPost = vector<long>(nrPosts); tempPre = vector<vector<long> >(nrPosts); weights = vector<vector<float> >(nrPosts); delays = vector<vector<float> >(nrPosts); MPI_Bcast(&tempPost[0],nrPosts,MPI_LONG,mpiRank,*comm);//,NETWORK_COMM_WORLD); for(int j=0;j<nrPosts;j++) { int nrPre; MPI_Bcast(&nrPre,1,MPI_INT,mpiRank,*comm);//,NETWORK_COMM_WORLD); if(nrPre>0) { tempPre[j] = vector<long>(nrPre); weights[j] = vector<float>(nrPre); delays[j] = vector<float>(nrPre); MPI_Bcast(&tempPre[j][0],nrPre,MPI_LONG,mpiRank,*comm);//,NETWORK_COMM_WORLD); MPI_Bcast(&weights[j][0],nrPre,MPI_FLOAT,mpiRank,*comm);//,NETWORK_COMM_WORLD); MPI_Bcast(&delays[j][0],nrPre,MPI_FLOAT,mpiRank,*comm);//,NETWORK_COMM_WORLD); } } } } } vector<long>::iterator it; // put in list to build for(int j=0;j<tempPost.size();j++) { for(int m=0;m<tempPre[j].size();m++) { if(tempPre[j][m] >= startId && tempPre[j][m] <= endId) { it = find(postsToAdd.begin(),postsToAdd.end(),tempPre[j][m]); if(it == postsToAdd.end()) { postsToAdd.push_back(tempPre[j][m]); vector<long> preAdd(1); vector<float> weightAdd(1); vector<float> delayAdd(1); preAdd[0] = tempPost[j]; weightAdd[0] = weights[j][m]; delayAdd[0] = delays[j][m]; weightsToAdd.push_back(weightAdd); delaysToAdd.push_back(delayAdd); presToAdd.push_back(preAdd); } else { presToAdd[it-postsToAdd.begin()].push_back(tempPost[j]); weightsToAdd[it-postsToAdd.begin()].push_back(weights[j][m]); delaysToAdd[it-postsToAdd.begin()].push_back(delays[j][m]); } } } } } // build new Projections at the same time for(int i=0;i<postsToAdd.size();i++) { conn->AddProjections(presToAdd[i],postsToAdd[i],-1); // -1 will force a lookup of the local id value for(int j=0;j<presToAdd[i].size();j++) { m_network->SetWeight(weightsToAdd[i][j],presToAdd[i][j],postsToAdd[i]); //m_network->SetDelay(delaysToAdd[i][j],presToAdd[i][j],postsToAdd[i]); } } // check symmetry bool checkSymmetry = true; if(checkSymmetry) { vector<long> postIds = conn->GetPostIds(); bool symmetric = true; for(int i=0;i<postIds.size();i++) { for(int j=0;j<postIds.size();j++) { if(i!=j) { vector<long> preIds1 = conn->GetPreIds(postIds[i]); vector<long> preIds2 = conn->GetPreIds(postIds[j]); if(find(preIds2.begin(),preIds2.end(),postIds[i]) != preIds2.end()) { if(find(preIds1.begin(),preIds1.end(),postIds[j]) == preIds1.end()) symmetric = false; // if(find(preIds2.begin(),preIds2.end(),postIds[i]) == preIds2.end()) // symmetric = false; } } } } if(m_network->MPIGetNodeId() == 0) { cout<<"\nSymmetric == "<<symmetric<<"\n";cout.flush(); } } } }