Commit Graph

184 Commits

Author SHA1 Message Date
Kenneth Moreland
ea560e9486 Remove deprecated virtual methods
Several revisions ago, the ability to use virtual methods in the
execution environment was deprecated. Completely remove this
functionality for the VTK-m 2.0 release.
2022-10-28 10:56:52 -06:00
Kenneth Moreland
cb3bb43ff9 Completely deprecate virtual methods
Deprecate `VirtualObjectHandle` and all other classes that are used to
implement objects with virtual methods in the execution environment.

Additionally, the code is updated so that if the
`VTKm_NO_DEPRECATED_VIRTUAL` flag is set none of the code is compiled at
all. This opens us up to opportunities that do not work with virtual
methods such as backends that do not support virtual methods and dynamic
libraries for CUDA.
2021-04-28 07:28:32 -06:00
Nick Thompson
4133e40c06 Remove printing of expected errors. 2021-04-12 18:51:53 -04:00
Nick Thompson
eb760e04ef Revert removal of print statements. 2021-04-12 18:51:53 -04:00
Nick Thompson
e7c075b5c4 Remove unused variable. 2021-04-12 18:51:53 -04:00
Nick Thompson
cb83b81793 Save another 10 seconds. 2021-04-12 18:51:52 -04:00
Kenneth Moreland
d9c988b200 Allow for different types in basic type operators
The basic type operators in `Types.h` (i.e. `vtkm::Add`,
`vtkm::Subtract`, `vtkm::Multiply` and `vtkm::Divide`) required the same
type for both arguments. This caused problems when used with `Reduce`
and the initial value type did not match exactly.

Use some tricks from `BinaryOperators.h` to be flexible about using
different types.
2021-03-03 09:39:45 -07:00
Kenneth Moreland
c55d15f397 Deprecate ArrayHandle::ExecutionTypes
The newer version of `ArrayHandle` no longer supports different types of
portals for different devices. Thus, the `ReadPortalType` and
`WritePortalType` are sufficient for all types of portals across all
devices.

This significantly simplifies supporting execution objects on devices,
and thus this change also includes many changes to various execution
objects to remove their dependence on the device adapter tag.
2021-02-08 12:17:37 -07:00
Kenneth Moreland
7df5c39358 Remove device template argument from AtomicArrayExecutionObject
The actual code for AtomicArrayExecutionObject does not need to be
specialized by the device. The functionality is implemented by calling
the vtkm::Atomic* methods, which are properly implemented on each
device.
2021-02-04 08:47:28 -07:00
Kenneth Moreland
34412ff298 Deprecate ArrayHandle::Shrink
This method has been subsumed by Allocate with vtkm::CopyFlag::On.
2021-02-01 08:07:40 -07:00
Kenneth Moreland
5ef4e7eeee Make new style of ArrayHandle the expected style
What was previously declared as `ArrayHandleNewStyle` is now just the
implementation of `ArrayHandle`. The old implementation of `ArrayHandle`
has been moved to `ArrayHandleDeprecated`, and `ArrayHandle`s still
using this implementation must declare `VTKM_ARRAY_HANDLE_DEPRECATED` to
use it.
2021-01-12 07:17:53 -07:00
Kenneth Moreland
28ecf3636d Change interface of atomic compare and swap
The old atomic compare and swap operations (`vtkm::AtomicCompareAndSwap`
and `vtkm::exec::AtomicArrayExecutionObject::CompareAndSwap`) had an
order of arguments that was confusing. The order of the arguments was
shared pointer (or index), desired value, expected value. Most people
probably assume expected value comes before desired value. And this
order conflicts with the order in the `std` methods, GCC atomics, and
Kokkos.

Change the interface of atomic operations to be patterned off the
`std::atomic_compare_exchange` and `std::atomic<T>::compare_exchange`
methods. First, these methods have a more intuitive order of parameters
(shared pointer, expected, desired). Second, rather than take a value
for the expected and return the actual old value, they take a pointer to
the expected value (or reference in `AtomicArrayExecutionObject`) and
modify this value in the case that it does not match the actual value.
This makes it harder to mix up the expected and desired parameters.
Also, because the methods return a bool indicating whether the value was
changed, there is an additional benefit that compare-exchange loops are
implemented easier.

For example, consider you want to apply the function `MyOp` on a
`sharedValue` atomically. With the old interface, you would have to do
something like this.

```cpp
T oldValue;
T newValue;
do
{
  oldValue = *sharedValue;
  newValue = MyOp(oldValue);
} while (vtkm::AtomicCompareAndSwap(sharedValue, newValue, oldValue) != oldValue);
```

With the new interface, this is simplfied to this.

```cpp
T oldValue = *sharedValue;
while (!vtkm::AtomicCompareExchange(sharedValue, &oldValue, MyOp(oldValue));
```
2020-10-20 08:39:22 -06:00
Robert Maynard
22dfb4776e Remove unused functions from TestingDeviceAdapter 2020-10-09 14:13:45 -04:00
Sujin Philip
452f61e290 Add Kokkos backend 2020-08-12 13:55:24 -04:00
Kenneth Moreland
d1a4aecc59 Improvements to moving data into ArrayHandle
We have made several improvements to adding data into an `ArrayHandle`.

## Moving data from an `std::vector`

For numerous reasons, it is convenient to define data in a `std::vector`
and then wrap that into an `ArrayHandle`. It is often the case that an
`std::vector` is filled and then becomes unused once it is converted to an
`ArrayHandle`. In this case, what we really want is to pass the data off to
the `ArrayHandle` so that the `ArrayHandle` is now managing the data and
not the `std::vector`.

C++11 has a mechanism to do this: move semantics. You can now pass
variables to functions as an "rvalue" (right-hand value). When something is
passed as an rvalue, it can pull state out of that variable and move it
somewhere else. `std::vector` implements this movement so that an rvalue
can be moved to another `std::vector` without actually copying the data.
`make_ArrayHandle` now also takes advantage of this feature to move rvalue
`std::vector`s.

There is a special form of `make_ArrayHandle` named `make_ArrayHandleMove`
that takes an rvalue. There is also a special overload of
`make_ArrayHandle` itself that handles an rvalue `vector`. (However, using
the explicit move version is better if you want to make sure the data is
actually moved.)

## Make `ArrayHandle` from initalizer list

A common use case for using `std::vector` (particularly in our unit tests)
is to quickly add an initalizer list into an `ArrayHandle`. Now you can
by simply passing an initializer list to `make_ArrayHandle`.

## Deprecated `make_ArrayHandle` with default shallow copy

For historical reasons, passing an `std::vector` or a pointer to
`make_ArrayHandle` does a shallow copy (i.e. `CopyFlag` defaults to `Off`).
Although more efficient, this mode is inherintly unsafe, and making it the
default is asking for trouble.

To combat this, calling `make_ArrayHandle` without a copy flag is
deprecated. In this way, if you wish to do the faster but more unsafe
creation of an `ArrayHandle` you should explicitly express that.

This requried quite a few changes through the VTK-m source (particularly in
the tests).

## Similar changes to `Field`

`vtkm::cont::Field` has a `make_Field` helper function that is similar to
`make_ArrayHandle`. It also features the ability to create fields from
`std::vector`s and C arrays. It also likewise had the same unsafe behavior
by default of not copying from the source of the arrays.

That behavior has similarly been depreciated. You now have to specify a
copy flag.

The ability to construct a `Field` from an initializer list of values has
also been added.
2020-07-23 10:53:38 -06:00
Kenneth Moreland
a47fd42bc1 Pin user provided memory in ArrayHandle
Often when a user gives memory to an `ArrayHandle`, she wants data to be
written into the memory given to be used elsewhere. Previously, the
`Buffer` objects would delete the given buffer as soon as a write buffer
was created elsewhere. That was a problem if a user wants VTK-m to write
results right into a given buffer.

Instead, when a user provides memory, "pin" that memory so that the
`ArrayHandle` never deletes it.
2020-06-25 14:02:46 -06:00
Kenneth Moreland
56bec1dd7b Replace basic ArrayHandle implementation to use Buffers
This encapsulates a lot of the required memory management into the
Buffer object and related code.

Many now unneeded classes were deleted.
2020-06-25 14:02:26 -06:00
Kenneth Moreland
8f7b0d18be Add Buffer class
The buffer class encapsulates the movement of raw C arrays between
host and devices.

The `Buffer` class itself is not associated with any device. Instead,
`Buffer` is used in conjunction with a new templated class named
`DeviceAdapterMemoryManager` that can allocate data on a given
device and transfer data as necessary. `DeviceAdapterMemoryManager`
will eventually replace the more complicated device adapter classes
that manage data on a device.

The code in `DeviceAdapterMemoryManager` is actually enclosed in
virtual methods. This allows us to limit the number of classes that
need to be compiled for a device. Rather, the implementation of
`DeviceAdapterMemoryManager` is compiled once with whatever compiler
is necessary, and then the `RuntimeDeviceInformation` is used to
get the correct object instance.
2020-06-25 14:01:39 -06:00
Allison Vacanti
6c98cbc6e4 Add missing Algorithm::Synchronize() in timer test. 2020-05-17 12:53:14 -04:00
NAThompson
46faf574fa ReadPortal().Get(idx) is slow in a loop. 2020-05-08 11:30:59 -04:00
Kenneth Moreland
94f0d2f8a5 Restore device tests
While debugging, I commented out a section of the device adapter tests
to narrow down on some issues. Oops, I forgot to restore the test. Do
that now.
2020-04-21 11:46:40 -06:00
Kenneth Moreland
6dc0b394a9 Fix reduce-by-key with a fancy output array
If you gave ReduceByKey a fancy output array that decorated another
array, you could get a runtime error for using an invalid array (if the
device adapter used the generic algorithm). The problem was that
ReduceByKey creates a temporary array, and that array was given the same
storage as the output array. That might not be valid for fancy arrays,
so instead use the default storage for the temporary array.
2020-04-16 14:19:44 -06:00
Kenneth Moreland
52f157e420 Fix scan-by-key with a fancy output array
If you gave ScanInclusiveByKey a fancy output array that decorated
another array, you would get a runtime error for using an invalid array.
The problem was that ScanInclusiveByKey creates a temporary output array
and then copies the result to the actual output array. The problem was
that the temporary output array was given the same storage as the output
array, which won't work if the output array is fancy. Instead, make the
storage for the temporary array default.
2020-04-16 10:37:48 -06:00
Kenneth Moreland
10e8a4a7f9 Remove locking control ArrayPortals
Previously, when a ReadPortal or a WritePortal was returned from an
ArrayHandle, it had wrapped in it a Token that was attached to the
ArrayHandle. This Token would prevent other reads and writes from the
ArrayHandle.

This added safety in the form of making sure that the ArrayPortal was
always valid. Unfortunately, it also made deadlocks very easy. They
happened when an ArrayPortal did not leave scope immediately after use
(which is not all that uncommon).

Now, the ArrayPortal no longer locks up the ArrayHandle. Instead, when
an access happens on the ArrayPortal, it checks to make sure that
nothing has happened to the data being accessed. If it has, a fatal
error is reported to the log.
2020-03-16 07:10:10 -06:00
Kenneth Moreland
ec34cb56c4 Use new ways to get array portal in control environment
Also fix deadlocks that occur when portals are not destroyed
in time.
2020-02-26 13:10:46 -07:00
Kenneth Moreland
6b089be03e Add ArrayPortalToken object and implement Read/WritePortal
To get a portal to access ArrayHandle values in the control
environment, you now use the ReadPortal and WritePortal methods.
The portals returned are wrapped in an ArrayPortalToken object
so that the data between the portal and the ArrayHandle are
guaranteed to be consistent.
2020-02-26 13:10:37 -07:00
Kenneth Moreland
098e0fed16 Back out of passing a token when transfering virtual objects
It is questionable whether there is a point to having a token object
when transfering a virtual object to a device (since there is a handle
object that is managing it anyway). Back out of passing the token all
the way down unless there is an actual need for that.
2020-02-25 09:39:29 -07:00
Kenneth Moreland
b2fdf236e7 Fix deadlocks in device adapters and low level tests
The new Token functionality makes it easy for a thread to deadlock
itself if it does not detach a token after it is done.
2020-02-25 09:39:27 -07:00
Kenneth Moreland
ad0a53af71 Convert execution preparation to use tokens
Marked the old versions of PrepareFor* that do not use tokens as
deprecated and moved all of the code to use the new versions that
require a token. This makes the scope of the execution object more
explicit so that it will be kept while in use and can potentially be
reclaimed afterward.
2020-02-25 09:39:19 -07:00
Allison Vacanti
84eedc8855 Make BinaryOperators/Predicates more flexible.
Allow the argument types to differ. This allows ArrayPortalValueReferences to be used.
2019-12-18 15:51:59 -05:00
Allison Vacanti
afe1bd12dd Add ScanExtended device algorithm.
This behaves just like `ScanExclusive`, but rather than returning the
total sum, it is appended to the end of the output array.

This is in preparation for the CellSetExplicit refactoring described in
issue #408.
2019-09-03 15:02:41 -04:00
Allison Vacanti
884616788a Simplify and extend AtomicArray implementation.
- Use AtomicInterface to implement device-specific atomic operations.
- Remove DeviceAdapterAtomicArrayImplementations.
- Extend supported atomic types to include unsigned 32/64-bit ints.
- Add a static_assert to check that AtomicArray type is supported.
- Add documentation for AtomicArrayExecutionObject, including a CAS
  example.
- Add a `T Get(idx)` method to AtomicArrayExecutionObject that does
  an atomic load, and update existing CAS usage to use this instead
  of `Add(idx, 0)`.
2019-08-23 15:40:37 -04:00
Allison Vacanti
112024dae2 Fix CUDA shfl usage.
There was a bug in the implementations of CountSetBits and
BitFieldToUnorderedSet.
2019-08-01 10:57:57 -04:00
Kenneth Moreland
0be50c119d Update VTK-m code to use new Vec aliases
Should make the code easier to read.
2019-07-31 12:55:40 -06:00
Allison Vacanti
f370857c15 Add CountSetBits and Fill device algorithms. 2019-06-25 11:30:39 -04:00
Robert Maynard
4020f51988 RuntimeDeviceTracker can't be copied and is only accessible via reference.
As the RuntimeDeviceTracker is a per thread construct we now make
it explicit that you can only get a reference to the per-thread
version and can't copy it.
2019-05-20 11:43:05 -04:00
Robert Maynard
065d117838 Testing Device Adapter now uses ArrayHandle for all device transfers
The consistent API for control to execution memory transfers is
the ArrayHandle class. Previously the tests would verify memory
transfer by calling the ArrayManagerExecution class directly. This
is problematic as the class isn't used by ArrayHandle<T, StorageBasic>.
2019-04-30 13:50:08 -04:00
Robert Maynard
d8cc067caa Remove DeviceAdapterError as it isn't needed any more.
Fixes #277

DeviceAdapterError existed to make sure that the default device adapter
template was being handled properly. Since the default device adapter doesn't
exist, and nothing is templated over it we can now remove DeviceAdapterError.
2019-04-18 15:09:57 -04:00
nadavi
fbcea82e78 conslidate the license statement 2019-04-17 10:57:13 -06:00
Robert Maynard
a5dbe1ece3 Merge topic 'bitfields'
661fb64de AtomicInterfaceControl functions are marked with VTKM_SUPPRESS_EXEC_WARNINGS
0c70f9b9a Add BitFieldIn/Out/InOut worklet signature tags.
a66510e81 Add ArrayHandleBitField, a boolean-valued AH backed by a BitField.
56cc5c3d3 Add support for BitFields.
d01b97382 Allow VTKM_SUPPRESS_EXEC_WARNINGS to be used inside macros.
2f2ca9370 Add bit operations FindFirstSetBit and CountSetBits to Math.h.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1629
2019-04-11 12:32:03 -04:00
Allison Vacanti
56cc5c3d3a Add support for BitFields.
BitFields are:
- Stored in memory using a contiguous buffer of bits.
- Accessible via portals, a la ArrayHandle.
- Portals operate on individual bits or words.
- Operations may be atomic for safe use from concurrent kernels.

The new BitFieldToUnorderedSet device algorithm produces an ArrayHandle
containing the indices of all set bits, in no particular order.

The new AtomicInterface classes provide an abstraction into bitwise
atomic operations across control and execution environments and are used
to implement the BitPortals.
2019-04-11 08:27:17 -04:00
Robert Maynard
89ec4aae2f Reduction on CUDA handles different input and output types better
When reducing an input type that differs from the output type
you need to write a custom binary operator that also implements
how to do the unary transformation.
2019-04-10 14:44:44 -04:00
Robert Maynard
ae11e115a0 RuntimeDeviceTracker: Remove Global from names 2019-03-22 08:53:26 -07:00
Haocheng LIU
415252c662 Introduce asynchronous and device independent timer
The timer class now is asynchronous and device independent. it's using an
similiar API as vtkOpenGLRenderTimer with Start(), Stop(), Reset(), Ready(),
and GetElapsedTime() function. For convenience and backward compability, Each
Start() function call will call Reset() internally and each GetElapsedTime()
function call will call Stop() function if it hasn't been called yet for keeping
backward compatibility purpose.

Bascially it can be used in two modes:

* Create a Timer without any device info. vtkm::cont::Timer time;

  * It would enable timers for all enabled devices on the machine. Users can get a
specific elapsed time by passing a device id into the GetElapsedtime function.
If no device is provided, it would pick the maximum of all timer results - the
logic behind this decision is that if cuda is disabled, openmp, serial and tbb
roughly give the same results; if cuda is enabled it's safe to return the
maximum elapsed time since users are more interested in the device execution
time rather than the kernal launch time. The Ready function can be handy here
to query the status of the timer.

* Create a Timer with a device id. vtkm::cont::Timer time((vtkm::cont::DeviceAdapterTagCuda()));

  * It works as the old timer that times for a specific device id.
2019-02-05 12:01:56 -05:00
Robert Maynard
d6f66d17a3 Testing run methods now take argc/argv to init logging/runtime device
`vtkm::cont::testing` now initializes with logging enabled and support
for device being passed on the command line, `vtkm::testing` only
enables logging.
2019-01-17 13:16:27 -06:00
Haocheng LIU
bb06717803 Make RuntimeDeviceInformation class template independent
By making RuntimeDeviceInformation class template independent, vtkm is
able to detect
device info at runtime with a runtime specified deviceId. In the past
it's impossible
because the CRTP pattern does not allow function overloading(compiler
would complain
that DeviceAdapterRuntimeDetector does not have Exists() function
defined).
2018-11-01 14:55:33 -04:00
Robert Maynard
45422478cf Refactor VirtualObjectHandle to support new virtual design 2018-10-15 17:38:54 -04:00
luz.paz
d5beb69ec1 Misc. typos
Found via `codespell`
2018-10-04 10:30:33 -04:00
Robert Maynard
554bc3d369 At runtime TryExecute supports a specific deviceId to execute on.
Instead of always using the first enabled device, now TryExecute
can be told which device at runtime to use.
2018-08-07 17:22:18 -04:00
Robert Maynard
3533975694 Remove usages of std::vector from OpenMP reduction algorithm
The OpenMP Device Reduction algorithm previously used a std::vector<T>
to store the reduction results of each thread. This caused problems
when T=bool as the types became a proxy type which isn't usable
with vtkm BinaryOperators.

Additionally by fixing this issue in the FunctorsOpenMP we
can remove a workaround in FunctorsGeneral that caused
compile failures when using complex BinaryOperators
such as MinAndMax.
2018-08-06 13:08:33 -04:00