1
1
# Vectorization
2
2
3
- <!--
4
3
Programmers and Data Scientists want to take advantage of fast and parallel
5
4
computational devices. Writing vectorized code is necessary to get
6
- therust,noplayperust,noplaypen performance out of the current generation parallel hardware and
5
+ the best performance out of the current generation parallel hardware and
7
6
scientific computing software. However, writing vectorized code may not be
8
7
immediately intuitive. ArrayFire provides many ways to vectorize a given code
9
- segment. In this tutorial , we present several methods to vectorize code
8
+ segment. In this chapter , we present several methods to vectorize code
10
9
using ArrayFire and discuss the benefits and drawbacks associated with each method.
11
10
12
- ### Generic/Default vectorization
13
- -->
11
+ ## Generic/Default vectorization
14
12
By its very nature, ArrayFire is a vectorized library. Most functions operate on
15
13
Arrays as a whole -- on all elements in parallel. For example consider the following code:
16
14
@@ -26,7 +24,7 @@ A small subset of such vectorized ArrayFire functions are given below for quick
26
24
27
25
| Operator Category | Functions |
28
26
| --------------------------------------------------------------| ----------------------------|
29
- | Arithmetic operations | +, -, * , /, %, >>, << |
27
+ | Arithmetic operations | +, -, \ * , /, %, >>, << |
30
28
| Logical operations | &&, \|\| , <, >, ==, != etc. |
31
29
| Numeric functions | [ abs] ( ../fn.abs.html ) , [ floor] ( ../fn.floor.html ) , [ round] ( ../fn.round.html ) , [ min] ( ../fn.min.html ) , [ max] ( ../fn.max.html ) , etc. |
32
30
| Complex operations | [ real] ( ../fn.real.html ) , [ imag] ( ../fn.imag.html ) , [ conjg] ( ../fn.conjg.html ) , etc. |
@@ -69,103 +67,18 @@ let rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR);
69
67
70
68
Although * most* functions in ArrayFire do support vectorization, some do not.
71
69
Most notably, all linear algebra functions. Even though they are not vectorized
72
- linear algebra operations still execute in parallel on your hardware.
70
+ linear algebra operations, they still execute in parallel on your hardware.
73
71
74
72
Using the built in vectorized operations should be the first
75
73
and preferred method of vectorizing any code written with ArrayFire.
76
74
77
- <!--
78
- # Batching
75
+ ## GFOR
79
76
80
- The batchFunc() function allows the broad application of existing ArrayFire
81
- functions to multiple sets of data. Effectively, batchFunc() allows ArrayFire
82
- functions to execute in "batch processing" mode. In this mode, functions will
83
- find a dimension which contains "batches" of data to be processed and will
84
- parallelize the procedure.
77
+ This construct is similar to gfor loop from C++ API of ArrayFire. It has not
78
+ been implemented in rust wrapper. This section will be updated once the feature
79
+ has been added to the crate.
85
80
86
- Consider the following example. Here we create a filter which we would like
87
- to apply to each of the weight vectors. The naive solution would be using a
88
- for-loop as we have seen previously:
81
+ ## batch\_ func
89
82
90
- ```rust,noplaypen
91
- // Create the filter and the weight vectors
92
- af::array filter = randn(1, 5);
93
- af::array weights = randu(5, 5);
94
-
95
- // Apply the filter using a for-loop
96
- af::array filtered_weights = constant(0, 5, 5);
97
- for(int i=0; i<weights.dims(1); ++i){
98
- filtered_weights.col(i) = filter * weights.col(i);
99
- }
100
- ```
101
-
102
- However, as we have discussed above, this solution will be very inefficient.
103
- One may be tempted to implement a vectorized solution as follows:
104
-
105
- ```rust,noplaypen
106
- // Create the filter and the weight vectors
107
- af::array filter = randn(1, 5);
108
- af::array weights = randu(5, 5);
109
-
110
- af::array filtered_weights = filter * weights; // fails due to dimension mismatch
111
- ```
112
-
113
- However, the dimensions of `filter` and `weights` do not match, thus ArrayFire
114
- will generate a runtime error.
115
-
116
- `batchfunc()` was created to solve this specific problem.
117
- The signature of the function is as follows:
118
-
119
- ```
120
- array batchFunc(const array &lhs, const array &rhs, batchFunc_t func);
121
- ```
122
-
123
- where `__batchFunc_t__` is a function pointer of the form:
124
-
125
- ```
126
- typedef array (*batchFunc_t) (const array &lhs, const array &rhs);
127
- ```
128
-
129
- So, to use batchFunc(), we need to provide the function we wish to apply as a
130
- batch operation. For illustration's sake, let's "implement" a multiplication
131
- function following the format.
132
-
133
- ```
134
- af::array my_mult (const af::array &lhs, const af::array &rhs){
135
- return lhs * rhs;
136
- }
137
- ```
138
-
139
- Our final batch call is not much more difficult than the ideal
140
- syntax we imagined.
141
-
142
- ```
143
- // Create the filter and the weight vectors
144
- af::array filter = randn(1, 5);
145
- af::array weights = randu(5, 5);
146
-
147
- // Apply the batch function
148
- af::array filtered_weights = batchFunc( filter, weights, my_mult );
149
- ```
150
-
151
- The batch function will work with many previously mentioned vectorized ArrayFire
152
- functions. It can even work with a combination of those functions if they are
153
- wrapped inside a helper function matching the `__batchFunc_t__` signature.
154
- One limitation of `batchfunc()` is that it cannot be used from within a
155
- `gfor()` loop at the present time.
156
-
157
- # Advanced Vectorization
158
-
159
- We have seen the different methods ArrayFire provides to vectorize our code. Tying
160
- them all together is a slightly more involved process that needs to consider data
161
- dimensionality and layout, memory usage, nesting order, etc. An excellent example
162
- and discussion of these factors can be found on our blog:
163
-
164
- http://arrayfire.com/how-to-write-vectorized-code/
165
-
166
- It's worth noting that the content discussed in the blog has since been transformed
167
- into a convenient af::nearestNeighbour() function. Before writing something from
168
- scratch, check that ArrayFire doesn't already have an implementation. The default
169
- vectorized nature of ArrayFire and an extensive collection of functions will
170
- speed things up in addition to replacing dozens of lines of code!
171
- -->
83
+ This another pending feature that is similar to our C++ API of
84
+ [ batchFunc()] ( http://arrayfire.org/docs/namespaceaf.htm#aa0eb9e160f5be4b95234543e5c47934b )
0 commit comments