2.3. Non-dense blocks

In the following example, we construct a subview of a dense view, aliasing every second value from a dense view, yielding a view with stride 2:

void process(float *data, ptrdiff_t stride, size_t size);
...
Vector<float> v(8);
Vector<float>::subview_type subview = view.get(Domain<1>(0, 2, 4));
vsip_csl::dda::Ext_data<Vector<float>::block_type> ext(v.block());
process(ext.data(), ext.stride(), ext.size());

However, some functions may require unit-stride input. In that case, it is possible to force unit-stride access. The Ext_data<> object will copy the data into temporary storage, which the user then operates on, and synchronize back with the block it was constructed from. This synchronization may not always be necessary, and so it is possible to express whether to synchronize only from the block to the Ext_data<> object, the inverse, or both.

typedef Vector<float>::subview_type::block_type block_type;
typedef dda::Layout<1, row1_type, dda::Stride_unit> layout_type;

dda::Ext_data<block_type, layout_type> ext(subview.block(), dda::SYNC_OUT);
ramp(ext.data(), ext.size());

As this access type may involve a performance penalty (temporary data allocation, as well as one or two copy operations), it is desirable to be able to query whether the direct data access comes with an extra cost. A user may decide to prefer unit-stride, as long as no copies are involved, but fall back to non-unit stride access otherwise:

typedef Vector<float>::subview_type::block_type block_type;
typedef dda::Layout<1, row1_type, dda::Stride_unit> layout_type;
if (dda::Ext_data<block_type, layout_type>::CT_Cost != 0)
{
  // If unit-stride access would require a copy,
  // choose non-unit stride access
  dda::Ext_data<block_type> ext(subview.block());
  ramp(ext.data(), ext.stride(0), ext.size());
}
else
{
  dda::Ext_data<block_type, layout_type> ext(subview.block(), dda::SYNC_OUT);
  ramp(ext.data(), ext.size());
}

Note that the Ext_data<>::CT_cost value is a compile-time constant, and thus can be used in compile-time expressions. Therefore, the above conditional may be done via compile-time decisions (e.g. template specializations).

In the above example we have considered unit- versus non-unit stride direct data access. However, there are other cases where data can never be accessed directly without copies, for example if the block represents an expression.