Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursion handling #93

Merged
merged 146 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 143 commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
def154a
Farting the current output into a hard-coded file (#52)
bencopl Aug 24, 2022
2ed6823
Farting the current output into a hard-coded file (#52)
bencopl Aug 24, 2022
8832dd5
Merge branch '52-outputting-to-file' of github.com:MetOffice/profiler…
bencopl Aug 31, 2022
c5d4b9d
Merge branch '52-outputting-to-file' of github.com:MetOffice/profiler…
bencopl Aug 31, 2022
696693b
Merge branch '52-outputting-to-file' of github.com:MetOffice/profiler…
bencopl Sep 1, 2022
e436793
Support for setting the outfile name via an environment variable (#52)
bencopl Sep 1, 2022
778b5de
MPI support, one output file per rank (#52)
bencopl Sep 9, 2022
da26ea1
Farting the current output into a hard-coded file (#52)
bencopl Aug 24, 2022
4ca8a4b
Farting the current output into a hard-coded file (#52)
bencopl Aug 24, 2022
5edf819
Support for setting the outfile name via an environment variable (#52)
bencopl Sep 1, 2022
338ddb1
MPI support, one output file per rank (#52)
bencopl Sep 9, 2022
44a7559
Merge branch '52-outputting-to-file' of github.com:MetOffice/profiler…
bencopl Oct 4, 2022
4a5f354
Tidying up profiler's write function (#52)
bencopl Oct 13, 2022
b916d29
Initial workflow [checking gcov works before messing with lcov] (#45)
bencopl Oct 27, 2022
e61735d
Cosmetic changes to yml file
bencopl Oct 27, 2022
db80d24
Fixing error messsage from actions tab
bencopl Oct 27, 2022
1229a45
Merge pull request #2 from bencopl/45-unit-test-coverage
bencopl Oct 27, 2022
5b7172c
Typo in yml file
bencopl Oct 27, 2022
2281558
Disabling doxygen, explicitly declaring compilers using matrix method
bencopl Oct 27, 2022
639cc26
Including GTest
bencopl Oct 27, 2022
d1739a9
Disabling fortran tests in cmake config
bencopl Oct 27, 2022
af8279a
Altering gcov flags
bencopl Oct 27, 2022
b8dc143
Attempting conda install of gcov and lcov
bencopl Oct 27, 2022
0a4bb78
Merging into single job
bencopl Oct 27, 2022
f1b7758
Fixed typo
bencopl Oct 27, 2022
ea03f9d
Removing environment file line from conda setup
bencopl Oct 27, 2022
1e34eaa
Removing conda install of gcov
bencopl Oct 27, 2022
ffeea84
Including conda forge channel
bencopl Oct 27, 2022
db9f09a
Attempting to fix lcov command not working by including shell -l {0} …
bencopl Oct 27, 2022
df89b09
Also adding shell command to genhtml step, workflow should now run al…
bencopl Oct 27, 2022
683aaba
Trying default workspace option part-way through job
bencopl Oct 27, 2022
c5849a5
Removing steps from line56
bencopl Oct 27, 2022
ee78b36
Added default shell
bencopl Oct 27, 2022
39de6d1
Removing defaults option...
bencopl Oct 27, 2022
808be57
Added step that updates github pages
bencopl Oct 28, 2022
51d8c91
Resolving unknown branch issue
bencopl Oct 28, 2022
020d4a7
Typo in final step
bencopl Oct 28, 2022
88e6628
Removing git remote update line
bencopl Oct 28, 2022
0673329
Fixing error msg when github tries to remove folder that isnt there
bencopl Oct 28, 2022
ba54fbe
Removing git prefix from rm -rf
bencopl Oct 28, 2022
2939272
Altering docs folder
bencopl Oct 28, 2022
906910e
Filtering out STL headers
bencopl Oct 28, 2022
4eb1ce4
Fixed typo in shell option
bencopl Oct 28, 2022
336dc18
Attempt to include fortran tests
bencopl Oct 28, 2022
37ac655
Scrapping fortran tests
bencopl Oct 28, 2022
afd98f4
Getting Doxygen AND coverage docs to appear
bencopl Oct 28, 2022
28dd901
Merge pull request #3 from bencopl/45-unit-test-coverage
bencopl Oct 28, 2022
9f9de39
Fixed error in documentation.yml
bencopl Oct 28, 2022
3807f79
Changing where doxygen documentation is put
bencopl Oct 28, 2022
62b4cd8
Testing putting both workflows straight into docs
bencopl Oct 28, 2022
eb12dfb
Separating them into documentation and coverage files
bencopl Oct 28, 2022
cbb643a
Typo in coverage.yml
bencopl Oct 28, 2022
dc2f0b4
Another typo in coverage.yml
bencopl Oct 28, 2022
1590af5
Hopefully final error with coverage.yml
bencopl Oct 28, 2022
62d4585
Overhead times reported from all threads.
mo-mglover Nov 3, 2022
cbda186
Draft of new IO structure contained within the two new files (#52)
bencopl Nov 3, 2022
c3a40d2
Formatting mostly there but not working with multiple threads (#70)
bencopl Nov 3, 2022
0c6c8b0
Draft solution for combining all hashtables together (#70)
bencopl Nov 4, 2022
46a6d11
Added HashVec class that collects all hashtables, then sorts & writes…
bencopl Nov 8, 2022
9d56df8
Adding banners and fixing includes (#70)
bencopl Nov 8, 2022
2df6214
Switching to getter that returns a reference (instead of using pointe…
bencopl Nov 8, 2022
7c6fb2f
Improved comments (#70)
bencopl Nov 8, 2022
3b378b8
Capture Fortran time (appending null character).
mo-mglover Nov 8, 2022
427b68a
Adding in PLACEHOLDER block of info above table (#70)
bencopl Nov 9, 2022
b169421
Switching to functions rather than single-method objects (#52)
bencopl Nov 9, 2022
91f430c
Move post final gettime time updates to pointer / ref increments.
mo-mglover Nov 9, 2022
cb7a77b
Merge branch 'main' into 52-outputting-to-file
bencopl Nov 9, 2022
dbc5a8a
Attempting to debug mpi issue in workflow (#52)
bencopl Nov 10, 2022
c7cb133
Installing mpich in workflow (#52)
bencopl Nov 10, 2022
9cfa153
Changing workflow step name to reflect mpich installation (#52)
bencopl Nov 10, 2022
b4e32fd
Slight comment changes (#52)
bencopl Nov 10, 2022
6436572
Printing mpich version within workflow (#52)
bencopl Nov 10, 2022
a426c3b
Trying to print OpenMP version (#52)
bencopl Nov 10, 2022
244295f
Updating readme with correct OpenMP version number (#52)
bencopl Nov 10, 2022
af7b1f4
Merge pull request #4 from MetOffice/52-outputting-to-file
bencopl Nov 10, 2022
db3e744
Merge branch '70-mimic-drhooks-output' into 72-multiple-output-format…
bencopl Nov 11, 2022
cd1256b
Change the traceback from std::vector to std::array.
mo-mglover Nov 11, 2022
f16bbc4
Catch the case where a stop calliper is called before a start calliper.
mo-mglover Nov 11, 2022
28127da
Double stdfunction strategy pattern that includes ouput format (#72)
bencopl Nov 11, 2022
588f264
Correct handling of child time for top-level calls.
mo-mglover Nov 21, 2022
e7303b7
Draft of visitor pattern solution (#72)
bencopl Nov 22, 2022
e256b4e
Better comment blocks in visitor pattern solution (#72)
bencopl Nov 22, 2022
a4c8914
Slight change in how the visitor method is called (#72)
bencopl Nov 22, 2022
2d87e70
Combination of std::function and virtual strategy methods (#72)
bencopl Nov 24, 2022
472d045
Updating comment blocks (#72)
bencopl Nov 25, 2022
20c258b
Tidying up and updating call count unit test (#72)
bencopl Nov 25, 2022
c3f143f
Adding some const's where appropriate and slight comment changes (#72)
bencopl Nov 25, 2022
ee43d2b
Modifying string concatenation (#72)
bencopl Nov 28, 2022
3821115
Persistent entries for each region stored in vector; use iterators.
mo-mglover Nov 29, 2022
32dd850
Fixing mistake in string concatenation (#72)
bencopl Nov 29, 2022
1b82942
Erroneous line in HashTable::append_to() (#72)
bencopl Nov 29, 2022
4200288
Better timings - don't rehash the hashes (plus a few consts).
mo-mglover Nov 29, 2022
b8ebee4
Changing final loop in call count unit test (#72)
bencopl Nov 29, 2022
7329318
Removing accidental addition of new coverage worklow (#72)
bencopl Nov 29, 2022
fa1c2ad
Fixing documentation workflow based on removal of coverage one (#72)
bencopl Nov 29, 2022
75935db
Hopeful solution to call count unit test error (#72)
bencopl Nov 29, 2022
383fd34
Modifications to query_insert()
mo-mglover Nov 29, 2022
fa4e239
Altering call count test - removing pair from vector (#72)
bencopl Nov 30, 2022
060c551
Final tidying up (#72)
bencopl Nov 30, 2022
165d09a
Index-based addressing for the vector. Sorting needs attention.
mo-mglover Nov 30, 2022
35e8859
Correct lookup_table's view of hashvec indices after sort.
mo-mglover Nov 30, 2022
da863ea
Separate sort method; TracebackEntry; other tweaks.
mo-mglover Dec 2, 2022
f0be730
Modified comment blocks, plus other tweaks.
mo-mglover Dec 2, 2022
16b2955
Remove unused variable.
mo-mglover Dec 5, 2022
d24c614
Don't include asserts that might trap application-level coding faults.
mo-mglover Dec 5, 2022
e8919a9
Add test for case where traceback array exhausted.
mo-mglover Jan 5, 2023
f059b78
Add [[maybe_unused]] in traceback entry exhaustion test.
mo-mglover Jan 5, 2023
ff1774f
Merge branch 'main' into 64-better-overhead-measurement
mo-mglover Jan 5, 2023
73b179d
Tidy up around start parts and namespacing threadprivate storage.
mo-mglover Jan 6, 2023
cc44fd7
Minor correction to commenting.
mo-mglover Jan 20, 2023
269bf2c
Merging suggested changes from MG branch (#72)
bencopl Feb 7, 2023
7e4da7f
Minor cosmetic/comment additions or adjustments (#72)
bencopl Feb 8, 2023
861d0eb
Accidentally removed required include in last commit (#72)
bencopl Feb 8, 2023
0aad380
Merge branch 'main' into 72-multiple-output-format-options
bencopl Feb 8, 2023
b718d07
Merge branch '72-multiple-output-format-options' into 64-better-overh…
mo-mglover Feb 14, 2023
6f35fc1
Merge branch 'main' into 64-better-overhead-management-merge72
mo-mglover Apr 19, 2023
fce0d9a
Corrections following merge of formatting changes on main.
mo-mglover Apr 20, 2023
28694dd
Add __profiler__ region name test, alongside tests for other regions.
mo-mglover Apr 20, 2023
8cb8d71
Move RegionRecord constructor.
mo-mglover Apr 24, 2023
c708ac1
Working byte copying, with appropriate changes to unit tests.
mo-mglover May 5, 2023
9e32240
Tweaks to typecasting (remove build warning messages).
mo-mglover May 5, 2023
9e88a55
Use PROF_STRING_BUFFER_LENGTH.
mo-mglover May 5, 2023
095e8dd
Return overhead time pointers through argument list, not returned fro…
mo-mglover May 11, 2023
e8a40ac
Forward declare HashVecHandler; use hashvec_t in one place; Traceback…
mo-mglover May 12, 2023
ff402ad
Corrections to doxygen comments.
mo-mglover May 12, 2023
4e2a8c2
Make start_part1 and start_part2 methods private in Profiler class.
mo-mglover May 12, 2023
d170cb4
Return overhead time pointers through argument list.
mo-mglover May 12, 2023
b128a8d
Remove extraneous hash of __profiler__.
mo-mglover May 13, 2023
928c5de
add_child_time -> add_child_time_to_parent.
mo-mglover May 17, 2023
ece55a7
reference -> pointer in comments in one place.
mo-mglover May 17, 2023
5f5ccca
Merge branch '64-better-overhead-measurement' into 64-better-overhead…
mo-mglover May 18, 2023
b4f019a
Correct handling of total times with recursions
mo-mglover May 26, 2023
4dcc912
File-scope variables become static data members.
mo-mglover May 31, 2023
78ca084
Overloaded const and non-const hash2record. (Can have same name.)
mo-mglover Jun 1, 2023
bf7ee06
Merge branch '64-better-overhead-measurement' into byte-copy-thread-id
mo-mglover Jun 1, 2023
4265d61
Merge branch 'byte-copy-thread-id' into byte-copy-thread-id-and-recur…
mo-mglover Jun 1, 2023
807b39a
Add recursion test; handle recursion_total_time_ slightly differently.
mo-mglover Jun 2, 2023
0ed7c87
Merge branch 'main' into recursion-handling
mo-mglover Jul 25, 2023
4ce4b2c
Merge branch 'main' into recursion-handling
mo-mglover Aug 23, 2023
a1e1170
Swap recursion level to unsigned int.
mo-mglover Aug 23, 2023
339e75d
Add direct recursion test. Slacken time tolerance.
mo-mglover Aug 23, 2023
d85d26a
Remove extraneous spaces.
mo-mglover Aug 23, 2023
c5046c4
Make test_recursion threadsafe.
mo-mglover Aug 24, 2023
15aa1bd
Add doxygen comments for recursion increment / decrement.
mo-mglover Aug 25, 2023
341b88a
Remove forward declarations in test_recursion.
mo-mglover Aug 25, 2023
b767e34
Reinstate one forward declaration.
mo-mglover Aug 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/c++/hashtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "hashvec_handler.h"

#include <cassert>
#include <cstring>
#include <iterator>
#include <cstring>
#include <cstddef>
Expand Down Expand Up @@ -148,14 +149,32 @@ void meto::HashTable::update(record_index_t const record_index,

auto& record = hashvec_[record_index];

// Increment the walltime for this hash entry.
record.total_walltime_ += time_delta;
// Increment the walltime for this hash entry. If this region has been called
// recursively, directly or indirectly, the time goes into a different bucket.
if (record.recursion_level_ > 0){
record.recursion_total_walltime_ += time_delta;
}
else{
record.total_walltime_ += time_delta;
}

// Update the number of times this region has been called
++record.call_count_;

}

void meto::HashTable::increment_recursion_level(record_index_t const record_index)
andrewcoughtrie marked this conversation as resolved.
Show resolved Hide resolved
{
auto& record = hashvec_[record_index];
++record.recursion_level_;
}

void meto::HashTable::decrement_recursion_level(record_index_t const record_index)
andrewcoughtrie marked this conversation as resolved.
Show resolved Hide resolved
{
auto& record = hashvec_[record_index];
--record.recursion_level_;
}

/**
* @brief Add in time spent calling child regions. Also retuns a pointer
* to the overhead time so that it can be incremented downstream,
Expand Down Expand Up @@ -216,14 +235,15 @@ void meto::HashTable::sort_records()
* @details Times computed are: the region self time and the total time minus
* directly incurred profiling overhead costs.
*
* @param [in] record The region record to compute.
* @param [inout] record The region record to compute.
*/

void meto::HashTable::prepare_computed_times(RegionRecord& record)
{

// Self time
record.self_walltime_ = record.total_walltime_
+ record.recursion_total_walltime_
- record.child_walltime_
- record.overhead_walltime_;

Expand Down
4 changes: 4 additions & 0 deletions src/c++/hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ class HashTable{
std::string get_decorated_region_name(size_t const hash) const;
unsigned long long int get_call_count(size_t const hash) const;
unsigned long long int get_prof_call_count() const;

void increment_recursion_level(record_index_t const);
void decrement_recursion_level(record_index_t const);

};

} // End meto namespace
Expand Down
12 changes: 7 additions & 5 deletions src/c++/hashvec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ meto::RegionRecord::RegionRecord(size_t const region_hash,
int tid)
: region_hash_(region_hash)
, region_name_(region_name)
, total_walltime_ (time_duration_t::zero())
, total_raw_walltime_ (time_duration_t::zero())
, self_walltime_ (time_duration_t::zero())
, child_walltime_ (time_duration_t::zero())
, overhead_walltime_ (time_duration_t::zero())
, total_walltime_ (time_duration_t::zero())
, recursion_total_walltime_ (time_duration_t::zero())
, total_raw_walltime_ (time_duration_t::zero())
, self_walltime_ (time_duration_t::zero())
, child_walltime_ (time_duration_t::zero())
, overhead_walltime_ (time_duration_t::zero())
, call_count_(0)
, recursion_level_(0)
{
decorated_region_name_ = region_name_;
decorated_region_name_ += '@';
Expand Down
2 changes: 2 additions & 0 deletions src/c++/hashvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ struct RegionRecord {
std::string region_name_;
std::string decorated_region_name_;
time_duration_t total_walltime_;
time_duration_t recursion_total_walltime_;
time_duration_t total_raw_walltime_;
time_duration_t self_walltime_;
time_duration_t child_walltime_;
time_duration_t overhead_walltime_;
unsigned long long int call_count_;
unsigned int recursion_level_;

};

Expand Down
8 changes: 5 additions & 3 deletions src/c++/vernier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ size_t meto::Vernier::start_part2(std::string_view const region_name)
size_t hash;
record_index_t record_index;
thread_hashtables_[tid].query_insert(region_name, tid_int, hash, record_index);
thread_hashtables_[tid].increment_recursion_level(record_index);

// Store the calliper and region start times.
++call_depth_;
Expand Down Expand Up @@ -163,9 +164,9 @@ void meto::Vernier::stop(size_t const hash)
exit (101);
}

// Get reference to the traceback entry.
auto call_depth_index = static_cast<traceback_index_t>(call_depth_);
auto& traceback_entry = thread_traceback_[tid].at(call_depth_index);
// Get reference to the traceback entry.
auto call_depth_index = static_cast<traceback_index_t>(call_depth_);
auto& traceback_entry = thread_traceback_[tid].at(call_depth_index);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cosmetic - aligning indentation.


// Check: which hash is last on the traceback list?
size_t last_hash_on_list = traceback_entry.record_hash_;
Expand All @@ -178,6 +179,7 @@ void meto::Vernier::stop(size_t const hash)
auto region_duration = region_stop_time - traceback_entry.region_start_time_;

// Do the hashtable update for the child region.
thread_hashtables_[tid].decrement_recursion_level(traceback_entry.record_index_);
thread_hashtables_[tid].update(traceback_entry.record_index_, region_duration);

// Precompute times as far as possible. We just need the calliper stop time
Expand Down
1 change: 1 addition & 0 deletions tests/unit_tests/c++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ add_unit_test(test_regionname test_regionname.cpp)
add_unit_test(test_hashtable test_hashtable.cpp)
add_unit_test(test_proftests test_proftests.cpp)
add_unit_test(test_callcount test_callcount.cpp)
add_unit_test(test_recursion test_recursion.cpp)
190 changes: 190 additions & 0 deletions tests/unit_tests/c++/test_recursion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*----------------------------------------------------------------------------*\
(c) Crown copyright 2023 Met Office. All rights reserved.
The file LICENCE, distributed with this code, contains details of the terms
under which the code may be used.
\*----------------------------------------------------------------------------*/

#include <gtest/gtest.h>
#include <omp.h>

#include "vernier.h"

int const max_depth = 3;
int const sleep_seconds = 1;

// The time tolerance can be reasonably loose. If the total times were incorrect
// as a result of mis-handled recursion, they would be too large by multiples of
// sleep_seconds.
double const time_tolerance = 0.001;

// ------------------------------------------------------------------------------
// Structs
// ------------------------------------------------------------------------------

// Structure To hold timings from the various recursive functions.
struct Timings
{
double zeroth_function_total_time_ = 0.0;
double first_function_total_time_ = 0.0;
double second_function_total_time_ = 0.0;
};

// ------------------------------------------------------------------------------
// Forward declarations
// ------------------------------------------------------------------------------

void zeroth_function(Timings&);
andrewcoughtrie marked this conversation as resolved.
Show resolved Hide resolved
void first_function (Timings&);
void second_function(Timings&);

// ------------------------------------------------------------------------------
// Zeroth function - calls itself
// ------------------------------------------------------------------------------

void zeroth_function(Timings& timings)
{

static int recursion_depth = 1;
#pragma omp threadprivate(recursion_depth)

auto prof_handle = meto::vernier.start("first_function");

sleep(sleep_seconds);
++recursion_depth;

if (recursion_depth <= max_depth)
{
zeroth_function(timings);
}

meto::vernier.stop(prof_handle);

// Update the total walltime so far spent in this function.
int const tid = omp_get_thread_num();
timings.zeroth_function_total_time_ = meto::vernier.get_total_walltime(prof_handle, tid);

}

// ------------------------------------------------------------------------------
// First function - calls the second function.
// ------------------------------------------------------------------------------

void first_function(Timings& timings)
{

static int recursion_depth = 1;
#pragma omp threadprivate(recursion_depth)

auto prof_handle = meto::vernier.start("first_function");

sleep(sleep_seconds);
++recursion_depth;

if (recursion_depth <= max_depth)
{
second_function(timings);
}

meto::vernier.stop(prof_handle);

// Update the total walltime so far spent in this function. Do here while we
// have access to the prof_handle.
int const tid = omp_get_thread_num();
timings.first_function_total_time_ = meto::vernier.get_total_walltime(prof_handle, tid);

}

// ------------------------------------------------------------------------------
// Second function - calls the first function.
// ------------------------------------------------------------------------------

void second_function(Timings& timings)
{
static int recursion_depth = 1;
#pragma omp threadprivate(recursion_depth)

auto prof_handle = meto::vernier.start("second_function");

sleep(sleep_seconds);
++recursion_depth;

if (recursion_depth <= max_depth)
{
first_function(timings);
}

meto::vernier.stop(prof_handle);

// Update the total walltime so far spent in this function. Do here while we
// have access to the prof_handle.
int const tid = omp_get_thread_num();
timings.second_function_total_time_ = meto::vernier.get_total_walltime(prof_handle, tid);
}

// -------------------------------------------------------------------------------
// Main tests
// -------------------------------------------------------------------------------

//
// Direct recursion
//

TEST(RecursionTest,DirectRecursion)
{
auto prof_handle = meto::vernier.start("test_recursion");

// Test independently on each thread.
#pragma omp parallel
{
auto prof_handle_threaded = meto::vernier.start("test_recursion:threads");

Timings timings;
double t1 = omp_get_wtime();

// Function calls itself
zeroth_function(timings);

double t2 = omp_get_wtime();
double overall_time = t2-t1;

EXPECT_LE (timings.zeroth_function_total_time_, overall_time);
EXPECT_NEAR(timings.zeroth_function_total_time_, overall_time, time_tolerance);

meto::vernier.stop(prof_handle_threaded);
}

meto::vernier.stop(prof_handle);
}

//
// Indirect recursion
//

TEST(RecursionTest,IndirectRecursion)
{
auto prof_handle = meto::vernier.start("test_recursion");

// Test independently on each thread.
#pragma omp parallel
{
auto prof_handle_threaded = meto::vernier.start("test_recursion:threads");

Timings timings;
double t1 = omp_get_wtime();

// Function calls a second function
first_function(timings);

double t2 = omp_get_wtime();
double overall_time = t2-t1;

EXPECT_LE (timings.first_function_total_time_, overall_time);
EXPECT_NEAR(timings.first_function_total_time_, overall_time, time_tolerance);
EXPECT_NEAR(timings.second_function_total_time_, timings.first_function_total_time_ - sleep_seconds, time_tolerance);

meto::vernier.stop(prof_handle_threaded);
}

meto::vernier.stop(prof_handle);
}