summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--samples/cache.c1
-rw-r--r--samples/dgemv.c1
-rw-r--r--samples/haxpy.c1
-rw-r--r--samples/sasum.c1
-rw-r--r--samples/sgemm.c1
-rw-r--r--samples/sgemm.cpp1
-rw-r--r--src/clpp11.hpp33
8 files changed, 28 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG
index fe8f7221..725eb116 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
Development version (next release)
- Updated to version 6.0 of the CLCudaAPI C++11 OpenCL header
- Fixed proper MSVC dllimport and dllexport declarations
+- Fixed memory leaks related to events not being released
Version 0.8.0
- Added support for half-precision floating-point (fp16) in the library
diff --git a/samples/cache.c b/samples/cache.c
index 7f876be1..a592824d 100644
--- a/samples/cache.c
+++ b/samples/cache.c
@@ -113,6 +113,7 @@ void run_example_routine(const cl_device_id device) {
// Wait for completion
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
// Retrieves the execution time
clock_t diff = clock() - start;
diff --git a/samples/dgemv.c b/samples/dgemv.c
index 6ea0deb0..c22c9f37 100644
--- a/samples/dgemv.c
+++ b/samples/dgemv.c
@@ -85,6 +85,7 @@ int main(void) {
// Wait for completion
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
// Example completed. See "clblast_c.h" for status codes (0 -> success).
printf("Completed DGEMV with status %d\n", status);
diff --git a/samples/haxpy.c b/samples/haxpy.c
index 3c7bb33a..d5b98e12 100644
--- a/samples/haxpy.c
+++ b/samples/haxpy.c
@@ -78,6 +78,7 @@ int main(void) {
// Wait for completion
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
// Copies the result back to the host
clEnqueueReadBuffer(queue, device_b, CL_TRUE, 0, n*sizeof(cl_half), host_b, 0, NULL, NULL);
diff --git a/samples/sasum.c b/samples/sasum.c
index 3fdbb0eb..1518cc13 100644
--- a/samples/sasum.c
+++ b/samples/sasum.c
@@ -74,6 +74,7 @@ int main(void) {
// Wait for completion
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
// Copies the result back to the host
clEnqueueReadBuffer(queue, device_output, CL_TRUE, 0, 1*sizeof(float), host_output, 0, NULL, NULL);
diff --git a/samples/sgemm.c b/samples/sgemm.c
index 79f30c83..b4827777 100644
--- a/samples/sgemm.c
+++ b/samples/sgemm.c
@@ -88,6 +88,7 @@ int main(void) {
// Wait for completion
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
// Example completed. See "clblast_c.h" for status codes (0 -> success).
printf("Completed SGEMM with status %d\n", status);
diff --git a/samples/sgemm.cpp b/samples/sgemm.cpp
index 5fe7490a..a4b89968 100644
--- a/samples/sgemm.cpp
+++ b/samples/sgemm.cpp
@@ -96,6 +96,7 @@ int main() {
// Record the execution time
clWaitForEvents(1, &event);
+ clReleaseEvent(event);
auto elapsed_time = std::chrono::steady_clock::now() - start_time;
auto time_ms = std::chrono::duration<double,std::milli>(elapsed_time).count();
diff --git a/src/clpp11.hpp b/src/clpp11.hpp
index f8bc2b02..1eeaf702 100644
--- a/src/clpp11.hpp
+++ b/src/clpp11.hpp
@@ -72,15 +72,24 @@ inline void CheckError(const cl_int status) {
class Event {
public:
- // Constructor based on the regular OpenCL data-type
- explicit Event(const cl_event event): event_(event) { }
+ // Constructor based on the regular OpenCL data-type: memory management is handled elsewhere
+ explicit Event(const cl_event event):
+ event_(new cl_event) {
+ *event_ = event;
+ }
- // Regular constructor
- explicit Event(): event_(nullptr) { }
+ // Regular constructor with memory management
+ explicit Event():
+ event_(new cl_event, [](cl_event* e) {
+ if (*e) { CheckError(clReleaseEvent(*e)); }
+ delete e;
+ }) {
+ *event_ = nullptr;
+ }
// Waits for completion of this event
void WaitForCompletion() const {
- CheckError(clWaitForEvents(1, &event_));
+ CheckError(clWaitForEvents(1, &(*event_)));
}
// Retrieves the elapsed time of the last recorded event. Note that no error checking is done on
@@ -89,20 +98,20 @@ class Event {
float GetElapsedTime() const {
WaitForCompletion();
auto bytes = size_t{0};
- clGetEventProfilingInfo(event_, CL_PROFILING_COMMAND_START, 0, nullptr, &bytes);
+ clGetEventProfilingInfo(*event_, CL_PROFILING_COMMAND_START, 0, nullptr, &bytes);
auto time_start = size_t{0};
- clGetEventProfilingInfo(event_, CL_PROFILING_COMMAND_START, bytes, &time_start, nullptr);
- clGetEventProfilingInfo(event_, CL_PROFILING_COMMAND_END, 0, nullptr, &bytes);
+ clGetEventProfilingInfo(*event_, CL_PROFILING_COMMAND_START, bytes, &time_start, nullptr);
+ clGetEventProfilingInfo(*event_, CL_PROFILING_COMMAND_END, 0, nullptr, &bytes);
auto time_end = size_t{0};
- clGetEventProfilingInfo(event_, CL_PROFILING_COMMAND_END, bytes, &time_end, nullptr);
+ clGetEventProfilingInfo(*event_, CL_PROFILING_COMMAND_END, bytes, &time_end, nullptr);
return (time_end - time_start) * 1.0e-6f;
}
// Accessor to the private data-member
- cl_event& operator()() { return event_; }
- cl_event* pointer() { return &event_; }
+ cl_event& operator()() { return *event_; }
+ cl_event* pointer() { return &(*event_); }
private:
- cl_event event_;
+ std::shared_ptr<cl_event> event_;
};
// Pointer to an OpenCL event