From ff9fdb5c0daf4e8b14e4d1767b88319bbf05c06c Mon Sep 17 00:00:00 2001 From: cstyl Date: Sun, 17 Dec 2023 13:14:21 +0000 Subject: [PATCH] Updated tests --- CMakeLists.txt | 3 + examples/decision-tree-tuner/CMakeLists.txt | 3 +- src/CMakeLists.txt | 1 + .../MorpheusOracle_Loader_Impl.hpp | 2 +- src/impl/MorpheusOracle_Loader_Utils.cpp | 26 +++ src/impl/MorpheusOracle_Loader_Utils.hpp | 23 +- .../MorpheusOracle_Loader_Impl.hpp | 2 +- tests/CMakeLists.txt | 76 ++---- tests/TestMain.cpp | 4 +- tests/Test_RunFirstTuner.hpp | 169 ++++++-------- tests/Test_TuneRunFirst.hpp | 101 ++++---- tests/Test_TypeTraits.hpp | 220 ++++++++++++++++++ tests/category_files/TestCuda_Category.hpp | 36 --- tests/category_files/TestHIP_Category.hpp | 36 --- tests/category_files/TestOpenMP_Category.hpp | 36 --- tests/category_files/TestSerial_Category.hpp | 36 --- 16 files changed, 399 insertions(+), 375 deletions(-) create mode 100644 src/impl/MorpheusOracle_Loader_Utils.cpp delete mode 100644 tests/category_files/TestCuda_Category.hpp delete mode 100644 tests/category_files/TestHIP_Category.hpp delete mode 100644 tests/category_files/TestOpenMP_Category.hpp delete mode 100644 tests/category_files/TestSerial_Category.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ac0a74..508f938 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,9 @@ else() set(MORPHEUS_IS_SUBDIRECTORY FALSE) endif() +# Enable C++17 +set(CMAKE_CXX_STANDARD 17) + include(cmake/morpheusoracle_utils.cmake) option(BUILD_SHARED_LIBS "Build shared libraries" OFF) diff --git a/examples/decision-tree-tuner/CMakeLists.txt b/examples/decision-tree-tuner/CMakeLists.txt index 1729a91..ed8ab04 100644 --- a/examples/decision-tree-tuner/CMakeLists.txt +++ b/examples/decision-tree-tuner/CMakeLists.txt @@ -11,8 +11,7 @@ elseif(Morpheus_ENABLE_HIP) target_compile_definitions(MorpheusOracle_decision_tree_tuner_HIP PRIVATE EXAMPLE_ENABLE_HIP) target_link_libraries(MorpheusOracle_decision_tree_tuner_HIP PUBLIC Morpheus::morpheus) elseif(Morpheus_ENABLE_OPENMP) - morpheusoracle_add_test_executable(decision_tree_tuner_OPENMP SOURCES - decision_tree_tuner.cpp) + morpheusoracle_add_test_executable(decision_tree_tuner_OPENMP SOURCES decision_tree_tuner.cpp) target_compile_definitions(MorpheusOracle_decision_tree_tuner_OPENMP PRIVATE EXAMPLE_ENABLE_OPENMP) target_link_libraries(MorpheusOracle_decision_tree_tuner_OPENMP PUBLIC Morpheus::morpheus) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eff367a..a1e17d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ install( set(MORPHEUS_ORACLE_SOURCES) append_glob(MORPHEUS_ORACLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +append_glob(MORPHEUS_ORACLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp) set(MORPHEUS_ORACLE_HEADERS) append_glob(MORPHEUS_ORACLE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) diff --git a/src/impl/DecisionTree/MorpheusOracle_Loader_Impl.hpp b/src/impl/DecisionTree/MorpheusOracle_Loader_Impl.hpp index 7534b50..4b9065c 100644 --- a/src/impl/DecisionTree/MorpheusOracle_Loader_Impl.hpp +++ b/src/impl/DecisionTree/MorpheusOracle_Loader_Impl.hpp @@ -155,7 +155,7 @@ void load_text(std::ifstream& stree, Tree& tree, std::vector tokens; std::string line; std::getline(stree, line); - Impl::tokenize(tokens, line); + Oracle::Impl::tokenize(tokens, line); size_t nfeatures, nclasses, nodecount, maxdepth; std::istringstream(tokens[0]) >> nfeatures; diff --git a/src/impl/MorpheusOracle_Loader_Utils.cpp b/src/impl/MorpheusOracle_Loader_Utils.cpp new file mode 100644 index 0000000..6452f83 --- /dev/null +++ b/src/impl/MorpheusOracle_Loader_Utils.cpp @@ -0,0 +1,26 @@ +#include + +namespace Morpheus { +namespace Oracle { +namespace Impl { + +void tokenize(std::vector& tokens, const std::string& str, + const std::string& delimiters) { + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + +} // namespace Impl +} // namespace Oracle +} // namespace Morpheus \ No newline at end of file diff --git a/src/impl/MorpheusOracle_Loader_Utils.hpp b/src/impl/MorpheusOracle_Loader_Utils.hpp index 2d0194f..1129875 100644 --- a/src/impl/MorpheusOracle_Loader_Utils.hpp +++ b/src/impl/MorpheusOracle_Loader_Utils.hpp @@ -29,27 +29,14 @@ #include #include #include +#include namespace Morpheus { namespace Oracle { namespace Impl { void tokenize(std::vector& tokens, const std::string& str, - const std::string& delimiters = "\n\r\t ") { - // Skip delimiters at beginning. - std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); - // Find first "non-delimiter". - std::string::size_type pos = str.find_first_of(delimiters, lastPos); - - while (std::string::npos != pos || std::string::npos != lastPos) { - // Found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - // Skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - // Find next "non-delimiter" - pos = str.find_first_of(delimiters, lastPos); - } -} + const std::string& delimiters = "\n\r\t "); template void skip_comment(Stream& input, const std::string delimiter = "#") { @@ -76,7 +63,7 @@ void load_array(std::vector& vec, Stream& input, std::getline(input, line); std::vector tokens; - Impl::tokenize(tokens, line); + Oracle::Impl::tokenize(tokens, line); if (tokens.size() != vec.size()) { throw std::runtime_error("Entries (" + std::to_string(tokens.size()) + @@ -102,7 +89,7 @@ void load_array(Vector& vec, Stream& input, bool skip_comments = true, std::getline(input, line); std::vector tokens; - Impl::tokenize(tokens, line); + Oracle::Impl::tokenize(tokens, line); if (tokens.size() != vec.size()) { throw std::runtime_error("Entries (" + std::to_string(tokens.size()) + @@ -131,7 +118,7 @@ void load_2d_array(Matrix& mat, size_t dim1, size_t dim2, Stream& input, std::getline(input, line); std::vector tokens; - Impl::tokenize(tokens, line); + Oracle::Impl::tokenize(tokens, line); if (tokens.size() != dim2) { throw std::runtime_error("Entries (" + std::to_string(tokens.size()) + diff --git a/src/impl/RandomForest/MorpheusOracle_Loader_Impl.hpp b/src/impl/RandomForest/MorpheusOracle_Loader_Impl.hpp index f127d01..dd74e1a 100644 --- a/src/impl/RandomForest/MorpheusOracle_Loader_Impl.hpp +++ b/src/impl/RandomForest/MorpheusOracle_Loader_Impl.hpp @@ -120,7 +120,7 @@ void load_text(std::ifstream& sforest, Tree& forest, std::vector tokens; std::string line; std::getline(sforest, line); - Impl::tokenize(tokens, line); + Oracle::Impl::tokenize(tokens, line); size_t nfeatures, nclasses, noutputs, nestimators; std::istringstream(tokens[0]) >> nfeatures; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bf295b9..32a0554 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,71 +2,23 @@ message(STATUS "Morpheus-Oracle Tests are enabled") morpheusoracle_include_directories(${CMAKE_CURRENT_BINARY_DIR}) morpheusoracle_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -morpheusoracle_include_directories( - ${MorpheusOracle_SOURCE_DIR}/tests/category_files) -foreach(Tag Serial;OpenMP;Cuda;HIP) - string(TOUPPER ${Tag} DEVICE) - string(TOLOWER ${Tag} dir) - global_set(${Tag}_SOURCES) +global_set(TEST_SOURCES) - if(Morpheus_ENABLE_${DEVICE}) - set(testdir ${CMAKE_CURRENT_BINARY_DIR}/${dir}) - file(MAKE_DIRECTORY ${testdir}) +set(testdir ${CMAKE_CURRENT_BINARY_DIR}) +file(MAKE_DIRECTORY ${testdir}) - foreach(Name RunFirstTuner TuneRunFirst TypeTraits) - set(file ${testdir}/Test_${Tag}_${Name}.cpp) - # Write to a temporary intermediate file and call configure_file to avoid - # updating timestamps triggering unnecessary rebuilds on subsequent cmake - # runs. - file(WRITE ${testdir}/dummy.cpp "#include \n" - "#include \n") - configure_file(${testdir}/dummy.cpp ${file}) - global_append(${Tag}_SOURCES ${file}) - endforeach() - endif() +foreach(Name RunFirstTuner TuneRunFirst TypeTraits) + set(file ${testdir}/Test_${Name}.cpp) + # Write to a temporary intermediate file and call configure_file to avoid + # updating timestamps triggering unnecessary rebuilds on subsequent cmake + # runs. + file(WRITE ${testdir}/dummy.cpp "#include \n") + configure_file(${testdir}/dummy.cpp ${file}) + global_append(TEST_SOURCES ${file}) endforeach() -set(ALL_SOURCES) +morpheusoracle_add_executable_and_test( + UnitTest SOURCES TestMain.cpp ${TEST_SOURCES} TESTONLYLIBS + morpheusoracle_gtest) -if(Morpheus_ENABLE_SERIAL) - if(MorpheusOracle_ENABLE_INDIVIDUAL_TESTS) - morpheusoracle_add_executable_and_test( - UnitTest_Serial SOURCES TestMain.cpp ${Serial_SOURCES} TESTONLYLIBS - morpheusoracle_gtest) - endif() - list(APPEND ALL_SOURCES ${Serial_SOURCES}) -endif() - -if(Morpheus_ENABLE_OPENMP) - if(MorpheusOracle_ENABLE_INDIVIDUAL_TESTS) - morpheusoracle_add_executable_and_test( - UnitTest_OpenMP SOURCES TestMain.cpp ${OpenMP_SOURCES} TESTONLYLIBS - morpheusoracle_gtest) - endif() - list(APPEND ALL_SOURCES ${OpenMP_SOURCES}) -endif() - -if(Morpheus_ENABLE_CUDA) - if(MorpheusOracle_ENABLE_INDIVIDUAL_TESTS) - morpheusoracle_add_executable_and_test( - UnitTest_Cuda SOURCES TestMain.cpp ${Cuda_SOURCES} TESTONLYLIBS - morpheusoracle_gtest) - endif() - list(APPEND ALL_SOURCES ${Cuda_SOURCES}) -endif() - -if(Morpheus_ENABLE_HIP) - if(MorpheusOracle_ENABLE_INDIVIDUAL_TESTS) - morpheusoracle_add_executable_and_test( - UnitTest_HIP SOURCES TestMain.cpp ${HIP_SOURCES} TESTONLYLIBS - morpheusoracle_gtest) - endif() - list(APPEND ALL_SOURCES ${HIP_SOURCES}) -endif() - -if(NOT MorpheusOracle_ENABLE_INDIVIDUAL_TESTS) - morpheusoracle_add_executable_and_test( - UnitTest SOURCES TestMain.cpp ${ALL_SOURCES} TESTONLYLIBS - morpheusoracle_gtest) -endif() diff --git a/tests/TestMain.cpp b/tests/TestMain.cpp index 8e344ed..cff8186 100644 --- a/tests/TestMain.cpp +++ b/tests/TestMain.cpp @@ -30,9 +30,7 @@ int main(int argc, char *argv[]) { int result; ::testing::InitGoogleTest(&argc, argv); - Morpheus::initialize(argc, argv); - { result = RUN_ALL_TESTS(); } - Morpheus::finalize(); + result = RUN_ALL_TESTS(); return result; } \ No newline at end of file diff --git a/tests/Test_RunFirstTuner.hpp b/tests/Test_RunFirstTuner.hpp index 7f967cc..16ae93c 100644 --- a/tests/Test_RunFirstTuner.hpp +++ b/tests/Test_RunFirstTuner.hpp @@ -25,84 +25,42 @@ #define TEST_ORACLE_TEST_RUNFIRSTTUNER_HPP #include - -TEST(RunFirstTunerTest, DefaultConstruction) { - const int reps = 10; - const int nfmts = Morpheus::NFORMATS; - const bool verbose = false; - - Morpheus::Oracle::RunFirstTuner tuner; - - // Check timings shape - EXPECT_EQ(tuner.timings().nrows(), nfmts); - EXPECT_EQ(tuner.timings().ncols(), reps); - // Check timings values - for (size_t i = 0; i < tuner.timings().nrows(); i++) { - for (size_t j = 0; j < tuner.timings().ncols(); j++) { - EXPECT_EQ(tuner.timings()(i, j), 0); - } - } - - // Check maximum timings shape - EXPECT_EQ(tuner.max_timings().size(), nfmts); - // Check minimum timings shape - EXPECT_EQ(tuner.min_timings().size(), nfmts); - // Check average timings shape - EXPECT_EQ(tuner.avg_timings().size(), nfmts); - // Check values of each timing vector - for (auto i = 0; i < nfmts; i++) { - EXPECT_EQ(tuner.max_timings()(i), 0); - EXPECT_EQ(tuner.min_timings()(i), 0); - EXPECT_EQ(tuner.avg_timings()(i), 0); - } - - EXPECT_EQ(tuner.format_id(), - Morpheus::Oracle::RunFirstTuner::INVALID_FORMAT_STATE); - - EXPECT_EQ(tuner.format_count(), 0); - EXPECT_EQ(tuner.nformats(), nfmts); - - EXPECT_EQ(tuner.repetition_count(), 0); - EXPECT_EQ(tuner.repetition_limit(), reps); - - EXPECT_EQ(tuner.is_verbose(), verbose); -} +#include TEST(RunFirstTunerTest, Construction) { const int reps = 5; - const int nfmts = Morpheus::NFORMATS; + const int nstates = 10; const bool verbose = true; + int invalid_state = Morpheus::Oracle::RunFirstTuner::INVALID_STATE; - Morpheus::Oracle::RunFirstTuner tuner(reps, verbose); + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps, verbose); // Check timings shape - EXPECT_EQ(tuner.timings().nrows(), nfmts); - EXPECT_EQ(tuner.timings().ncols(), reps); + EXPECT_EQ(tuner.timings().size(), nstates * reps); // Check timings values - for (size_t i = 0; i < tuner.timings().nrows(); i++) { - for (size_t j = 0; j < tuner.timings().ncols(); j++) { - EXPECT_EQ(tuner.timings()(i, j), 0); + for (size_t i = 0; i < nstates; i++) { + for (size_t j = 0; j < reps; j++) { + EXPECT_EQ(tuner.timings()[i * reps + j], 0); } } // Check maximum timings shape - EXPECT_EQ(tuner.max_timings().size(), nfmts); + EXPECT_EQ(tuner.max_timings().size(), nstates); // Check minimum timings shape - EXPECT_EQ(tuner.min_timings().size(), nfmts); + EXPECT_EQ(tuner.min_timings().size(), nstates); // Check average timings shape - EXPECT_EQ(tuner.avg_timings().size(), nfmts); + EXPECT_EQ(tuner.avg_timings().size(), nstates); // Check values of each timing vector - for (auto i = 0; i < nfmts; i++) { - EXPECT_EQ(tuner.max_timings()(i), 0); - EXPECT_EQ(tuner.min_timings()(i), 0); - EXPECT_EQ(tuner.avg_timings()(i), 0); + for (auto i = 0; i < nstates; i++) { + EXPECT_EQ(tuner.max_timings()[i], 0); + EXPECT_EQ(tuner.min_timings()[i], 0); + EXPECT_EQ(tuner.avg_timings()[i], 0); } - EXPECT_EQ(tuner.format_id(), - Morpheus::Oracle::RunFirstTuner::INVALID_FORMAT_STATE); + EXPECT_EQ(tuner.state_id(), invalid_state); - EXPECT_EQ(tuner.format_count(), 0); - EXPECT_EQ(tuner.nformats(), nfmts); + EXPECT_EQ(tuner.state_count(), 0); + EXPECT_EQ(tuner.nstates(), nstates); EXPECT_EQ(tuner.repetition_count(), 0); EXPECT_EQ(tuner.repetition_limit(), reps); @@ -111,56 +69,67 @@ TEST(RunFirstTunerTest, Construction) { } TEST(RunFirstTunerTest, Step) { - Morpheus::Oracle::RunFirstTuner tuner; + const int reps = 5; + const int nstates = 3; + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps); - for (int fmt = 0; fmt < tuner.nformats(); fmt++) { + for (int state = 0; state < tuner.nstates(); state++) { for (size_t rep = 0; rep < tuner.repetition_limit(); rep++) { - EXPECT_EQ(tuner.format_count(), fmt); + EXPECT_EQ(tuner.state_count(), state); EXPECT_EQ(tuner.repetition_count(), rep); ++tuner; } } - EXPECT_EQ(tuner.format_count(), tuner.nformats()); + EXPECT_EQ(tuner.state_count(), tuner.nstates()); EXPECT_EQ(tuner.repetition_count(), 0); } TEST(RunFirstTunerTest, Finish) { - Morpheus::Oracle::RunFirstTuner tuner; + const int reps = 5; + const int nstates = 3; + int invalid_state = Morpheus::Oracle::RunFirstTuner::INVALID_STATE; + + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps); - for (int fmt = 0; fmt < tuner.nformats(); fmt++) { + for (int state = 0; state < tuner.nstates(); state++) { for (size_t rep = 0; rep < tuner.repetition_limit(); rep++) { EXPECT_FALSE(tuner.finished()); ++tuner; } } EXPECT_TRUE(tuner.finished()); - EXPECT_NE(tuner.format_id(), - Morpheus::Oracle::RunFirstTuner::INVALID_FORMAT_STATE); + EXPECT_NE(tuner.state_id(), invalid_state); } TEST(RunFirstTunerTest, RegisterRun) { - Morpheus::Oracle::RunFirstTuner tuner; + const int reps = 5; + const int nstates = 3; + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps); - for (int fmt = 0; fmt < tuner.nformats(); fmt++) { + for (int state = 0; state < tuner.nstates(); state++) { for (size_t rep = 0; rep < tuner.repetition_limit(); rep++) { - double rt = tuner.repetition_count() + tuner.format_count(); + double rt = tuner.repetition_count() + tuner.state_count(); tuner.register_run(rt); ++tuner; } } - for (int fmt = 0; fmt < tuner.nformats(); fmt++) { + for (int state = 0; state < tuner.nstates(); state++) { for (size_t rep = 0; rep < tuner.repetition_limit(); rep++) { - EXPECT_EQ(tuner.timings()(fmt, rep), rep + fmt); + EXPECT_EQ(tuner.timings()[state * tuner.repetition_limit() + rep], + rep + state); } } } TEST(RunFirstTunerTest, FinishStats) { - Morpheus::Oracle::RunFirstTuner tuner; + const int reps = 5; + const int nstates = 3; + + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps); while (!tuner.finished()) { - double rt = tuner.repetition_count() + tuner.format_count(); + double rt = tuner.repetition_count() + tuner.state_count(); tuner.register_run(rt); ++tuner; } @@ -171,24 +140,26 @@ TEST(RunFirstTunerTest, FinishStats) { repsum += i; } - for (int fmt = 0; fmt < tuner.nformats(); fmt++) { - EXPECT_EQ(tuner.min_timings()(fmt), fmt); - EXPECT_EQ(tuner.max_timings()(fmt), (tuner.repetition_limit() - 1) + fmt); - EXPECT_EQ( - tuner.avg_timings()(fmt), - (repsum + (tuner.repetition_limit() * fmt)) / tuner.repetition_limit()); + for (int state = 0; state < tuner.nstates(); state++) { + EXPECT_EQ(tuner.min_timings()[state], state); + EXPECT_EQ(tuner.max_timings()[state], + (tuner.repetition_limit() - 1) + state); + EXPECT_EQ(tuner.avg_timings()[state], + (repsum + (tuner.repetition_limit() * state)) / + tuner.repetition_limit()); } } TEST(RunFirstTunerTest, Reset) { const int reps = 5; - const int nfmts = Morpheus::NFORMATS; + const int nstates = 10; const bool verbose = false; + int invalid_state = Morpheus::Oracle::RunFirstTuner::INVALID_STATE; - Morpheus::Oracle::RunFirstTuner tuner(reps, verbose); + Morpheus::Oracle::RunFirstTuner tuner(nstates, reps, verbose); while (!tuner.finished()) { - double rt = tuner.repetition_count() + tuner.format_count(); + double rt = tuner.repetition_count() + tuner.state_count(); tuner.register_run(rt); ++tuner; } @@ -196,33 +167,31 @@ TEST(RunFirstTunerTest, Reset) { tuner.reset(); // Check timings shape - EXPECT_EQ(tuner.timings().nrows(), nfmts); - EXPECT_EQ(tuner.timings().ncols(), reps); + EXPECT_EQ(tuner.timings().size(), nstates * reps); // Check timings values - for (size_t i = 0; i < tuner.timings().nrows(); i++) { - for (size_t j = 0; j < tuner.timings().ncols(); j++) { - EXPECT_EQ(tuner.timings()(i, j), 0); + for (size_t i = 0; i < nstates; i++) { + for (size_t j = 0; j < reps; j++) { + EXPECT_EQ(tuner.timings()[i * reps + j], 0); } } // Check maximum timings shape - EXPECT_EQ(tuner.max_timings().size(), nfmts); + EXPECT_EQ(tuner.max_timings().size(), nstates); // Check minimum timings shape - EXPECT_EQ(tuner.min_timings().size(), nfmts); + EXPECT_EQ(tuner.min_timings().size(), nstates); // Check average timings shape - EXPECT_EQ(tuner.avg_timings().size(), nfmts); + EXPECT_EQ(tuner.avg_timings().size(), nstates); // Check values of each timing vector - for (auto i = 0; i < nfmts; i++) { - EXPECT_EQ(tuner.max_timings()(i), -std::numeric_limits::max()); - EXPECT_EQ(tuner.min_timings()(i), -std::numeric_limits::max()); - EXPECT_EQ(tuner.avg_timings()(i), -std::numeric_limits::max()); + for (auto i = 0; i < nstates; i++) { + EXPECT_EQ(tuner.max_timings()[i], -std::numeric_limits::max()); + EXPECT_EQ(tuner.min_timings()[i], -std::numeric_limits::max()); + EXPECT_EQ(tuner.avg_timings()[i], -std::numeric_limits::max()); } - EXPECT_EQ(tuner.format_id(), - Morpheus::Oracle::RunFirstTuner::INVALID_FORMAT_STATE); + EXPECT_EQ(tuner.state_id(), invalid_state); - EXPECT_EQ(tuner.format_count(), 0); - EXPECT_EQ(tuner.nformats(), nfmts); + EXPECT_EQ(tuner.state_count(), 0); + EXPECT_EQ(tuner.nstates(), nstates); EXPECT_EQ(tuner.repetition_count(), 0); EXPECT_EQ(tuner.repetition_limit(), reps); diff --git a/tests/Test_TuneRunFirst.hpp b/tests/Test_TuneRunFirst.hpp index 1bd2c27..fe49481 100644 --- a/tests/Test_TuneRunFirst.hpp +++ b/tests/Test_TuneRunFirst.hpp @@ -25,63 +25,76 @@ #define TEST_ORACLE_TEST_TUNE_RUNFIRST_HPP #include +#include + +#include TEST(TuneMultiply, RunFirstTuner) { - using backend = typename TEST_CUSTOM_EXECSPACE::backend; - using DynamicMatrix = Morpheus::DynamicMatrix; - using Vector = Morpheus::DenseVector; - using CsrMatrix = Morpheus::CsrMatrix; - - Morpheus::Oracle::RunFirstTuner tuner(10, false); - DynamicMatrix A; - typename CsrMatrix::HostMirror Acsr_h(4, 3, 6); - - // initialize matrix entries - Acsr_h.row_offsets(0) = 0; - Acsr_h.row_offsets(1) = 2; - Acsr_h.row_offsets(2) = 2; - Acsr_h.row_offsets(3) = 3; - Acsr_h.row_offsets(4) = 6; - - Acsr_h.column_indices(0) = 0; - Acsr_h.values(0) = 10; - Acsr_h.column_indices(1) = 2; - Acsr_h.values(1) = 20; - Acsr_h.column_indices(2) = 2; - Acsr_h.values(2) = 30; - Acsr_h.column_indices(3) = 0; - Acsr_h.values(3) = 40; - Acsr_h.column_indices(4) = 1; - Acsr_h.values(4) = 50; - Acsr_h.column_indices(5) = 2; - Acsr_h.values(5) = 60; - - CsrMatrix Acsr(4, 3, 6); - Morpheus::copy(Acsr_h, Acsr); - - A = Acsr; - - Morpheus::Oracle::RunFirstMultiplyFunctor f(A.nrows(), - A.ncols()); - Morpheus::Oracle::tune(A, f, tuner); + using Data = std::variant; + + struct RunFirstFunctor + : public Morpheus::Oracle::RunFirstFunctorBase { + RunFirstFunctor() {} + + auto clone(const Data& data) { + auto mirror = data; + + return mirror; + } + + auto clone_host(Data& dev) { + auto mirror_h = dev; + + return mirror_h; + } + + bool state_transition(const Morpheus::Oracle::RunFirstTuner& tuner, + Data& dev, Data& host, int& current_state) { + switch (current_state) { + case 0: host = 0.55f; break; + case 1: host = 2; break; + case 2: host = 6.76; break; + default: host = 6.76; break; + } + dev = host; + current_state = tuner.state_count(); + + return true; + } + + void run(const Data& dev) { + Data res; + std::visit([&](auto&& arg1, auto&& arg2) { arg1 = arg2 * arg2; }, res, + dev); + } + + double postprocess_runtime(double runtime) { return runtime; } + }; + + Morpheus::Oracle::RunFirstTuner tuner(3, 10, false); + RunFirstFunctor f; + + Data input = 1.111; + + Morpheus::Oracle::tune(input, f, tuner); EXPECT_TRUE(tuner.finished()); // Check average timings were recorded for (size_t i = 0; i < tuner.avg_timings().size(); i++) { - EXPECT_GE(tuner.avg_timings()(i), 0.0); + EXPECT_GE(tuner.avg_timings()[i], 0.0); } // Figure out which format was the best on average - double mint = tuner.avg_timings()(0); - int best_format_id = 0; + double mint = tuner.avg_timings()[0]; + int best_state_id = 0; for (size_t i = 0; i < tuner.avg_timings().size(); i++) { - if (tuner.avg_timings()(i) < mint) { - mint = tuner.avg_timings()(i); - best_format_id = i; + if (tuner.avg_timings()[i] < mint) { + mint = tuner.avg_timings()[i]; + best_state_id = i; } } // Check if the tuner also got the same format index - EXPECT_EQ(best_format_id, tuner.format_id()); + EXPECT_EQ(best_state_id, tuner.state_id()); } #endif // TEST_ORACLE_TEST_TUNE_RUNFIRST_HPP \ No newline at end of file diff --git a/tests/Test_TypeTraits.hpp b/tests/Test_TypeTraits.hpp index fa6ca93..8859206 100644 --- a/tests/Test_TypeTraits.hpp +++ b/tests/Test_TypeTraits.hpp @@ -25,6 +25,7 @@ #define TEST_ORACLE_TEST_TYPETRAITS_HPP #include +#include TEST(TypeTraits, IsRunFirstTuner) { int res = Morpheus::Oracle::is_run_first_tuner::value; @@ -48,4 +49,223 @@ TEST(TypeTraits, IsRunFirstTuner) { EXPECT_EQ(res, 1); } +TEST(TypeTraits, IsDecisionTree) { + int res = Morpheus::Oracle::is_decision_tree::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_decision_tree::value; + EXPECT_EQ(res, 0); + + res = + Morpheus::Oracle::is_decision_tree::value; + EXPECT_EQ(res, 1); + + class NewTree : public Morpheus::Oracle::DecisionTree {}; + res = Morpheus::Oracle::is_decision_tree::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_decision_tree_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_decision_tree_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_decision_tree_v; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_decision_tree_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsRandomForest) { + int res = Morpheus::Oracle::is_random_forest::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_random_forest::value; + EXPECT_EQ(res, 0); + + res = + Morpheus::Oracle::is_random_forest::value; + EXPECT_EQ(res, 1); + + class NewForest : public Morpheus::Oracle::RandomForest {}; + res = Morpheus::Oracle::is_random_forest::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_random_forest_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_random_forest_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_random_forest_v; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_random_forest_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsDecisionTreeTuner) { + int res = Morpheus::Oracle::is_decision_tree_tuner::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_decision_tree_tuner::value; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_decision_tree_tuner< + Morpheus::Oracle::DecisionTreeTuner>::value; + EXPECT_EQ(res, 1); + + class NewTreeTuner : public Morpheus::Oracle::DecisionTreeTuner {}; + res = Morpheus::Oracle::is_decision_tree_tuner::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_decision_tree_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_decision_tree_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_decision_tree_tuner_v< + Morpheus::Oracle::DecisionTreeTuner>; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_decision_tree_tuner_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsRandomForestTuner) { + int res = Morpheus::Oracle::is_random_forest_tuner::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_random_forest_tuner::value; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_random_forest_tuner< + Morpheus::Oracle::RandomForestTuner>::value; + EXPECT_EQ(res, 1); + + class NewForestTuner : public Morpheus::Oracle::RandomForestTuner {}; + res = Morpheus::Oracle::is_random_forest_tuner::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_random_forest_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_random_forest_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_random_forest_tuner_v< + Morpheus::Oracle::RandomForestTuner>; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_random_forest_tuner_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsMLTuner) { + int res = Morpheus::Oracle::is_ml_tuner::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_ml_tuner::value; + EXPECT_EQ(res, 0); + + res = + Morpheus::Oracle::is_ml_tuner::value; + EXPECT_EQ(res, 1); + + res = + Morpheus::Oracle::is_ml_tuner::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_ml_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_ml_tuner_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_ml_tuner_v; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_ml_tuner_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsMLFunctor) { + int res = Morpheus::Oracle::is_ml_functor::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_ml_functor::value; + EXPECT_EQ(res, 0); + + struct NewMLFunctor : public Morpheus::Oracle::MLFunctorBase { + NewMLFunctor() {} + + void extract_features(const std::vector&) { return; } + + std::vector& features() { return _features; } + + void inference(Morpheus::Oracle::RandomForestTuner&) { return; } + + private: + std::vector _features; + }; + + res = Morpheus::Oracle::is_ml_functor::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_ml_functor_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_ml_functor_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_ml_functor_v; + EXPECT_EQ(res, 1); +} + +TEST(TypeTraits, IsRunFirstFunctor) { + int res = Morpheus::Oracle::is_runfirst_functor::value; + EXPECT_EQ(res, 0); + + struct A {}; + res = Morpheus::Oracle::is_runfirst_functor::value; + EXPECT_EQ(res, 0); + + struct NewRunFirstFunctor + : public Morpheus::Oracle::RunFirstFunctorBase { + auto clone(const std::vector& data) { return data; } + + auto clone_host(const std::vector& data) { return data; } + + bool state_transition(const Morpheus::Oracle::RunFirstTuner&, + std::vector& dev, std::vector&, + int&) { + return true; + } + + void run(const std::vector&) { return; } + + double postprocess_runtime(double runtime) { return runtime; } + }; + + res = Morpheus::Oracle::is_runfirst_functor::value; + EXPECT_EQ(res, 1); + + res = Morpheus::Oracle::is_runfirst_functor_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_runfirst_functor_v; + EXPECT_EQ(res, 0); + + res = Morpheus::Oracle::is_runfirst_functor_v; + EXPECT_EQ(res, 1); +} + #endif // TEST_ORACLE_TEST_TYPETRAITS_HPP \ No newline at end of file diff --git a/tests/category_files/TestCuda_Category.hpp b/tests/category_files/TestCuda_Category.hpp deleted file mode 100644 index a8241ee..0000000 --- a/tests/category_files/TestCuda_Category.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * TestCuda_Category.hpp - * - * EPCC, The University of Edinburgh - * - * (c) 2021 The University of Edinburgh - * - * Contributing Authors: - * Christodoulos Stylianou (c.stylianou@ed.ac.uk) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MORPHEUS_ORACLE_TEST_CUDA_HPP -#define MORPHEUS_ORACLE_TEST_CUDA_HPP - -#include - -#define TEST_CATEGORY cuda -#define TEST_CATEGORY_NUMBER 5 -#define TEST_EXECSPACE Kokkos::Cuda -#define TEST_CUSTOM_EXECSPACE Morpheus::Custom::Cuda -#define TEST_GENERIC_EXECSPACE Morpheus::Generic::Cuda -#define TEST_CATEGORY_FIXTURE(name) cuda_##name - -#endif // MORPHEUS_ORACLE_TEST_CUDA_HPP \ No newline at end of file diff --git a/tests/category_files/TestHIP_Category.hpp b/tests/category_files/TestHIP_Category.hpp deleted file mode 100644 index 9dd7cda..0000000 --- a/tests/category_files/TestHIP_Category.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * TestHIP_Category.hpp - * - * EPCC, The University of Edinburgh - * - * (c) 2021 The University of Edinburgh - * - * Contributing Authors: - * Christodoulos Stylianou (c.stylianou@ed.ac.uk) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MORPHEUS_ORACLE_TEST_HIP_HPP -#define MORPHEUS_ORACLE_TEST_HIP_HPP - -#include - -#define TEST_CATEGORY hip -#define TEST_CATEGORY_NUMBER 7 -#define TEST_EXECSPACE Kokkos::HIP -#define TEST_CUSTOM_EXECSPACE Morpheus::Custom::HIP -#define TEST_GENERIC_EXECSPACE Morpheus::Generic::HIP -#define TEST_CATEGORY_FIXTURE(name) hip_##name - -#endif // MORPHEUS_ORACLE_TEST_HIP_HPP \ No newline at end of file diff --git a/tests/category_files/TestOpenMP_Category.hpp b/tests/category_files/TestOpenMP_Category.hpp deleted file mode 100644 index f650810..0000000 --- a/tests/category_files/TestOpenMP_Category.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * TestOpenMP_Category.hpp - * - * EPCC, The University of Edinburgh - * - * (c) 2021 The University of Edinburgh - * - * Contributing Authors: - * Christodoulos Stylianou (c.stylianou@ed.ac.uk) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MORPHEUS_ORACLE_TEST_OPENMP_HPP -#define MORPHEUS_ORACLE_TEST_OPENMP_HPP - -#include - -#define TEST_CATEGORY openmp -#define TEST_CATEGORY_NUMBER 2 -#define TEST_EXECSPACE Kokkos::OpenMP -#define TEST_CUSTOM_EXECSPACE Morpheus::Custom::OpenMP -#define TEST_GENERIC_EXECSPACE Morpheus::Generic::OpenMP -#define TEST_CATEGORY_FIXTURE(name) openmp_##name - -#endif // MORPHEUS_ORACLE_TEST_OPENMP_HPP \ No newline at end of file diff --git a/tests/category_files/TestSerial_Category.hpp b/tests/category_files/TestSerial_Category.hpp deleted file mode 100644 index 19ac674..0000000 --- a/tests/category_files/TestSerial_Category.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * TestSerial_Category.hpp - * - * EPCC, The University of Edinburgh - * - * (c) 2021 The University of Edinburgh - * - * Contributing Authors: - * Christodoulos Stylianou (c.stylianou@ed.ac.uk) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MORPHEUS_ORACLE_TEST_SERIAL_HPP -#define MORPHEUS_ORACLE_TEST_SERIAL_HPP - -#include - -#define TEST_CATEGORY serial -#define TEST_CATEGORY_NUMBER 0 -#define TEST_EXECSPACE Kokkos::Serial -#define TEST_CUSTOM_EXECSPACE Morpheus::Custom::Serial -#define TEST_GENERIC_EXECSPACE Morpheus::Generic::Serial -#define TEST_CATEGORY_FIXTURE(name) serial_##name - -#endif // MORPHEUS_ORACLE_TEST_SERIAL_HPP \ No newline at end of file