1+ /*
2+ // Copyright (c) 2025 Ben Ashbaugh
3+ //
4+ // SPDX-License-Identifier: MIT
5+ */
6+
7+ #include < popl/popl.hpp>
8+
9+ #include < CL/opencl.hpp>
10+
11+ #include < iostream>
12+ #include < chrono>
13+ #include < ctime>
14+ #include < thread>
15+
16+ #include < cinttypes>
17+
18+ void getGlobalTimeStamps (cl::Device& device,
19+ uint64_t *DeviceTimestamp,
20+ uint64_t *HostTimestamp)
21+ {
22+ auto times = device.getDeviceAndHostTimer ();
23+
24+ if (DeviceTimestamp) {
25+ *DeviceTimestamp = times.first ;
26+ }
27+ if (HostTimestamp) {
28+ *HostTimestamp = times.second ;
29+ }
30+ }
31+
32+ int main (int argc, char ** argv)
33+ {
34+ int platformIndex = 0 ;
35+ int deviceIndex = 0 ;
36+
37+ {
38+ popl::OptionParser op (" Supported Options" );
39+ op.add <popl::Value<int >>(" p" , " platform" , " Platform Index" , platformIndex, &platformIndex);
40+ op.add <popl::Value<int >>(" d" , " device" , " Device Index" , deviceIndex, &deviceIndex);
41+
42+ bool printUsage = false ;
43+ try {
44+ op.parse (argc, argv);
45+ } catch (std::exception& e) {
46+ fprintf (stderr, " Error: %s\n\n " , e.what ());
47+ printUsage = true ;
48+ }
49+
50+ if (printUsage || !op.unknown_options ().empty () || !op.non_option_args ().empty ()) {
51+ fprintf (stderr,
52+ " Usage: timerdrift [options]\n "
53+ " %s" , op.help ().c_str ());
54+ return -1 ;
55+ }
56+ }
57+
58+ std::vector<cl::Platform> platforms;
59+ cl::Platform::get (&platforms);
60+
61+ printf (" Running on platform: %s\n " ,
62+ platforms[platformIndex].getInfo <CL_PLATFORM_NAME>().c_str () );
63+
64+ std::vector<cl::Device> devices;
65+ platforms[platformIndex].getDevices (CL_DEVICE_TYPE_ALL, &devices);
66+
67+ printf (" Running on device: %s\n " ,
68+ devices[deviceIndex].getInfo <CL_DEVICE_NAME>().c_str () );
69+
70+ uint64_t BaseHostTime = 0 , CurrentHostTime = 0 , BaseDeviceTime = 0 , CurrentDeviceTime = 0 ;
71+
72+ for (int i = 0 ; i < 32 ; i++) {
73+ if (i == 0 ) {
74+ getGlobalTimeStamps (devices[deviceIndex], &BaseDeviceTime, &BaseHostTime);
75+ CurrentDeviceTime = BaseDeviceTime;
76+ CurrentHostTime = BaseHostTime;
77+ } else {
78+ getGlobalTimeStamps (devices[deviceIndex], &CurrentDeviceTime, &CurrentHostTime);
79+ }
80+ auto DeviceTimePast = CurrentDeviceTime - BaseDeviceTime;
81+ auto HostTimePast = CurrentHostTime - BaseHostTime;
82+ #if 0
83+ std::cout << "Iteration: " << i << std::endl;
84+ std::cout << "Device time past since base time: " << DeviceTimePast
85+ << std::endl;
86+ std::cout << "Host time past since base time: " << HostTimePast
87+ << std::endl;
88+ std::cout << "Abs diff: "
89+ << std::abs((int64_t)HostTimePast - (int64_t)DeviceTimePast)
90+ << std::endl
91+ << std::endl;
92+ #else
93+ printf (" Iteration: %2d, Delta: %" PRId64 " \n " ,
94+ i, (int64_t )HostTimePast - (int64_t )DeviceTimePast);
95+ #endif
96+
97+ // Emulate the first iteration taking longer
98+ if (i == 0 ) {
99+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
100+ } else {
101+ std::this_thread::sleep_for (std::chrono::milliseconds (50 ));
102+ }
103+ }
104+
105+ return 0 ;
106+ }
0 commit comments