Skip to content

Commit fec264d

Browse files
committed
add a cuda test and make sure it actually works
1 parent 85686f8 commit fec264d

File tree

9 files changed

+146
-52
lines changed

9 files changed

+146
-52
lines changed

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ include(GNUInstallDirs)
1212
include(GetVersionFromGit)
1313

1414
# possibility to turn of features with special dependencies
15-
option(USE_CUDA "Compile with cuda features" OFF)
15+
option(USE_CUDA "Compile with cuda features" ON)
1616
option(USE_OPENGL "Compile with openGL features" ON)
1717

1818
# enable languages
@@ -115,6 +115,9 @@ target_link_libraries( mpUtils ${LIBRARIES})
115115

116116
# set properties
117117
set_target_properties(mpUtils PROPERTIES VERSION ${VERSION_SHORT} SOVERSION ${VERSION_MAJOR})
118+
if (USE_CUDA)
119+
set_target_properties( mpUtils PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
120+
endif ()
118121

119122
# set include dir (in this case also the src)
120123
target_include_directories(mpUtils PUBLIC src ${INCLUDE_PATHES})

exec/devTest/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
cmake_minimum_required(VERSION 3.3)
1+
cmake_minimum_required(VERSION 3.8)
22

33
# set src files
44
set(SOURCE_FILES
5-
main.cpp
6-
)
5+
main.cpp
6+
cudaTest.cu)
77

88
# create target
99
add_executable(devTest ${SOURCE_FILES})
10+
#set_target_properties( devTest PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
1011

1112
# link libraries
1213
target_link_libraries(devTest mpUtils)

exec/devTest/cudaTest.cu

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* mpUtils
3+
* cudaTest.cpp
4+
*
5+
* @author: Hendrik Schwanekamp
6+
7+
*
8+
* Copyright (c) 2018 Hendrik Schwanekamp
9+
*
10+
*/
11+
12+
#include "cudaTest.h"
13+
#include <Cuda/cudaUtils.h>
14+
15+
class Managed
16+
{
17+
public:
18+
void *operator new(size_t len) {
19+
void *ptr;
20+
assert_cuda(cudaMallocManaged(&ptr, len));
21+
assert_cuda(cudaDeviceSynchronize());
22+
return ptr;
23+
}
24+
25+
void operator delete(void *ptr) {
26+
assert_cuda(cudaDeviceSynchronize());
27+
assert_cuda(cudaFree(ptr));
28+
}
29+
};
30+
31+
class Array : public Managed
32+
{
33+
public:
34+
Array(size_t n) : length(n) {cudaMallocManaged(&data,n* sizeof(float));}
35+
~Array() {cudaFree(data);}
36+
37+
__host__ __device__
38+
float& operator[](int pos) {return data[pos];}
39+
40+
const size_t length;
41+
private:
42+
float* data;
43+
};
44+
45+
// CUDA kernel to add elements of two arrays
46+
__global__
47+
void add(size_t n, Array& x, Array& y)
48+
{
49+
int index = blockIdx.x * blockDim.x + threadIdx.x;
50+
int stride = blockDim.x * gridDim.x;
51+
52+
53+
for (int i = index; i < n; i += stride)
54+
{
55+
y[i] = x[i] + y[i];
56+
}
57+
}
58+
59+
void testCuda()
60+
{
61+
size_t N = 1<<20;
62+
auto x=std::make_unique<Array>(N);
63+
auto y=std::make_unique<Array>(N);
64+
65+
assert_cuda( cudaPeekAtLastError() );
66+
67+
// initialize x and y arrays on the host
68+
for (int i = 0; i < N; i++) {
69+
(*x)[i] = 1.0f;
70+
(*y)[i] = 2.0f;
71+
}
72+
73+
// Launch kernel on 1M elements on the GPU
74+
int blockSize = 256;
75+
int numBlocks = (N + blockSize - 1) / blockSize;
76+
add<<<numBlocks, blockSize>>>(N, *x, *y);
77+
78+
// Wait for GPU to finish before accessing on host
79+
cudaDeviceSynchronize();
80+
81+
// Check for errors (all values should be 3.0f)
82+
float maxError = 0.0f;
83+
for (int i = 0; i < N; i++)
84+
maxError = fmax(maxError, fabs((*y)[i]-3.0f));
85+
logINFO("TEST") << "Max error: " << maxError << std::endl;
86+
87+
return;
88+
}

exec/devTest/cudaTest.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* mpUtils
3+
* cudaTest.h
4+
*
5+
* @author: Hendrik Schwanekamp
6+
7+
*
8+
* Copyright (c) 2018 Hendrik Schwanekamp
9+
*
10+
*/
11+
#ifndef MPUTILS_CUDATEST_H
12+
#define MPUTILS_CUDATEST_H
13+
14+
// includes
15+
//--------------------
16+
//--------------------
17+
18+
void testCuda();
19+
20+
#endif //MPUTILS_CUDATEST_H

exec/devTest/main.cpp

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,14 @@
1212
*
1313
*/
1414

15-
#include <stringUtils.h>
16-
#include <Timer/Stopwatch.h>
17-
#include <iostream>
18-
#include <Log/Log.h>
19-
#include <Log/ConsoleSink.h>
20-
#include <Log/FileSink.h>
21-
#include <Log/SyslogSink.h>
15+
#include <mpUtils.h>
2216
#include <chrono>
23-
24-
#include <typeinfo>
25-
#include <ctime>
26-
#include "Timer/DeltaTimer.h"
27-
#include <thread>
28-
#include "Timer/Timer.h"
29-
#include "Timer/AsyncTimer.h"
30-
#include <thread> // std::thread
31-
#include <mutex> // std::mutex, std::unique_lock
32-
#include <condition_variable> // std::condition_variable
33-
#include <syslog.h>
34-
17+
#include "cudaTest.h"
3518

3619
using namespace mpu;
3720
using namespace std;
3821
using namespace std::chrono;
3922

40-
constexpr int numRuns = 10;
41-
double dTime =0;
42-
4323
int main()
4424
{
4525
CpuStopwatch timer;
@@ -50,19 +30,10 @@ int main()
5030

5131
myLog(LogLvl::INFO, MPU_FILEPOS , "TEST") << "Hi, a log";
5232

53-
logINFO("TEST") << "Some generic Info";
54-
logWARNING("TEST") << "Some log warning";
55-
logERROR("MODULE_TEST") << "some stuff has happend";
56-
logDEBUG("some stuff") << "some stuff is debugging stuff";
57-
logDEBUG2("some stuff") << "more debugging stuff";
58-
59-
timer.getSeconds();
60-
61-
yield();
62-
sleep(2);
63-
yield();
33+
logINFO("TEST") << "Testing Cuda.";
34+
testCuda();
6435

36+
logINFO("TEST") << "It took me " << timer.getSeconds() << " seconds" << endl;
6537
myLog.close();
66-
cout << "It took me " << dTime << " seconds" << endl;
6738
return 0;
6839
}

src/Cuda/cudaUtils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <device_launch_parameters.h>
2020
#include <cstdio>
2121
#include <cstdlib>
22+
#include "../Log/Log.h"
2223
//--------------------
2324

2425
// make clion understand some cuda specific stuff
@@ -55,4 +56,19 @@ typedef long long longlong;
5556
#endif
5657
//--------------------
5758

59+
#define assert_cuda(CODE) _cudaAssert((CODE),MPU_FILEPOS);
60+
61+
inline void _cudaAssert(cudaError_t code, std::string&& filepos)
62+
{
63+
if (code != cudaSuccess)
64+
{
65+
std::string message("Cuda error: " + std::string(cudaGetErrorString(code)));
66+
67+
if (!(mpu::Log::noGlobal() || mpu::Log::getGlobal().getLogLevel() < mpu::LogLvl::FATAL_ERROR))
68+
mpu::Log::getGlobal()(mpu::LogLvl::FATAL_ERROR, std::move(filepos), "cuda") << message;
69+
70+
throw std::runtime_error("Cuda error: " + message);
71+
}
72+
}
73+
5874
#endif //MPUTILS_CUDAUTILS_H

src/Graphics/Window.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ class Window
9090
GLFWwindowiconifyfun setMinimizeCallback(GLFWwindowiconifyfun cb) {glfwSetWindowIconifyCallback(m_w.get(),cb);} //!< callback will be called when the window is minimized
9191

9292
// input callbacks
93-
GLFWkeyfun setKeyCallback(GLFWkeyfun cb) {glfwSetKeyCallback(m_w.get(),cb);} //!< callback will be called when key input is availible
94-
GLFWcharfun setCharCallback(GLFWcharfun cb) {glfwSetCharCallback(m_w.get(),cb);} //!< callback provides character input
95-
GLFWcharmodsfun setCharmodsCallback(GLFWcharmodsfun cb) {glfwSetCharModsCallback(m_w.get(),cb);} //!< callback provides charater input with modifier keys
96-
GLFWmousebuttonfun setMousebuttonCallback(GLFWmousebuttonfun cb) {glfwSetMouseButtonCallback(m_w.get(),cb);} //!< called when a mouse button is pressed
97-
GLFWcursorposfun setCoursorposCallback(GLFWcursorposfun cb) {glfwSetCursorPosCallback(m_w.get(),cb);} //!< called when the cursor is moved
98-
GLFWcursorenterfun setCoursorenterCallback(GLFWcursorenterfun cb) {glfwSetCursorEnterCallback(m_w.get(),cb);} //!< called when the cursor enters or leaves the window
99-
GLFWscrollfun setScrollCallback(GLFWscrollfun cb) {glfwSetScrollCallback(m_w.get(),cb);} //!< called when the scroll wheel is moved
100-
GLFWdropfun setDropCallbac(GLFWdropfun cb) {glfwSetDropCallback(m_w.get(),cb);} //!< called when someting is drag'n droped onto the window
93+
GLFWkeyfun setKeyCallback(GLFWkeyfun cb) {return glfwSetKeyCallback(m_w.get(),cb);} //!< callback will be called when key input is availible
94+
GLFWcharfun setCharCallback(GLFWcharfun cb) {return glfwSetCharCallback(m_w.get(),cb);} //!< callback provides character input
95+
GLFWcharmodsfun setCharmodsCallback(GLFWcharmodsfun cb) {return glfwSetCharModsCallback(m_w.get(),cb);} //!< callback provides charater input with modifier keys
96+
GLFWmousebuttonfun setMousebuttonCallback(GLFWmousebuttonfun cb) {return glfwSetMouseButtonCallback(m_w.get(),cb);} //!< called when a mouse button is pressed
97+
GLFWcursorposfun setCoursorposCallback(GLFWcursorposfun cb) {return glfwSetCursorPosCallback(m_w.get(),cb);} //!< called when the cursor is moved
98+
GLFWcursorenterfun setCoursorenterCallback(GLFWcursorenterfun cb) {return glfwSetCursorEnterCallback(m_w.get(),cb);} //!< called when the cursor enters or leaves the window
99+
GLFWscrollfun setScrollCallback(GLFWscrollfun cb) {return glfwSetScrollCallback(m_w.get(),cb);} //!< called when the scroll wheel is moved
100+
GLFWdropfun setDropCallbac(GLFWdropfun cb) {return glfwSetDropCallback(m_w.get(),cb);} //!< called when someting is drag'n droped onto the window
101101

102102
// input functions
103103
void setInputMode(int mode, int value) {glfwSetInputMode(m_w.get(),mode,value);} //!< see glfwSetInputMode for reference

src/mpUtils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,5 @@
3838
#include "Graphics/Graphics.h"
3939
#endif
4040

41-
// include cuda
42-
#ifdef USE_CUDA
43-
#include "Cuda/cudaUtils.h"
44-
#endif
45-
4641

4742
#endif //MPUTILS_MPUTILS_H

src/stringUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ auto makeFuncCopyable( F&& f )
122122
auto spf = std::make_shared<F>(std::forward<F>(f) );
123123
return [spf](auto&&... args)->decltype(auto)
124124
{
125-
return (*spf)( decltype(args)(args)... );
125+
return (*spf)( (args)... );
126126
};
127127
}
128128

0 commit comments

Comments
 (0)