Skip to content

Commit bb06edd

Browse files
Merge pull request #813 from UWB-Biocomputing/AndrewDevelopment
[ISSUE-783][ISSUE-773][ISSUE-319] Validation Mode and Cleanup
2 parents 55255df + be054b0 commit bb06edd

18 files changed

+397
-58
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,6 @@ Testing/RegressionTesting/TestOutput/*.xml
9797
Testing/RegressionTesting/TestOutput/*.h5
9898
Testing/UnitTesting/TestOutput/*.xml
9999
Testing/UnitTesting/TestOutput/*.h5
100+
101+
# Machine Specific build script
102+
build.sh

CMakeLists.txt

Lines changed: 144 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.12)
88
#
99
#You can also pass this flag when running cmake from the command line like this:
1010
#
11-
#cmake..- D ENABLE_CUDA = YES
11+
#cmake -D ENABLE_CUDA=YES ..
1212
#
1313
#"YES" / GPU choice only available if CUDA library is installed and the GPU is CUDA capable.
1414
############################################################################################
@@ -21,17 +21,24 @@ if(NOT PERFORMANCE_METRICS)
2121
set(PERFORMANCE_METRICS NO)
2222
endif()
2323

24-
#CONDITIONAL FLAG to turn on the Gprof profiler( \
25-
# Gprof is a performance analysis tool for Unix applications)
26-
#Steps to run Gprof
27-
#Step 01 : set(GPROF YES) below
28-
#Step 02 : Compile and run the simulation on CPU or GPU as usual
29-
#Step 03 : Run the generated gmon.out file from the build directory and save the output in an txt \
30-
# file to improve readability \
31-
#If using CPU - "~/Graphitti/build$ gprof cgraphitti gmon.out > analysis_test.txt"
32-
#If using GPU - "~/Graphitti/build$ gprof ggraphitti gmon.out > analysis_test.txt"
33-
if(NOT GPROF)
34-
set(GPROF NO)
24+
############################################################################################
25+
#CONDITIONAL FLAG to change target architecture for the GPU simulator from the default
26+
#
27+
#You can pass this flag when running cmake from the command line like this, setting TARGET_ARCH \
28+
# to your desired architecture: \
29+
#
30+
#cmake -D ENABLE_CUDA=YES -D TARGET_ARCH=70 ..
31+
#
32+
#"YES" / GPU choice only available if CUDA library is installed and the GPU is CUDA capable.
33+
#If no TARGET_ARCH is passed in then it will default to 37 which is the kepler architecture
34+
############################################################################################
35+
if(NOT DEFINED TARGET_ARCH)
36+
set(TARGET_ARCH 37)
37+
endif()
38+
39+
#CONDITIONAL FLAG to turn on the validation mode
40+
if(NOT VALIDATION_MODE)
41+
set(VALIDATION_MODE NO)
3542
endif()
3643

3744
#Creates the Graphitti project with the correct languages, depending on if using GPU or not
@@ -45,31 +52,112 @@ if(ENABLE_CUDA)
4552
add_compile_definitions(USE_GPU)
4653
#Specify the CUDA architecture / gencode that will be targeted
4754
### Set gencode and architecture variables to the correct values for your specific NVIDIA hardware
48-
set(CMAKE_CUDA_ARCHITECTURES 37)
49-
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode=arch=compute_37,code=sm_37)
55+
set(CMAKE_CUDA_ARCHITECTURES ${TARGET_ARCH})
56+
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode=arch=compute_${TARGET_ARCH},code=sm_${TARGET_ARCH})
57+
message(STATUS "Using CUDA architecture: ${TARGET_ARCH}")
5058

5159
else()
5260
message("\n----Generating Makefile for Graphitti CPU version----")
5361
project(Graphitti LANGUAGES CXX C)
5462
endif()
5563

64+
# -----------------------------------------------------------------------------
65+
# Build Type Configuration
66+
#
67+
# CMake support for different build types controling optimization, debugging and profiling:
68+
#
69+
# - Debug : No optimizations (`-O0`), includes debug symbols (`-g`).
70+
# - Release : Optimized build (`-O3`), removes debug symbols.
71+
# - RelWithDebInfo: Optimized (`-O2`) but keeps debug symbols (`-g`) for profiling.
72+
# - Profiling : Custom build type (defined in this project) that enables:
73+
# - CPU profiling via `-pg` (GPROF)
74+
# - CUDA profiling via `-lineinfo` (for Nsight Compute)
75+
#
76+
# Selecting a Build Type:
77+
# - By default, CMake does NOT set a build type for single-config generators.
78+
# - If no build type is specified, this script defaults to "Release" for performance.
79+
# - You can explicitly set the build type when configuring CMake:
80+
#
81+
# cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug # Debug mode
82+
# cmake -S . -B build -DCMAKE_BUILD_TYPE=Release # Release mode
83+
# cmake -S . -B build -DCMAKE_BUILD_TYPE=Profiling # Profiling mode
84+
#
85+
# If you don't want to pass in the build type flag, you can edit this file and add...
86+
# set(CMAKE_BUILD_TYPE "Debug") or whichever build type you want
87+
# -----------------------------------------------------------------------------
88+
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;Profiling" CACHE STRING "Supported build types" FORCE)
89+
90+
# Ensure single-config generators use a valid default
91+
if(NOT CMAKE_BUILD_TYPE)
92+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type." FORCE)
93+
endif()
94+
95+
# Set flags for all build types
96+
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
97+
# We should consider using the -DNDEBUG flag for release code, it disables assert() calls and is higher performance
98+
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
99+
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
100+
101+
# Define a custom build type: "Profiling"
102+
set(CMAKE_CXX_FLAGS_PROFILING "-pg -O2")
103+
set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-pg")
104+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")
105+
106+
# Apply the correct flags based on the selected build type
107+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
108+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}")
109+
if(ENABLE_CUDA)
110+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -g -G")
111+
endif()
112+
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
113+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE}")
114+
if(ENABLE_CUDA)
115+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -O3")
116+
endif()
117+
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
118+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
119+
elseif(CMAKE_BUILD_TYPE STREQUAL "Profiling")
120+
message(STATUS "Profiling build enabled: Adding -pg (GPROF)")
121+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_PROFILING}")
122+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_PROFILING}")
123+
if(ENABLE_CUDA)
124+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo")
125+
# set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo -Xptxas=-v")
126+
endif()
127+
endif()
128+
129+
130+
# Gprof is a performance analysis tool for Unix applications)
131+
#Steps to run Gprof
132+
#Step 01 : set build configuration to Profiling ... -DCMAKE_BUILD_TYPE=Profiling
133+
#Step 02 : Compile and run the simulation on CPU or GPU as usual
134+
#Step 03 : Run the generated gmon.out file from the build directory and save the output in an txt \
135+
# file to improve readability \
136+
#If using CPU - "~/Graphitti/build$ gprof cgraphitti gmon.out > analysis_test.txt"
137+
#If using GPU - "~/Graphitti/build$ gprof ggraphitti gmon.out > analysis_test.txt"
138+
139+
140+
# Print build type for verification
141+
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
142+
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
143+
144+
message(STATUS "ENABLE_CUDA: ${ENABLE_CUDA}")
145+
if(ENABLE_CUDA)
146+
message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")
147+
endif()
148+
149+
56150
#Setting the base version to C++ 17
57151
set(CMAKE_CXX_STANDARD 17)
58152

59-
#set(DEBUG_MODE YES) for debugging, no optimization
60-
#set(DEBUG_MODE NO) for production code, -O3 optimization enabled
61-
set(DEBUG_MODE NO)
62-
63153
if(PERFORMANCE_METRICS)
64154
message("-- Setting PEREFORMANCE_METRICS: ON")
65155
add_definitions(-DPERFORMANCE_METRICS)
66156
endif()
67157

68-
if(GPROF)
69-
message("-- Setting GPROF: ON")
70-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
71-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
72-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")
158+
if(VALIDATION_MODE)
159+
message("-- Setting VALIDATION_MODE: ON")
160+
add_definitions(-DVALIDATION_MODE)
73161
endif()
74162

75163
#HDF5 Support, finds HDF5 package for C and C++ and links the hdf5 libraries to the executable \
@@ -116,11 +204,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
116204
#Set extra warning flags
117205
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
118206

119-
if (NOT DEBUG_MODE)
120-
message("-- Setting Optimization flag: O3")
121-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
122-
endif()
123-
124207
#define TIXML_USE_STL as a preproccersser macro to use the C++ standard library with TinyXML
125208
add_compile_definitions(TIXML_USE_STL)
126209
message("-- Setting Compile Definition: TIMXL_USE_STL")
@@ -282,9 +365,33 @@ add_library(RNG STATIC ${RNG_Source})
282365

283366

284367
# Create Utils library
285-
file(GLOB Utils_Source Simulator/Utils/*.cpp Simulator/Utils/*.h)
368+
file(GLOB Utils_Source Simulator/Utils/*.cpp Simulator/Utils/*.h)
286369
list(REMOVE_ITEM Utils_Source "${CMAKE_CURRENT_SOURCE_DIR}/Simulator/Utils/Factory.cpp")
287-
add_library(Utils ${Utils_Source})
370+
371+
if(CMAKE_BUILD_TYPE STREQUAL "Profiling")
372+
if(ENABLE_CUDA)
373+
# Find NVTX Library
374+
find_library(NVTX_LIBRARY nvToolsExt)
375+
if(NVTX_LIBRARY)
376+
message(STATUS "Found NVTX: ${NVTX_LIBRARY} included in Profiling")
377+
add_compile_definitions(ENABLE_NVTX)
378+
else()
379+
message(STATUS "NVTX library not found! Not included in Profiling.")
380+
list(REMOVE_ITEM Utils_Source "${CMAKE_CURRENT_SOURCE_DIR}/Simulator/Utils/NvtxHelper.cpp")
381+
endif()
382+
endif()
383+
384+
else()
385+
list(REMOVE_ITEM Utils_Source "${CMAKE_CURRENT_SOURCE_DIR}/Simulator/Utils/NvtxHelper.cpp")
386+
endif()
387+
388+
# Always create the Utils library (even if NVTX and CUDA are missing)
389+
add_library(Utils ${Utils_Source})
390+
391+
# Only link NVTX if it was found
392+
if(NVTX_LIBRARY)
393+
target_link_libraries(Utils PRIVATE ${NVTX_LIBRARY})
394+
endif()
288395

289396

290397
# Used to locate and run other CMakeLists.txt files from Third Party resources for further compilation of the project.
@@ -352,6 +459,9 @@ endif()
352459
# ------ TESTS EXECUTABLE ------
353460
# Add the file that contains main (RunTests.cpp) and all test files. GoogleTest will only recognize them if they are
354461
# included in the executable.
462+
target_compile_options(gtest PRIVATE -Wno-error=maybe-uninitialized)
463+
target_compile_options(gtest_main PRIVATE -Wno-error=maybe-uninitialized)
464+
355465
add_executable(tests
356466
Testing/RunTests.cpp
357467
Testing/UnitTesting/OperationManagerTests.cpp
@@ -426,3 +536,7 @@ target_link_libraries(serialSecondHalfTest combinedLib)
426536
unset(ENABLE_CUDA CACHE)
427537
unset(PERFORMANCE_METRICS CACHE)
428538
unset(GPROF CACHE)
539+
unset(CMAKE_BUILD_TYPE CACHE)
540+
unset(NVTX_LIBRARY CACHE)
541+
unset(TARGET_ARCH CACHE)
542+
unset(VALIDATION_MODE CACHE)

Simulator/Core/GPUModel.cpp

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
#include "AllVertices.h"
1313
#include "Connections.h"
1414
#include "Global.h"
15-
15+
#ifdef VALIDATION_MODE
16+
#include "AllIFNeurons.h"
17+
#include "OperationManager.h"
18+
#endif
1619
#ifdef PERFORMANCE_METRICS
1720
float g_time;
1821
cudaEvent_t start, stop;
@@ -144,8 +147,21 @@ void GPUModel::advance()
144147
AllVertices &vertices = layout_->getVertices();
145148
AllEdges &edges = connections_->getEdges();
146149

150+
#ifdef VALIDATION_MODE
151+
int verts = Simulator::getInstance().getTotalVertices();
152+
std::vector<float> randNoise_h(verts);
153+
for (int i = verts - 1; i >= 0; i--) {
154+
randNoise_h[i] = (*noiseRNG)();
155+
}
156+
//static int testNumbers = 0;
157+
// for (int i = 0; i < verts; i++) {
158+
// outFile << "index: " << i << " " << randNoise_h[i] << endl;
159+
// }
160+
cudaMemcpy(randNoise_d, randNoise_h.data(), verts * sizeof(float), cudaMemcpyHostToDevice);
161+
#else
147162
normalMTGPU(randNoise_d);
148-
163+
#endif
164+
//LOG4CPLUS_DEBUG(vertexLogger_, "Index: " << index << " Vm: " << Vm);
149165
#ifdef PERFORMANCE_METRICS
150166
cudaLapTime(t_gpu_rndGeneration);
151167
cudaStartTimer();
@@ -155,7 +171,41 @@ void GPUModel::advance()
155171
// Advance vertices ------------->
156172
vertices.advanceVertices(edges, allVerticesDevice_, allEdgesDevice_, randNoise_d,
157173
edgeIndexMapDevice_);
174+
#ifdef VALIDATION_MODE
175+
//(AllIFNeuronsDeviceProperties *)allVerticesDevice,
176+
log4cplus::Logger vertexLogger_ = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("vertex"));
177+
std::vector<float> sp_h(verts);
178+
std::vector<float> vm_h(verts);
179+
std::vector<float> Inoise_h(verts);
180+
AllIFNeuronsDeviceProperties validationNeurons;
181+
HANDLE_ERROR(cudaMemcpy((void *)&validationNeurons, allVerticesDevice_,
182+
sizeof(AllIFNeuronsDeviceProperties), cudaMemcpyDeviceToHost));
183+
HANDLE_ERROR(cudaMemcpy(sp_h.data(), validationNeurons.spValidation_, verts * sizeof(float),
184+
cudaMemcpyDeviceToHost));
185+
HANDLE_ERROR(cudaMemcpy(vm_h.data(), validationNeurons.Vm_, verts * sizeof(float),
186+
cudaMemcpyDeviceToHost));
187+
HANDLE_ERROR(cudaMemcpy(Inoise_h.data(), validationNeurons.Inoise_, verts * sizeof(float),
188+
cudaMemcpyDeviceToHost));
158189

190+
for (int i = verts - 1; i >= 0; i--) {
191+
LOG4CPLUS_DEBUG(vertexLogger_, endl
192+
<< "Advance Index[" << i << "] :: Noise = "
193+
<< randNoise_h[i] << "\tVm: " << vm_h[i] << endl
194+
<< "\tsp = " << sp_h[i] << endl
195+
<< "\tInoise = " << Inoise_h[i] << endl);
196+
}
197+
#endif
198+
//LOG4CPLUS_DEBUG(vertexLogger_, "ADVANCE NEURON LIF[" << index << "] :: Noise = " << noise);
199+
//LOG4CPLUS_DEBUG(vertexLogger_, "Index: " << index << " Vm: " << Vm);
200+
// LOG4CPLUS_DEBUG(vertexLogger_, "NEURON[" << index << "] {" << endl
201+
// << "\tVm = " << Vm << endl
202+
// << "\tVthresh = " << Vthresh << endl
203+
// << "\tsummationPoint = " << summationPoint << endl
204+
// << "\tI0 = " << I0 << endl
205+
// << "\tInoise = " << Inoise << endl
206+
// << "\tC1 = " << C1 << endl
207+
// << "\tC2 = " << C2 << endl
208+
// << "}" << endl);
159209
#ifdef PERFORMANCE_METRICS
160210
cudaLapTime(t_gpu_advanceNeurons);
161211
cudaStartTimer();

Simulator/Core/GPUModel.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
#include "AllEdges.h"
2525
#include "AllVertices.h"
2626

27+
#ifdef VALIDATION_MODE
28+
#include <fstream>
29+
#include <iostream>
30+
#endif // VALIDATION_MODE
31+
2732
#ifdef __CUDACC__
2833
#include "Book.h"
2934
#endif

Simulator/Core/Simulator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Simulator::Simulator()
3131

3232
consoleLogger_ = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("console"));
3333
fileLogger_ = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("file"));
34+
fileLogger_.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);
3435
edgeLogger_ = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("edge"));
3536
workbenchLogger_ = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("workbench"));
3637

Simulator/Utils/NvtxHelper.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @file NvtxHelper.cpp
3+
*
4+
* @ingroup Simulator/Utils
5+
*
6+
* @brief Helper functions to enable nvtx profiling
7+
* When ENABLE_NVTX is false the functions are replaced with blank inline functions which are removed by the compiler
8+
* This file is only included in the utils library when ENABLE_CUDA=YES
9+
*/
10+
11+
#include "NvtxHelper.h"
12+
#include <cuda_runtime.h>
13+
#include <nvToolsExt.h>
14+
15+
void nvtxPushColor(const std::string &name, Color pColor)
16+
{
17+
nvtxEventAttributes_t eventAttrib = {};
18+
eventAttrib.version = NVTX_VERSION;
19+
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
20+
eventAttrib.colorType = NVTX_COLOR_ARGB;
21+
eventAttrib.color = static_cast<uint32_t>(pColor);
22+
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
23+
eventAttrib.message.ascii = name.c_str();
24+
25+
nvtxRangePushEx(&eventAttrib);
26+
}
27+
28+
void nvtxPop()
29+
{
30+
nvtxRangePop();
31+
}

0 commit comments

Comments
 (0)