While in the transition between two types of `ArrayHandle`
implementations, we need to declare when an `ArrayHandle` is implemented
with the new style. To consolidate, create a
`VTKM_ARRAY_HANDLE_NEW_STYLE` to override the default `ArrayHandle`
implementation with the `ArrayHandleNewStyle` implementation.
The `UnitTestVTKDataSetReader` test reads in .vtk files of multiple
formats. The origins of this test predate the use of git-lfs and a data
directory, so the test defined in the source code several strings
containing the contents of the files.
That is no longer necessary. This change removes those strings from the
file and creates actual files in the data directory. This is easier to
manage as well as more convenient if you want to use the same data in a
different test or just take a look at the data in a different program
(such as VisIt or ParaView).
The testing helper class provided a method named `GetTestDataBasePath`
that returned the base path to all the data files stored in the VTK-m
repo. This is fine, but it was a little cumbersome to build filenames.
To make things easier, there is now a new method named `DataPath` that
takes a string of the filename (or, rather, subpath) to the file in that
directory and automatically builds the path to it.
4345fe26b Store the number of bits of a BitField in the Buffer's metadata
da0403be7 Add metadata to Buffer object.
a84891cd3 Update ArrayHandleBitField to new array style with Buffer
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2218
The number of bits in a `BitField` cannot be directly implied from the
size of the buffer (because the buffer gets padded to the nearest sized
word). Thus, the `BitField stored the number of bits in its own
internals.
Unfortunately, that caused issues when passing the `BitField` data
between it and an `ArrayHandleBitField`. If the `ArrayHandleBitField`
resized itself, the `BitField` would not see the new size because it
ignored the new buffer size.
To get around this problem, `BitField` now declares its own
`BufferMetaData` that stores the number of bits. Now, since the number
of bits is stored in the `Buffer` object, it is sufficient to just share
the `Buffer` to synchronize all of the state.
One of the goals of the `Buffer` object is to allow sharing of data
among objects that will interpret the data differently or give a
different interface over the data. However, when sharing only the array,
important metadata can become lost.
Provide a field that can store some custom metadata in the buffer object
so that the rest of the state can follow the buffer object around.
b48c19f25 Correct warnings found by using clang as the host compiler for cuda
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland <kmorel@sandia.gov>
Merge-request: !2232
6cbcb9f5d Fix behavior of Cuda AtomicLoad with SequentiallyConsistent
7573d4ed5 Fix compiler warnings
147dd24d0 Remove ARM intrinsics in MSVC
2229c22f4 Avoid invalid Kokkos atomic calls
3b147878f Always use our implementation of Cuda atomics
9e6fe8fb6 Add memory order semantics to atomic functions
d2ac4b860 Be more careful in casting with Atomic functions
13056b3af Deprecate AtomicInterfaceControl and AtomicInterfaceExecution
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2223
According to Allie Vacanti, a sequentially consistent load requires a
full fence on Cuda hardware to be conforming.
Also improved the documentation of `MemoryOrder` based on Allie's
suggestion.
Also removed the `Consume` memory order based on Allie's suggestion. It
is tricky to use correctly, and most implementations just regress to the
safer `Acquired` behavior anyway.
Previously, if Kokkos was enabled we always used Kokkos atomics.
However, if a user, for some reason, compiled with a version of Kokkos
that was _not_ compiled for Cuda and we turned on our own Cuda device
adapter, that would cause a problem. The old code assumed Kokkos would
create the Cuda version of the atomics, but it would not. Thus, there
would be no atomics for Cuda.
Resolved this problem by switching the order in which we try to define
atomics. Use our version of atomics whenever compiling for a Cuda
device. Otherwise, try to compile the Kokkos version (and if that is not
available, use ours as before.
To ensure correctness of an atomic function, it is often necessary to
force a compiler to order operations correctly. However, doing so may
slow things down, so it is helpful to relax these constraints if they
are not necessary. Add the ability to select the correct memory order
constraints in the atomic functions.
Previously, the atomic functions accepted any type as its operand and
then cast that to the storage type. That could cause some rather
unexpected behavior. For example, casting a floating point number to an
integer might not give you the behavior as expected. So that behavior as
been removed and now the operand has to match the pointer.
However, all the currently supported atomics are unsigned, and there are
many reasons that it might be easier to use signed as operands. (For
example, C literals are signed.) Thus, a second condition that allows
the sign to be swapped has been added so that you don't get annoying
signed/unsigned conversion warnings.
Now that we have the functions in `vtkm/Atomic.h`, we can deprecate (and
eventually remove) the more cumbersome classes `AtomicInterfaceControl`
and `AtomicInterfaceExecution`.
Also reversed the order of the `expected` and `desired` parameters of
`vtkm::AtomicCompareAndSwap`. I think the former order makes more sense
and matches more other implementations (such as `std::atomic` and the
GCC `__atomic` built ins). However, there are still some non-deprecated
classes with similar methods that cannot easily be switched. Thus, it's
better to be inconsistent with most other libraries and consistent with
ourself than to be inconsitent with ourself.
If the Kokkos device is enabled, we use the Kokkos atomic functions for
implementation since Kokkos has already ported all of these to each
device.
If Kokkos is compiled with CUDA, then the functions are marked with
`__device__` and `__host__`. Makes sense right?
Unless we are trying to use the atomic functions on host code compiled
only for the host. In that case, modifiers like `__device__` will cause
compiler errors.
So we want to disable Kokkos from using `__device__`, but only if CUDA
is enabled and we are not using the CUDA compiler. Had to hack things up
to get that to work.
Now that we have atomic free functions (e.g. `vtkm::AtomicAdd()`), we no
longer need special implementations for control and each execution
device. (Well, technically we do have special implementations for each,
but they are handled with compiler directives in the free functions.)
Convert the old atomic interface classes (`AtomicInterfaceControl` and
`AtomicInterfaceExecution`) to use the new atomic free functions. This
will allow us to test the new atomic functions everywhere that atomics
are used in VTK-m.
Once verified, we can deprecate the old atomic interface classes.
Previously, all atomic functions were stored in classes named
`AtomicInterfaceControl` and `AtomicInterfaceExecution`, which required
you to know at compile time which device was using the methods. That in
turn means that anything using an atomic needed to be templated on the
device it is running on.
That can be a big hassle (and is problematic for some code structure).
Instead, these methods are moved to free functions in the `vtkm`
namespace. These functions operate like those in `Math.h`. Using
compiler directives, an appropriate version of the function is compiled
for the current device the compiler is using.