CARLsim  5.0.0
CARLsim: a GPU-accelerated SNN simulator
poisson_rate.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Regents of the University of California. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * 3. The names of its contributors may not be used to endorse or promote
16  * products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * *********************************************************************************************** *
32  * CARLsim
33  * created by: (MDR) Micah Richert, (JN) Jayram M. Nageswaran
34  * maintained by: (MA) Mike Avery <averym@uci.edu>, (MB) Michael Beyeler <mbeyeler@uci.edu>,
35  * (KDC) Kristofor Carlson <kdcarlso@uci.edu>
36  * (TSC) Ting-Shuo Chou <tingshuc@uci.edu>
37  *
38  * CARLsim available from http://socsci.uci.edu/~jkrichma/CARLsim/
39  * Ver 6/13/2016
40  */
41 #include <cassert> // assert
42 #include <cstdio> // printf
43 #include <cstring> // string, memset
44 #include <cstdlib> // malloc, free, rand
45 
46 #include <poisson_rate.h>
47 #include <carlsim_definitions.h> // ALL
48 #ifndef __NO_CUDA__
49  #include <cuda_version_control.h>
50 #endif
51 
52 
53 
55 public:
56  // +++++ PUBLIC METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
57  Impl(int nNeur, bool onGPU): nNeur_(nNeur), onGPU_(onGPU) {
58  assert(nNeur>0);
59 
60  h_rates_ = NULL;
61  d_rates_ = NULL;
62 
63  if (onGPU) {
64 #ifndef __NO_CUDA__
65  // allocate rates on device and set to zero
66  CUDA_CHECK_ERRORS(cudaMalloc((void**)&d_rates_, sizeof(float)*nNeur));
67  CUDA_CHECK_ERRORS(cudaMemset(d_rates_, 0, sizeof(float)*nNeur));
68 #else
69  printf("Cannot use onGPU when compiled without CUDA library.\n");
70  assert(false);
71 #endif
72  } else {
73  // allocate rates on host and set to zero
74  h_rates_ = new float[nNeur];
75  memset(h_rates_, 0, sizeof(float)*nNeur);
76  }
77  }
78 
79  ~Impl() {
80  if (isOnGPU()) {
81 #ifndef __NO_CUDA__
82  // clean up device
83  if (d_rates_!=NULL) {
84  CUDA_CHECK_ERRORS(cudaFree(d_rates_)); // free memory
85  d_rates_ = NULL;
86  }
87 #endif
88  } else {
89  // clean up host
90  if (h_rates_!=NULL) {
91  delete[] h_rates_;
92  }
93  h_rates_ = NULL;
94  }
95  }
96 
97  int getNumNeurons() {
98  return nNeur_;
99  }
100 
101  // get rate of certain neuron
102  float getRate(int neurId) {
103  assert(neurId>=0 && neurId<getNumNeurons());
104 
105  if (isOnGPU()) {
106 #ifndef __NO_CUDA__
107  // get data from device (might have kernel launch overhead because float is small)
108  float h_d_rate = 0.0f;
109  CUDA_CHECK_ERRORS( cudaMemcpy(&h_d_rate, &(d_rates_[neurId]), sizeof(float), cudaMemcpyDeviceToHost) );
110  return h_d_rate;
111 #endif
112  } else {
113  // data is on host
114  return h_rates_[neurId];
115  }
116  }
117 
118  // get all rates as vector
119  std::vector<float> getRates() {
120  if (isOnGPU()) {
121 #ifndef __NO_CUDA__
122  // get data from device
123  float *h_d_rates = (float*)malloc(sizeof(float)*getNumNeurons());
124  CUDA_CHECK_ERRORS( cudaMemcpy(h_d_rates, d_rates_, sizeof(float)*getNumNeurons(), cudaMemcpyDeviceToHost) );
125 
126  // copy data to vec
127  std::vector<float> rates(h_d_rates, h_d_rates + getNumNeurons());
128  free(h_d_rates);
129 
130  return rates;
131 #endif
132  } else {
133  // data is on host
134  std::vector<float> rates(h_rates_, h_rates_ + getNumNeurons()); // copy to vec
135  return rates;
136  }
137  }
138 
139  // get pointer to rate array on CPU
140  float* getRatePtrCPU() {
141  assert(!isOnGPU());
142  return h_rates_;
143  }
144 
145  // get pointer to rate array on GPU
146  float* getRatePtrGPU() {
147  assert(isOnGPU());
148  return d_rates_;
149  }
150 
151  bool isOnGPU() {
152  return onGPU_;
153  }
154 
155  // set rate of a specific neuron
156  void setRate(int neurId, float rate) {
157  if (neurId==ALL) {
158  setRates(rate);
159  } else {
160  assert(neurId>=0 && neurId<getNumNeurons());
161  if (isOnGPU()) {
162 #ifndef __NO_CUDA__
163  // copy float to device (might have kernel launch overhead because float is small)
164  CUDA_CHECK_ERRORS( cudaMemcpy(&(d_rates_[neurId]), &rate, sizeof(float), cudaMemcpyHostToDevice) );
165 #endif
166  } else {
167  // set float in host array
168  h_rates_[neurId] = rate;
169  }
170  }
171  }
172 
173  // set rate of all neurons to same value
174  void setRates(float rate) {
175  assert(rate>=0.0f);
176 
177  std::vector<float> rates(getNumNeurons(), rate);
178  setRates(rates);
179  }
180 
181  // set rates with vector
182  void setRates(const std::vector<float>& rate) {
183  assert(rate.size()==getNumNeurons());
184 
185  if (isOnGPU()) {
186 #ifndef __NO_CUDA__
187  // copy to device
188  float *h_rates_arr = new float[getNumNeurons()];
189  std::copy(rate.begin(), rate.end(), h_rates_arr);
190  CUDA_CHECK_ERRORS( cudaMemcpy(d_rates_, h_rates_arr, sizeof(float)*getNumNeurons(), cudaMemcpyHostToDevice) );
191  delete[] h_rates_arr;
192 #endif
193  } else {
194  // set host array
195  std::copy(rate.begin(), rate.end(), h_rates_);
196  }
197  }
198 
199 
200 private:
201  // +++++ PRIVATE METHODS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
202 
203  // +++++ PRIVATE STATIC PROPERTIES ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
204 
205  // +++++ PRIVATE PROPERTIES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
206 
207  float *h_rates_;
208  float *d_rates_;
209  const int nNeur_;
210  const bool onGPU_;
211 };
212 
213 
214 // ****************************************************************************************************************** //
215 // POISSONRATE API IMPLEMENTATION
216 // ****************************************************************************************************************** //
217 
218 // create and destroy a pImpl instance
219 PoissonRate::PoissonRate(int nNeur, bool onGPU) : _impl( new Impl(nNeur, onGPU) ) {}
220 PoissonRate::~PoissonRate() { delete _impl; }
221 
222 int PoissonRate::getNumNeurons() { return _impl->getNumNeurons(); }
223 float PoissonRate::getRate(int neurId) { return _impl->getRate(neurId); }
224 std::vector<float> PoissonRate::getRates() { return _impl->getRates(); }
225 float* PoissonRate::getRatePtrCPU() { return _impl->getRatePtrCPU(); }
226 float* PoissonRate::getRatePtrGPU() { return _impl->getRatePtrGPU(); }
227 bool PoissonRate::isOnGPU() { return _impl->isOnGPU(); }
228 void PoissonRate::setRate(int neurId, float rate) { _impl->setRate(neurId, rate); }
229 void PoissonRate::setRates(float rate) { _impl->setRates(rate); }
230 void PoissonRate::setRates(const std::vector<float>& rates) { _impl->setRates(rates); }
PoissonRate::setRates
void setRates(float rate)
Assigns the same mean firing rate to all neurons.
Definition: poisson_rate.cpp:229
PoissonRate::getRatePtrCPU
float * getRatePtrCPU()
Returns pointer to CPU-allocated firing rate array (deprecated)
Definition: poisson_rate.cpp:225
PoissonRate::Impl::setRates
void setRates(const std::vector< float > &rate)
Definition: poisson_rate.cpp:182
cuda_version_control.h
PoissonRate::Impl::setRates
void setRates(float rate)
Definition: poisson_rate.cpp:174
PoissonRate::Impl::getRates
std::vector< float > getRates()
Definition: poisson_rate.cpp:119
PoissonRate::Impl::getNumNeurons
int getNumNeurons()
Definition: poisson_rate.cpp:97
PoissonRate::getNumNeurons
int getNumNeurons()
Returns the number of neurons for which to generate Poisson spike trains.
Definition: poisson_rate.cpp:222
PoissonRate::Impl::Impl
Impl(int nNeur, bool onGPU)
Definition: poisson_rate.cpp:57
PoissonRate::getRate
float getRate(int neurId)
Returns the mean firing rate of a specific neuron ID.
Definition: poisson_rate.cpp:223
ALL
#define ALL
CARLsim common definitions.
Definition: carlsim_definitions.h:56
PoissonRate::~PoissonRate
~PoissonRate()
PoissonRate destructor.
Definition: poisson_rate.cpp:220
poisson_rate.h
PoissonRate::Impl::setRate
void setRate(int neurId, float rate)
Definition: poisson_rate.cpp:156
PoissonRate::setRate
void setRate(int neurId, float rate)
Sets the mean firing rate of a particular neuron ID.
Definition: poisson_rate.cpp:228
PoissonRate::PoissonRate
PoissonRate(int nNeur, bool onGPU=false)
PoissonRate constructor.
Definition: poisson_rate.cpp:219
PoissonRate::Impl
Definition: poisson_rate.cpp:54
PoissonRate::getRates
std::vector< float > getRates()
Returns a vector of firing rates, one element per neuron.
Definition: poisson_rate.cpp:224
PoissonRate::Impl::getRate
float getRate(int neurId)
Definition: poisson_rate.cpp:102
PoissonRate::Impl::~Impl
~Impl()
Definition: poisson_rate.cpp:79
PoissonRate::Impl::isOnGPU
bool isOnGPU()
Definition: poisson_rate.cpp:151
PoissonRate::getRatePtrGPU
float * getRatePtrGPU()
Returns pointer to GPU-allocated firing rate array (deprecated)
Definition: poisson_rate.cpp:226
carlsim_definitions.h
PoissonRate::Impl::getRatePtrCPU
float * getRatePtrCPU()
Definition: poisson_rate.cpp:140
PoissonRate::Impl::getRatePtrGPU
float * getRatePtrGPU()
Definition: poisson_rate.cpp:146
PoissonRate::isOnGPU
bool isOnGPU()
Checks whether the firing rates are allocated on CPU or GPU.
Definition: poisson_rate.cpp:227