151c0b2f7Stbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2020-2021 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
1751c0b2f7Stbbdev #include "common/test.h"
1851c0b2f7Stbbdev #include "common/utils.h"
1951c0b2f7Stbbdev 
2049e08aacStbbdev #include "oneapi/tbb/tick_count.h"
2149e08aacStbbdev #include "oneapi/tbb/detail/_template_helpers.h"
2251c0b2f7Stbbdev #include <type_traits>
2351c0b2f7Stbbdev 
2451c0b2f7Stbbdev //! \file conformance_tick_count.cpp
2551c0b2f7Stbbdev //! \brief Test for [timing] specification
2651c0b2f7Stbbdev 
2751c0b2f7Stbbdev //! Testing default construction
2851c0b2f7Stbbdev //! \brief \ref interface
2951c0b2f7Stbbdev TEST_CASE("Default construction") {
3049e08aacStbbdev     oneapi::tbb::tick_count t1;
3151c0b2f7Stbbdev     utils::suppress_unused_warning(t1);
3251c0b2f7Stbbdev }
3351c0b2f7Stbbdev 
3451c0b2f7Stbbdev //! Testing subtraction operation
3551c0b2f7Stbbdev //! Subtraction of two equal tick_counts after call seconds must be equal to 0
3651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
3751c0b2f7Stbbdev TEST_CASE("Subtraction of equal tick_counts") {
3849e08aacStbbdev     oneapi::tbb::tick_count tick_f = oneapi::tbb::tick_count::now();
3949e08aacStbbdev     oneapi::tbb::tick_count tick_s(tick_f);
4051c0b2f7Stbbdev     CHECK_EQ((tick_f - tick_s).seconds(), 0);
4151c0b2f7Stbbdev }
4251c0b2f7Stbbdev 
4351c0b2f7Stbbdev //! Testing subsequent timestamp
4451c0b2f7Stbbdev //! \brief \ref requirement
4551c0b2f7Stbbdev TEST_CASE("Subtraction subsequent timestamp") {
4649e08aacStbbdev     oneapi::tbb::tick_count tick_f(oneapi::tbb::tick_count::now());
4749e08aacStbbdev     oneapi::tbb::tick_count tick_s(oneapi::tbb::tick_count::now());
4851c0b2f7Stbbdev     while ((tick_s - tick_f).seconds() == 0) {
4949e08aacStbbdev         tick_s = oneapi::tbb::tick_count::now();
5051c0b2f7Stbbdev     }
5151c0b2f7Stbbdev     CHECK_GT((tick_s - tick_f).seconds(), 0);
5251c0b2f7Stbbdev }
5351c0b2f7Stbbdev 
5451c0b2f7Stbbdev // Wait for given duration.
5551c0b2f7Stbbdev // The duration parameter is in units of seconds.
WaitForDuration(double duration)5651c0b2f7Stbbdev static void WaitForDuration( double duration ) {
5751c0b2f7Stbbdev     CHECK_GT(duration, 0);
5849e08aacStbbdev     oneapi::tbb::tick_count start = oneapi::tbb::tick_count::now();
5951c0b2f7Stbbdev     double sec = 0;
6051c0b2f7Stbbdev     do {
6149e08aacStbbdev         sec = (oneapi::tbb::tick_count::now() - start).seconds();
6251c0b2f7Stbbdev         CHECK_GE(sec, 0);
6351c0b2f7Stbbdev     } while (sec < duration);
6451c0b2f7Stbbdev }
6551c0b2f7Stbbdev 
6651c0b2f7Stbbdev // CHECK that two times in seconds are very close.
CheckNear(double x,double y)6751c0b2f7Stbbdev void CheckNear( double x, double y ) {
6851c0b2f7Stbbdev     CHECK_GE(x-y, -1.0E-10);
6951c0b2f7Stbbdev     CHECK_GE(1.0E-10, x-y);
7051c0b2f7Stbbdev }
7151c0b2f7Stbbdev 
7251c0b2f7Stbbdev //! Test arithmetic operators on tick_count::interval_t
7351c0b2f7Stbbdev //! \brief \ref interface \ref requirement
7451c0b2f7Stbbdev TEST_CASE("Arithmetic operators") {
7549e08aacStbbdev     oneapi::tbb::tick_count t1 = oneapi::tbb::tick_count::now();
7651c0b2f7Stbbdev     WaitForDuration(0.000001);
7749e08aacStbbdev     oneapi::tbb::tick_count t2 = oneapi::tbb::tick_count::now();
7851c0b2f7Stbbdev     WaitForDuration(0.0000012);
7949e08aacStbbdev     oneapi::tbb::tick_count t3 = oneapi::tbb::tick_count::now();
8051c0b2f7Stbbdev 
8149e08aacStbbdev     using interval_type = oneapi::tbb::tick_count::interval_t;
8251c0b2f7Stbbdev     interval_type i = t2 - t1;
8351c0b2f7Stbbdev     interval_type j = t3 - t2;
8451c0b2f7Stbbdev     interval_type k = t3 - t1;
8549e08aacStbbdev     CHECK_EQ(std::is_same<oneapi::tbb::tick_count::interval_t, decltype(i - j)>::value, true);
8649e08aacStbbdev     CHECK_EQ(std::is_same<oneapi::tbb::tick_count::interval_t, decltype(i + j)>::value, true);
8751c0b2f7Stbbdev     CheckNear((i + j).seconds(), k.seconds());
8851c0b2f7Stbbdev     CheckNear((k - j).seconds(), i.seconds());
8951c0b2f7Stbbdev     CheckNear(((k - j) + (j - i)).seconds(), k.seconds() - i.seconds());
9051c0b2f7Stbbdev     interval_type sum;
9151c0b2f7Stbbdev     sum += i;
9251c0b2f7Stbbdev     sum += j;
9351c0b2f7Stbbdev     CheckNear(sum.seconds(), k.seconds());
9451c0b2f7Stbbdev     sum -= i;
9551c0b2f7Stbbdev     CheckNear(sum.seconds(), j.seconds());
9651c0b2f7Stbbdev     sum -= j;
9751c0b2f7Stbbdev     CheckNear(sum.seconds(), 0.0);
9851c0b2f7Stbbdev }
9951c0b2f7Stbbdev 
10051c0b2f7Stbbdev 
10149e08aacStbbdev //! Test resolution of oneapi::tbb::tick_count::interval_t
10251c0b2f7Stbbdev //! \brief \ref interface \ref requirement
10349e08aacStbbdev TEST_CASE("oneapi::tbb::tick_count::interval_t resolution") {
10451c0b2f7Stbbdev     static double target_value = 0.314159265358979323846264338327950288419;
10551c0b2f7Stbbdev     static double step_value = 0.00027182818284590452353602874713526624977572;
10651c0b2f7Stbbdev     static int range_value = 100;
10751c0b2f7Stbbdev     for (int i = -range_value; i <= range_value; ++i) {
10851c0b2f7Stbbdev         double my_time = target_value + step_value * i;
10949e08aacStbbdev         oneapi::tbb::tick_count::interval_t t0(my_time);
11051c0b2f7Stbbdev         double interval_time = t0.seconds();
11151c0b2f7Stbbdev         //! time always truncates
11251c0b2f7Stbbdev         CHECK_GE(interval_time, 0);
11349e08aacStbbdev         CHECK_LT(my_time - interval_time, oneapi::tbb::tick_count::resolution());
11451c0b2f7Stbbdev     }
11551c0b2f7Stbbdev }
116