|
1 | 1 | # GPUArrays
|
2 | 2 |
|
3 |
| -*Abstract GPU Array package for Julia's various GPU backends.* |
| 3 | +*Abstract GPU array functionality for Julia's various GPU backends.* |
4 | 4 |
|
5 |
| -[![][docs-stable-img]][docs-stable-url] [![][docs-dev-img]][docs-dev-url] [](https://codecov.io/gh/JuliaGPU/GPUArrays.jl) |
| 5 | +| **Documentation** | **Build Status** | |
| 6 | +|:-------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------:| |
| 7 | +| [![][docs-stable-img]][docs-stable-url] [![][docs-dev-img]][docs-dev-url] | [![][gitlab-img]][gitlab-url] [![][travis-img]][travis-url] [![][codecov-img]][codecov-url] | |
6 | 8 |
|
7 |
| -[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg |
8 |
| -[docs-stable-url]: http://JuliaGPU.github.io/GPUArrays.jl/stable/ |
9 |
| -[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg |
10 |
| -[docs-dev-url]: http://JuliaGPU.github.io/GPUArrays.jl/dev/ |
| 9 | +[gitlab-img]: https://gitlab.com/JuliaGPU/CuArrays.jl/badges/master/pipeline.svg |
| 10 | +[gitlab-url]: https://gitlab.com/JuliaGPU/CuArrays.jl/commits/master |
11 | 11 |
|
| 12 | +[travis-img]: https://api.travis-ci.org/JuliaGPU/GPUArrays.jl.svg?branch=master |
| 13 | +[travis-url]: https://travis-ci.org/JuliaGPU/GPUArrays.jl |
12 | 14 |
|
13 |
| -[Benchmarks](https://github.com/JuliaGPU/GPUBenchmarks.jl/blob/master/results/results.md) |
| 15 | +[codecov-img]: https://codecov.io/gh/JuliaGPU/CuArrays.jl/branch/master/graph/badge.svg |
| 16 | +[codecov-url]: https://codecov.io/gh/JuliaGPU/CuArrays.jl |
14 | 17 |
|
15 |
| -This package is the counterpart of Julia's `Base.AbstractArray` interface, but |
16 |
| -for GPU array types. Currently, you either need to install |
17 |
| -[CLArrays](https://github.com/JuliaGPU/CLArrays.jl) or |
18 |
| -[CuArrays](https://github.com/JuliaGPU/CuArrays.jl) for a concrete |
19 |
| -implementation. |
| 18 | +[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg |
| 19 | +[docs-stable-url]: http://JuliaGPU.github.io/GPUArrays.jl/stable/ |
20 | 20 |
|
| 21 | +[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg |
| 22 | +[docs-dev-url]: http://JuliaGPU.github.io/GPUArrays.jl/dev/ |
21 | 23 |
|
22 |
| -# Why another GPU array package in yet another language? |
| 24 | +This package is the counterpart of Julia's `AbstractArray` interface, but for GPU array |
| 25 | +types: It provides functionality and tooling to speed-up development of new GPU array types. |
| 26 | +**This package is not intended for end users!** Instead, you should use one of the packages |
| 27 | +that builds on GPUArrays.jl, such as [CuArrays](https://github.com/JuliaGPU/CuArrays.jl). |
23 | 28 |
|
24 |
| -Julia offers great advantages for programming the GPU. |
25 |
| -This [blog post](http://mikeinnes.github.io/2017/08/24/cudanative.html) outlines a few of those. |
26 | 29 |
|
27 |
| -E.g., we can use Julia's JIT to generate optimized kernels for map/broadcast operations. |
| 30 | +# Functionality |
28 | 31 |
|
29 |
| -This works even for things like complex arithmetic, since we can compile what's already in Julia Base. |
30 |
| -This isn't restricted to Julia Base, GPUArrays works with all kind of user defined types and functions! |
| 32 | +The GPUArrays.jl package essentially provides two abstract array types: `AbstractGPUArray` |
| 33 | +for GPU arrays that live on the hose, and `AbstractDeviceArray` for the device-side |
| 34 | +counterpart. |
31 | 35 |
|
32 |
| -GPUArrays relies heavily on Julia's dot broadcasting. |
33 |
| -The great thing about dot broadcasting in Julia is, that it |
34 |
| -[actually fuses operations syntactically](http://julialang.org/blog/2017/01/moredots), which is vital for performance on the GPU. |
35 |
| -E.g.: |
| 36 | +## `AbstractGPUArray` |
36 | 37 |
|
37 |
| -```Julia |
38 |
| -out .= a .+ b ./ c .+ 1 |
39 |
| -#turns into this one broadcast (map): |
40 |
| -broadcast!(out, a, b, c) do a, b, c |
41 |
| - a + b / c + 1 |
42 |
| -end |
43 |
| -``` |
| 38 | +TODO: describe functionality |
44 | 39 |
|
45 |
| -Will result in one GPU kernel call to a function that combines the operations without any extra allocations. |
46 |
| -This allows GPUArrays to offer a lot of functionality with minimal code. |
| 40 | +## `AbstractDeviceArray` |
47 | 41 |
|
48 |
| -Also, when compiling Julia for the GPU, we can use all the cool features from Julia, e.g. |
49 |
| -higher order functions, multiple dispatch, meta programming and generated functions. |
50 |
| -Checkout the examples, to see how this can be used to emit specialized code while not losing flexibility: |
| 42 | +TODO: describe functionality |
51 | 43 |
|
52 |
| -[<img src="https://raw.githubusercontent.com/JuliaGPU/GPUBenchmarks.jl/master/results/plots/juliaset_result.png" height="150">](https://github.com/JuliaGPU/GPUBenchmarks.jl/blob/master/results/results.md) |
53 |
| -[<img src="https://user-images.githubusercontent.com/1010467/40832645-12ca1f50-658c-11e8-9fb4-170871db2499.png" height="150">](https://juliagpu.github.io/GPUShowcases.jl/latest/) |
54 | 44 |
|
55 |
| -In theory, we could go as far as inspecting user defined callbacks (we can get the complete AST), count operations and estimate register usage and use those numbers to optimize our kernels! |
| 45 | +# Interfaces |
56 | 46 |
|
| 47 | +To extend the above functionality to a new array type, you should implement the following |
| 48 | +interfaces: |
57 | 49 |
|
58 |
| -# Scope |
| 50 | +TODO |
59 | 51 |
|
60 |
| -Interface offered for all backends: |
61 | 52 |
|
62 |
| -```Julia |
63 |
| -map(f, ::GPUArray...) |
64 |
| -map!(f, dest::GPUArray, ::GPUArray...) |
| 53 | +# Test suite |
65 | 54 |
|
66 |
| -broadcast(f, ::GPUArray...) |
67 |
| -broadcast!(f, dest::GPUArray, ::GPUArray...) |
| 55 | +GPUArrays also provides an extensive test suite that covers all of the functionality that |
| 56 | +should be available after implementing the required interfaces. This test suite is part of |
| 57 | +this package, but for dependency reasons it is not available when importing the package. |
| 58 | +Instead, you should include the code from your `runtests.jl` as follows: |
68 | 59 |
|
69 |
| -mapreduce(f, op, ::GPUArray...) # so support for sum/mean/minimum etc comes for free |
| 60 | +```julia |
| 61 | +import GPUArrays |
| 62 | +gpuarrays = pathof(GPUArrays) |
| 63 | +gpuarrays_root = dirname(dirname(gpuarrays)) |
| 64 | +include(joinpath(gpuarrays_root, "test", "testsuite.jl")) |
| 65 | +``` |
70 | 66 |
|
71 |
| -getindex, setindex!, push!, append!, splice!, append!, copy!, reinterpret, convert |
| 67 | +This however implies that the test system will not know about extra dependencies that are |
| 68 | +required by the test suite. To remedy this, you should add the following dependencies to |
| 69 | +your `Project.toml`: |
72 | 70 |
|
73 |
| -From (CL/CU)FFT |
74 |
| -fft!/fft/ifft/ifft! and the matching plan_fft functions. |
75 |
| -From (CL/CU)BLAS |
76 |
| -gemm!, scal!, gemv! and the high level functions that are implemented with these, like A * B, A_mul_B!, etc. |
| 71 | +``` |
| 72 | +[extras] |
| 73 | +FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" |
| 74 | +FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" |
| 75 | +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" |
| 76 | +... |
| 77 | +
|
| 78 | +[targets] |
| 79 | +test = [..., "FFTW", "ForwardDiff", "FillArrays"] |
77 | 80 | ```
|
78 | 81 |
|
79 |
| -# Currently supported subset of Julia Code |
80 |
| - |
81 |
| -Working with immutable isbits (not containing pointers) type should be completely supported |
82 |
| -with non-allocating code (so no constructs like `x = [1, 2, 3]`). Note that tuples are isbits, so this works x = (1, 2, 3). |
83 |
| -Transpiler/OpenCL has problems with putting GPU arrays on the gpu into a struct - so no views and actually no multidimensional indexing. For that `size` is needed which would need to be part of the array struct. A fix for that is in sight, though. |
84 | 82 |
|
85 |
| -# JLArray |
| 83 | +# `JLArray` |
86 | 84 |
|
87 |
| -The `JLArray` is a `GPUArray` which doesn't run on the GPU and rather uses Julia's async constructs as its backend. It serves as a fallback for testing compatibility with `GPUArray`s in cases where a GPU does not exist and as a reference implementation. It is constructed as follows: |
| 85 | +The `JLArray` type is a reference implementation of the GPUArray interfaces. It does not run |
| 86 | +on the GPU, but rather uses Julia's async constructs as its backend. It is constructed as |
| 87 | +follows: |
88 | 88 |
|
89 | 89 | ```julia
|
90 | 90 | gA = JLArray(A)
|
91 | 91 | ```
|
92 |
| - |
93 |
| -# TODO / up for grabs |
94 |
| - |
95 |
| -* stencil operations, convolutions |
96 |
| -* more tests and benchmarks |
97 |
| -* tests, that only switch the backend but use the same code |
98 |
| -* performance improvements!! |
99 |
| -* interop between OpenCL, CUDA and OpenGL is there as a protype, but needs proper hooking up via `Base.copy!` / `convert` |
100 |
| - |
101 |
| - |
102 |
| -# Installation |
103 |
| - |
104 |
| -See CuArrays or CLArrays for installation instructions. |
0 commit comments