From 0add5ad91c3fa113c4d25c09b3e66486eacecad1 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Fri, 13 May 2022 09:57:07 -0400 Subject: [PATCH] latest from coda-oss --- .../coda-oss/modules/c++/include/TestCase.h | 63 ++++++++++++++----- .../c++/mt/include/mt/GenerationThreadPool.h | 31 +++++++++ 2 files changed, 77 insertions(+), 17 deletions(-) diff --git a/externals/coda-oss/modules/c++/include/TestCase.h b/externals/coda-oss/modules/c++/include/TestCase.h index 659a91cb9..4d7461e0e 100644 --- a/externals/coda-oss/modules/c++/include/TestCase.h +++ b/externals/coda-oss/modules/c++/include/TestCase.h @@ -71,17 +71,35 @@ template inline void diePrintf_eq(const std::string& testName, const char* file, const char* func, int line, const TX1& X1, const TX2& X2) { - diePrintf("%s (%s,%s,%d): FAILED: Recv'd %s, Expected %s\n", testName, file, func, line, X1, X2); + diePrintf("%s (%s,%s,%d): FAILED: Recv'd %s, Expected %s\n", testName, file, func, line, X1, X2); } #define CODA_OSS_test_diePrintf_eq_(X1, X2) test::diePrintf_eq(testName, __FILE__, SYS_FUNC, __LINE__, X1, X2) +template +inline void diePrintf_eq_msg(const std::string& testName, const TMsg& msg, const char* file, int line, + const TX1& X1, const TX2& X2) +{ + sys::diePrintf("%s (%s,%d): FAILED (%s): Recv'd %s, Expected %s\n", testName.c_str(), file, line, (msg).c_str(), + str::toString((X1)).c_str(), str::toString((X2)).c_str()); +} +#define CODA_OSS_test_diePrintf_eq_msg_(msg, X1, X2) test::diePrintf_eq_msg(testName, msg, __FILE__, __LINE__, X1, X2) + template inline void diePrintf_ne(const std::string& testName, const char* file, const char* func, int line, const TX1& X1, const TX2& X2) { diePrintf("%s (%s,%s,%d): FAILED: Recv'd %s should not equal %s\n", testName, file, func, line, X1, X2); } -#define CODA_OSS_test_diePrintf_ne_(X1, X2) test::diePrintf_ne(testName, __FILE__, SYS_FUNC, __LINE__, X1, X2) +#define CODA_OSS_test_diePrintf_not_eq_(X1, X2) test::diePrintf_ne(testName, __FILE__, SYS_FUNC, __LINE__, X1, X2) + +template +inline void diePrintf_ne_msg(const std::string& testName, const TMsg& msg, const char* file, int line, + const TX1& X1, const TX2& X2) +{ + sys::diePrintf("%s (%s,%d): FAILED (%s): Recv'd %s should not equal %s\n", testName.c_str(), file, line, (msg).c_str(), + str::toString((X1)).c_str(), str::toString((X2)).c_str()); +} +#define CODA_OSS_test_diePrintf_not_eq_msg_(msg, X1, X2) test::diePrintf_ne_msg(testName, msg, __FILE__, __LINE__, X1, X2) template inline void check(TFunc f, const std::string& testName) @@ -118,6 +136,14 @@ inline void assert_null(const TX& X, const std::string& testName, const char* f diePrintf("%s (%s,%s,%d): FAILED: Value should be NULL\n", testName, file, func, line); } } +template +inline void assert_not_null(const TX& X, const std::string& testName, const char* file, const char* func, int line) +{ + if ((X == nullptr) || (!(X != nullptr))) + { + diePrintf("%s (%s,%s,%d): FAILED: Value should *not* be NULL\n", testName, file, func, line); + } +} template inline void test_assert_false(const TX& X, const std::string& testName, const char* file, const char* func, int line) @@ -146,24 +172,21 @@ inline void test_assert_true(const TX& X, const std::string& testName, const ch // is std::vector::size() (size_t) compared to a literal 1 which is an "int" not "size_t". template -inline void assert_almost_eq_eps(TX1&& X1, TX2&& X2, TEPS&& EPS, +inline void assert_almost_eq_eps(const TX1& X1, const TX2& X2, const TEPS& EPS, const std::string& testName, const char* file, const char* func, int line) { const auto abs_difference = std::abs(X1 - X2); if (abs_difference > EPS || IS_NAN(abs_difference)) { - diePrintf("%s (%s,%d): FAILED: Recv'd %s, Expected %s\n", testName, file, func, line, X1, X2); + diePrintf("%s (%s,%s,%d): FAILED: Recv'd %s, Expected %s\n", testName, file, func, line, X1, X2); } } template -inline void assert_almost_eq(TX1&& X1, TX2&& X2, +inline void assert_almost_eq(const TX1& X1, const TX2& X2, const std::string& testName, const char* file, const char* func, int line) { - const auto abs_difference = std::abs(X1 - X2); - if (abs_difference > std::numeric_limits::epsilon() || IS_NAN(abs_difference)) - { - diePrintf("%s (%s,%s,%d): FAILED: Recv'd %s, Expected %s\n", testName, file, func, line, X1, X2); - } + const auto eps = std::numeric_limits::epsilon(); + assert_almost_eq_eps(X1, X2, eps, testName, file, func, line); } template @@ -244,6 +267,7 @@ inline int main(TFunc f) #define TEST_CHECK(X) test::check([&](const std::string& testName) { X(testName); }, #X) #define TEST_ASSERT(X) test::assert_(X, testName, __FILE__, SYS_FUNC, __LINE__) #define TEST_ASSERT_NULL(X) test::assert_null(X, testName, __FILE__, SYS_FUNC, __LINE__) +#define TEST_ASSERT_NOT_NULL(X) test::assert_not_null(X, testName, __FILE__, SYS_FUNC, __LINE__) #define TEST_ASSERT_FALSE(X) test::test_assert_false(X, testName, __FILE__, SYS_FUNC, __LINE__) #define TEST_ASSERT_TRUE(X) test::test_assert_true(X, testName, __FILE__, SYS_FUNC, __LINE__) #define TEST_ASSERT_ALMOST_EQ_EPS(X1, X2, EPS) test::assert_almost_eq_eps(X1, X2, EPS, testName, __FILE__, SYS_FUNC, __LINE__) @@ -255,6 +279,7 @@ inline int main(TFunc f) "%s (%s,%s,%d): FAILED: Should have thrown exception: " # Y , testName, __FILE__, SYS_FUNC, __LINE__) # define TEST_CASE(X) void X(std::string testName) #define TEST_MAIN(X) int main() { return test::main([&](){X;}); } +#define TEST_MAIN_ARGS(X) int main(int argc, char* argv[]) { return test::main([&](){X;}); } /* # define TEST_CHECK(X) try{ X(std::string(#X)); std::cerr << #X << ": PASSED" << std::endl; } \ catch(const except::Throwable& ex) { die_printf("%s: FAILED: Exception thrown: %s\n", std::string(#X).c_str(), ex.toString().c_str()); } \ @@ -264,14 +289,18 @@ inline int main(TFunc f) # define TEST_ASSERT_FALSE(X) if ((X)) { die_printf("%s (%s,%s,%d): FAILED: Value should evaluate to false\n", testName.c_str(), __FILE__, SYS_FUNC, __LINE__); } # define TEST_ASSERT_TRUE(X) if (!(X)) { die_printf("%s (%s,%s,%d): FAILED: Value should evaluate to true\n", testName.c_str(), __FILE__, SYS_FUNC, __LINE__); } */ -#define CODA_OSS_test_eq_(X1, X2) (((X1) == (X2)) && ((X2) == (X1))) // X1 == X2 means X2 == X1 -#define CODA_OSS_test_ne_(X1, X2) (((X1) != (X2)) && ((X2) != (X1))) // X1 != X2 means X2 != X1 -#define CODA_OSS_test_ne(X1, X2) (CODA_OSS_test_ne_(X1, X2) && !CODA_OSS_test_eq_(X1, X2)) +//#define CODA_OSS_test_eq_(X1, X2) (((X1) == (X2)) && ((X2) == (X1))) // X1 == X2 means X2 == X1 +#define CODA_OSS_test_eq_(X1, X2) ((X1) == (X2)) // above breaks CODA :-( +//#define CODA_OSS_test_ne_(X1, X2) (((X1) != (X2)) && ((X2) != (X1))) // X1 != X2 means X2 != X1 +#define CODA_OSS_test_ne_(X1, X2) ((X1) != (X2)) // above breaks CODA :-( +//#define CODA_OSS_test_ne(X1, X2) (CODA_OSS_test_ne_(X1, X2) && !CODA_OSS_test_eq_(X1, X2)) +#define CODA_OSS_test_ne(X1, X2) CODA_OSS_test_ne_(X1, X2) // above breaks CODA :-( #define TEST_ASSERT_EQ(X1, X2) if (CODA_OSS_test_ne((X1), (X2))) { CODA_OSS_test_diePrintf_eq_(X1, X2); } -#define TEST_ASSERT_EQ_MSG(msg, X1, X2) if (CODA_OSS_test_ne((X1), (X2))) { die_printf("%s (%s,%d): FAILED (%s): Recv'd %s, Expected %s\n", testName.c_str(), __FILE__, __LINE__, (msg).c_str(), str::toString((X1)).c_str(), str::toString((X2)).c_str()); } -#define CODA_OSS_test_eq(X1, X2) (CODA_OSS_test_eq_(X1, X2) && !CODA_OSS_test_ne_(X1, X2)) -#define TEST_ASSERT_NOT_EQ(X1, X2) if (CODA_OSS_test_eq((X1), (X2))) { CODA_OSS_test_diePrintf_ne_(X1, X2); } -#define TEST_ASSERT_NOT_EQ_MSG(msg, X1, X2) if (CODA_OSS_test_eq((X1), (X2))) { die_printf("%s (%s,%d): FAILED (%s): Recv'd %s should not equal %s\n", testName.c_str(), __FILE__, __LINE__, (msg).c_str(), str::toString((X1)).c_str(), str::toString((X2)).c_str()); } +#define TEST_ASSERT_EQ_MSG(msg, X1, X2) if (CODA_OSS_test_ne((X1), (X2))) { CODA_OSS_test_diePrintf_eq_msg_(msg, X1, X2); } +//#define CODA_OSS_test_eq(X1, X2) (CODA_OSS_test_eq_(X1, X2) && !CODA_OSS_test_ne_(X1, X2)) +#define CODA_OSS_test_eq(X1, X2) CODA_OSS_test_eq_(X1, X2) // above breaks CODA :-( +#define TEST_ASSERT_NOT_EQ(X1, X2) if (CODA_OSS_test_eq((X1), (X2))) { CODA_OSS_test_diePrintf_not_eq_(X1, X2); } +#define TEST_ASSERT_NOT_EQ_MSG(msg, X1, X2) if (CODA_OSS_test_eq((X1), (X2))) { CODA_OSS_test_diePrintf_not_eq_msg_(msg, X1, X2); } # define TEST_ASSERT_GREATER_EQ(X1, X2) if ((X1) < X2) { test::diePrintf("%s (%s,%s,%d): FAILED: Value should be greater than or equal\n", testName, __FILE__, SYS_FUNC, __LINE__); } # define TEST_ASSERT_GREATER(X1, X2) if ((X1) <= X2) { test::diePrintf("%s (%s,%s,%d): FAILED: Value should be greater than\n", testName, __FILE__, SYS_FUNC, __LINE__); } # define TEST_ASSERT_LESSER_EQ(X1, X2) if ((X1) > X2) { test::diePrintf("%s (%s,%s,%d): FAILED: Value should be less than or equal\n", testName, __FILE__, SYS_FUNC, __LINE__); } diff --git a/externals/coda-oss/modules/c++/mt/include/mt/GenerationThreadPool.h b/externals/coda-oss/modules/c++/mt/include/mt/GenerationThreadPool.h index 0de601b13..c047110aa 100644 --- a/externals/coda-oss/modules/c++/mt/include/mt/GenerationThreadPool.h +++ b/externals/coda-oss/modules/c++/mt/include/mt/GenerationThreadPool.h @@ -32,6 +32,8 @@ #include "mt/BasicThreadPool.h" #include "mt/CPUAffinityInitializer.h" #include "mt/CPUAffinityThreadInitializer.h" +#include "mt/Runnable1D.h" + namespace mt { @@ -105,6 +107,35 @@ namespace mt waitGroup(); } + + /*! + * \brief Runs a given operation on a sequence of numbers in parallel + * + * \param numElements The number of elements to run - op will be called + * with 0 through numElements-1 + * \param op A function-like object taking a parameter of type + * size_t which will be called for each number in the + * given range + */ + template + void run1D(size_t numElements, const OpT& op) + { + std::vector runnables; + const ThreadPlanner planner(numElements, mNumThreads); + + size_t threadNum(0); + size_t startElement(0); + size_t numElementsThisThread(0); + while(planner.getThreadInfo(threadNum++, startElement, numElementsThisThread)) + { + runnables.push_back(new Runnable1D( + startElement, numElementsThisThread, op)); + } + addAndWaitGroup(runnables); + + } + + }; } #endif