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.
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.
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.
When a single `ArrayHandle` is given to multiple arguments of a worklet
dispatch, the `PrepareFor*` methods will be called multiple times with
the same token. If one of them is a `PrepareForInPlace` or
`PrepareForOutput`, then the two requests will deadlock. To prevent
this, allow the `PrepareFor*` to happen if the same token was used
previously.
Duplicated the new versions of PrepareFor* methods from the basic
ArrayHandle that take a token in addition to the other arguments. The
ArrayHandle attaches itself to the token and will not allow operaitons
that make the returned portal invalid until the token goes out of scope.
Later the old versions will be deprecated.
When it was originally created, it was assumed that the ArrayHandle
class would be used by a single thread. As the use of VTK-m expands,
that is no longer a safe assumption. To ensure that operations on
ArrayHandle happen correctly, add a mutex to the Internals of
ArrayHandle and require all operations on the Internals lock that mutex.
Previously when ApplyPolicyFieldOfType was used in cases where not all
of the types matched not all of the storages, those invalid arrays were
replaced with an ArrayHandleDiscard. This unnecessarily increased the
length of the type names used for the resulting ArrayHandleMultiplexer.
Now, ListTagRemoveIf is used to remove any invalid arrays so that the
resulting ArrayHandleMultiplexer only includes the valid arrays.
IsWritableArrayHandle can now be used directly as `std::true_type` or
`std::false_type` without having to pull the `type` member out of a
dependent namespace.
Previously, IsWriteableArrayHandle just checked to see if an
ArrayHandle's portal has a ValueType of void* because we had coded the
special read-only array handles to have fake portals for writing.
However, we recently removed that because it was more trouble than it
was worth. Now IsWritableArrayHandle checks for the existance of the Set
method. If it does not exist, then the portal is considered read-only.
Also corrected spelling (writeable -> writable).
This adds an ExecutionSignature tag named Device that passes the
DeviceAdapterTag as an argument to the worklet's operator(). This allows
worklets to specialize their code based on the device.
There is a test to ensure that basic VTK-m classes have proper move
constructors that do not throw exceptions. Some of these are subclasses
of ArrayHandle. Add these move constructors to the
VTK_M_ARRAY_HANDLE_SUBCLASS macros so they get automatically added.
The original design of invoke and the transport infrastructure
relied on the implementation behavior of vtkm::cont types
such as ArrayHandle that used an internal shared_ptr to managed
state. This allowed passing by value instead of passing by
non-const ref when needing to transfer information to the device.
As VTK-m adds support for classes that use virtuals the ability
to pass by base pointer type allows for us to invoke worklets
using a base type without the risk of type slicing.
Additional by moving over to a non-const ref Invocation we
can update all transports that have 'output' to now be
by ref and therefore support types that can't be copied while
being 'more' correct.
1. Have a per-thread pinned array for cuda errors
2. Check for errors before scheduling new tasks and at explicit sync points
3. Remove explicit synchronizations from most places
Addresses part 2 of #168
Previously, to query whether an ArrayHandle was writable with
IsWriteableArrayHandle, you had to specify a device adapter. The idea
was that it would look at the portal used for that device adapter.
Instead, check the control pointer, which should give the same
indication without having to have a separate check for every type of
device.
Previously memory that was allocated outside of VTK-m was impossible to transfer to
VTK-m as we didn't know how to free it. By extending the ArrayHandle constructors
to support a Storage object that is being moved, we can clearly express that
the ArrayHandle now owns memory it didn't allocate.
Here is an example of how this is done:
```cpp
T* buffer = new T[100];
auto user_free_function = [](void* ptr) { delete[] static_cast<T*>(ptr); };
vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>
storage(buffer, 100, user_free_function);
vtkm::cont::ArrayHandle<T> arrayHandle(std::move(storage));
```
By pruning the invalid combinations first we reduce the amount of work
the compiler has to do. Additionally it makes for smaller callstacks when
the compiler errors out during a CastAndCall.
By hard coding the PrepareForDevice to know about all the different VTK-m
devices, we can have a single base class do the execution allocation, and not
have that logic repeated in each child class.
1. Add option to copy user supplied array in make_ArrayHandle.
2. Replace Field constructors that take user supplied arrays with make_Field.
3. Replace CoordinateSystem constructors that take user supplied arrays with
make_CoordinateSystem.
In generic code, it's a pain to use the equality operators since they
requires the ValueType and Storage to match, else the operator is undefined.
This commit adds operators for such comparisons, as well as a unit test.
Sandia National Laboratories recently changed management from the
Sandia Corporation to the National Technology & Engineering Solutions
of Sandia, LLC (NTESS). The copyright statements need to be updated
accordingly.
The old templated array transfer mechanism generated a lot of code
that ended up doing a simple, type-agnostic memcpy for most devices.
This patch specialized array handles for basic storage and uses a
fast-path array transfer implementation. This reduces the size of the
vtkm_cont library by 27% on gcc (from 6.2MB to 4.5MB).