-
Notifications
You must be signed in to change notification settings - Fork 13
New HyPerLayer Buffer
The standard HyPerLayer class contains a membrane potential V, and an
activity buffer A. For many purposes this is enough, but you may
have occasion to write a derived class that uses additional buffers.
This page describes the preferred procedure for adding a buffer to a subclass.
The buffer must be declared as a pointer with a type other than void\*
.
Throughout, we assume that the buffer is a member variable called newBuffer
.
In the constructor, initialize newBuffer
to NULL. If you follow the
guidelines in the Subclassing HyPerLayer page,
set newBuffer
to NULL in the initialize_base()
method.
Override the allocateDataStructures()
method. It should call the parent
class's allocateDataStructures()
, and then call the appropriate buffer
allocation method.
-
allocateBuffer(&newBuffer, size, description)
is the most general method. Note that it is thesize
is an integer indicating the number of values in the buffer, anddescription
is a character array (C-style string) used to provide a descriptive error message if the allocation fails. -
allocateRestrictedBuffer(&newBuffer, description)
is a wrapper to be used when*newBuffer
is of typepvdata_t
(currentlyfloat
) and is a restricted buffer. It callsallocateBuffer
with a size ofnbatch*nx*ny*nf
. -
allocateExtendedBuffer(&newBuffer, description)
is a wrapper to be used when*newBuffer
is of typepvdata_t
and is an extended buffer. It callsallocateBuffer
with a size ofnbatch*(nx+halo->lt+halo->rt)*(ny+halo->dn+halo->up)*nf
.
To free the buffer, in the destructor call the appropriate buffer deallocation method.
-
freeBuffer(&newBuffer)
is the most general method. -
freeRestrictedBuffer(&newBuffer)
andfreeExtendedBuffer(&newBuffer)
are provided to balanceallocateRestrictedBuffer()
andallocateExtendedBuffer()
. Note, however, that these functions are merely wrappers aroundfreeBuffer()
. There are no checks on whether the provided argument was originally created withallocateBuffer()
or a related method.
Example:
Code fragments for DerivedClass.hpp
:
class DerivedClass : public ParentClass {
...
public
virtual DerivedClass::~DerivedClass();
pvdata_t const * getNewBuffer() const { return newBuffer; }
protected:
virtual int allocateDataStructures();
pvdata_t * newBuffer;
private:
int initialize_base();
...
};
Code fragments for DerivedClass.cpp
:
// In DerivedClass.cpp:
int DerivedClass::initialize_base() {
newBuffer = NULL;
}
int DerivedClass::allocateDataStructures() {
int status = ParentClass::allocateDataStructures();
if (status==PV_SUCCESS) {
status = allocateBuffer(&newBuffer, 1024, "the new buffer");
}
return status;
}
DerivedClass::~DerivedClass() {
freeBuffer(&newBuffer);
}
If the contents of the buffer are necessary for recreating the layer's state, you will need to checkpoint the buffer. Assuming that newBuffer is the size of either a restricted or an extended layer buffer, do the following.
To have the buffer appear in checkpoints, override checkpointWrite()
,
calling the parent class's checkpointWrite()
method and then call
writeBufferFile() with the address of the buffer.
To have the buffer get read when initializing or restarting from a checkpoint,
override readStateFromCheckpoint()
, calling the parent class's
checkpointWrite()
method and then call readBufferFile()
with the address
of the buffer.
Example:
Code fragments for DerivedClass.hpp
:
class DerivedClass : public ParentClass {
...
public
int checkpointWrite(char const * cpDir);
int readStateFromCheckpoint(char const * cpDir, double * timeptr);
...
};
Code fragments for DerivedClass.cpp
:
// In DerivedClass.cpp:
int DerivedClass::checkpointWrite(char const * cpDir) {
int status = ParentClass::checkpointWrite(cpDir);
if (status==PV_SUCCESS) {
char * filename = parent->pathInCheckpoint(cpDir, getName(), "_newBuffer.pvp");
double timed = (double) parent->simulationTime();
bool isExtended = /*whether the buffer is extended or not*/;
status = writeBufferFile(
filename, parent->icCommunicator(), timed, &newBuffer,
1/*number of bands; generally one*/,
isExtended, getLayerLoc());
free(filename);
}
return status;
}
int DerivedClass::readStateFromCheckpoint(char const * cpDir, double * timeptr) {
int status = ParentClass::readStateFromCheckpoint(cpDir, timeptr);
if (status==PV_SUCCESS) {
char * filename = parent->pathInCheckpoint(cpDir, getName(), "_newBuffer.pvp");
status = readBufferFile(
filename, parent->icCommunicator(), timeptr, &newBuffer,
1,
/*extended*/false, getLayerLoc());
free(filename);
}
return status;
}
This section is under construction.