Skip to content

Commit 8e2cb8c

Browse files
committed
Improve existing tutorials
1 parent cc94322 commit 8e2cb8c

File tree

5 files changed

+67
-104
lines changed

5 files changed

+67
-104
lines changed

src/arith/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,6 @@ mod op_assign {
857857
bit_assign_func!(BitAndAssign, bitand_assign, bitand);
858858
bit_assign_func!(BitOrAssign, bitor_assign, bitor);
859859
bit_assign_func!(BitXorAssign, bitxor_assign, bitxor);
860-
861860
}
862861

863862
///Implement negation trait for Array

tutorials-book/src/array_and_matrix_manipulation.md

+29
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,32 @@ transpose(&a, False) //Second parameter to be used for conjugate transpose
269269
3.0000 1.0000 2.0000
270270
3.0000 3.0000 1.0000
271271
```
272+
273+
### Combining functions to enumerate grid coordinates
274+
275+
By using a combination of the functions, one can quickly code complex manipulation patterns with
276+
a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis
277+
goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small
278+
combination of the above functions.
279+
280+
```rust,noplaypen
281+
let a = iota::<u32>(Dim4::new(&[3, 1, 1, 1]),
282+
Dim4::new(&[1, 3, 1, 1]));
283+
let b = transpose(&a, false);
284+
let coords = join(1, &flat(&a), &flat(&b));
285+
print(&coords);
286+
```
287+
288+
The output for a `[3 3 1 1]` matrix will be the following.
289+
```rust,noplaypen
290+
[9 2 1 1]
291+
0 0
292+
1 0
293+
2 0
294+
0 1
295+
1 1
296+
2 1
297+
0 2
298+
1 2
299+
2 2
300+
```

tutorials-book/src/getting_started.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,23 @@ get it using the [scalar()](\ref af::array::scalar) function:
218218

219219
In addition to supporting standard mathematical functions, Arrays
220220
that contain integer data types also support bitwise operators including
221-
and, or, and shift etc.
221+
and, or, and shift etc. Operator traits for Array as well as separate functions
222+
are also defined to support various use cases.
223+
224+
```rust,noplaypen
225+
let dims = Dim4::new(&[5, 3, 1, 1]);
226+
let a = randu::<bool>(dims);
227+
let b = randu::<bool>(dims);
228+
229+
print(&a);
230+
print(&b);
231+
232+
let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid
233+
let d = bitand(&a, &b, false);
234+
235+
print(&c);
236+
print(&d);
237+
```
222238

223239
## Where to go for help?
224240

tutorials-book/src/indexing.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
# Indexing
22

3+
Indexing in ArrayFire is a powerful but easy to abuse feature. This feature
4+
allows you to reference or copy subsections of a larger array and perform
5+
operations on only a subset of elements.
6+
37
[Indexer](../struct.Indexer.html) structure is the key element used in Rust
4-
wrapper for ArrayFire for creating references to existing Arrays. Given
5-
below are few of such functions and their corresponding example use cases.
8+
wrapper of ArrayFire for creating references to existing Arrays. Given
9+
below are few of such functions and their corresponding use cases.
610
Use [Indexer::new](../struct.Indexer.html#method.new) to create an Indexer
711
object and set either a `Seq` object or `Array` as indexing object for a
812
given dimension.
913

1014
## Using Seq objects to index Array
1115

12-
Create a view of an existing Array using Sequences and [index](../fn.index.html).
16+
Create a view of an existing Array using Sequences and the function [index](../fn.index.html).
1317

1418
```rust,noplaypen
1519
let dims = Dim4::new(&[5, 5, 1, 1]);
@@ -55,6 +59,8 @@ print(&sub);
5559
// 2.0 2.0 2.0
5660
```
5761

62+
> **NOTE** Normally you want to avoid accessing individual elements of the array like this for performance reasons.
63+
5864
## Using Array and Seq combination to index Array
5965

6066
Create a view of an existing Array using another Array and Sequence.

tutorials-book/src/vectorization.md

+12-99
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
# Vectorization
22

3-
<!--
43
Programmers and Data Scientists want to take advantage of fast and parallel
54
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
76
scientific computing software. However, writing vectorized code may not be
87
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
109
using ArrayFire and discuss the benefits and drawbacks associated with each method.
1110

12-
### Generic/Default vectorization
13-
-->
11+
## Generic/Default vectorization
1412
By its very nature, ArrayFire is a vectorized library. Most functions operate on
1513
Arrays as a whole -- on all elements in parallel. For example consider the following code:
1614

@@ -26,7 +24,7 @@ A small subset of such vectorized ArrayFire functions are given below for quick
2624

2725
| Operator Category | Functions |
2826
|--------------------------------------------------------------|----------------------------|
29-
| Arithmetic operations | +, -, *, /, %, >>, << |
27+
| Arithmetic operations | +, -, \*, /, %, >>, << |
3028
| Logical operations | &&, \|\|, <, >, ==, != etc. |
3129
| Numeric functions | [abs](../fn.abs.html), [floor](../fn.floor.html), [round](../fn.round.html), [min](../fn.min.html), [max](../fn.max.html), etc. |
3230
| 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);
6967

7068
Although *most* functions in ArrayFire do support vectorization, some do not.
7169
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.
7371

7472
Using the built in vectorized operations should be the first
7573
and preferred method of vectorizing any code written with ArrayFire.
7674

77-
<!--
78-
# Batching
75+
## GFOR
7976

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.
8580

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
8982

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

Comments
 (0)