Protecting Vectorview from Magnetic Contamination The Vectorview system is comprised of 306 thin-film superconducting interference devices (SQUIDs). The sensors are ultra-sensitive in that they can pick up changes in a magnetic field in the range of femtoteslas. Because of this sensitivity, the Vectorview is placed inside a MSR. Our Vectorview systems contains 102 magnetometers and 204 planar gradiometers. Magnetometers consist of a single coil which measures the magnetic flux perpendicular to its surface. Planar gradiometers consist of a 'figure-of-eight'-type coil configuration. Represents a read-only view of a sequential collection of objects that can be individually accessed by index. The type of each object in the collection is specified by the template parameter.

Introduction

This tutorial introduces vectors in TNL. Vector, in addition to Array, offers also basic operations from linear algebra. The reader will mainly learn how to do Blas level 1 operations in TNL. Thanks to the design of TNL, it is easier to implement, hardware architecture transparent and in some cases even faster then Blas or cuBlas implementation.

Vectors

Vector is, similar to Array, templated class defined in namespace TNL::Containers having three template parameters:

  • Real is type of data to be stored in the vector
  • Device is the device where the vector is allocated. Currently it can be either Devices::Host for CPU or Devices::Cuda for GPU supporting CUDA.
  • Index is the type to be used for indexing the vector elements.

Vector, unlike Array, requires that the Real type is numeric or a type for which basic algebraic operations are defined. What kind of algebraic operations is required depends on what vector operations the user will call. Vector is derived from Array so it inherits all its methods. In the same way the Array has its counterpart ArraView, Vector has VectorView which is derived from ArrayView. We refer to to Arrays tutorial for more details.

Horizontal operations

By horizontal operations we mean vector expressions where we have one or more vectors as an input and a vector as an output. In TNL, this kind of operations is performed by the Expression Templates. It makes algebraic operations with vectors easy to do and very efficient at the same time. In some cases, one get even more efficient code compared to Blas and cuBlas. See the following example.

#include <TNL/Containers/Vector.h>
using namespace TNL::Containers;
template< typename Device >
{
using VectorType = Vector< RealType, Device >;
* Create vectors
constint size = 11;
VectorType a_v( size ), b_v( size ), c_v( size );

Vector Viewer For Mac

ViewType b = b_v.getView();
a.forAllElements( [] __cuda_callable__ ( int i, RealType& value ) { value = 3.14 * ( i - 5.0 ) / 5.0; } );
c = 3 * a + sign( a ) * sin( a );
std::cout << 'sin( a ) = ' << sin( a ) << std::endl;
std::cout << 'abs( sin( a ) ) = ' << abs( sin ( a ) ) << std::endl;
std::cout << 'c = ' << c << std::endl;
{
* Perform test on CPU
std::cout << 'Expressions on CPU ...' << std::endl;
* Perform test on GPU
std::cout << std::endl;
std::cout << 'Expressions on GPU ...' << std::endl;
}
T endl(T... args)
Namespace for TNL containers.
The main TNL namespace.

Victor Vieweg

__cuda_callable__ T abs(const T &n)
This function returns absolute value of given number n.
VectorView
__cuda_callable__ T sign(const T &a)
Definition: Math.h:487
T sin(T... args)

Output is:

a = [ -3.14, -2.512, -1.884, -1.256, -0.628, 0, 0.628, 1.256, 1.884, 2.512, 3.14 ]
sin( a ) = [ -0.00159255, -0.588816, -0.951351, -0.950859, -0.587528, 0, 0.587528, 0.950859, 0.951351, 0.588816, 0.00159255 ]
abs( sin( a ) ) = [ 0.00159255, 0.588816, 0.951351, 0.950859, 0.587528, 0, 0.587528, 0.950859, 0.951351, 0.588816, 0.00159255 ]
b = [ 9.8596, 6.31014, 3.54946, 1.57754, 0.394384, 0, 0.394384, 1.57754, 3.54946, 6.31014, 9.8596 ]
c = [ -9.41841, -6.94718, -4.70065, -2.81714, -1.29647, 0, 2.47153, 4.71886, 6.60335, 8.12482, 9.42159 ]
Expressions on GPU ...
a = [ -3.14, -2.512, -1.884, -1.256, -0.628, 0, 0.628, 1.256, 1.884, 2.512, 3.14 ]
sin( a ) = [ -0.00159255, -0.588816, -0.951351, -0.950859, -0.587528, 0, 0.587528, 0.950859, 0.951351, 0.588816, 0.00159255 ]
abs( sin( a ) ) = [ 0.00159255, 0.588816, 0.951351, 0.950859, 0.587528, 0, 0.587528, 0.950859, 0.951351, 0.588816, 0.00159255 ]
b = [ 9.8596, 6.31014, 3.54946, 1.57754, 0.394384, 0, 0.394384, 1.57754, 3.54946, 6.31014, 9.8596 ]
c = [ -9.41841, -6.94718, -4.70065, -2.81714, -1.29647, 0, 2.47153, 4.71886, 6.60335, 8.12482, 9.42159 ]

Vector expressions work only with VectorView not with Vector. The expression is evaluated on the same device where the vectors are allocated, this is done automatically. One cannot, however, mix vectors from different devices in one expression. Vector expression may contain any common function like min, max, abs, sin, cos, exp, log, sqrt, pow etc.

Vertical operations

By vertical operations we mean (parallel) reduction based operations where we have one vector expressions as an input and one value as an output. For example computing scalar product, vector norm or finding minimum or maximum of vector elements is based on reduction. See the following example.

#include <TNL/Containers/Vector.h>
using namespace TNL::Containers;
template< typename Device >
{
using VectorType = Vector< RealType, Device >;
* Create vectors
constint size = 11;
VectorType a_v( size ), b_v( size ), c_v( size );
ViewType b = b_v.getView();
a.forAllElements( [] __cuda_callable__ ( int i, RealType& value ) { value = i; } );
b.forAllElements( [] __cuda_callable__ ( int i, RealType& value ) { value = i - 5.0; } );
std::cout << 'b = ' << b << std::endl;
auto arg_min_a = argMin( a );
auto arg_min_b = argMin( b );
std::cout << 'min( a ) = ' << arg_min_a.second << ' at ' << arg_min_a.first << std::endl;
std::cout << 'max( a ) = ' << arg_max_a.second << ' at ' << arg_max_a.first << std::endl;
std::cout << 'min( b ) = ' << arg_min_b.second << ' at ' << arg_min_b.first << std::endl;
std::cout << 'max( b ) = ' << arg_max_b.second << ' at ' << arg_max_b.first << std::endl;
std::cout << 'min( abs( b ) ) = ' << min( abs( b ) ) << std::endl;
std::cout << 'sum( b ) = ' << sum( b ) << std::endl;
std::cout << 'sum( abs( b ) ) = ' << sum( abs( b ) ) << std::endl;
std::cout << 'Scalar product: ( a, b ) = ' << ( a, b ) << std::endl;
std::cout << 'Scalar product: ( a + 3, abs( b ) / 2 ) = ' << ( a + 3, abs( b ) / 2 ) << std::endl;
std::cout << 'abs( a + b ) <= abs( a ) + abs( b ) holds' << std::endl;
{
* Perform test on CPU
std::cout << 'Expressions on CPU ...' << std::endl;
* Perform test on GPU
#ifdef HAVE_CUDA
std::cout << 'Expressions on GPU ...' << std::endl;
#endif
__cuda_callable__ ResultType min(const T1 &a, const T2 &b)
Definition: Math.h:32

Output is:

a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
c = [ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5 ]
max( a ) = 10 at 10
max( b ) = 10 at 5
sum( b ) = 0
Scalar product: ( a, b ) = 110
abs( a + b ) <= abs( a ) + abs( b ) holds
Expressions on GPU ...
b = [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 ]
c = [ -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5 ]
max( a ) = 10 at 10
max( b ) = 10 at 5
sum( b ) = 0
Scalar product: ( a, b ) = 110
abs( a + b ) <= abs( a ) + abs( b ) holds

Static vectors

Static vectors are derived from static arrays and so they are allocated on the stack and can be created in CUDA kernels as well. Their size is fixed as well and it is given by a template parameter. Static vector is a templated class defined in namespace TNL::Containers having two template parameters:

  • Size is the array size.
  • Real is type of numbers stored in the array.

The interface of StaticVectors is smillar to Vector. Probably the most important methods are those related with static vector expressions which are handled by expression templates. They make the use of static vectors simpel and efficient at the same time. See the following simple demonstration:

#include <TNL/Containers/StaticVector.h>
using namespace TNL;
{
Vector v1( 1.0 ), v2( 1.0, 2.0, 3.0 ), v3( v1 - v2 / 2.0 );
v5 *= v3;
std::cout << 'v2 = ' << v2 << std::endl;
std::cout << 'v4 = ' << v4 << std::endl;
std::cout << 'abs( v3 - 2.0 ) = ' << abs( v3 - 2.0 ) << std::endl;
std::cout << 'v2 * v2 = ' << v2 * v2 << std::endl;

The output looks as:

v2 = [ 1, 2, 3 ]
v4 = [ 1, 2, 3 ]
abs( v3 - 2.0 ) = [ 1.5, 2, 2.5 ]

Distributed vectors

Vector Viewer

TODO

Coments are closed

Recent News

  • Instruments Quiz
  • Blop Blop
  • PhotoMarks
  • Avocode
  • Tune-Instructor

Scroll to top