From 508cc3accb08c40de497a784493d197fd2450c1c Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Fri, 4 Aug 2023 14:03:45 -0600 Subject: [PATCH] Improve = operators in VecFromPortal Previously, `VecFromPortal` could only be set to a standard `Vec`. However, because this is a `Vec`-like object with a runtime-size, it is hard to do general arithmetic on it. It is easier to do in place so there is some place to put the result. To make it easier to operate on this as the result of other `Vec`-likes, extend the operators like `+=`, `*=`, etc to support this. --- docs/changelog/vecfromportal-operators.md | 8 ++ vtkm/VecFromPortal.h | 97 ++++++++++++++++++++++- 2 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 docs/changelog/vecfromportal-operators.md diff --git a/docs/changelog/vecfromportal-operators.md b/docs/changelog/vecfromportal-operators.md new file mode 100644 index 000000000..747c34222 --- /dev/null +++ b/docs/changelog/vecfromportal-operators.md @@ -0,0 +1,8 @@ +# Improved = operators in VecFromPortal + +Previously, `VecFromPortal` could only be set to a standard `Vec`. +However, because this is a `Vec`-like object with a runtime-size, it is +hard to do general arithmetic on it. It is easier to do in place so +there is some place to put the result. To make it easier to operate on +this as the result of other `Vec`-likes, extend the operators like `+=`, +`*=`, etc to support this. diff --git a/vtkm/VecFromPortal.h b/vtkm/VecFromPortal.h index 4f2330981..35cf2726b 100644 --- a/vtkm/VecFromPortal.h +++ b/vtkm/VecFromPortal.h @@ -73,10 +73,11 @@ public: index + this->Offset); } - template - VTKM_EXEC_CONT VecFromPortal& operator=(const vtkm::Vec& src) + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT VecFromPortal& operator=(const OtherVecType& src) { - vtkm::IdComponent numComponents = vtkm::Min(N, this->NumComponents); + vtkm::IdComponent numComponents = vtkm::Min(src.GetNumberOfComponents(), this->NumComponents); for (vtkm::IdComponent index = 0; index < numComponents; ++index) { this->Portal.Set(index + this->Offset, src[index]); @@ -84,6 +85,96 @@ public: return *this; } + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT VecFromPortal& operator+=(const OtherVecType& other) + { + vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents); + for (vtkm::IdComponent index = 0; index < numComponents; ++index) + { + (*this)[index] += other[index]; + } + return *this; + } + + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT VecFromPortal& operator-=(const OtherVecType& other) + { + vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents); + for (vtkm::IdComponent index = 0; index < numComponents; ++index) + { + (*this)[index] -= other[index]; + } + return *this; + } + +private: + template + VTKM_EXEC_CONT void Multiply(const OtherVecType& other, vtkm::TypeTraitsVectorTag) + { + vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents); + for (vtkm::IdComponent index = 0; index < numComponents; ++index) + { + (*this)[index] *= other[index]; + } + } + + template + VTKM_EXEC_CONT void Multiply(ScalarType other, vtkm::TypeTraitsScalarTag) + { + for (vtkm::IdComponent index = 0; index < this->NumComponents; ++index) + { + (*this)[index] *= other; + } + } + +public: + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT VecFromPortal& operator*=(const OtherVecType& other) + { + this->Multiply(other, typename vtkm::TypeTraits::DimensionalityTag{}); + return *this; + } + + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT VecFromPortal& operator/=(const OtherVecType& other) + { + vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents); + for (vtkm::IdComponent index = 0; index < numComponents; ++index) + { + (*this)[index] /= other[index]; + } + return *this; + } + + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT bool operator==(const OtherVecType& other) + { + if (this->NumComponents != other.GetNumberOfComponents()) + { + return false; + } + for (vtkm::IdComponent index = 0; index < this->NumComponents; ++index) + { + if (this->Portal.Get(index + this->Offset) != other[index]) + { + return false; + } + } + return true; + } + + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + VTKM_EXEC_CONT bool operator!=(const OtherVecType& other) + { + return !(*this == other); + } + VTKM_EXEC_CONT const PortalType& GetPortal() const { return this->Portal; } VTKM_EXEC_CONT vtkm::Id GetOffset() const { return this->Offset; }