Skip to content

Commit 35aa665

Browse files
authored
Merge pull request #726 from jszuppe/pr_device_host_timers
Add wrappers for clGetHostTimer and clGetDeviceAndHostTimer
2 parents 23ce38e + 8f0b1bb commit 35aa665

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

include/boost/compute/device.hpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <boost/compute/config.hpp>
2222
#include <boost/compute/exception.hpp>
2323
#include <boost/compute/types/fundamental.hpp>
24+
#include <boost/compute/detail/duration.hpp>
2425
#include <boost/compute/detail/get_object_info.hpp>
2526
#include <boost/compute/detail/assert_cl_success.hpp>
2627

@@ -395,6 +396,85 @@ class device
395396
}
396397
#endif // BOOST_COMPUTE_CL_VERSION_1_2
397398

399+
#if defined(BOOST_COMPUTE_CL_VERSION_2_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
400+
/// Returns the current value of the host clock as seen by device
401+
/// in nanoseconds.
402+
///
403+
/// \see_opencl_ref{clGetHostTimer}
404+
///
405+
/// \opencl_version_warning{2,1}
406+
ulong_ get_host_timer() const
407+
{
408+
ulong_ host_timestamp = 0;
409+
cl_int ret = clGetHostTimer(m_id, &host_timestamp);
410+
if(ret != CL_SUCCESS){
411+
BOOST_THROW_EXCEPTION(opencl_error(ret));
412+
}
413+
return host_timestamp;
414+
}
415+
416+
/// Returns a reasonably synchronized pair of timestamps from the device timer
417+
/// and the host timer as seen by device in nanoseconds. The first of returned
418+
/// std::pair is a device timer timestamp, the second is a host timer timestamp.
419+
///
420+
/// \see_opencl_ref{clGetDeviceAndHostTimer}
421+
///
422+
/// \opencl_version_warning{2,1}
423+
std::pair<ulong_, ulong_> get_device_and_host_timer() const
424+
{
425+
ulong_ host_timestamp;
426+
ulong_ device_timestamp;
427+
cl_int ret = clGetDeviceAndHostTimer(
428+
m_id, &device_timestamp, &host_timestamp
429+
);
430+
if(ret != CL_SUCCESS){
431+
BOOST_THROW_EXCEPTION(opencl_error(ret));
432+
}
433+
return std::make_pair(
434+
device_timestamp, host_timestamp
435+
);
436+
}
437+
438+
#if !defined(BOOST_COMPUTE_NO_HDR_CHRONO) || !defined(BOOST_COMPUTE_NO_BOOST_CHRONO)
439+
/// Returns the current value of the host clock as seen by device
440+
/// as duration.
441+
///
442+
/// For example, to print the current value of the host clock as seen by device
443+
/// in milliseconds:
444+
/// \code
445+
/// std::cout << device.get_host_timer<std::chrono::milliseconds>().count() << " ms";
446+
/// \endcode
447+
///
448+
/// \see_opencl_ref{clGetHostTimer}
449+
///
450+
/// \opencl_version_warning{2,1}
451+
template<class Duration>
452+
Duration get_host_timer() const
453+
{
454+
const ulong_ nanoseconds = this->get_host_timer();
455+
return detail::make_duration_from_nanoseconds(Duration(), nanoseconds);
456+
}
457+
458+
/// Returns a reasonably synchronized pair of timestamps from the device timer
459+
/// and the host timer as seen by device as a std::pair<Duration, Duration> value.
460+
/// The first of returned std::pair is a device timer timestamp, the second is
461+
/// a host timer timestamp.
462+
///
463+
/// \see_opencl_ref{clGetDeviceAndHostTimer}
464+
///
465+
/// \opencl_version_warning{2,1}
466+
template<class Duration>
467+
std::pair<Duration, Duration> get_device_and_host_timer() const
468+
{
469+
const std::pair<ulong_, ulong_> timestamps = this->get_device_and_host_timer();
470+
return std::make_pair(
471+
detail::make_duration_from_nanoseconds(Duration(), timestamps.first),
472+
detail::make_duration_from_nanoseconds(Duration(), timestamps.second)
473+
);
474+
}
475+
#endif // !defined(BOOST_COMPUTE_NO_HDR_CHRONO) || !defined(BOOST_COMPUTE_NO_BOOST_CHRONO)
476+
#endif // BOOST_COMPUTE_CL_VERSION_2_1
477+
398478
/// Returns \c true if the device is the same at \p other.
399479
bool operator==(const device &other) const
400480
{
@@ -579,6 +659,14 @@ BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
579659
)
580660
#endif // BOOST_COMPUTE_CL_VERSION_2_0
581661

662+
#ifdef BOOST_COMPUTE_CL_VERSION_2_1
663+
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
664+
((std::string, CL_DEVICE_IL_VERSION))
665+
((cl_uint, CL_DEVICE_MAX_NUM_SUB_GROUPS))
666+
((bool, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS))
667+
)
668+
#endif // BOOST_COMPUTE_CL_VERSION_2_1
669+
582670
} // end compute namespace
583671
} // end boost namespace
584672

include/boost/compute/platform.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(platform,
241241
((std::string, CL_PLATFORM_EXTENSIONS))
242242
)
243243

244+
#ifdef BOOST_COMPUTE_CL_VERSION_2_1
245+
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(platform,
246+
((cl_ulong, CL_PLATFORM_HOST_TIMER_RESOLUTION))
247+
)
248+
#endif // BOOST_COMPUTE_CL_VERSION_2_1
249+
244250
inline boost::compute::platform device::platform() const
245251
{
246252
return boost::compute::platform(get_info<CL_DEVICE_PLATFORM>());

test/test_device.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,54 @@ BOOST_AUTO_TEST_CASE(get_info_specializations)
232232

233233
std::cout << device.get_info<CL_DEVICE_NAME>() << std::endl;
234234
}
235+
236+
#ifdef BOOST_COMPUTE_CL_VERSION_2_1
237+
BOOST_AUTO_TEST_CASE(get_host_timer)
238+
{
239+
boost::compute::device device = boost::compute::system::default_device();
240+
BOOST_CHECK(device.get_host_timer() != 0);
241+
242+
#ifndef BOOST_COMPUTE_NO_HDR_CHRONO
243+
typedef std::chrono::milliseconds stdms;
244+
BOOST_CHECK(device.get_host_timer<stdms>().count() != 0);
245+
#endif
246+
247+
#ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
248+
typedef boost::chrono::milliseconds bms;
249+
BOOST_CHECK(device.get_host_timer<bms>().count() != 0);
250+
#endif
251+
}
252+
253+
BOOST_AUTO_TEST_CASE(get_device_and_host_timer)
254+
{
255+
boost::compute::device device = boost::compute::system::default_device();
256+
typedef std::pair<boost::compute::ulong_, boost::compute::ulong_> dah_timer;
257+
dah_timer timer;
258+
BOOST_CHECK_NO_THROW(timer = device.get_device_and_host_timer());
259+
BOOST_CHECK(timer.first != 0);
260+
BOOST_CHECK(timer.second != 0);
261+
262+
#ifndef BOOST_COMPUTE_NO_HDR_CHRONO
263+
typedef std::chrono::milliseconds stdms;
264+
BOOST_CHECK(device.get_device_and_host_timer<stdms>().first.count() != 0);
265+
BOOST_CHECK(device.get_device_and_host_timer<stdms>().second.count() != 0);
266+
#endif
267+
268+
#ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
269+
typedef boost::chrono::milliseconds bms;
270+
BOOST_CHECK(device.get_device_and_host_timer<bms>().first.count() != 0);
271+
BOOST_CHECK(device.get_device_and_host_timer<bms>().second.count() != 0);
272+
#endif
273+
}
274+
275+
BOOST_AUTO_TEST_CASE(get_info_opencl21_queries)
276+
{
277+
boost::compute::device device = boost::compute::system::default_device();
278+
279+
BOOST_CHECK(!device.get_info<CL_DEVICE_IL_VERSION>().empty());
280+
BOOST_CHECK(device.get_info<CL_DEVICE_MAX_NUM_SUB_GROUPS>() > 0);
281+
BOOST_CHECK_NO_THROW(
282+
device.get_info<CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS>()
283+
);
284+
}
285+
#endif // BOOST_COMPUTE_CL_VERSION_2_1

0 commit comments

Comments
 (0)