18 #ifndef viskores_cont_ArrayHandleBitField_h
19 #define viskores_cont_ArrayHandleBitField_h
33 template <
typename BitPortalType>
34 class ArrayPortalBitField
37 using ValueType = bool;
40 explicit ArrayPortalBitField(
const BitPortalType& portal) noexcept
46 explicit ArrayPortalBitField(BitPortalType&& portal) noexcept
47 : BitPortal{ std::move(portal) }
51 ArrayPortalBitField() noexcept = default;
52 ArrayPortalBitField(const ArrayPortalBitField&) noexcept = default;
53 ArrayPortalBitField(ArrayPortalBitField&&) noexcept = default;
54 ArrayPortalBitField& operator=(const ArrayPortalBitField&) noexcept = default;
55 ArrayPortalBitField& operator=(ArrayPortalBitField&&) noexcept = default;
58 viskores::
Id GetNumberOfValues() const noexcept {
return this->BitPortal.GetNumberOfBits(); }
61 ValueType
Get(
viskores::Id index)
const noexcept {
return this->BitPortal.GetBit(index); }
68 this->BitPortal.SetBitAtomic(index, value);
72 BitPortalType BitPortal;
75 struct VISKORES_ALWAYS_EXPORT StorageTagBitField
80 class Storage<bool, StorageTagBitField>
82 using BitPortalType = viskores::cont::detail::BitPortal;
83 using BitPortalConstType = viskores::cont::detail::BitPortalConst;
86 static constexpr
viskores::Id BlockSize = viskores::cont::detail::BitFieldTraits::BlockSize;
90 using ReadPortalType = viskores::cont::internal::ArrayPortalBitField<BitPortalConstType>;
91 using WritePortalType = viskores::cont::internal::ArrayPortalBitField<BitPortalType>;
93 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
95 return std::vector<viskores::cont::internal::Buffer>(1);
100 const std::vector<viskores::cont::internal::Buffer>& buffers,
104 const viskores::Id bytesNeeded = (numberOfBits + CHAR_BIT - 1) / CHAR_BIT;
105 const viskores::Id blocksNeeded = (bytesNeeded + BlockSize - 1) / BlockSize;
109 "BitField Allocation: %llu bits, blocked up to %s bytes.",
110 static_cast<unsigned long long>(numberOfBits),
113 buffers[0].SetNumberOfBytes(numBytes, preserve, token);
114 buffers[0].GetMetaData<viskores::cont::internal::BitFieldMetaData>().NumberOfBits =
119 const std::vector<viskores::cont::internal::Buffer>&)
125 const std::vector<viskores::cont::internal::Buffer>& buffers)
129 buffers[0].GetMetaData<viskores::cont::internal::BitFieldMetaData>().NumberOfBits;
130 VISKORES_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
134 VISKORES_CONT static void Fill(
const std::vector<viskores::cont::internal::Buffer>& buffers,
145 viskores::Id totalBitsInArray = GetNumberOfValues(buffers);
146 if (endBit >= totalBitsInArray)
148 endBit = ((totalBitsInArray + (wordNumBits - 1)) / wordNumBits) * wordNumBits;
150 if (((startBit % wordNumBits) == 0) && ((endBit % wordNumBits) == 0))
152 WordType fillWord = (fillValue ? ~WordType{ 0 } : WordType{ 0 });
153 buffers[0].Fill(&fillWord, wordTypeSize, startBit / CHAR_BIT, endBit / CHAR_BIT, token);
155 else if (((startBit % CHAR_BIT) == 0) && ((endBit % CHAR_BIT) == 0))
158 buffers[0].Fill(&fillWord, 1, startBit / CHAR_BIT, endBit / CHAR_BIT, token);
167 const std::vector<viskores::cont::internal::Buffer>& buffers,
173 VISKORES_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
175 return ReadPortalType(
176 BitPortalConstType(buffers[0].ReadPointerDevice(device, token), numberOfBits));
180 const std::vector<viskores::cont::internal::Buffer>& buffers,
186 VISKORES_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
188 return WritePortalType(
189 BitPortalType(buffers[0].WritePointerDevice(device, token), numberOfBits));
226 #endif // viskores_cont_ArrayHandleBitField_h