Skip to content

Commit 5d7ee8c

Browse files
committed
Merge branch 'SharedDevelopment' into AndrewDevelopment
2 parents 7aa77eb + 945ccda commit 5d7ee8c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+437
-428
lines changed

Contributors.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ Andrew Madison
8585

8686
Padmanabh Patil
8787

88+
Lawrence Scott
89+
8890
<!-- ---------------------------------------------------------------------------------- -->
8991
# Graduate
9092

Simulator/Core/Core.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ int Core::runSimulation(string executableName, string cmdLineArguments)
206206
}
207207

208208
// Helper function for recorder to register spike history variables for all neurons.
209-
simulator.getModel().getLayout().getVertices().registerHistoryVariables();
209+
OperationManager::getInstance().executeOperation(Operations::registerHistoryVariables);
210210

211211
// Run simulation
212212
LOG4CPLUS_TRACE(consoleLogger, "Starting Simulation");
@@ -247,4 +247,4 @@ int Core::runSimulation(string executableName, string cmdLineArguments)
247247
cout << "time elapsed: " << timeElapsed << endl;
248248
cout << "ssps (simulation seconds / real time seconds): " << ssps << endl;
249249
return 0;
250-
}
250+
}

Simulator/Core/GPUModel.cpp

Lines changed: 69 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "AllVertices.h"
1313
#include "Connections.h"
1414
#include "Global.h"
15+
#include "OperationManager.h"
16+
1517
#ifdef VALIDATION_MODE
1618
#include "AllIFNeurons.h"
1719
#include "OperationManager.h"
@@ -27,31 +29,34 @@ GPUModel::GPUModel() :
2729
Model::Model(), edgeIndexMapDevice_(nullptr), randNoise_d(nullptr), allVerticesDevice_(nullptr),
2830
allEdgesDevice_(nullptr)
2931
{
32+
// Register allocNeuronDeviceStruct function as a allocateGPU operation in the OperationManager
33+
function<void()> allocateGPU = bind(&GPUModel::allocDeviceStruct, this);
34+
OperationManager::getInstance().registerOperation(Operations::allocateGPU, allocateGPU);
35+
36+
// Register copyCPUtoGPU function as a copyCPUtoGPU operation in the OperationManager
37+
function<void()> copyCPUtoGPU = bind(&GPUModel::copyCPUtoGPU, this);
38+
OperationManager::getInstance().registerOperation(Operations::copyToGPU, copyCPUtoGPU);
39+
40+
// Note: We do not register a corresponding copyFromGPU operation here because
41+
// we are only copying the synapseIndexMap to the GPU. This map is a read-only lookup table
42+
// that gets recreated from scratch on each update. As a result, we only need to allocate,
43+
// copy to GPU, and deallocate — there is no meaningful data to copy back from the GPU.
44+
45+
// Register deleteSynapseImap function as a deallocateGPUMemory operation in the OperationManager
46+
function<void()> deallocateGPUMemory = bind(&GPUModel::deleteDeviceStruct, this);
47+
OperationManager::getInstance().registerOperation(Operations::deallocateGPUMemory,
48+
deallocateGPUMemory);
3049
}
3150

3251
/// Allocates and initializes memories on CUDA device.
33-
/// @param[out] allVerticesDevice Memory location of the pointer to the vertices list on device memory.
34-
/// @param[out] allEdgesDevice Memory location of the pointer to the edges list on device memory.
35-
void GPUModel::allocDeviceStruct(void **allVerticesDevice, void **allEdgesDevice)
52+
void GPUModel::allocDeviceStruct()
3653
{
37-
// Get vertices and edges
38-
AllVertices &vertices = layout_->getVertices();
39-
AllEdges &edges = connections_->getEdges();
40-
41-
// Allocate vertices and edges structs on GPU device memory
42-
vertices.allocVerticesDeviceStruct(allVerticesDevice);
43-
edges.allocEdgeDeviceStruct(allEdgesDevice);
44-
4554
// Allocate memory for random noise array
4655
int numVertices = Simulator::getInstance().getTotalVertices();
4756
// BGSIZE randNoise_d_size = numVertices * sizeof(float); // size of random noise array
4857
// HANDLE_ERROR(cudaMalloc((void **)&randNoise_d, randNoise_d_size));
4958

50-
// Copy host vertex and edge arrays into GPU device
51-
vertices.copyToDevice(*allVerticesDevice);
52-
edges.copyEdgeHostToDevice(*allEdgesDevice);
53-
54-
// Allocate edge inverse map in device memory
59+
// Allocate synapse inverse map in device memory
5560
allocEdgeIndexMap(numVertices);
5661

5762
// Create the CUDA stream used to launch synchronous GPU kernels during the simulation.
@@ -62,16 +67,8 @@ void GPUModel::allocDeviceStruct(void **allVerticesDevice, void **allEdgesDevice
6267
}
6368

6469
/// Copies device memories to host memories and deallocates them.
65-
/// @param[out] allVerticesDevice Memory location of the pointer to the vertices list on device memory.
66-
/// @param[out] allEdgesDevice Memory location of the pointer to the edges list on device memory.
67-
void GPUModel::deleteDeviceStruct(void **allVerticesDevice, void **allEdgesDevice)
70+
void GPUModel::deleteDeviceStruct()
6871
{
69-
// Get vertices and edges
70-
AllVertices &vertices = layout_->getVertices();
71-
AllEdges &edges = connections_->getEdges();
72-
73-
// Copy device edge and vertex structs to host memory
74-
vertices.copyFromDevice(*allVerticesDevice);
7572
// Deallocate device memory
7673
vertices.deleteVerticesDeviceStruct(*allVerticesDevice);
7774
// Copy device edge and vertex structs to host memory
@@ -115,13 +112,9 @@ void GPUModel::setupSim()
115112
t_gpu_advanceSynapses = 0.0;
116113
t_gpu_calcSummation = 0.0;
117114
#endif // PERFORMANCE_METRICS
118-
119-
// allocates memories on CUDA device
120-
allocDeviceStruct((void **)&allVerticesDevice_, (void **)&allEdgesDevice_);
121-
122-
EdgeIndexMap &edgeIndexMap = connections_->getEdgeIndexMap();
123-
// copy inverse map to the device memory
124-
copyEdgeIndexMapHostToDevice(edgeIndexMap, Simulator::getInstance().getTotalVertices());
115+
// Allocate and copy neuron/synapse data structures to GPU memory
116+
OperationManager::getInstance().executeOperation(Operations::allocateGPU);
117+
OperationManager::getInstance().executeOperation(Operations::copyToGPU);
125118

126119
AllEdges &edges = connections_->getEdges();
127120
// set some parameters used for advanceVerticesDevice
@@ -137,11 +130,14 @@ void GPUModel::setupSim()
137130
/// Performs any finalization tasks on network following a simulation.
138131
void GPUModel::finish()
139132
{
133+
// copy device synapse and neuron structs to host memory
134+
OperationManager::getInstance().executeOperation(Operations::copyFromGPU);
140135
// deallocates memories on CUDA device
136+
// TODO: Resolve whether the deletion operations below that don't seem bundled
137+
// with the OperationManager are necessary, should be moved, or if they can be removed.
141138
AsyncGenerator_.deleteDeviceStruct();
142-
deleteDeviceStruct((void **)&allVerticesDevice_, (void **)&allEdgesDevice_);
139+
OperationManager::getInstance().executeOperation(Operations::deallocateGPUMemory);
143140
deleteEdgeIndexMap();
144-
145141
#ifdef PERFORMANCE_METRICS
146142
cudaEventDestroy(start);
147143
cudaEventDestroy(stop);
@@ -250,7 +246,7 @@ void GPUModel::updateConnections()
250246
AllVertices &vertices = layout_->getVertices();
251247
AllEdges &edges = connections_->getEdges();
252248

253-
vertices.copyFromDevice(allVerticesDevice_);
249+
vertices.copyFromDevice();
254250

255251
// Update Connections data
256252
if (connections_->updateConnections(vertices)) {
@@ -260,8 +256,7 @@ void GPUModel::updateConnections()
260256
// create edge index map
261257
connections_->createEdgeIndexMap();
262258
// copy index map to the device memory
263-
copyEdgeIndexMapHostToDevice(connections_->getEdgeIndexMap(),
264-
Simulator::getInstance().getTotalVertices());
259+
copyCPUtoGPU();
265260
}
266261
}
267262

@@ -298,81 +293,53 @@ void GPUModel::allocEdgeIndexMap(int count)
298293
cudaMemcpyHostToDevice));
299294
}
300295

301-
/// Deallocate device memory for edge inverse map.
302-
void GPUModel::deleteEdgeIndexMap()
303-
{
304-
EdgeIndexMapDevice edgeIndexMapDevice;
305-
HANDLE_ERROR(cudaMemcpy(&edgeIndexMapDevice, edgeIndexMapDevice_, sizeof(EdgeIndexMapDevice),
306-
cudaMemcpyDeviceToHost));
307-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.outgoingEdgeBegin_));
308-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.outgoingEdgeCount_));
309-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.outgoingEdgeIndexMap_));
310-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.incomingEdgeBegin_));
311-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.incomingEdgeCount_));
312-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.incomingEdgeIndexMap_));
313-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice_));
314-
}
315-
316-
/// Copy EdgeIndexMap in host memory to EdgeIndexMap in device memory.
317-
/// @param edgeIndexMapHost Reference to the EdgeIndexMap in host memory.
318-
void GPUModel::copyEdgeIndexMapHostToDevice(EdgeIndexMap &edgeIndexMapHost, int numVertices)
296+
/// Allocate and Copy CPU Synapse data to GPU.
297+
void GPUModel::copyCPUtoGPU()
319298
{
320-
AllEdges &edges = connections_->getEdges();
321-
int totalEdgeCount = edges.totalEdgeCount_;
322-
if (totalEdgeCount == 0)
299+
EdgeIndexMap synapseIndexMapHost = connections_->getEdgeIndexMap();
300+
int numVertices = Simulator::getInstance().getTotalVertices();
301+
AllEdges &synapses = connections_->getEdges();
302+
int totalSynapseCount = dynamic_cast<AllEdges &>(synapses).totalEdgeCount_;
303+
if (totalSynapseCount == 0)
323304
return;
324-
EdgeIndexMapDevice edgeIndexMapDevice;
325-
HANDLE_ERROR(cudaMemcpy(&edgeIndexMapDevice, edgeIndexMapDevice_, sizeof(EdgeIndexMapDevice),
305+
EdgeIndexMapDevice synapseIMapDevice;
306+
HANDLE_ERROR(cudaMemcpy(&synapseIMapDevice, edgeIndexMapDevice_, sizeof(EdgeIndexMapDevice),
326307
cudaMemcpyDeviceToHost));
327-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.outgoingEdgeBegin_,
328-
edgeIndexMapHost.outgoingEdgeBegin_.data(), numVertices * sizeof(BGSIZE),
329-
cudaMemcpyHostToDevice));
330-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.outgoingEdgeCount_,
331-
edgeIndexMapHost.outgoingEdgeCount_.data(), numVertices * sizeof(BGSIZE),
332-
cudaMemcpyHostToDevice));
333-
if (edgeIndexMapDevice.outgoingEdgeIndexMap_ != nullptr) {
334-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.outgoingEdgeIndexMap_));
308+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.outgoingEdgeBegin_,
309+
synapseIndexMapHost.outgoingEdgeBegin_.data(),
310+
numVertices * sizeof(BGSIZE), cudaMemcpyHostToDevice));
311+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.outgoingEdgeCount_,
312+
synapseIndexMapHost.outgoingEdgeCount_.data(),
313+
numVertices * sizeof(BGSIZE), cudaMemcpyHostToDevice));
314+
if (synapseIMapDevice.outgoingEdgeIndexMap_ != nullptr) {
315+
HANDLE_ERROR(cudaFree(synapseIMapDevice.outgoingEdgeIndexMap_));
335316
}
336-
HANDLE_ERROR(cudaMalloc((void **)&edgeIndexMapDevice.outgoingEdgeIndexMap_,
337-
totalEdgeCount * sizeof(BGSIZE)));
338-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.outgoingEdgeIndexMap_,
339-
edgeIndexMapHost.outgoingEdgeIndexMap_.data(),
340-
totalEdgeCount * sizeof(BGSIZE), cudaMemcpyHostToDevice));
317+
HANDLE_ERROR(cudaMalloc((void **)&synapseIMapDevice.outgoingEdgeIndexMap_,
318+
totalSynapseCount * sizeof(BGSIZE)));
319+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.outgoingEdgeIndexMap_,
320+
synapseIndexMapHost.outgoingEdgeIndexMap_.data(),
321+
totalSynapseCount * sizeof(BGSIZE), cudaMemcpyHostToDevice));
341322
// active synapse map
342-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.incomingEdgeBegin_,
343-
edgeIndexMapHost.incomingEdgeBegin_.data(), numVertices * sizeof(BGSIZE),
344-
cudaMemcpyHostToDevice));
345-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.incomingEdgeCount_,
346-
edgeIndexMapHost.incomingEdgeCount_.data(), numVertices * sizeof(BGSIZE),
347-
cudaMemcpyHostToDevice));
323+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.incomingEdgeBegin_,
324+
synapseIndexMapHost.incomingEdgeBegin_.data(),
325+
numVertices * sizeof(BGSIZE), cudaMemcpyHostToDevice));
326+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.incomingEdgeCount_,
327+
synapseIndexMapHost.incomingEdgeCount_.data(),
328+
numVertices * sizeof(BGSIZE), cudaMemcpyHostToDevice));
348329
// the number of synapses may change, so we reallocate the memory
349-
if (edgeIndexMapDevice.incomingEdgeIndexMap_ != nullptr) {
350-
HANDLE_ERROR(cudaFree(edgeIndexMapDevice.incomingEdgeIndexMap_));
351-
edgeIndexMapDevice.incomingEdgeIndexMap_ = nullptr;
330+
if (synapseIMapDevice.incomingEdgeIndexMap_ != nullptr) {
331+
HANDLE_ERROR(cudaFree(synapseIMapDevice.incomingEdgeIndexMap_));
332+
synapseIMapDevice.incomingEdgeIndexMap_ = nullptr;
352333
}
353-
HANDLE_ERROR(cudaMalloc((void **)&edgeIndexMapDevice.incomingEdgeIndexMap_,
354-
totalEdgeCount * sizeof(BGSIZE)));
355-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice.incomingEdgeIndexMap_,
356-
edgeIndexMapHost.incomingEdgeIndexMap_.data(),
357-
totalEdgeCount * sizeof(BGSIZE), cudaMemcpyHostToDevice));
358-
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice_, &edgeIndexMapDevice, sizeof(EdgeIndexMapDevice),
334+
HANDLE_ERROR(cudaMalloc((void **)&synapseIMapDevice.incomingEdgeIndexMap_,
335+
totalSynapseCount * sizeof(BGSIZE)));
336+
HANDLE_ERROR(cudaMemcpy(synapseIMapDevice.incomingEdgeIndexMap_,
337+
synapseIndexMapHost.incomingEdgeIndexMap_.data(),
338+
totalSynapseCount * sizeof(BGSIZE), cudaMemcpyHostToDevice));
339+
HANDLE_ERROR(cudaMemcpy(edgeIndexMapDevice_, &synapseIMapDevice, sizeof(EdgeIndexMapDevice),
359340
cudaMemcpyHostToDevice));
360341
}
361342

362-
/// Copy GPU edge data to CPU.
363-
void GPUModel::copyGPUtoCPU()
364-
{
365-
// copy device edge structs to host memory
366-
connections_->getEdges().copyEdgeDeviceToHost(allEdgesDevice_);
367-
}
368-
369-
/// Copy CPU edge data to GPU.
370-
void GPUModel::copyCPUtoGPU()
371-
{
372-
// copy host edge structs to device memory
373-
connections_->getEdges().copyEdgeHostToDevice(allEdgesDevice_);
374-
}
375-
376343
/// Print out EdgeProps on the GPU.
377344
void GPUModel::printGPUEdgesPropsModel() const
378345
{

Simulator/Core/GPUModel.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
#pragma once
2323

2424
#include "AllEdges.h"
25+
#include "AllSpikingNeurons.h"
26+
#include "AllSpikingSynapses.h"
2527
#include "AllVertices.h"
2628
#include "AsyncPhilox_d.h"
2729
#ifdef USE_GPU
2830
#include <cuda_runtime.h>
2931
#endif
32+
#include "OperationManager.h"
3033

3134
#ifdef VALIDATION_MODE
3235
#include <fstream>
@@ -85,25 +88,33 @@ class GPUModel : public Model {
8588
/// over the past epoch. Should be called once every epoch.
8689
virtual void updateConnections() override;
8790

88-
/// Copy GPU edge data to CPU.
89-
virtual void copyGPUtoCPU() override;
90-
91-
/// Copy CPU edge data to GPU.
91+
/// Copies neuron and synapse data from CPU to GPU memory.
92+
/// TODO: Refactor this. Currently, GPUModel handles low-level memory transfer for vertices and edges.
93+
/// Consider moving this responsibility to a more appropriate class, such as a dedicated memory manager
94+
/// or the OperationManager, to better separate concerns and keep the model focused on high-level coordination.
9295
virtual void copyCPUtoGPU() override;
9396

97+
// GPUModel itself does not have anything to be copied back, this function is a
98+
// dummy function just to make GPUModel non virtual
99+
virtual void copyGPUtoCPU() override
100+
{
101+
}
102+
94103
/// Print out EdgeProps on the GPU.
95104
void printGPUEdgesPropsModel() const;
96105

106+
/// Getter for edge (synapse) structures in device memory
107+
AllEdgesDeviceProperties *&getAllEdgesDevice();
108+
109+
/// Getter for vertex (neuron) structures in device memory
110+
AllVerticesDeviceProperties *&getAllVerticesDevice();
111+
97112
protected:
98113
/// Allocates and initializes memories on CUDA device.
99-
/// @param[out] allVerticesDevice Memory location of the pointer to the vertices list on device memory.
100-
/// @param[out] allEdgesDevice Memory location of the pointer to the edges list on device memory.
101-
void allocDeviceStruct(void **allVerticesDevice, void **allEdgesDevice);
114+
void allocDeviceStruct();
102115

103-
/// Copies device memories to host memories and deallocates them.
104-
/// @param[out] allVerticesDevice Memory location of the pointer to the vertices list on device memory.
105-
/// @param[out] allEdgesDevice Memory location of the pointer to the edges list on device memory.
106-
virtual void deleteDeviceStruct(void **allVerticesDevice, void **allEdgesDevice);
116+
/// Deallocates device memories.
117+
virtual void deleteDeviceStruct();
107118

108119
/// Pointer to device random noise array.
109120
float *randNoise_d;
@@ -131,11 +142,6 @@ class GPUModel : public Model {
131142
private:
132143
void allocEdgeIndexMap(int count);
133144

134-
void deleteEdgeIndexMap();
135-
136-
public: //2020/03/14 changed to public for accessing in Core
137-
void copyEdgeIndexMapHostToDevice(EdgeIndexMap &edgeIndexMapHost, int numVertices);
138-
139145
private:
140146
void updateHistory();
141147

Simulator/Core/OperationManager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ string OperationManager::operationToString(const Operations &operation) const
7171
return "copyToGPU";
7272
case Operations::copyFromGPU:
7373
return "copyFromGPU";
74+
case Operations::allocateGPU:
75+
return "allocateGPU";
7476
default:
7577
return "Operation isn't in OperationManager::operationToString()";
7678
}
77-
}
79+
}

Simulator/Core/Operations.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ enum class Operations {
2020
deallocateGPUMemory, // Make sure deallocate memory isn't called until all GPU memory is copied back.
2121
restoreToDefault, // Not sure what this refers to.
2222
copyToGPU,
23-
copyFromGPU
23+
copyFromGPU,
24+
allocateGPU,
25+
registerHistoryVariables
2426
};

Simulator/Core/Serializer.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ bool Serializer::deserialize()
6969

7070
#if defined(USE_GPU)
7171
GPUModel &gpuModel = static_cast<GPUModel &>(simulator.getModel());
72-
gpuModel.copyEdgeIndexMapHostToDevice(simulator.getModel().getConnections().getEdgeIndexMap(),
73-
simulator.getTotalVertices());
72+
gpuModel.copyCPUtoGPU();
7473
#endif // USE_GPU
7574

7675
return true;
@@ -110,4 +109,4 @@ template <typename Archive> bool Serializer::processArchive(Archive &archive, Si
110109
return false;
111110
}
112111
return true;
113-
}
112+
}

0 commit comments

Comments
 (0)