From 6a6cd726ac52ad2a9f7e477cdb00ba9b4146d737 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 1 Nov 2024 17:39:13 -0700 Subject: [PATCH 1/4] Fix and enable tensor error tests Signed-off-by: Anna Gringauze --- docker/build/assets.Dockerfile | 4 +-- unittests/utils/Tensor.cpp | 27 ++++++++++---------- unittests/utils/exceptions.h | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 unittests/utils/exceptions.h diff --git a/docker/build/assets.Dockerfile b/docker/build/assets.Dockerfile index 8f14d77342..7a5c71765c 100644 --- a/docker/build/assets.Dockerfile +++ b/docker/build/assets.Dockerfile @@ -271,9 +271,7 @@ RUN if [ ! -x "$(command -v nvidia-smi)" ] || [ -z "$(nvidia-smi | egrep -o "CUD # Removing gcc packages remove the CUDA toolkit since it depends on them source /cuda-quantum/scripts/configure_build.sh install-cudart; \ fi && cd /cuda-quantum && \ - # FIXME: Tensor unit tests for runtime errors throw a different exception. - # Issue: https://github.com/NVIDIA/cuda-quantum/issues/2321 - excludes+=" --exclude-regex ctest-nvqpp|ctest-targettests|Tensor.*Error" && \ + excludes+=" --exclude-regex ctest-nvqpp|ctest-targettests" && \ ctest --output-on-failure --test-dir build $excludes ENV PATH="${PATH}:/usr/local/cuda/bin" diff --git a/unittests/utils/Tensor.cpp b/unittests/utils/Tensor.cpp index 1493cc8709..530af7da4b 100644 --- a/unittests/utils/Tensor.cpp +++ b/unittests/utils/Tensor.cpp @@ -7,6 +7,7 @@ ******************************************************************************/ #include "cudaq/utils/tensor.h" +#include "exceptions.h" #include "gtest/gtest.h" TEST(Tensor, initialization) { @@ -27,8 +28,8 @@ TEST(Tensor, initialization) { TEST(Tensor, initializationError) { { - EXPECT_THROW(cudaq::matrix_2 m1({1., 2., 3., 4., 5.}, {2, 3}), - std::runtime_error); + EXPECT_THROW_MIXED_STDLIB(cudaq::matrix_2 m1({1., 2., 3., 4., 5.}, {2, 3}), + std::runtime_error); } } @@ -61,22 +62,22 @@ TEST(Tensor, accessError) { { cudaq::matrix_2 m0; - EXPECT_THROW((m0[{0}]), std::runtime_error); - EXPECT_THROW((m0[{0, 1}]), std::runtime_error); - EXPECT_THROW((m0[{0, 0, 0}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m0[{0}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m0[{0, 1}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m0[{0, 0, 0}]), std::runtime_error); } { cudaq::matrix_2 m1({1., 0., 0., 1.}); - EXPECT_THROW((m1[{0, 2}]), std::runtime_error); - EXPECT_THROW((m1[{0, 0, 0}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m1[{0, 2}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m1[{0, 0, 0}]), std::runtime_error); } { cudaq::matrix_2 m1({1., 2., 3., 4., 5., 6.}, {2, 3}); - EXPECT_THROW((m1[{0, 3}]), std::runtime_error); - EXPECT_THROW((m1[{2, 1}]), std::runtime_error); - EXPECT_THROW((m1[{0, 2, 3}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m1[{0, 3}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m1[{2, 1}]), std::runtime_error); + EXPECT_THROW_MIXED_STDLIB((m1[{0, 2, 3}]), std::runtime_error); } } @@ -100,7 +101,7 @@ TEST(Tensor, productError) { { cudaq::matrix_2 m2({2., 1., 3., 4.}); cudaq::matrix_2 m3({1., 2., 3., 4., 5., 6.}, {3, 2}); - EXPECT_THROW(m2 * m3, std::runtime_error); + EXPECT_THROW_MIXED_STDLIB(m2 * m3, std::runtime_error); } } @@ -117,7 +118,7 @@ TEST(Tensor, additionError) { { cudaq::matrix_2 m5({2., 1., 3., 4.}); cudaq::matrix_2 m6({1., 2., 3., 4., 5., 6.}, {3, 2}); - EXPECT_THROW(m5 + m6, std::runtime_error); + EXPECT_THROW_MIXED_STDLIB(m5 + m6, std::runtime_error); } } @@ -133,7 +134,7 @@ TEST(Tensor, subtractionError) { { cudaq::matrix_2 m8({2., 1., 3., 4.}); cudaq::matrix_2 m9({1., 2., 3., 4., 5., 6.}, {3, 2}); - EXPECT_THROW(m8 - m9, std::runtime_error); + EXPECT_THROW_MIXED_STDLIB(m8 - m9, std::runtime_error); } } diff --git a/unittests/utils/exceptions.h b/unittests/utils/exceptions.h new file mode 100644 index 0000000000..873990ce64 --- /dev/null +++ b/unittests/utils/exceptions.h @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +#include "gtest/gtest.h" +#define GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::TrueWithString gtest_msg{}) { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \ + catch (...) { \ + std::string exType = __cxxabiv1::__cxa_current_exception_type()->name();\ + auto demangledPtr =\ + __cxxabiv1::__cxa_demangle(exType.c_str(), nullptr, nullptr, nullptr);\ + if (demangledPtr) {\ + std::string demangledName(demangledPtr); \ + if (demangledName != #expected_exception) {\ + gtest_msg.value = "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws a different type: " + demangledName; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else /*NOLINT*/ \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ + : fail(gtest_msg.value.c_str()) + +#define EXPECT_THROW_MIXED_STDLIB(statement, expected_exception) \ +GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, GTEST_NONFATAL_FAILURE_) From 08da1ad2ef69a0731b056b98b50c22bde9f930a7 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 1 Nov 2024 17:47:13 -0700 Subject: [PATCH 2/4] Format --- unittests/utils/exceptions.h | 71 +++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/unittests/utils/exceptions.h b/unittests/utils/exceptions.h index 873990ce64..aaaf7827e2 100644 --- a/unittests/utils/exceptions.h +++ b/unittests/utils/exceptions.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************-*- C++ -*-**** * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * * All rights reserved. * * * @@ -7,39 +7,42 @@ ******************************************************************************/ #include "gtest/gtest.h" -#define GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::TrueWithString gtest_msg{}) { \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (expected_exception const&) { \ - gtest_caught_expected = true; \ - } \ - GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \ - catch (...) { \ - std::string exType = __cxxabiv1::__cxa_current_exception_type()->name();\ - auto demangledPtr =\ - __cxxabiv1::__cxa_demangle(exType.c_str(), nullptr, nullptr, nullptr);\ - if (demangledPtr) {\ - std::string demangledName(demangledPtr); \ - if (demangledName != #expected_exception) {\ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws a different type: " + demangledName; \ +#define GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::TrueWithString gtest_msg{}) { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (expected_exception const &) { \ + gtest_caught_expected = true; \ + } \ + GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \ + catch (...) { \ + std::string exType = __cxxabiv1::__cxa_current_exception_type()->name(); \ + auto demangledPtr = __cxxabiv1::__cxa_demangle(exType.c_str(), nullptr, \ + nullptr, nullptr); \ + if (demangledPtr) { \ + std::string demangledName(demangledPtr); \ + if (demangledName != #expected_exception) { \ + gtest_msg.value = \ + "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws a different type: " + \ + demangledName; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } \ - } \ - if (!gtest_caught_expected) { \ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else /*NOLINT*/ \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ + } \ + } \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else /*NOLINT*/ \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ : fail(gtest_msg.value.c_str()) -#define EXPECT_THROW_MIXED_STDLIB(statement, expected_exception) \ -GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_THROW_MIXED_STDLIB(statement, expected_exception) \ + GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, \ + GTEST_NONFATAL_FAILURE_) From efea3935923ebea61a89e73d07bfa3becc3a0a6d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 1 Nov 2024 17:51:13 -0700 Subject: [PATCH 3/4] DCO Remediation Commit for Anna Gringauze I, Anna Gringauze , hereby add my Signed-off-by to this commit: 08da1ad2ef69a0731b056b98b50c22bde9f930a7 Signed-off-by: Anna Gringauze --- unittests/utils/exceptions.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittests/utils/exceptions.h b/unittests/utils/exceptions.h index aaaf7827e2..0b5e7546fa 100644 --- a/unittests/utils/exceptions.h +++ b/unittests/utils/exceptions.h @@ -6,6 +6,8 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ +/// Additional test API that can catch and verify exceptions in code compiled +/// with `libstdc++` that were thrown in code compiled with `libc++`. #include "gtest/gtest.h" #define GTEST_TEST_THROW_MIXED_STDLIB(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ From 5482d427f7f72093845248c1fab5a56a93332092 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 5 Nov 2024 09:34:23 -0800 Subject: [PATCH 4/4] Fix an error in exception detection Signed-off-by: Anna Gringauze --- unittests/utils/exceptions.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/unittests/utils/exceptions.h b/unittests/utils/exceptions.h index 0b5e7546fa..0cb891a5d5 100644 --- a/unittests/utils/exceptions.h +++ b/unittests/utils/exceptions.h @@ -25,7 +25,9 @@ nullptr, nullptr); \ if (demangledPtr) { \ std::string demangledName(demangledPtr); \ - if (demangledName != #expected_exception) { \ + if (demangledName == #expected_exception) { \ + gtest_caught_expected = true; \ + } else { \ gtest_msg.value = \ "Expected: " #statement \ " throws an exception of type " #expected_exception \ @@ -33,6 +35,13 @@ demangledName; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ + } else { \ + gtest_msg.value = \ + "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual (cannot demangle): it throws a different type: " + \ + exType; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } \ if (!gtest_caught_expected) { \