Whan an `UnknownArrayHandler` is constructed from an `ArrayHandle`, it uses
the `VecTraits` of the component type to construct its internal functions.
This meant that you could not put an `ArrayHandle` with a component type
that did not have `VecTraits` into an `UnknownArrayHandle`.
`UnknownArrayHandle` now no longer needs the components of its arrays to
have `VecTraits`. If the component type of the array does not have
`VecTraits`, it treats the components as if they are a scalar type.
Rather than require `ArrayCopy` to create special versions of copy for
all arrays, use a precompiled versions. This should speed up compiles,
reduce the amount of code being generated, and require the device
compiler on fewer source files.
There are some cases where you still need to copy arrays that are not
well supported by the precompiled versions in `ArrayCopy`. (It will
always work, but the fallback is very slow.) In this case, you will want
to switch over to `ArrayCopyDevice`, which has the old behavior.
Under some circumstances, `IsType` can return false for a type that
exactly matches the type used to create the `UnknownArrayHandle`.
This is because types like `ArrayHandleCast` get converted to
the array they contain. Thus, `IsType` will return false when it
is expected to be true. In most cases, you should use
`CanConvert`. The `IsType` documentation now points you there.
For some reason, GCC is dropping the templated function instances use
for the `UnknownArrayHandle` constructor. Apparently, something in the
compiler or the linker is being over aggressive about removing unused
symbols and is actually dropping symbols that are being used. Maybe it
is because the functions are not directly called but their pointers are
used.
To get around this problem, mark these templated functions in
UnknownArrayHandle.h with the `used` attribute to force the compiler/
linker to keep them. There should be no consequence to that as these
function templates are only instantiated if they are used.
`vtkm::cont::UnknownArrayHandle` now provides a set of method that
allows you to copy data from one `UnknownArrayHandle` to another. The
first method, `DeepCopyFrom`, takes a source `UnknownArrayHandle` and
deep copies the data to the called one. If the `UnknownArrayHandle`
already points to a real `ArrayHandle`, the data is copied into that
`ArrayHandle`. If the `UnknownArrayHandle` does not point to an existing
`ArrayHandle`, then a new `ArrayHandleBasic` with the same value type as
the source is created and copied into.
The second method, `CopyShallowIfPossibleFrom` behaves similarly to
`DeepCopyFrom` except that it will perform a shallow copy if possible.
That is, if the target `UnknownArrayHandle` points to an `ArrayHandle`
of the same type as the source `UnknownArrayHandle`, then a shallow copy
occurs and the underlying `ArrayHandle` will point to the source. If the
types differ, then a deep copy is performed. If the target
`UnknownArrayHandle` does not point to an `ArrayHandle`, then the
behavior is the same as the `=` operator.
One of the intentions of these new methods is to allow you to copy
arrays without using a device compiler (e.g. `nvcc`). Calling
`ArrayCopy` requires you to include the `ArrayCopy.h` header file, and
that in turn requires device adapter algorithms. These methods insulate
you from these.
835467753 Fix link issue with discarded section
42acb9a66 Properly check whether ArrayHandleRecombineVec is on device
c17a5569f Do not try to use ArrayGetValue on arrays of non-basic types
9ca0cd1f6 Report array type when UnknownArrayHandle::ExtractComponent fails
e1ac918bc Compile ArrayGetValues implementation in library
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Li-Ta Lo <ollie@lanl.gov>
Merge-request: !2551
In VTK-m we have a constant tension between minimizing the number of
types we have to compile for (to reduce compile times and library size)
and maximizing the number of types that our filters support.
Unfortunately, if you don't compile a filter for a specific array type
(value type and storage), trying to run that filter will simply fail.
To compromise between the two, added methods to `DataSet` and `Field`
that will automatically convert the data in the `Field` arrays to a type
that VTK-m will understand. Although this will cause an extra data copy,
it will at least prevent the program from failing, and thus make it more
feasible to reduce types.
In one of the dashboards, we got a link error about one of the
UnknownArrayHandle internal methods being discarded and then used. Add
an explicit `__attribute__((used))` modifier to prevent this from
happening.
Having UnknownArrayHandle.h include DefaultTypes.h is problematic,
because that header includes lots of other classes like cell sets.
Keeping these from in turn depending back on UnknownArrayHandle.h is
difficult. So this dependancy is broken.
Added features with reporting types with `UnknownArrayHandle`. First,
added a method named `GetArrayTypeName` that returns a string containing
the type of the contained array. There were already methods
`GetValueType` and `GetStorageType`, but this provides a convenience to
get the whole name in one go.
Also improved the reporting when an `AsArrayHandle` call failed. Before,
the thrown method just reported that the `UnknownArrayHandle` could not
be converted to the given type. Now, it also reports the type actually
held by the `UnknownArrayHandle` so the user can better understand why
the conversion failed.
`UnknownArrayHandle` supported an `Allocate` method to change
the size of the underlying array without knowing its type.
However, it did not give all the features of `ArrayHandle`'s
allocate. Namely, you could not specify that the data should
be preserved and you could not provide a `Token` object. This
change adds these (optional) parameters.
`UnknownArrayHandle` treats a `ArrayHandleCast` and
`ArrayHandleMultiplexer` special. When you put one of these arrays in an
`UnknownArrayHandle`, it takes the original array out and stores it. If
you try to take an array of that type out, it will again do the proper
conversion.
The only problem is that if you use `IsType`, the result can be
unexpected. This is what happened with `CastAndCall`, which was using
`IsType` internally. Changed that to `CanConvert` to properly get the
array handle out.
Add an overload of `ArrayCopy` that takes `UnknownArrayHandle`s and
copies them for (almost) any `ArrayHandle` type.
The code uses `CastAndCallWithExtractedArray` to reduce the total number
of copy conditions to about 100, which are all precompiled into the
library. On a debug build on my mac, this creates a .o file of 21MB.
That's not great, but not terrible. Hopefully, this can be used to
consolidate copy implementations elsewhere.
This provides the ability to convert an array handle of an unknown value
type to an array handle that has `vtkm::FloatDefault` as its base
component type. Thus subsequently lets you pull the components as
`vtkm::FloatDefault` without having to worry about type conflicts.
The `VariantArrayHandle` will soon be deprecated for its replacement of
`UnknownArrayHandle`. Thus, `Field` and related classes should start
using the new `UnknownArrayHandle`.
The base C types have several "duplicate" types that the compiler
considers different even though the byte representation is the same. For
example, `char` and `signed char` have the same meaning but are treated
as different types. Likewise, 'long', 'int', and 'long long' are all
different types even though 'long' is the same as either 'int' or 'long
long'.
When pulling extracted components from `UnknownArrayHandle`, there is
little value for creating multiple code paths for types like `char` and
`signed char`. Instead, allow implicit conversion among these types.
This method was originally deprecated to avoid confusion with the
indexing of the components in `ExtractComponent`. However, there might
be good reason to want to know the non-flat number of components, so
maybe getting rid of it is not a great idea. Unmark the method as
deprecated, at least for now.
This method allows you to extract an `ArrayHandle` from
`UnknownArrayHandle` when you only know the base component type.
Also removed the `Read/WritePortalForBaseComponentType` method
from `UnknownArrayHandle`. This functionality is subsumed by
`ExtractArrayFromComponents`.
The previous implementation of test_equal_ArrayHandles was several
templates that had to be resolved by any test that used them, which
could be costly for unknown array types. Simplify this a bit by moving
the implementation of testing unknown arrays into a library.
Another advantage of the new implementation is that is handles more
cases. Thus, you should not need to `ResetTypes` on the unknown/
uncertain arrays.
Previously, the `MapFieldMergeAverage` and `MapFieldPermutation` helper
function had to iterate over every possible type and create a separate
code path. This change uses the new extract component functionality to
create separate code paths only for different component types. This both
requires less code (the common filter library dropped from 66MB to 42MB
on my Mac) and covers more cases (such as `Vec`s larger than 4
components).
To make the implementation easier, `UnknownArrayHandle` now can create a
new `UnknownArrayHandle` of the same `ValueType` but with the basic
storage (so you can work with read-only storage) and the ability to
allocate the unknown array.
This allows you to handle just about every type of array with about 10
basic types. It allows you to ignore both the size of `Vec`s and the
actual storage of the data.
One of the features of `UnknownArrayHandle` is that it allows you to
query how many `Vec` components each value has without resolve the type
of the array. The functionality to implement this failed if you tried to
store an `ArrayHandle` that stored `Vec`-like objects with `Vec` sizes
that varied from value to value (i.e. an `ArrayHandleGroupVecVariable`).
Storing such an array in `UnknownArrayHandle` might not be the best
idea, but it should probably work. This change allows you to store such
an array. If you try to query the number of components, you will get 0.
The Visual Studio compiler has an annoying habit where if you use a
templated class or method with a deprecated class as a template
parameter, you will get a deprecation warning where that class is used
in the templated thing. Thus, if you want to suppress the warning, you
have to supress every instance of the template, not just where the
template is declared.
This is annoying behavior that is thankfully not replicated in other
compilers.
The implementation of `VariantArrayHandle` has been changed to be a
relatively trivial subclass of `UnknownArrayHandle`.
The advantage of this change is twofold. First, it removes
`VariantArrayHandle`'s dependence on `ArrayHandleVirtual`, which gets us
much closer to deprecating that class. Second, it ensures that
`UnknownArrayHandle` is a reasonable replacement for
`VariantArrayHandle`, so we can move forward with replacing that.