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