Skip to content

Commit b8ef4f0

Browse files
authored
Merge pull request #52 from JuliaArrays/teh/remove_training_wheels
Introduce full support for array operations
2 parents cc0ae52 + 1b8216b commit b8ef4f0

File tree

6 files changed

+117
-240
lines changed

6 files changed

+117
-240
lines changed

README.md

Lines changed: 3 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ like Fortran.
88
```julia
99
julia> using OffsetArrays
1010

11-
julia> y = OffsetArray{Float64}(uninitialized, -1:1, -7:7, -128:512, -5:5, -1:1, -3:3, -2:2, -1:1);
11+
julia> y = OffsetArray{Float64}(undef, -1:1, -7:7, -128:512, -5:5, -1:1, -3:3, -2:2, -1:1);
1212

1313
julia> summary(y)
1414
"OffsetArrays.OffsetArray{Float64,8,Array{Float64,8}} with indices -1:1×-7:7×-128:512×-5:5×-1:1×-3:3×-2:2×-1:1"
@@ -20,119 +20,6 @@ julia> y[-1,-7,-128,-5,-1,-3,-2,-1] += 5
2020
19.0
2121
```
2222

23-
Support for such arrays is based on new functionality in Julia v0.5,
24-
and the modern package is not usable on earlier Julia versions.
23+
## Notes on supporting OffsetArrays
2524

26-
## Special note for Julia 0.7
27-
28-
During the transition to allowing arrays with
29-
arbitrary indices, certain operations (like `size` and `length`) are
30-
deliberately unsupported; see the
31-
[documentation](http://docs.julialang.org/en/latest/devdocs/offset-arrays/)
32-
describing the reasoning behind this decision. The general
33-
recommendation is to use iteration and `eachindex` and `LinearIndices` for most
34-
operations where `size` and `length` would have formerly been used.
35-
36-
If your package makes use of OffsetArrays, you can also add the
37-
following internal convenience definitions:
38-
39-
```jl
40-
_size(A::AbstractArray) = size(LinearIndices(A))
41-
_size(A) = size(A)
42-
43-
_length(A::AbstractArray) = length(LinearIndices(A))
44-
_length(A) = length(A)
45-
```
46-
47-
These versions should work for all types.
48-
49-
## Performance optimization with @unsafe
50-
51-
Also during Julia 0.5, `@inbounds` will not remove the internal
52-
bounds-checking that happens when using an OffsetArray. Until this
53-
changes, you can often accomplish the same task with `@unsafe`:
54-
55-
```jl
56-
v = OffsetArray(rand(1000), 0:999)
57-
@unsafe for i in indices(v, 1)
58-
v[i] += 1
59-
end
60-
```
61-
62-
With such annotation, `OffsetArray`s are as performant as `Array`s.
63-
64-
`@unsafe` is not as powerful as `@inbounds`, and it is possible to set
65-
up situations where it fails to remove bounds checks. However, it
66-
suffices for many uses.
67-
68-
# Comparison with Fortran
69-
70-
The original purpose of the package was to simplify translation of Fortran codes, say
71-
* the codes accompanying the book _Numerical Solution of Hyperbolic Partial Differential Equations_ by prof. John A. Trangenstein
72-
Please refer [here](http://www.math.duke.edu/~johnt/) and [here](http://www.cambridge.org/us/academic/subjects/mathematics/differential-and-integral-equations-dynamical-systems-and-co/numerical-solution-hyperbolic-partial-differential-equations)
73-
* Clawpack (stands for *Conservation Laws Package*) by prof. Randall J. LeVeque
74-
75-
+ [classic ClawPack](http://depts.washington.edu/clawpack/)
76-
77-
+ [ClawPack 5.0](http://clawpack.github.io/index.html)
78-
79-
see also [translation to Julia of Fortran codes from ClawPack](https://github.com/alsam/Claw.jl)
80-
81-
The directory _examples_ of [hyperbolic_PDE](https://github.com/alsam/hyperbolic_PDE.jl) contains at the moment a translation of explicit upwind finite difference scheme for scalar law advection equation from
82-
the book _Numerical Solution of Hyperbolic Partial Differential Equations_ by prof. John A. Trangenstein.
83-
84-
+ examples/scalar_law/PROGRAM0/main.jl
85-
The original Fortran arrays `u(-2:ncells+1), x(0:ncells), flux(0:ncells)` transformed to 1-based Julia arrays by shifting index expressions
86-
```julia
87-
u = Array(Float64, ncells+4)
88-
x = Array(Float64, ncells+1)
89-
flux = Array(Float64, ncells+1)
90-
```
91-
92-
+ examples/scalar_law/PROGRAM0/main_offset_array.jl
93-
Exemplary _use case_ of this package
94-
```julia
95-
u = OffsetArray(Float64, -2:ncells+1)
96-
x = OffsetArray(Float64, 0:ncells)
97-
flux = OffsetArray(Float64, 0:ncells)
98-
```
99-
100-
+ Timings for baseline with `@unsafe` annotation:
101-
```sh
102-
0.103402 seconds (21 allocations: 235.531 KB)
103-
```
104-
105-
+ Timing for `OffsetArray` version with `@unsafe` annotation:
106-
```sh
107-
0.103987 seconds (16 allocations: 235.094 KB)
108-
```
109-
110-
+ Timing for `sub` macro version with `@unsafe` annotation (doesn't work without `@unsafe`):
111-
```sh
112-
0.105967 seconds (217 allocations: 268.094 KB)
113-
```
114-
Only the 2nd timing after warming up is given.
115-
116-
+ UPDATE:
117-
Added
118-
+ examples/scalar_law/PROGRAM1/...
119-
```sh
120-
[~/w/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=10000 --runs=3 ms master|✚ 1…
121-
0.672295 seconds (42.90 k allocations: 1.990 MB)
122-
0.509693 seconds (18 allocations: 313.281 KB)
123-
0.512243 seconds (18 allocations: 313.281 KB)
124-
[~/w/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=100000 --runs=3 6134ms master|✚ 1…
125-
7.270463 seconds (42.90 k allocations: 4.736 MB)
126-
7.177485 seconds (18 allocations: 3.053 MB)
127-
7.248687 seconds (18 allocations: 3.053 MB)
128-
```
129-
130-
Fortran timing for `100000` number of cells
131-
```sh
132-
real 0m4.781s
133-
user 0m4.760s
134-
sys 0m0.000s
135-
136-
```
137-
138-
That is 7.2s for Julia script vs. 4.8s for Fortran.
25+
Julia supports generic programming with arrays that doesn't require you to assume that indices start with 1, see the [documentation](http://docs.julialang.org/en/latest/devdocs/offset-arrays/).

READMEOLD.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Comparison with Fortran
2+
3+
The original purpose of the package was to simplify translation of Fortran codes, say
4+
* the codes accompanying the book _Numerical Solution of Hyperbolic Partial Differential Equations_ by prof. John A. Trangenstein
5+
Please refer [here](http://www.math.duke.edu/~johnt/) and [here](http://www.cambridge.org/us/academic/subjects/mathematics/differential-and-integral-equations-dynamical-systems-and-co/numerical-solution-hyperbolic-partial-differential-equations)
6+
* Clawpack (stands for *Conservation Laws Package*) by prof. Randall J. LeVeque
7+
8+
+ [classic ClawPack](http://depts.washington.edu/clawpack/)
9+
10+
+ [ClawPack 5.0](http://clawpack.github.io/index.html)
11+
12+
see also [translation to Julia of Fortran codes from ClawPack](https://github.com/alsam/Claw.jl)
13+
14+
The directory _examples_ of [hyperbolic_PDE](https://github.com/alsam/hyperbolic_PDE.jl) contains at the moment a translation of explicit upwind finite difference scheme for scalar law advection equation from
15+
the book _Numerical Solution of Hyperbolic Partial Differential Equations_ by prof. John A. Trangenstein.
16+
17+
+ examples/scalar_law/PROGRAM0/main.jl
18+
The original Fortran arrays `u(-2:ncells+1), x(0:ncells), flux(0:ncells)` transformed to 1-based Julia arrays by shifting index expressions
19+
```julia
20+
u = Array{Float64}(undef, ncells+4)
21+
x = Array{Float64}(undef, ncells+1)
22+
flux = Array{Float64}(undef, ncells+1)
23+
```{+ examp}(undef,es/scalar_law/PROGRAM0/main_offset_array.jl
24+
Exemplary _use case_ of this package
25+
```julia
26+
u = OffsetArray{Float64}(undef, -2:ncells+1)
27+
x = OffsetArray{Float64}(undef, 0:ncells)
28+
flux = OffsetArray{Float64}(undef, 0:ncells)
29+
```
30+
31+
+ Timings for baseline with `@inbounds` annotation:
32+
```sh
33+
0.103402 seconds (21 allocations: 235.531 KB)
34+
```
35+
36+
+ Timing for `OffsetArray` version with `@inbounds` annotation:
37+
```sh
38+
0.103987 seconds (16 allocations: 235.094 KB)
39+
```
40+
41+
+ UPDATE:
42+
Added
43+
+ examples/scalar_law/PROGRAM1/...
44+
```sh
45+
[~/w/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=10000 --runs=3 ms master|✚ 1…
46+
0.672295 seconds (42.90 k allocations: 1.990 MB)
47+
0.509693 seconds (18 allocations: 313.281 KB)
48+
0.512243 seconds (18 allocations: 313.281 KB)
49+
[~/w/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=100000 --runs=3 6134ms master|✚ 1…
50+
7.270463 seconds (42.90 k allocations: 4.736 MB)
51+
7.177485 seconds (18 allocations: 3.053 MB)
52+
7.248687 seconds (18 allocations: 3.053 MB)
53+
```
54+
55+
Fortran timing for `100000` number of cells
56+
```sh
57+
real 0m4.781s
58+
user 0m4.760s
59+
sys 0m0.000s
60+
61+
```
62+
63+
That is 7.2s for Julia script vs. 4.8s for Fortran.

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
julia 0.7.0-beta.73
1+
julia 0.7.0-beta.270

benchmark/benchmarks.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ using OffsetArrays
33

44
const dim = 1000
55

6-
x = Array(Float64, 2*dim)
7-
y = OffsetArray(Float64, -dim + 1 : dim)
8-
x2d = Array(Float64, 2*dim, 2*dim)
9-
y2d = OffsetArray(Float64, -dim + 1 : dim, -dim + 1 : dim)
6+
x = Array{Float64}(undef, 2*dim)
7+
y = OffsetArray{Float64}(undef, -dim + 1 : dim)
8+
x2d = Array{Float64}(undef, 2*dim, 2*dim)
9+
y2d = OffsetArray{Float64}(undef, -dim + 1 : dim, -dim + 1 : dim)
1010

11-
fill(x) = for i in indices(x,1); x[i] = i; end
12-
fill2d(x) = for j in indices(x,2); for i in indices(x,1); x[i,j] = i + j; end; end
13-
update(x) = for i in indices(x,1); x[i] = x[i] + i; end
14-
update2d(x) = for j in indices(x,2); for i in indices(x,1); x[i,j] = x[i,j] + i + j; end; end
11+
fill(x) = for i in axes(x,1); x[i] = i; end
12+
fill2d(x) = for j in axes(x,2); for i in axes(x,1); x[i,j] = i + j; end; end
13+
update(x) = for i in axes(x,1); x[i] = x[i] + i; end
14+
update2d(x) = for j in axes(x,2); for i in axes(x,1); x[i,j] = x[i,j] + i + j; end; end
1515
update_eachindex(x) = for i in eachindex(x); x[i] = x[i] + i; end
1616

17-
unsafe_fill(x) = @unsafe(for i in indices(x,1); x[i] = i; end)
18-
unsafe_fill2d(x) = @unsafe(for j in indices(x,2); for i in indices(x,1); x[i,j] = i + j; end; end)
19-
unsafe_update(x) = @unsafe(for i in indices(x,1); x[i] = x[i] + i; end)
20-
unsafe_update2d(x) = @unsafe(for j in indices(x,2); for i in indices(x,1); x[i,j] = x[i,j] + i + j; end; end)
21-
unsafe_update_eachindex(x) = @unsafe(for i in eachindex(x); x[i] = x[i] + i; end)
17+
unsafe_fill(x) = @inbounds(for i in axes(x,1); x[i] = i; end)
18+
unsafe_fill2d(x) = @inbounds(for j in axes(x,2); for i in axes(x,1); x[i,j] = i + j; end; end)
19+
unsafe_update(x) = @inbounds(for i in axes(x,1); x[i] = x[i] + i; end)
20+
unsafe_update2d(x) = @inbounds(for j in axes(x,2); for i in axes(x,1); x[i,j] = x[i,j] + i + j; end; end)
21+
unsafe_update_eachindex(x) = @inbounds(for i in eachindex(x); x[i] = x[i] + i; end)
2222

2323
@show @benchmark fill(x)
2424
@show @benchmark fill(y)

0 commit comments

Comments
 (0)