From aa5c9dba28b540bb5b23592d29ce1c9306217bbb Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 22 Feb 2021 18:26:55 -0500 Subject: [PATCH] Remove problematic lambda functions The GCC 7 compiler on summit was failing to compile all of the code. The problematic parts involved using lambda functions. I think the problem is that the compiler has a bug where it has a problem resolving the type of variables captured by reference. The problem seems similar to this bug reported to Kokkos: https://github.com/kokkos/kokkos-kernels/issues/349 Solved the problem by removing the lambdas with either a named method or just inline code. I suspect the problem arose (without anyone's knowledge) with MR !2331, which moved VTK-m to C++14. This GCC error seems to happen with C++14 but not C++11. (The features of lambdas changed between these two versions of C++.) --- vtkm/cont/testing/TestingBitField.h | 79 ++++++++++++++++------------- vtkm/worklet/OrientCellNormals.h | 17 +++---- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/vtkm/cont/testing/TestingBitField.h b/vtkm/cont/testing/TestingBitField.h index c631b7bcb..879c4b660 100644 --- a/vtkm/cont/testing/TestingBitField.h +++ b/vtkm/cont/testing/TestingBitField.h @@ -165,6 +165,23 @@ struct TestingBitField "memory."); } + template + VTKM_EXEC_CONT static bool TestBitValue(const char* operation, + vtkm::Id i, + PortalType portal, + bool& bit, + bool originalBit) + { + auto expected = bit; + auto result = portal.GetBitAtomic(i); + DEVICE_ASSERT_MSG(result == expected, operation); + + // Reset + bit = originalBit; + portal.SetBitAtomic(i, bit); + return true; + } + template VTKM_EXEC_CONT static bool HelpTestBit(vtkm::Id i, PortalType portal) { @@ -173,36 +190,25 @@ struct TestingBitField const auto mod = RandomBitFromIndex(i + NUM_BITS); - auto testValues = [&](const char* op) -> bool { - auto expected = bit; - auto result = portal.GetBitAtomic(i); - DEVICE_ASSERT_MSG(result == expected, op); - - // Reset: - bit = origBit; - portal.SetBitAtomic(i, bit); - return true; - }; - bit = mod; portal.SetBitAtomic(i, mod); - DEVICE_ASSERT(testValues("SetBitAtomic")); + DEVICE_ASSERT(TestBitValue("SetBitAtomic", i, portal, bit, origBit)); bit = !bit; portal.NotBitAtomic(i); - DEVICE_ASSERT(testValues("NotBitAtomic")); + DEVICE_ASSERT(TestBitValue("NotBitAtomic", i, portal, bit, origBit)); bit = bit && mod; portal.AndBitAtomic(i, mod); - DEVICE_ASSERT(testValues("AndBitAtomic")); + DEVICE_ASSERT(TestBitValue("AndBitAtomic", i, portal, bit, origBit)); bit = bit || mod; portal.OrBitAtomic(i, mod); - DEVICE_ASSERT(testValues("OrBitAtomic")); + DEVICE_ASSERT(TestBitValue("OrBitAtomic", i, portal, bit, origBit)); bit = bit != mod; portal.XorBitAtomic(i, mod); - DEVICE_ASSERT(testValues("XorBitAtomic")); + DEVICE_ASSERT(TestBitValue("XorBitAtomic", i, portal, bit, origBit)); const auto notBit = !bit; // A compare-exchange that should fail @@ -223,6 +229,23 @@ struct TestingBitField return true; } + template + VTKM_EXEC_CONT static bool TestWordValue(const char* operation, + vtkm::Id i, + const PortalType& portal, + WordType& word, + WordType originalWord) + { + auto expected = word; + auto result = portal.template GetWordAtomic(i); + DEVICE_ASSERT_MSG(result == expected, operation); + + // Reset + word = originalWord; + portal.SetWordAtomic(i, word); + return true; + } + template VTKM_EXEC_CONT static bool HelpTestWord(vtkm::Id i, PortalType portal) { @@ -231,42 +254,30 @@ struct TestingBitField const auto mod = RandomWordFromIndex(i + NUM_BITS); - auto testValues = [&](const char* op) -> bool { - auto expected = word; - auto result = portal.template GetWordAtomic(i); - DEVICE_ASSERT_MSG(result == expected, op); - - // Reset: - word = origWord; - portal.SetWordAtomic(i, word); - - return true; - }; - portal.SetWord(i, word); - DEVICE_ASSERT(testValues("SetWord")); + DEVICE_ASSERT(TestWordValue("SetWord", i, portal, word, origWord)); word = mod; portal.SetWordAtomic(i, mod); - DEVICE_ASSERT(testValues("SetWordAtomic")); + DEVICE_ASSERT(TestWordValue("SetWordAtomic", i, portal, word, origWord)); // C++ promotes e.g. uint8 to int32 when performing bitwise not. Silence // conversion warning and mask unimportant bits: word = static_cast(~word); portal.template NotWordAtomic(i); - DEVICE_ASSERT(testValues("NotWordAtomic")); + DEVICE_ASSERT(TestWordValue("NotWordAtomic", i, portal, word, origWord)); word = word & mod; portal.AndWordAtomic(i, mod); - DEVICE_ASSERT(testValues("AndWordAtomic")); + DEVICE_ASSERT(TestWordValue("AndWordAtomic", i, portal, word, origWord)); word = word | mod; portal.OrWordAtomic(i, mod); - DEVICE_ASSERT(testValues("OrWordAtomic")); + DEVICE_ASSERT(TestWordValue("OrWordAtomic", i, portal, word, origWord)); word = word ^ mod; portal.XorWordAtomic(i, mod); - DEVICE_ASSERT(testValues("XorWordAtomic")); + DEVICE_ASSERT(TestWordValue("XorWordAtomic", i, portal, word, origWord)); // Compare-exchange that should fail const WordType notWord = static_cast(~word); diff --git a/vtkm/worklet/OrientCellNormals.h b/vtkm/worklet/OrientCellNormals.h index 37e1db4aa..1822f5f65 100644 --- a/vtkm/worklet/OrientCellNormals.h +++ b/vtkm/worklet/OrientCellNormals.h @@ -264,17 +264,16 @@ public: // One of the cells must be marked visited already. Find it and use it as // an alignment reference for the others: const vtkm::IdComponent numCells = cellIds.GetNumberOfComponents(); - const vtkm::Id refCellId = [&]() -> vtkm::Id { - for (vtkm::IdComponent c = 0; c < numCells; ++c) + vtkm::Id refCellId = INVALID_ID; + for (vtkm::IdComponent c = 0; c < numCells; ++c) + { + const vtkm::Id cellId = cellIds[c]; + if (visitedCells.GetBit(cellId)) { - const vtkm::Id cellId = cellIds[c]; - if (visitedCells.GetBit(cellId)) - { - return cellId; - } + refCellId = cellId; + break; } - return INVALID_ID; - }(); + } VTKM_ASSERT("No reference cell found." && refCellId != INVALID_ID);