-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunctor.txt
64 lines (43 loc) · 2.54 KB
/
functor.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Operations
There are three different cases:
1. We want the operation to happen in place, e.g., x += 1
2. We want the operation to allocate new storage, e.g., y = x + 1
3. We want the result in existing storage, e.g., y[0] = x + 1 This would also
happen in case 2 if y were a view.
Going into existing storage via operator=() can be wasteful if it's a view,
i.e., there is a temporary. The solution seems to be to define all vector
operations to take the target storage as an argument. For some BLAS
operations, the natural operation is to overwrite. In this case, the BLAS
wrapper can allocate or not.
If the output variable is equal to the input variable we have case 1. If it's
not defined at all we have case 2. If it's defined ahead we have case 3.
Cases 1 and 3 are basically the same.
The output variable has to be either reference or pointer because it may not be
an array and has to be written to. It cannot be const.
Broadcasting
For unary functors, the situation seems quite clear: we just set mDim to the
dimension of the function. E.g., a DFT is typically 1 dimensional, mDim is 1,
and the broadcast is over all 1D vectors in var.
For binary functors, there are four possible semantics:
1. If var2 is a scalar, it just gets broadcast over the whole of var1. E.g., a
matrix plus a scalar. This is a special case of case 2.
2. Arithmetic Functor. Var2 is a tensor, it is broadcast over all var2 sized
bits of var1. In this case, all of var2 gets broadcast each time. E.g., var1
is matrix, var2 is vector; each row of the matrix has the vector applied to it.
This is the case for basic arithmetic where, additionally, the shapes of the
broadcast dimensions must match.
3. Var2 is a tensor, it has the same dimension as some part of var1; those
dimensions are broadcast together. So, the loop goes over var1 and var2
together. E.g., row concatenation: var1 is matrix, var2 is matrix, they have
the same number of rows. Row 1 of var2 is applied to row 1 of var1.
This case generalises to N-ary functors with N arguments.
4. Matrix multiplication. var2 is a fixed matrix; it is broadcast over each
row of var1.
Scalars and vectors interpretted as views
There are cases where something is defined in terms of a view, but the argument
might be a scalar or vector. How do we handle these?
In C, a vector is a row vector. To make it explicitly a column vector we need
to say y = x.view({n,1}).
There is an issue about whether to interpret a row vector as a column vector if
it is not otherwise indicated by a view.
Concatenate seems to need a column vector.