Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 639e9e0

Browse files
author
Omar Awile
authored
Allow NetSendBuffer_t to grow (#395)
Until now NetSendBuffer_t was allocated at a fixed size that could not be changed. When using buffered net_send and invoking multiple net_send's in INITIAL blocks in NMODL it may happen that we run out of buffer. Currently this case is not handled and causes a buffer overflow. As a first step NetSendBuffer_t has been given a constructor and destructor as well as a grow function that doubles all internal buffer sizes and copies data to the new buffers. - By inheriting from MemoryManaged the class overloads new and free operators to use cudaMallocManaged alloctors when necessary. - Check for OpenACC and throw an error, as reallocation will not work on device
1 parent e0a2774 commit 639e9e0

File tree

4 files changed

+58
-27
lines changed

4 files changed

+58
-27
lines changed

coreneuron/io/nrn_setup.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -732,15 +732,7 @@ void nrn_cleanup() {
732732

733733
NetSendBuffer_t* nsb = ml->_net_send_buffer;
734734
if (nsb) {
735-
if (nsb->_size) {
736-
free_memory(nsb->_sendtype);
737-
free_memory(nsb->_vdata_index);
738-
free_memory(nsb->_pnt_index);
739-
free_memory(nsb->_weight_index);
740-
free_memory(nsb->_nsb_t);
741-
free_memory(nsb->_nsb_flag);
742-
}
743-
free_memory(nsb);
735+
delete nsb;
744736
}
745737

746738
if (tml->dependencies)

coreneuron/io/phase2.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -464,23 +464,9 @@ void Phase2::set_net_send_buffer(Memb_list** ml_list, const std::vector<int>& pn
464464
// Does this thread have this type.
465465
Memb_list* ml = ml_list[type];
466466
if (ml) { // needs a NetSendBuffer
467-
NetSendBuffer_t* nsb = (NetSendBuffer_t*)ecalloc_align(1, sizeof(NetSendBuffer_t));
468-
ml->_net_send_buffer = nsb;
469-
470467
// begin with a size equal to twice number of instances
471-
// at present there is no provision for dynamically increasing this.
472-
nsb->_size = ml->nodecount * 2;
473-
nsb->_cnt = 0;
474-
475-
nsb->_sendtype = (int*)ecalloc_align(nsb->_size, sizeof(int));
476-
nsb->_vdata_index = (int*)ecalloc_align(nsb->_size, sizeof(int));
477-
nsb->_pnt_index = (int*)ecalloc_align(nsb->_size, sizeof(int));
478-
nsb->_weight_index = (int*)ecalloc_align(nsb->_size, sizeof(int));
479-
// when == 1, NetReceiveBuffer_t is newly allocated (i.e. we need to free previous copy
480-
// and recopy new data
481-
nsb->reallocated = 1;
482-
nsb->_nsb_t = (double*)ecalloc_align(nsb->_size, sizeof(double));
483-
nsb->_nsb_flag = (double*)ecalloc_align(nsb->_size, sizeof(double));
468+
NetSendBuffer_t* nsb = new NetSendBuffer_t(ml->nodecount * 2);
469+
ml->_net_send_buffer = nsb;
484470
}
485471
}
486472
}

coreneuron/mechanism/mechanism.hpp

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ THE POSSIBILITY OF SUCH DAMAGE.
2727
*/
2828
#pragma once
2929

30+
#include <string.h>
31+
3032
#include "coreneuron/nrnconf.h"
33+
#include "coreneuron/utils/memory.h"
3134

3235
namespace coreneuron {
3336
#if PG_ACC_BUGS
@@ -66,7 +69,7 @@ struct NetReceiveBuffer_t {
6669
int _pnt_offset;
6770
};
6871

69-
struct NetSendBuffer_t {
72+
struct NetSendBuffer_t : MemoryManaged {
7073
int* _sendtype; // net_send, net_event, net_move
7174
int* _vdata_index;
7275
int* _pnt_index;
@@ -76,6 +79,56 @@ struct NetSendBuffer_t {
7679
int _cnt;
7780
int _size; /* capacity */
7881
int reallocated; /* if buffer resized/reallocated, needs to be copy to cpu */
82+
83+
NetSendBuffer_t(int size) : _size(size) {
84+
_cnt = 0;
85+
86+
_sendtype = (int*)ecalloc_align(_size, sizeof(int));
87+
_vdata_index = (int*)ecalloc_align(_size, sizeof(int));
88+
_pnt_index = (int*)ecalloc_align(_size, sizeof(int));
89+
_weight_index = (int*)ecalloc_align(_size, sizeof(int));
90+
// when == 1, NetReceiveBuffer_t is newly allocated (i.e. we need to free previous copy
91+
// and recopy new data
92+
reallocated = 1;
93+
_nsb_t = (double*)ecalloc_align(_size, sizeof(double));
94+
_nsb_flag = (double*)ecalloc_align(_size, sizeof(double));
95+
}
96+
97+
~NetSendBuffer_t() {
98+
free_memory(_sendtype);
99+
free_memory(_vdata_index);
100+
free_memory(_pnt_index);
101+
free_memory(_weight_index);
102+
free_memory(_nsb_t);
103+
free_memory(_nsb_flag);
104+
}
105+
106+
void grow() {
107+
#if defined(_OPENACC)
108+
int cannot_reallocate_on_device = 0;
109+
assert(cannot_reallocate_on_device);
110+
#else
111+
int new_size = _size * 2;
112+
grow_buf(&_sendtype, _size, new_size);
113+
grow_buf(&_vdata_index, _size, new_size);
114+
grow_buf(&_pnt_index, _size, new_size);
115+
grow_buf(&_weight_index, _size, new_size);
116+
grow_buf(&_nsb_t, _size, new_size);
117+
grow_buf(&_nsb_flag, _size, new_size);
118+
_size = new_size;
119+
#endif
120+
}
121+
122+
private:
123+
template <typename T>
124+
void grow_buf(T** buf, int size, int new_size) {
125+
T* new_buf = nullptr;
126+
new_buf = (T*)ecalloc_align(new_size, sizeof(T));
127+
memcpy(new_buf, *buf, size * sizeof(T));
128+
free(*buf);
129+
*buf = new_buf;
130+
}
131+
79132
};
80133

81134
struct Memb_list {

0 commit comments

Comments
 (0)