GeNN  3.3.0
GPU enhanced Neuronal Networks (GeNN)
sparseUtils.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Standard C++ includes
4 #include <string>
5 
6 // Standard C includes
7 #include <cmath>
8 #include <cstdlib>
9 #include <cstdio>
10 
11 // GeNN includes
12 #include "global.h"
13 #include "sparseProjection.h"
14 
15 using namespace std;
16 
17 
18 //--------------------------------------------------------------------------
22 //--------------------------------------------------------------------------
23 
24 template <class DATATYPE>
25 unsigned int countEntriesAbove(DATATYPE *Array, int sz, double includeAbove)
26 {
27  int count = 0;
28  for (int i = 0; i < sz; i++) {
29  if (abs(Array[i]) > includeAbove) count++;
30  }
31  fprintf(stdout, "\nCounted %u nonzero entries\n\n", count);
32  return count;
33 
34 }
35 
36 
37 //--------------------------------------------------------------------------
43 //--------------------------------------------------------------------------
44 
45 template <class DATATYPE>
46 DATATYPE getG(DATATYPE *wuvar, SparseProjection *sparseStruct, int x, int y)
47 {
48  fprintf(stderr,"WARNING: This function is deprecated, and if you are still using it \n\
49  you are probably trying to use the old sparse structures containing the g array. \n\
50  Conductance structures have changed: conductance values should be defined as synapse variables now; \n\
51  the structure is renamed as \"SparseProjection\" and contains only indexing arrays. \n\n\
52  The replacement function for getG is \n\
53  getSparseVar(DATATYPE * wuvar, SparseProjection * sparseStruct, int x, int y).\n\n\
54  calling getSparseVar...");
55  getSparseVar(wuvar, &sparseStruct, x, y);
56 }
57 
58 template <class DATATYPE>
59 float getSparseVar(DATATYPE *wuvar, SparseProjection *sparseStruct, unsigned int x, unsigned int y)
60 {
61  DATATYPE g = 0.0; //default return value implies zero weighted for x,y
62  int startSynapse = sparseStruct->indInG[x];
63  int endSynapse = sparseStruct->indInG[x+1];
64  for (int syn = startSynapse; syn < endSynapse; syn++) {
65  if (sparseStruct->ind[syn]==y) {//look for index y
66  g = wuvar[syn]; //set the real g
67  break; //stop looking
68  }
69  }
70  return g;
71 }
72 
73 
74 //--------------------------------------------------------------------------
78 //--------------------------------------------------------------------------
79 
80 template <class DATATYPE>
81 void setSparseConnectivityFromDense(DATATYPE *wuvar, int preN, int postN, DATATYPE *tmp_gRNPN, SparseProjection *sparseStruct)
82 {
83  int synapse = 0;
84  sparseStruct->indInG[0] = 0; //first neuron always gets first synapse listed.
85  for (int pre = 0; pre < preN; ++pre) {
86  for (int post = 0; post < postN; ++post) {
87  DATATYPE g = tmp_gRNPN[pre * postN + post];
89  sparseStruct->ind[synapse] = post;
90  wuvar[synapse] = g;
91  synapse ++;
92  }
93  }
94  sparseStruct->indInG[pre + 1] = synapse; //write start of next group
95  }
96 }
97 
98 
99 
100 //--------------------------------------------------------------------------
104 //--------------------------------------------------------------------------
105 
106 template <class DATATYPE>
107 void createSparseConnectivityFromDense(DATATYPE *wuvar, int preN, int postN, DATATYPE *tmp_gRNPN, SparseProjection *sparseStruct, bool runTest) {
108  sparseStruct->connN = countEntriesAbove(tmp_gRNPN, preN * postN, GENN_PREFERENCES::asGoodAsZero);
109  //sorry -- this is not functional anymore
110 
111  //allocateSparseArray(sparseStruct, sparseStruct.connN, preN, false);
112  int synapse = 0;
113  sparseStruct->indInG[0] = 0; //first neuron always gets first synapse listed.
114  for (int pre = 0; pre < preN; ++pre) {
115  for (int post = 0; post < postN; ++post) {
116  DATATYPE g = tmp_gRNPN[pre * postN + post];
118  sparseStruct->ind[synapse] = post;
119  wuvar[synapse] = g;
120  synapse ++;
121  }
122  }
123  sparseStruct->indInG[pre + 1] = synapse; //write start of next group
124  }
125  if (!runTest) return;
126 
127  //test correct
128  int fails = 0;
129  for (int test = 0; test < 10; ++test) {
130  int randX = rand() % preN;
131  int randY = rand() % postN;
132  float denseResult = tmp_gRNPN[randX * postN + randY];
133  float sparseResult = getG(wuvar, sparseStruct,randX,randY);
134  if (abs(denseResult-sparseResult) > GENN_PREFERENCES::asGoodAsZero) fails++;
135  }
136  if (fails > 0 ) {
137  fprintf(stderr, "ERROR: Sparse connectivity generator failed for %u out of 10 random checks.\n", fails);
138  exit(1);
139  }
140  fprintf(stdout, "Sparse connectivity generator passed %u out of 10 random checks.\n", fails);
141 }
142 
143 
144 //---------------------------------------------------------------------
147 //---------------------------------------------------------------------
148 void createPosttoPreArray(unsigned int preN, unsigned int postN, SparseProjection *C);
149 
150 //---------------------------------------------------------------------
153 //---------------------------------------------------------------------
154 template<typename PostIndexType>
155 void createPosttoPreArray(unsigned int preN, unsigned int postN, RaggedProjection<PostIndexType> * C)
156 {
157  // Zero column lengths
158  std::fill_n(C->colLength, postN, 0);
159 
160  // Loop through presynaptic neurons
161  for (unsigned int i = 0; i < preN; i++) {
162  // Loop through synapses in corresponding matrix row
163  for(unsigned int j = 0; j < C->rowLength[i]; j++) {
164  // Calculate index of this synapse in the row-major matrix
165  const unsigned int rowMajorIndex = (i * C->maxRowLength) + j;
166 
167  // Using this, lookup postsynaptic target
168  const unsigned int postIndex = C->ind[rowMajorIndex];
169 
170  // From this calculate index of this synapse in the column-major matrix
171  const unsigned int colMajorIndex = (postIndex * C->maxColLength) + C->colLength[postIndex];
172 
173  // Increment column length corresponding to this postsynaptic neuron
174  C->colLength[postIndex]++;
175 
176  // Add remapping entry
177  C->remap[colMajorIndex] = rowMajorIndex;
178  }
179  }
180 }
181 //--------------------------------------------------------------------------
185 //--------------------------------------------------------------------------
186 
187 void createPreIndices(unsigned int preN, unsigned int postN, SparseProjection *C);
188 
189 template<typename PostIndexType>
190 void createPreIndices(unsigned int preN, unsigned int, RaggedProjection<PostIndexType> * C)
191 {
192  unsigned int &synRemapCount = C->synRemap[0];
193  unsigned int *synRemap = &C->synRemap[1];
194  // Loop through presynaptic neurons
195  synRemapCount = 0;
196  for (unsigned int i = 0; i < preN; i++) {
197  // Loop through synapses in corresponding matrix row
198  for(unsigned int j = 0; j < C->rowLength[i]; j++) {
199  synRemap[synRemapCount++] = (i * C->maxRowLength) + j;
200  }
201  }
202 }
203 
204 #ifndef CPU_ONLY
205 //--------------------------------------------------------------------------
209 //--------------------------------------------------------------------------
210 
211 void initializeSparseArray(const SparseProjection &C, unsigned int *dInd, unsigned int *dIndInG, unsigned int preN);
212 
213 
214 //--------------------------------------------------------------------------
218 //--------------------------------------------------------------------------
219 template<typename PostIndexType>
220 void initializeRaggedArray(const RaggedProjection<PostIndexType> &C, PostIndexType *dInd, unsigned int *dRowLength, unsigned int preN)
221 {
222  CHECK_CUDA_ERRORS(cudaMemcpy(dInd, C.ind, C.maxRowLength * preN * sizeof(PostIndexType), cudaMemcpyHostToDevice));
223  CHECK_CUDA_ERRORS(cudaMemcpy(dRowLength, C.rowLength, preN * sizeof(unsigned int), cudaMemcpyHostToDevice));
224 }
225 
226 //--------------------------------------------------------------------------
230 //--------------------------------------------------------------------------
231 
232 void initializeSparseArrayRev(const SparseProjection &C, unsigned int *dRevInd, unsigned int *dRevIndInG, unsigned int *dRemap, unsigned int postN);
233 
234 //--------------------------------------------------------------------------
238 //--------------------------------------------------------------------------
239 
240 void initializeSparseArrayPreInd(const SparseProjection &C, unsigned int * dPreInd);
241 
242 //--------------------------------------------------------------------------
246 //--------------------------------------------------------------------------
247 template<typename PostIndexType>
248 void initializeRaggedArrayRev(const RaggedProjection<PostIndexType> &C, unsigned int *dColLength, unsigned int *dRemap, unsigned int postN)
249 {
250  CHECK_CUDA_ERRORS(cudaMemcpy(dColLength, C.colLength, postN * sizeof(unsigned int), cudaMemcpyHostToDevice));
251  CHECK_CUDA_ERRORS(cudaMemcpy(dRemap, C.remap, C.maxColLength * postN * sizeof(unsigned int), cudaMemcpyHostToDevice));
252 }
253 
254 //--------------------------------------------------------------------------
258 //--------------------------------------------------------------------------
259 template<typename PostIndexType>
260 void initializeRaggedArraySynRemap(const RaggedProjection<PostIndexType> &C, unsigned int *dSynRemap)
261 {
262  CHECK_CUDA_ERRORS(cudaMemcpy(dSynRemap, C.synRemap, (C.synRemap[0] + 1) * sizeof(unsigned int), cudaMemcpyHostToDevice));
263 }
264 #endif // CPU_ONLY
DATATYPE getG(DATATYPE *wuvar, SparseProjection *sparseStruct, int x, int y)
DEPRECATED Utility to get a synapse weight from a SPARSE structure by x,y coordinates NB: as the Spar...
Definition: sparseUtils.h:46
PostIndexType * ind
Ragged row-major matrix, padded to maxRowLength containing indices of target neurons.
Definition: sparseProjection.h:41
void createPosttoPreArray(unsigned int preN, unsigned int postN, SparseProjection *C)
Utility to generate the YALE array structure with post-to-pre arrangement from the original pre-to-po...
Definition: sparseUtils.cc:18
void initializeRaggedArray(const RaggedProjection< PostIndexType > &C, PostIndexType *dInd, unsigned int *dRowLength, unsigned int preN)
Function for initializing conductance array indices for sparse matrices on the GPU (by copying the va...
Definition: sparseUtils.h:220
float getSparseVar(DATATYPE *wuvar, SparseProjection *sparseStruct, unsigned int x, unsigned int y)
Definition: sparseUtils.h:59
void createSparseConnectivityFromDense(DATATYPE *wuvar, int preN, int postN, DATATYPE *tmp_gRNPN, SparseProjection *sparseStruct, bool runTest)
Utility to generate the SPARSE connectivity structure from a simple all-to-all array.
Definition: sparseUtils.h:107
const unsigned int maxColLength
Definition: sparseProjection.h:35
Global header file containing a few global variables. Part of the code generation section...
double asGoodAsZero
What is the default behaviour for sparse synaptic connectivity? Historically, everything was allocate...
Definition: global.cc:45
unsigned int countEntriesAbove(DATATYPE *Array, int sz, double includeAbove)
Utility to count how many entries above a specified value exist in a float array. ...
Definition: sparseUtils.h:25
Row-major ordered sparse matrix structure in &#39;ragged&#39; format.
Definition: sparseProjection.h:28
unsigned int * rowLength
Length of each row of matrix.
Definition: sparseProjection.h:38
unsigned int connN
Definition: sparseProjection.h:23
unsigned int * colLength
Length of each column of matrix.
Definition: sparseProjection.h:44
unsigned int * ind
Definition: sparseProjection.h:18
void initializeSparseArrayPreInd(const SparseProjection &C, unsigned int *dPreInd)
Function for initializing reversed conductance arrays presynaptic indices for sparse matrices on the ...
Definition: sparseUtils.cc:109
void initializeRaggedArrayRev(const RaggedProjection< PostIndexType > &C, unsigned int *dColLength, unsigned int *dRemap, unsigned int postN)
Function for initializing reversed conductance array indices for sparse matrices on the GPU (by copyi...
Definition: sparseUtils.h:248
#define CHECK_CUDA_ERRORS(call)
Definition: utils.h:64
unsigned int * synRemap
Indices back into ind for each synapse.
Definition: sparseProjection.h:53
const unsigned int maxRowLength
Maximum dimensions of matrices (used for sizing of ind and remap)
Definition: sparseProjection.h:34
void initializeRaggedArraySynRemap(const RaggedProjection< PostIndexType > &C, unsigned int *dSynRemap)
Function for initializing reversed conductance arrays presynaptic indices for sparse matrices on the ...
Definition: sparseUtils.h:260
void setSparseConnectivityFromDense(DATATYPE *wuvar, int preN, int postN, DATATYPE *tmp_gRNPN, SparseProjection *sparseStruct)
Function for setting the values of SPARSE connectivity matrix.
Definition: sparseUtils.h:81
unsigned int * indInG
Definition: sparseProjection.h:17
void createPreIndices(unsigned int preN, unsigned int postN, SparseProjection *C)
Function to create the mapping from the normal index array "ind" to the "reverse" array revInd...
Definition: sparseUtils.cc:64
class (struct) for defining a spars connectivity projection
Definition: sparseProjection.h:16
void initializeSparseArray(const SparseProjection &C, unsigned int *dInd, unsigned int *dIndInG, unsigned int preN)
Function for initializing conductance array indices for sparse matrices on the GPU (by copying the va...
Definition: sparseUtils.cc:82
unsigned int * remap
Ragged column-major matrix, padded to maxColLength containing indices back into ind.
Definition: sparseProjection.h:47
void initializeSparseArrayRev(const SparseProjection &C, unsigned int *dRevInd, unsigned int *dRevIndInG, unsigned int *dRemap, unsigned int postN)
Function for initializing reversed conductance array indices for sparse matrices on the GPU (by copyi...
Definition: sparseUtils.cc:95