1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include <stdio.h>
17 #include <CL/cl.h>
18 #include "harness/errorHelpers.h"
19 #include "harness/compat.h"
20 
21 #if !defined(_WIN32)
22     #include "unistd.h" // For "sleep"
23 #endif
24 
25 #define ALLOWED_ERROR 0.005f
26 
test_device_and_host_timers(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)27 int test_device_and_host_timers(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
28 {
29     int errors = 0;
30     cl_int result = CL_SUCCESS;
31     cl_ulong deviceStartTime, deviceEndTime, deviceTimeDiff;
32     cl_ulong hostStartTime, hostEndTime, hostTimeDiff;
33     cl_ulong hostOnlyStartTime, hostOnlyEndTime, hostOnlyTimeDiff;
34     cl_ulong observedDiff;
35     cl_ulong allowedDiff;
36 
37     result = clGetDeviceAndHostTimer(deviceID, &deviceStartTime, &hostStartTime);
38     if (result != CL_SUCCESS) {
39         log_error("clGetDeviceAndHostTimer failed with error %s\n", IGetErrorString(result));
40         errors++;
41         goto End;
42     }
43 
44     result = clGetHostTimer(deviceID, &hostOnlyStartTime);
45     if (result != CL_SUCCESS) {
46         log_error("clGetHostTimer failed with error %s\n", IGetErrorString(result));
47         errors++;
48         goto End;
49     }
50 
51     // Wait for a while to allow the timers to increment substantially.
52     sleep(5);
53 
54     result = clGetDeviceAndHostTimer(deviceID, &deviceEndTime, &hostEndTime);
55     if (result != CL_SUCCESS) {
56         log_error("clGetDeviceAndHostTimer failed with error %s\n", IGetErrorString(result));
57         errors++;
58         goto End;
59     }
60 
61     result = clGetHostTimer(deviceID, &hostOnlyEndTime);
62     if (result != CL_SUCCESS) {
63         log_error("clGetHostTimer failed with error %s\n", IGetErrorString(result));
64         errors++;
65         goto End;
66     }
67 
68     deviceTimeDiff = deviceEndTime - deviceStartTime ;
69     hostTimeDiff = hostEndTime - hostStartTime ;
70     hostOnlyTimeDiff = hostOnlyEndTime - hostOnlyStartTime;
71 
72     log_info("Checking results from clGetDeviceAndHostTimer ...\n");
73 
74     if (deviceEndTime <= deviceStartTime) {
75         log_error("Device timer is not monotonically increasing.\n");
76         log_error("    deviceStartTime: %lu, deviceEndTime: %lu\n", deviceStartTime, deviceEndTime);
77         errors++;
78     }
79 
80     if (hostEndTime <= hostStartTime) {
81         log_error("Error: Host timer is not monotonically increasing.\n");
82         log_error("    hostStartTime: %lu, hostEndTime: %lu\n", hostStartTime, hostEndTime);
83         errors++;
84     }
85 
86     if (deviceTimeDiff > hostTimeDiff) {
87         observedDiff = deviceTimeDiff - hostTimeDiff;
88         allowedDiff = (cl_ulong)(hostTimeDiff * ALLOWED_ERROR);
89     }
90     else {
91         observedDiff = hostTimeDiff - deviceTimeDiff;
92         allowedDiff = (cl_ulong)(deviceTimeDiff * ALLOWED_ERROR);
93     }
94 
95     if (observedDiff > allowedDiff) {
96         log_error("Error: Device and host timers did not increase by same amount\n");
97         log_error("    Observed difference between timers %lu (max allowed %lu).\n", observedDiff, allowedDiff);
98         errors++;
99     }
100 
101     log_info("Cross-checking results with clGetHostTimer ...\n");
102 
103     if (hostOnlyEndTime <= hostOnlyStartTime) {
104         log_error("Error: Host timer is not monotonically increasing.\n");
105         log_error("    hostStartTime: %lu, hostEndTime: %lu\n", hostOnlyStartTime, hostOnlyEndTime);
106         errors++;
107     }
108 
109     if (hostOnlyStartTime < hostStartTime) {
110         log_error("Error: Host start times do not correlate.\n");
111         log_error("clGetDeviceAndHostTimer was called before clGetHostTimer but timers are not in that order.\n");
112         log_error("    clGetDeviceAndHostTimer: %lu, clGetHostTimer: %lu\n", hostStartTime, hostOnlyStartTime);
113         errors++;
114     }
115 
116     if (hostOnlyEndTime < hostEndTime) {
117         log_error("Error: Host end times do not correlate.\n");
118         log_error("clGetDeviceAndHostTimer was called before clGetHostTimer but timers are not in that order.\n");
119         log_error("    clGetDeviceAndHostTimer: %lu, clGetHostTimer: %lu\n", hostEndTime, hostOnlyEndTime);
120         errors++;
121     }
122 
123 End:
124     return errors;
125 }
126 
test_timer_resolution_queries(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)127 int test_timer_resolution_queries(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
128 {
129     int errors = 0;
130     cl_int result = CL_SUCCESS;
131     cl_platform_id platform = 0;
132     cl_ulong deviceTimerResolution = 0;
133     cl_ulong hostTimerResolution = 0;
134 
135     result = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL);
136     if (result != CL_SUCCESS) {
137         log_error("clGetDeviceInfo(CL_DEVICE_PLATFORM) failed with error %s.\n", IGetErrorString(result));
138         errors++;
139     }
140 
141     result = clGetDeviceInfo(deviceID, CL_DEVICE_PROFILING_TIMER_RESOLUTION, sizeof(deviceTimerResolution), &deviceTimerResolution, NULL);
142     if (result != CL_SUCCESS) {
143         log_error("clGetDeviceInfo(CL_DEVICE_PROFILING_TIMER_RESOLUTION) failed with error %s.\n", IGetErrorString(result));
144         errors++;
145     }
146     else {
147         log_info("CL_DEVICE_PROFILING_TIMER_RESOLUTION == %lu nanoseconds\n", deviceTimerResolution);
148     }
149 
150     if (platform) {
151         result = clGetPlatformInfo(platform, CL_PLATFORM_HOST_TIMER_RESOLUTION, sizeof(hostTimerResolution), &hostTimerResolution, NULL);
152         if (result != CL_SUCCESS) {
153             log_error("clGetPlatformInfo(CL_PLATFORM_HOST_TIMER_RESOLUTION) failed with error %s.\n", IGetErrorString(result));
154             errors++;
155         }
156         else {
157             log_info("CL_PLATFORM_HOST_TIMER_RESOLUTION == %lu nanoseconds\n", hostTimerResolution);
158         }
159     }
160     else {
161         log_error("Could not find platform ID to query CL_PLATFORM_HOST_TIMER_RESOLUTION\n");
162     }
163 
164     return errors;
165 }
166