From da2e601b6a366006aaf13c617a9b5ee5088a4f98 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 12 Aug 2015 17:32:19 -0600 Subject: [PATCH] Add VecVariable This class holds a Vec and exposes some number of components. The class is used when you need a Vec of a size that is not known at compile time but that a maximum length of reasonable size is known. --- vtkm/CMakeLists.txt | 1 + vtkm/Matrix.h | 6 + vtkm/VecTraits.h | 1 + vtkm/VecVariable.h | 167 +++++++++++++++++++++++++++ vtkm/testing/CMakeLists.txt | 1 + vtkm/testing/Testing.h | 9 +- vtkm/testing/UnitTestTypes.cxx | 20 ---- vtkm/testing/UnitTestVecVariable.cxx | 117 +++++++++++++++++++ 8 files changed, 300 insertions(+), 22 deletions(-) create mode 100644 vtkm/VecVariable.h create mode 100644 vtkm/testing/UnitTestVecVariable.cxx diff --git a/vtkm/CMakeLists.txt b/vtkm/CMakeLists.txt index f6cd8aaa9..389def7a2 100644 --- a/vtkm/CMakeLists.txt +++ b/vtkm/CMakeLists.txt @@ -35,6 +35,7 @@ set(headers TypeTraits.h VectorAnalysis.h VecTraits.h + VecVariable.h UnaryPredicates.h ) diff --git a/vtkm/Matrix.h b/vtkm/Matrix.h index 1f924645f..12ebcd19c 100644 --- a/vtkm/Matrix.h +++ b/vtkm/Matrix.h @@ -557,6 +557,12 @@ public: typedef T ComponentType; static const vtkm::IdComponent NUM_COMPONENTS = NumRow*NumCol; typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents; + typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic; + + VTKM_EXEC_CONT_EXPORT + static vtkm::IdComponent GetNumberOfComponents(const MatrixType &) { + return NUM_COMPONENTS; + } VTKM_EXEC_CONT_EXPORT static const ComponentType &GetComponent(const MatrixType &matrix, diff --git a/vtkm/VecTraits.h b/vtkm/VecTraits.h index 1c373fc21..eb31f9639 100644 --- a/vtkm/VecTraits.h +++ b/vtkm/VecTraits.h @@ -146,6 +146,7 @@ struct VecTraits > /// Number of components in the given vector. /// + VTKM_EXEC_CONT_EXPORT static vtkm::IdComponent GetNumberOfComponents(const VecType &) { return NUM_COMPONENTS; } diff --git a/vtkm/VecVariable.h b/vtkm/VecVariable.h new file mode 100644 index 000000000..0d8e36933 --- /dev/null +++ b/vtkm/VecVariable.h @@ -0,0 +1,167 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2015 Sandia Corporation. +// Copyright 2015 UT-Battelle, LLC. +// Copyright 2015 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ +#ifndef vtk_m_VecVariable_h +#define vtk_m_VecVariable_h + +#include +#include +#include +#include + +namespace vtkm { + +/// \brief A short variable-length array with maximum length. +/// +/// The \c VecVariable class is a Vec-like class that holds a short array of +/// some maximum length. To avoid dynamic allocations, the maximum length is +/// specified at compile time. Internally, \c VecVariable holds a \c Vec of +/// the maximum length and exposes a subsection of it. +/// +template +class VecVariable +{ +public: + typedef T ComponentType; + + VTKM_EXEC_CONT_EXPORT + VecVariable() : NumComponents(0) { } + + template + VTKM_EXEC_CONT_EXPORT + VecVariable(const vtkm::VecVariable &src) + : NumComponents(src.GetNumberOfComponents()) + { + for (vtkm::IdComponent index = 0; index < this->NumComponents; index++) + { + this->Data[index] = src[index]; + } + } + + template + VTKM_EXEC_CONT_EXPORT + VecVariable(const vtkm::Vec &src) + : NumComponents(SrcSize) + { + for (vtkm::IdComponent index = 0; index < this->NumComponents; index++) + { + this->Data[index] = src[index]; + } + } + + VTKM_EXEC_CONT_EXPORT + vtkm::IdComponent GetNumberOfComponents() const { + return this->NumComponents; + } + + template + VTKM_EXEC_CONT_EXPORT + void CopyInto(vtkm::Vec &dest) const + { + vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->NumComponents); + for (vtkm::IdComponent index = 0; index < numComponents; index++) + { + dest[index] = this->Data[index]; + } + } + + VTKM_EXEC_CONT_EXPORT + const ComponentType &operator[](vtkm::IdComponent index) const + { + return this->Data[index]; + } + + VTKM_EXEC_CONT_EXPORT + ComponentType &operator[](vtkm::IdComponent index) + { + return this->Data[index]; + } + + VTKM_EXEC_CONT_EXPORT + void Append(ComponentType value) + { + this->Data[this->NumComponents] = value; + this->NumComponents++; + } + +private: + vtkm::Vec Data; + vtkm::IdComponent NumComponents; +}; + +template +struct TypeTraits > +{ + typedef typename vtkm::TypeTraits::NumericTag NumericTag; + typedef TypeTraitsVectorTag DimensionalityTag; + + VTKM_EXEC_CONT_EXPORT + static vtkm::VecVariable ZeroInitialization() + { + return vtkm::VecVariable(); + } +}; + +template +struct VecTraits > +{ + typedef vtkm::VecVariable VecType; + + typedef typename VecType::ComponentType ComponentType; + typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents; + typedef vtkm::VecTraitsTagSizeVariable IsSizeStatic; + + VTKM_EXEC_CONT_EXPORT + static vtkm::IdComponent GetNumberOfComponents(const VecType &vector) { + return vector.GetNumberOfComponents(); + } + + VTKM_EXEC_CONT_EXPORT + static const ComponentType &GetComponent(const VecType &vector, + vtkm::IdComponent componentIndex) + { + return vector[componentIndex]; + } + VTKM_EXEC_CONT_EXPORT + static ComponentType &GetComponent(VecType &vector, + vtkm::IdComponent componentIndex) + { + return vector[componentIndex]; + } + + VTKM_EXEC_CONT_EXPORT + static void SetComponent(VecType &vector, + vtkm::IdComponent componentIndex, + const ComponentType &value) + { + vector[componentIndex] = value; + } + + template + VTKM_EXEC_CONT_EXPORT + static void CopyInto(const VecType &src, + vtkm::Vec &dest) + { + src.CopyInto(dest); + } +}; + +} // namespace vtkm + +#endif //vtk_m_VecVariable_h diff --git a/vtkm/testing/CMakeLists.txt b/vtkm/testing/CMakeLists.txt index 2a5407dcb..46a48e385 100644 --- a/vtkm/testing/CMakeLists.txt +++ b/vtkm/testing/CMakeLists.txt @@ -42,6 +42,7 @@ set(unit_tests UnitTestUnaryPredicates.cxx UnitTestVectorAnalysis.cxx UnitTestVecTraits.cxx + UnitTestVecVariable.cxx ) VTKM_unit_tests(SOURCES ${unit_tests}) diff --git a/vtkm/testing/Testing.h b/vtkm/testing/Testing.h index c00e59e14..563bab6a5 100644 --- a/vtkm/testing/Testing.h +++ b/vtkm/testing/Testing.h @@ -277,10 +277,15 @@ bool test_equal(VectorType1 vector1, { typedef typename vtkm::VecTraits Traits1; typedef typename vtkm::VecTraits Traits2; - BOOST_STATIC_ASSERT(Traits1::NUM_COMPONENTS == Traits2::NUM_COMPONENTS); + + if (Traits1::GetNumberOfComponents(vector1) != + Traits2::GetNumberOfComponents(vector2)) + { + return false; + } for (vtkm::IdComponent component = 0; - component < Traits1::NUM_COMPONENTS; + component < Traits1::GetNumberOfComponents(vector1); component++) { vtkm::Float64 value1 = diff --git a/vtkm/testing/UnitTestTypes.cxx b/vtkm/testing/UnitTestTypes.cxx index f30801e5b..224bf137d 100644 --- a/vtkm/testing/UnitTestTypes.cxx +++ b/vtkm/testing/UnitTestTypes.cxx @@ -18,26 +18,6 @@ // this software. //============================================================================ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -// -// Copyright 2014 Sandia Corporation. -// Copyright 2014 UT-Battelle, LLC. -// Copyright 2014 Los Alamos National Security. -// -// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, -// the U.S. Government retains certain rights in this software. -// -// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National -// Laboratory (LANL), the U.S. Government retains certain rights in -// this software. -//============================================================================ - #include #include diff --git a/vtkm/testing/UnitTestVecVariable.cxx b/vtkm/testing/UnitTestVecVariable.cxx new file mode 100644 index 000000000..9877fef99 --- /dev/null +++ b/vtkm/testing/UnitTestVecVariable.cxx @@ -0,0 +1,117 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2015 Sandia Corporation. +// Copyright 2015 UT-Battelle, LLC. +// Copyright 2015 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include + +#include + +namespace { + +struct VecVariableTestFunctor +{ + // You will get a compile fail if this does not pass + template + void CheckNumericTag(NumericTag, NumericTag) const + { + std::cout << "NumericTag pass" << std::endl; + } + + // You will get a compile fail if this does not pass + void CheckDimensionalityTag(vtkm::TypeTraitsVectorTag) const + { + std::cout << "VectorTag pass" << std::endl; + } + + // You will get a compile fail if this does not pass + template + void CheckComponentType(T, T) const + { + std::cout << "ComponentType pass" << std::endl; + } + + // You will get a compile fail if this does not pass + void CheckHasMultipleComponents(vtkm::VecTraitsTagMultipleComponents) const + { + std::cout << "MultipleComponents pass" << std::endl; + } + + // You will get a compile fail if this does not pass + void CheckVariableSize(vtkm::VecTraitsTagSizeVariable) const + { + std::cout << "VariableSize" << std::endl; + } + + template + void operator()(T) const + { + static const vtkm::IdComponent SIZE = 5; + typedef vtkm::Vec VecType; + typedef vtkm::VecVariable VecVariableType; + typedef vtkm::TypeTraits TTraits; + typedef vtkm::VecTraits VTraits; + + std::cout << "Check NumericTag." << std::endl; + this->CheckNumericTag(typename TTraits::NumericTag(), + typename vtkm::TypeTraits::NumericTag()); + + std::cout << "Check DimensionalityTag." << std::endl; + this->CheckDimensionalityTag(typename TTraits::DimensionalityTag()); + + std::cout << "Check ComponentType." << std::endl; + this->CheckComponentType(typename VTraits::ComponentType(), T()); + + std::cout << "Check MultipleComponents." << std::endl; + this->CheckHasMultipleComponents(typename VTraits::HasMultipleComponents()); + + std::cout << "Check VariableSize." << std::endl; + this->CheckVariableSize(typename VTraits::IsSizeStatic()); + + VecType source = TestValue(0, VecType()); + + VecVariableType vec1(source); + VecType vecCopy; + vec1.CopyInto(vecCopy); + VTKM_TEST_ASSERT(test_equal(vec1, vecCopy), + "Bad init or copyinto."); + + vtkm::VecVariable vec2; + for (vtkm::IdComponent setIndex = 0; setIndex < SIZE; setIndex++) + { + VTKM_TEST_ASSERT(vec2.GetNumberOfComponents() == setIndex, + "Report wrong number of components"); + vec2.Append(source[setIndex]); + } + VTKM_TEST_ASSERT(test_equal(vec2, vec1), + "Bad values from Append."); + } +}; + +void TestVecVariable() +{ + vtkm::testing::Testing::TryTypes(VecVariableTestFunctor(), + vtkm::TypeListTagFieldScalar()); +} + +} // anonymous namespace + +int UnitTestVecVariable(int, char *[]) +{ + return vtkm::testing::Testing::Run(TestVecVariable); +}