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++.)
This commit is contained in:
Kenneth Moreland 2021-02-22 18:26:55 -05:00
parent 561db99b30
commit aa5c9dba28
2 changed files with 53 additions and 43 deletions

@ -165,6 +165,23 @@ struct TestingBitField
"memory.");
}
template <typename PortalType>
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 <typename PortalType>
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 <typename WordType, typename PortalType>
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<WordType>(i);
DEVICE_ASSERT_MSG(result == expected, operation);
// Reset
word = originalWord;
portal.SetWordAtomic(i, word);
return true;
}
template <typename WordType, typename PortalType>
VTKM_EXEC_CONT static bool HelpTestWord(vtkm::Id i, PortalType portal)
{
@ -231,42 +254,30 @@ struct TestingBitField
const auto mod = RandomWordFromIndex<WordType>(i + NUM_BITS);
auto testValues = [&](const char* op) -> bool {
auto expected = word;
auto result = portal.template GetWordAtomic<WordType>(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<WordType>(~word);
portal.template NotWordAtomic<WordType>(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<WordType>(~word);

@ -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);