Peano 4
Loading...
Searching...
No Matches
tarch::la::Vector< Size, Scalar > Struct Template Reference

Simple vector class. More...

#include <Vector.h>

Public Member Functions

 Vector () InlineMethod=default
 Clang requires the always_inline attribute, as it otherwise makes weird decisions.
 
 Vector (const Scalar *values) InlineMethod
 
 Vector (std::initializer_list< Scalar > values)
 Initialisation via initialisation list.
 
 Vector (const std::bitset< Size > &values) InlineMethod
 
 Vector (const Scalar &initialValue)
 Construct new vector and initialize all components with initialValue.
 
Vector< Size, Scalar > & operator= (const Vector< Size, Scalar > &toAssign) InlineMethod
 Assignment operator for any vector type.
 
 Vector (const Vector< Size, Scalar > &toCopy)
 Copy constructor to copy from any vector type.
 
int size () const
 Returns the number of components of the vector.
 
const Scalar & operator[] (int index) const InlineMethod
 Returns read-only ref.
 
Scalar & operator[] (int index) InlineMethod
 Returns ref.
 
const Scalar & operator() (int index) const InlineMethod
 Returns read-only ref.
 
Scalar & operator() (int index) InlineMethod
 Returns ref.
 
Scalar * data ()
 This routine returns a pointer to the first data element.
 
const Scalar * data () const
 

Private Attributes

Scalar _values [Size]
 

Detailed Description

template<int Size, typename Scalar>
struct tarch::la::Vector< Size, Scalar >

Simple vector class.

Most features concerning vectors are deployed into separate headers:

There are multiple ways how to construct a vector:

  • You can use the standard constructor which gives a vector with garbage entries. You can then set individual entries manually.
  • You can use the constructor with a scalar which initialises all entries with the same value.
  • You can use initialiser lists, i.e. lists in curly brackets { and }, to construct a vector from a list.

To access entries of a vector, the class provides both access via an array notation, i.e. through [...], and with round brackets. The latter notation resembles Matlab. No matter which accessor you use, enumeration always starts with zero.

The class wraps an array of fixed size. Therefore, you can access the raw data via data(), but this violates ideas of object-oriented programming and hence should be done with care. Peano for example does this if and only if it has to hand over raw pointers to MPI, e.g.

GPGPU offloading

OpenMP

To make the vector operations available on the GPU, they have to be labelled as offloadable according to Section 4.5.2 (page 117) of the standard (https://www.openmp.org/wp-content/uploads/openmp-examples-4.5.0.pdf). There, the text highlights that declare target is a declaration thing, i.e., should not be applied to the definition.

However, it is not clear whether the compiler expects the function definition to be within the declaration, too, and if this makes a difference here at all: As the vector is a template, it is header-only anyway. Therefore, the compiler implicitly should have the definition at hand and should be able to identify that code for the GPU has to be generated, too. We only have to be sure that no explicit instantiation of a vector ignores this context, i.e. do not use explicit instantation if you employ GPUs (through OpenMP).

With GCC, I struggled using the Vector's copy constructors. That is, my impression is that the GCC compiler struggles to handle templates plus overloading if these are implicitly used within a map clause. Therefore, I often offload code through the standard constructor, deploy the vector components manually, thus avoid all copy constructor invocations explicitly, and finally repuzzle the vector together on the GPU. This implies that GPU routines may never return a Vector instance. See the Rusanov.cpph kernels for examples where this leads to uglier code than necessary. But it works.

SYCL

Our SYCL kernels seem to be fine without explicit support of the vector, but this is mainly due to the fact that SYCL offers its own range class, and we construct our vectors typically from this range class. The other application domain is the double vectors within the cell descriptors, but we map those onto specialsed variants before we offload anyway, so they are on the GPU prior to the kernel launch. In the future, it might be appropriate to add explicit copyable traits to to the class such that they can directly go to the GPU:

template<>
struct sycl::is_device_copyable< tarch::la::Vector<2,double> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<3,double> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<4,double> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<5,double> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<2,int> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<3,int> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<4,int> >: std::true_type {};
template<>
struct sycl::is_device_copyable< tarch::la::Vector<5,int> >: std::true_type {};
Have to include this header, as I need access to the SYCL_EXTERNAL keyword.
Definition accelerator.h:17
Simple vector class.
Definition Vector.h:134

Definition at line 134 of file Vector.h.

Constructor & Destructor Documentation

◆ Vector() [1/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( )
default

Clang requires the always_inline attribute, as it otherwise makes weird decisions.

◆ Vector() [2/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( const Scalar * values)

Definition at line 2 of file Vector.cpph.

References values.

◆ Vector() [3/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( std::initializer_list< Scalar > values)

Initialisation via initialisation list.

There is seemingly a bug in this constructor.

You can't inline an initialisation list, as the realisation of this routine relies on an iterator and the iterator within the C++ std lib won't be inlined.

For instance, the arguments peano4::initSingletons to are two objects of type tarch::la::Vector, with length Dimensions. However, passing in two initializer lists which are longer than Dimensions will cause the second to borrow from the first.

Definition at line 14 of file Vector.cpph.

References values.

◆ Vector() [4/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( const std::bitset< Size > & values)

Definition at line 24 of file Vector.cpph.

◆ Vector() [5/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( const Scalar & initialValue)

Construct new vector and initialize all components with initialValue.

Definition at line 65 of file Vector.cpph.

References tarch::la::Vector< Size, Scalar >::_values.

◆ Vector() [6/6]

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar >::Vector ( const Vector< Size, Scalar > & toCopy)

Copy constructor to copy from any vector type.

The only way to accomplish this with enable-if is to specify a second dummy argument with default value, which is (hopefully) optimized away.

See also
operator= for a discussion of SSE optimisation.

Definition at line 48 of file Vector.cpph.

References tarch::la::Vector< Size, Scalar >::_values, and assertion.

Member Function Documentation

◆ data() [1/2]

template<int Size, typename Scalar >
Scalar * tarch::la::Vector< Size, Scalar >::data ( )

This routine returns a pointer to the first data element.

Not a beautiful one as it harms the OO idea, but in many cases it is convenient to have this operation.

Definition at line 254 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values.

Referenced by peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__generate_dastgen_input_file(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__get_file_name(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__get_full_qualified_file_name(), swift2.particle.Particle.Particle::__init__(), swift2.particle.Particle.Particle::_add_dependency_checks(), swift2.particle.Particle.Particle::_dependency_checks_modify_steps(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_boolean_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_boolean_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_double_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_double_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_enum_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_integer_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_integer_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_peano_double_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_peano_integer_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_string_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_user_defined_attributes(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::_get_dictionary_for_output(), toolbox::multiprecision::compress(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::construct_output(), peano4.datamodel.DynamicArrayOverPrimitivesToStdVector.DynamicArrayOverPrimitivesToStdVector::construct_output(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::construct_output(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::construct_output(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::construct_output(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::get_header_file_include(), peano4.datamodel.DynamicArrayOverPrimitivesToStdVector.DynamicArrayOverPrimitivesToStdVector::get_header_file_include(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::get_header_file_include(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::get_header_file_include(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::get_header_file_include(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::get_stack_container(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::get_stack_container(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::get_stack_container(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::get_stack_container(), swift2.particle.Particle.Particle::readme_descriptor(), swift2.particle.SPHLeapfrogFixedSearchRadius.SPHLeapfrogFixedSearchRadius::set_parameters(), swift2.particle.SPHParticle.SPHParticle::set_parameters(), and swift2.particle.tests.testLeapfrogFixedTimeStepSize.testLeapfrogFixedTimeStepSize::set_parameters().

Here is the caller graph for this function:

◆ data() [2/2]

template<int Size, typename Scalar >
const Scalar * tarch::la::Vector< Size, Scalar >::data ( ) const

Definition at line 258 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values.

Referenced by peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__generate_dastgen_input_file(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__get_file_name(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::__get_full_qualified_file_name(), swift2.particle.Particle.Particle::__init__(), swift2.particle.Particle.Particle::_add_dependency_checks(), swift2.particle.Particle.Particle::_dependency_checks_modify_steps(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_boolean_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_boolean_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_double_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_double_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_enum_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_integer_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_integer_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_peano_double_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_peano_integer_array_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_string_attributes(), swift2.particle.tests.DastgenTestDummyParticle.DastgenTestDummyParticle::_generate_user_defined_attributes(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::_get_dictionary_for_output(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::construct_output(), peano4.datamodel.DynamicArrayOverPrimitivesToStdVector.DynamicArrayOverPrimitivesToStdVector::construct_output(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::construct_output(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::construct_output(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::construct_output(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::get_header_file_include(), peano4.datamodel.DynamicArrayOverPrimitivesToStdVector.DynamicArrayOverPrimitivesToStdVector::get_header_file_include(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::get_header_file_include(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::get_header_file_include(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::get_header_file_include(), peano4.datamodel.DaStGenToLegacyTool.DaStGenToLegacyTool::get_stack_container(), peano4.datamodel.PatchToDoubleArray.PatchToDoubleArray::get_stack_container(), peano4.datamodel.PatchToDoubleArrayOnHeap.PatchToDoubleArrayOnHeap::get_stack_container(), peano4.datamodel.PatchToDoubleArrayWithSmartPointer.PatchToDoubleArrayWithSmartPointer::get_stack_container(), swift2.particle.Particle.Particle::readme_descriptor(), swift2.particle.SPHLeapfrogFixedSearchRadius.SPHLeapfrogFixedSearchRadius::set_parameters(), swift2.particle.SPHParticle.SPHParticle::set_parameters(), and swift2.particle.tests.testLeapfrogFixedTimeStepSize.testLeapfrogFixedTimeStepSize::set_parameters().

Here is the caller graph for this function:

◆ operator()() [1/2]

template<int Size, typename Scalar >
const Scalar & tarch::la::Vector< Size, Scalar >::operator() ( int index) const

Returns read-only ref.

to component of given index.

If we use the vector on the GPU, we cannot have assertions. If we use SYCL on the CPU for the multitasking, we cannot have assertions in the SYCL part either, as SYCL aims to be platform-independent, i.e. has to assume that the code generated also will be deployed to a GPU. See discussion on SYCL support.

See also
operator[] for remarks on SSE

Definition at line 228 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values, assertion3, and tarch::toString().

Here is the call graph for this function:

◆ operator()() [2/2]

template<int Size, typename Scalar >
Scalar & tarch::la::Vector< Size, Scalar >::operator() ( int index)

Returns ref.

to component of given index.

See also
operator[] for remarks on SSE

Definition at line 241 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values, assertion3, and tarch::toString().

Here is the call graph for this function:

◆ operator=()

template<int Size, typename Scalar >
tarch::la::Vector< Size, Scalar > & tarch::la::Vector< Size, Scalar >::operator= ( const Vector< Size, Scalar > & toAssign)

Assignment operator for any vector type.

Vectorisation

We do not allow assignment of a vector this itself. Consequently, we can insert an ivdep statement and thus allow the compiler to optimise.

Definition at line 31 of file Vector.cpph.

References tarch::la::Vector< Size, Scalar >::_values, and assertion.

◆ operator[]() [1/2]

template<int Size, typename Scalar >
const Scalar & tarch::la::Vector< Size, Scalar >::operator[] ( int index) const

Returns read-only ref.

to component of given index.

SSE Optimisation

  • We have to manually inline this operation. Otherwise, icc interprets operator calls, i.e. vector element accesses, as function calls and does not vectorise loops containing vector element accesses.

Definition at line 196 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values, assertion3, assertion4, and tarch::toString().

Here is the call graph for this function:

◆ operator[]() [2/2]

template<int Size, typename Scalar >
Scalar & tarch::la::Vector< Size, Scalar >::operator[] ( int index)

Returns ref.

to component of given index.

See also
operator[] for remarks on SSE

Definition at line 209 of file Vector.h.

References tarch::la::Vector< Size, Scalar >::_values, assertion3, and tarch::toString().

Here is the call graph for this function:

◆ size()

template<int Size, typename Scalar >
int tarch::la::Vector< Size, Scalar >::size ( ) const

Returns the number of components of the vector.

Definition at line 75 of file Vector.cpph.

Referenced by peano4.visualisation.Patch.Patch::__str__().

Here is the caller graph for this function:

Field Documentation

◆ _values


The documentation for this struct was generated from the following files: