Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for multiple synapses #39

Merged
merged 3 commits into from
Mar 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 99 additions & 77 deletions brian2genn/b2glib/convert_synapses.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,29 @@ void convert_dynamic_arrays_2_dense_matrix(vector<int32_t> &source, vector<int32
assert(source.size() == gvector.size());
unsigned int size= source.size();
for (int s= 0; s < srcNN; s++) {
for (int t= 0; t < trgNN; t++) {
g[s*trgNN+t]= (scalar) 0.0;
}
for (int t= 0; t < trgNN; t++) {
g[s*trgNN+t]= (scalar)NAN;
}
}
// cerr << size << "!!!!!!" << endl;

for (int i= 0; i < size; i++) {
assert(source[i] < srcNN);
assert(target[i] < trgNN);
// cerr << source[i] << " " << target[i] << " " << gvector[i] << endl;
g[source[i]*trgNN+target[i]]= gvector[i];
assert(source[i] < srcNN);
assert(target[i] < trgNN);
// Check for duplicate entries
if (! isnan(g[source[i]*trgNN+target[i]])) {
std::cerr << "*****" << std::endl;
std::cerr << "ERROR Cannot run GeNN simulation: More than one synapse for pair " << source[i] << " - " << target[i] << std::endl;
std::cerr << "*****" << std::endl;
exit(222);
}
g[source[i]*trgNN+target[i]]= gvector[i];
}
for (int s= 0; s < srcNN; s++) {
for (int t= 0; t < trgNN; t++) {
if (isnan(g[s*trgNN+t]))
g[s*trgNN+t] = 0.0;
}
}
// cerr << endl;
// cerr << "-------------------------";
}

namespace b2g {
Expand All @@ -46,52 +56,64 @@ void convert_dynamic_arrays_2_sparse_synapses(vector<int32_t> &source, vector<in
static vector<vector<scalar> > bypreG;
static unsigned int size;
if (mode == b2g::FULL_MONTY) {
assert(source.size() == target.size());
assert(source.size() == gvector.size());
bypre.clear();
bypre.resize(srcNN);
bypreG.clear();
bypreG.resize(srcNN);
size= source.size();
for (int i= 0; i < size; i++) {
assert(source[i] < srcNN);
assert(target[i] < trgNN);
bypre[source[i]].push_back(target[i]);
bypreG[source[i]].push_back(gvector[i]);
}
// convert this intermediate representation into the sparse synapses struct
// assume it has been allocated properly
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
size= bypre[i].size();
c.indInG[i]= cnt;
for (int j= 0; j < size; j++) {
c.ind[cnt]= bypre[i][j];
gv[cnt]= bypreG[i][j];
assert(source.size() == target.size());
assert(source.size() == gvector.size());
bypre.clear();
bypre.resize(srcNN);
bypreG.clear();
bypreG.resize(srcNN);
size= source.size();
for (int i= 0; i < size; i++) {
assert(source[i] < srcNN);
assert(target[i] < trgNN);
bypre[source[i]].push_back(target[i]);
bypreG[source[i]].push_back(gvector[i]);
}
// convert this intermediate representation into the sparse synapses struct
// assume it has been allocated properly
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
size= bypre[i].size();
c.indInG[i]= cnt;
for (int j= 0; j < size; j++) {
c.ind[cnt]= bypre[i][j];
gv[cnt]= bypreG[i][j];
// os << i << " " << c.ind[cnt] << " " << gv[cnt] << endl;
cnt++;
}
}
c.indInG[srcNN]= cnt;
cnt++;
}
}
c.indInG[srcNN]= cnt;
}
else { // COPY_ONLY
bypreG.clear();
bypreG.resize(srcNN);
size= source.size();
for (int i= 0; i < size; i++) {
bypreG[source[i]].push_back(gvector[i]);
}
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
size= bypre[i].size();
for (int j= 0; j < size; j++) {
gv[cnt]= bypreG[i][j];
bypreG.clear();
bypreG.resize(srcNN);
size= source.size();
for (int i= 0; i < size; i++) {
bypreG[source[i]].push_back(gvector[i]);
}
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
size= bypre[i].size();
for (int j= 0; j < size; j++) {
gv[cnt]= bypreG[i][j];
// os << i << " " << c.ind[cnt] << " " << gv[cnt] << endl;
cnt++;
}
}
cnt++;
}
}
}

// Check for duplicate entries
for (int i=0; i<srcNN; i++) {
vector<int32_t> targets = bypre[i];
std::sort(targets.begin(), targets.end());
auto duplicate_pos = std::adjacent_find(targets.begin(), targets.end());
if (duplicate_pos != targets.end()) {
std::cerr << "*****" << std::endl;
std::cerr << "ERROR Cannot run GeNN simulation: More than one synapse for pair " << source[i] << " - " << *duplicate_pos << std::endl;
std::cerr << "*****" << std::endl;
exit(222);
}
}
// convertCnt++;
}

template<class scalar>
Expand All @@ -101,9 +123,9 @@ void convert_dense_matrix_2_dynamic_arrays(scalar *g, int srcNN, int trgNN, vect
assert(source.size() == gvector.size());
unsigned int size= source.size();
for (int i= 0; i < size; i++) {
assert(source[i] < srcNN);
assert(target[i] < trgNN);
gvector[i]= g[source[i]*trgNN+target[i]];
assert(source[i] < srcNN);
assert(target[i] < trgNN);
gvector[i]= g[source[i]*trgNN+target[i]];
}
}

Expand All @@ -116,28 +138,28 @@ void convert_sparse_synapses_2_dynamic_arrays(Conductance &c, scalar *gv, int sr
// ofstream os(name.c_str());
// note: this does not preserve the original order of entries in the brian arrays - is that a problem?
if (mode == b2g::FULL_MONTY) {
assert(source.size() == target.size());
assert(source.size() == gvector.size());
unsigned int size= source.size();
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
for (int j= c.indInG[i]; j < c.indInG[i+1]; j++) {
source[cnt]= i;
target[cnt]= c.ind[j];
gvector[cnt]= gv[j];
assert(source.size() == target.size());
assert(source.size() == gvector.size());
unsigned int size= source.size();
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
for (int j= c.indInG[i]; j < c.indInG[i+1]; j++) {
source[cnt]= i;
target[cnt]= c.ind[j];
gvector[cnt]= gv[j];
// os << source[cnt] << " " << target[cnt] << " " << gvector[cnt] << endl;
cnt++;
}
}
cnt++;
}
}
}
else {
unsigned int size= source.size();
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
for (int j= c.indInG[i]; j < c.indInG[i+1]; j++) {
gvector[cnt++]= gv[j];
}
}
unsigned int size= source.size();
unsigned int cnt= 0;
for (int i= 0; i < srcNN; i++) {
for (int j= c.indInG[i]; j < c.indInG[i+1]; j++) {
gvector[cnt++]= gv[j];
}
}
}
// os.close();
// convertCnt++;
Expand All @@ -146,12 +168,12 @@ void convert_sparse_synapses_2_dynamic_arrays(Conductance &c, scalar *gv, int sr
void create_hidden_weightmatrix(vector<int32_t> &source, vector<int32_t> &target, char* hwm, int srcNN, int trgNN)
{
for (int s= 0; s < srcNN; s++) {
for (int t= 0; t < trgNN; t++) {
hwm[s*trgNN+t]= 0;
}
for (int t= 0; t < trgNN; t++) {
hwm[s*trgNN+t]= 0;
}
}
for (int i= 0; i < source.size(); i++) {
hwm[source[i]*trgNN+target[i]]= 1;
hwm[source[i]*trgNN+target[i]]= 1;
}
}
#endif
17 changes: 11 additions & 6 deletions brian2genn/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,12 +677,17 @@ def build(self, directory='GeNNworkspace', compile=True, run=True,
try:
self.run(directory, use_GPU, with_output)
except CalledProcessError as ex:
raise RuntimeError(('Project run failed (Command {cmd} '
'failed with error code {returncode}).\n'
'See the output above (if any) for more '
'details.').format(cmd=ex.cmd,
returncode=ex.returncode)
)
if ex.returncode == 222:
raise NotImplementedError('GeNN does not support multiple '
'synapses per neuron pair (use '
'multiple Synapses objects).')
else:
raise RuntimeError(('Project run failed (Command {cmd} '
'failed with error code {returncode}).\n'
'See the output above (if any) for more '
'details.').format(cmd=ex.cmd,
returncode=ex.returncode)
)

def generate_code_objects(self, writer):
# Generate data for non-constant values
Expand Down