response to review on VectorSoacontainer + more unit tests

This commit is contained in:
Peter Doak 2019-09-19 17:16:17 -04:00
parent 9b96b96e2f
commit 4e06b91d7b
2 changed files with 119 additions and 46 deletions

View File

@ -56,9 +56,8 @@ struct VectorSoaContainer
}
///default copy constructor
VectorSoaContainer(const VectorSoaContainer& in)
VectorSoaContainer(const VectorSoaContainer& in) : nLocal(0), nGhosts(0), nAllocated(0), myData(nullptr)
{
setDefaults();
resize(in.nLocal);
std::copy_n(in.myData, nGhosts * D, myData);
}
@ -75,29 +74,24 @@ struct VectorSoaContainer
}
///move constructor
VectorSoaContainer(VectorSoaContainer&& in) : nLocal(in.nLocal), nGhosts(in.nGhosts), nAllocated(in.nAllocated), myData(in.myData)
VectorSoaContainer(VectorSoaContainer&& in)
: nLocal(in.nLocal), nGhosts(in.nGhosts), nAllocated(in.nAllocated), myData(std::move(in.myData))
{
free(myAlloc);
myAlloc = std::move(in.myAlloc);
in.myData = nullptr;
in.nAllocated = 0;
in.nLocal = 0;
in.nGhosts = 0;
in.nLocal = 0;
in.nGhosts = 0;
}
/** constructor with size n without initialization
*/
explicit VectorSoaContainer(size_t n)
{
setDefaults();
resize(n);
}
explicit VectorSoaContainer(size_t n) : nLocal(0), nGhosts(0), nAllocated(0), myData(nullptr) { resize(n); }
/** constructor with ParticleAttrib<T1,D> */
template<typename T1>
VectorSoaContainer(const ParticleAttrib<TinyVector<T1, D>>& in)
: nLocal(0), nGhosts(0), nAllocated(0), myData(nullptr)
{
setDefaults();
resize(in.size());
copyIn(in);
}
@ -105,8 +99,7 @@ struct VectorSoaContainer
template<typename T1>
VectorSoaContainer& operator=(const ParticleAttrib<TinyVector<T1, D>>& in)
{
if (nLocal != in.size())
resize(in.size());
resize(in.size());
copyIn(in);
return *this;
}
@ -120,15 +113,6 @@ struct VectorSoaContainer
return *this;
}
///initialize the data members
__forceinline void setDefaults()
{
nLocal = 0;
nGhosts = 0;
nAllocated = 0;
myData = nullptr;
}
/** resize myData
* @param n nLocal
*
@ -136,34 +120,44 @@ struct VectorSoaContainer
*/
__forceinline void resize(size_t n)
{
static_assert(std::is_same<Element_t, typename Alloc::value_type>::value, "VectorSoaContainer and Alloc data types must agree!");
if (nAllocated)
myAlloc.deallocate(myData, nAllocated);
nLocal = n;
// Bail out to avoid some allocator implementations returning allocated ptr that
// must be freed, breaking the nAllocated scheme.
if(n == 0)
static_assert(std::is_same<Element_t, typename Alloc::value_type>::value,
"VectorSoaContainer and Alloc data types must agree!");
if (n == 0)
{
nAllocated = 0;
nGhosts = 0;
myData = nullptr;
free();
return;
}
else if (n == nLocal)
{
nLocal = n;
}
else
{
deallocate();
nLocal = n;
nGhosts = getAlignedSize<T, ALIGN>(n);
nAllocated = nGhosts * D;
myData = myAlloc.allocate(nAllocated);
return;
}
nGhosts = getAlignedSize<T, ALIGN>(n);
nAllocated = nGhosts * D;
myData = myAlloc.allocate(nAllocated);
}
/** free myData
*/
__forceinline void free()
// can't just deallocate because of attach ref feature
void deallocate()
{
if (nAllocated)
myAlloc.deallocate(myData, nAllocated);
nLocal = 0;
nGhosts = 0;
nAllocated = 0;
myData = nullptr;
}
/** clear status variables
*/
__forceinline void free()
{
deallocate();
nLocal = 0;
nGhosts = 0;
myData = nullptr;
}
/** attach to pre-allocated data
@ -177,6 +171,7 @@ struct VectorSoaContainer
{
if (nAllocated)
throw std::runtime_error("Pointer attaching is not allowed on VectorSoaContainer with allocated memory.");
free();
nAllocated = 0;
nLocal = n;
nGhosts = n_padded;
@ -256,7 +251,6 @@ struct VectorSoaContainer
__forceinline T* end() { return myData + D * nGhosts; }
///return the end
__forceinline const T* end() const { return myData + D * nGhosts; }
};
} // namespace qmcplusplus

View File

@ -2,9 +2,10 @@
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
// Copyright (c) 2019 QMCPACK developers.
//
// File developed by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
// Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
//
// File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
//////////////////////////////////////////////////////////////////////////////////////
@ -48,4 +49,82 @@ TEST_CASE("vector", "[OhmmsSoA]")
REQUIRE(RSoA[1][2] == Approx(1.68658058));
}
TEST_CASE("VectorSoaContainer copy constructor", "[OhmmsSoA]")
{
ParticleAttrib<TinyVector<double, 3>> R(4);
VectorSoaContainer<double, 3> RSoA(4);
R[0] = TinyVector<double, 3>(0.00000000, 0.00000000, 0.00000000);
R[1] = TinyVector<double, 3>(1.68658058, 1.68658058, 1.68658058);
R[2] = TinyVector<double, 3>(3.37316115, 3.37316115, 0.00000000);
R[3] = TinyVector<double, 3>(5.05974172, 5.05974172, 1.68658058);
RSoA.copyIn(R);
VectorSoaContainer<double, 3> rsoa_copy(RSoA);
// more importantly this test shall not leak memory
//check out value
REQUIRE(rsoa_copy[1][0] == Approx(1.68658058));
REQUIRE(rsoa_copy[1][1] == Approx(1.68658058));
REQUIRE(rsoa_copy[1][2] == Approx(1.68658058));
}
TEST_CASE("VectorSoaContainer move constructor", "[OhmmsSoA]")
{
ParticleAttrib<TinyVector<double, 3>> R(4);
VectorSoaContainer<double, 3> RSoA(4);
R[0] = TinyVector<double, 3>(0.00000000, 0.00000000, 0.00000000);
R[1] = TinyVector<double, 3>(1.68658058, 1.68658058, 1.68658058);
R[2] = TinyVector<double, 3>(3.37316115, 3.37316115, 0.00000000);
R[3] = TinyVector<double, 3>(5.05974172, 5.05974172, 1.68658058);
RSoA.copyIn(R);
VectorSoaContainer<double, 3> rsoa_move(std::move(RSoA));
// more importantly this test shall not leak memory
//check out value
REQUIRE(rsoa_move[1][0] == Approx(1.68658058));
REQUIRE(rsoa_move[1][1] == Approx(1.68658058));
REQUIRE(rsoa_move[1][2] == Approx(1.68658058));
}
TEST_CASE("VectorSoaContainer assignment", "[OhmmsSoA]")
{
ParticleAttrib<TinyVector<double, 3>> R(4);
VectorSoaContainer<double, 3> RSoA(4);
R[0] = TinyVector<double, 3>(0.00000000, 0.00000000, 0.00000000);
R[1] = TinyVector<double, 3>(1.68658058, 1.68658058, 1.68658058);
R[2] = TinyVector<double, 3>(3.37316115, 3.37316115, 0.00000000);
R[3] = TinyVector<double, 3>(5.05974172, 5.05974172, 1.68658058);
RSoA.copyIn(R);
VectorSoaContainer<double, 3> rsoa_assign;
rsoa_assign = RSoA;
REQUIRE(rsoa_assign[3][0] == Approx(5.05974172));
REQUIRE(rsoa_assign[3][1] == Approx(5.05974172));
REQUIRE(rsoa_assign[3][2] == Approx(1.68658058));
ParticleAttrib<TinyVector<double, 3>> r_big(5);
VectorSoaContainer<double, 3> r_soa_big(5);
r_big[0] = TinyVector<double, 3>(0.00000000, 0.00000000, 0.00000000);
r_big[1] = TinyVector<double, 3>(1.68658058, 1.68658058, 1.68658058);
r_big[2] = TinyVector<double, 3>(3.37316115, 3.37316115, 0.00000000);
r_big[3] = TinyVector<double, 3>(5.05974172, 5.05974172, 1.68658058);
r_big[4] = TinyVector<double, 3>(3.37316115, 3.37316115, 0.00000000);
r_soa_big.copyIn(r_big);
rsoa_assign = r_soa_big;
REQUIRE(rsoa_assign[4][0] == Approx(3.37316115));
REQUIRE(rsoa_assign[4][2] == Approx(0.00000000));
}
} // namespace qmcplusplus