1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #define BOOST_TEST_MODULE TestBuffer
12 #include <boost/test/unit_test.hpp>
14 #include <boost/compute/buffer.hpp>
15 #include <boost/compute/system.hpp>
16 #include <boost/bind.hpp>
18 #ifdef BOOST_COMPUTE_USE_CPP11
21 #endif // BOOST_COMPUTE_USE_CPP11
24 #include "context_setup.hpp"
26 namespace bc
= boost::compute
;
28 BOOST_AUTO_TEST_CASE(size
)
30 bc::buffer
buffer(context
, 100);
31 BOOST_CHECK_EQUAL(buffer
.size(), size_t(100));
32 BOOST_VERIFY(buffer
.max_size() > buffer
.size());
35 BOOST_AUTO_TEST_CASE(cl_context
)
37 bc::buffer
buffer(context
, 100);
38 BOOST_VERIFY(buffer
.get_context() == context
);
41 BOOST_AUTO_TEST_CASE(equality_operator
)
43 bc::buffer
a(context
, 10);
44 bc::buffer
b(context
, 10);
47 BOOST_VERIFY(!(a
== b
));
52 BOOST_VERIFY(!(a
!= b
));
55 BOOST_AUTO_TEST_CASE(construct_from_cl_mem
)
58 cl_mem mem
= clCreateBuffer(context
, CL_MEM_READ_WRITE
, 16, 0, 0);
61 // create boost::compute::buffer
62 boost::compute::buffer
buffer(mem
);
65 BOOST_CHECK(buffer
.get() == mem
);
66 BOOST_CHECK(buffer
.get_context() == context
);
67 BOOST_CHECK_EQUAL(buffer
.size(), size_t(16));
70 clReleaseMemObject(mem
);
73 BOOST_AUTO_TEST_CASE(reference_count
)
75 using boost::compute::uint_
;
77 boost::compute::buffer
buf(context
, 16);
78 BOOST_CHECK_GE(buf
.reference_count(), uint_(1));
81 BOOST_AUTO_TEST_CASE(get_size
)
83 boost::compute::buffer
buf(context
, 16);
84 BOOST_CHECK_EQUAL(buf
.size(), size_t(16));
85 BOOST_CHECK_EQUAL(buf
.get_info
<CL_MEM_SIZE
>(), size_t(16));
86 BOOST_CHECK_EQUAL(buf
.get_info
<size_t>(CL_MEM_SIZE
), size_t(16));
89 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
90 BOOST_AUTO_TEST_CASE(move_constructor
)
92 boost::compute::buffer
buffer1(context
, 16);
93 BOOST_CHECK(buffer1
.get() != 0);
94 BOOST_CHECK_EQUAL(buffer1
.size(), size_t(16));
96 boost::compute::buffer
buffer2(std::move(buffer1
));
97 BOOST_CHECK(buffer1
.get() == 0);
98 BOOST_CHECK(buffer2
.get() != 0);
99 BOOST_CHECK_EQUAL(buffer2
.size(), size_t(16));
101 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
103 BOOST_AUTO_TEST_CASE(clone_buffer
)
105 boost::compute::buffer
buffer1(context
, 16);
106 boost::compute::buffer buffer2
= buffer1
.clone(queue
);
107 BOOST_CHECK(buffer1
.get() != buffer2
.get());
108 BOOST_CHECK_EQUAL(buffer1
.size(), buffer2
.size());
109 BOOST_CHECK(buffer1
.get_memory_flags() == buffer2
.get_memory_flags());
112 #ifdef BOOST_COMPUTE_USE_CPP11
113 #ifdef BOOST_COMPUTE_CL_VERSION_1_1
114 std::mutex callback_mutex
;
115 std::condition_variable callback_condition_variable
;
117 static void BOOST_COMPUTE_CL_CALLBACK
118 destructor_callback_function(cl_mem
, void *user_data
)
120 std::lock_guard
<std::mutex
> lock(callback_mutex
);
122 bool *flag
= static_cast<bool *>(user_data
);
125 callback_condition_variable
.notify_one();
128 BOOST_AUTO_TEST_CASE(destructor_callback
)
130 REQUIRES_OPENCL_VERSION(1,2);
132 if(!supports_destructor_callback(device
))
137 bool invoked
= false;
139 boost::compute::buffer
buf(context
, 128);
140 buf
.set_destructor_callback(destructor_callback_function
, &invoked
);
143 std::unique_lock
<std::mutex
> lock(callback_mutex
);
144 callback_condition_variable
.wait_for(
145 lock
, std::chrono::seconds(1), [&](){ return invoked
; }
147 BOOST_CHECK(invoked
== true);
150 static void BOOST_COMPUTE_CL_CALLBACK
151 destructor_templated_callback_function(bool *flag
)
153 std::lock_guard
<std::mutex
> lock(callback_mutex
);
155 callback_condition_variable
.notify_one();
158 BOOST_AUTO_TEST_CASE(destructor_templated_callback
)
160 REQUIRES_OPENCL_VERSION(1,2);
162 if(!supports_destructor_callback(device
))
167 bool invoked
= false;
169 boost::compute::buffer
buf(context
, 128);
170 buf
.set_destructor_callback(boost::bind(destructor_templated_callback_function
, &invoked
));
173 std::unique_lock
<std::mutex
> lock(callback_mutex
);
174 callback_condition_variable
.wait_for(
175 lock
, std::chrono::seconds(1), [&](){ return invoked
; }
178 BOOST_CHECK(invoked
== true);
181 #endif // BOOST_COMPUTE_USE_CPP11
183 BOOST_AUTO_TEST_CASE(create_subbuffer
)
185 REQUIRES_OPENCL_VERSION(1, 1);
187 size_t base_addr_align
= device
.get_info
<CL_DEVICE_MEM_BASE_ADDR_ALIGN
>() / 8;
188 size_t multiplier
= 16;
189 size_t buffer_size
= base_addr_align
* multiplier
;
190 size_t subbuffer_size
= 64;
191 boost::compute::buffer
buffer(context
, buffer_size
);
193 for(size_t i
= 0; i
< multiplier
; ++i
)
195 boost::compute::buffer subbuffer
= buffer
.create_subbuffer(
196 boost::compute::buffer::read_write
, base_addr_align
* i
, subbuffer_size
);
197 BOOST_CHECK(buffer
.get() != subbuffer
.get());
198 BOOST_CHECK_EQUAL(subbuffer
.size(), subbuffer_size
);
202 #endif // BOOST_COMPUTE_CL_VERSION_1_1
204 BOOST_AUTO_TEST_CASE(create_buffer_doctest
)
207 boost::compute::buffer
buf(context
, 32 * sizeof(float));
210 BOOST_CHECK_EQUAL(buf
.size(), 32 * sizeof(float));
213 BOOST_AUTO_TEST_SUITE_END()