1 Getting Started {#gettingstarted}
8 ArrayFire is a high performance software library for parallel computing with
9 an easy-to-use API. ArrayFire abstracts away much of the details of
10 programming parallel architectures by providing a high-level container object,
11 the [array](\ref af::array), that represents data stored on a CPU, GPU, FPGA,
12 or other type of accelerator. This abstraction permits developers to write
13 massively parallel applications in a high-level language where they need
14 not be concerned about low-level optimizations that are frequently required to
15 achieve high throughput on most parallel architectures.
17 # Supported data types {#gettingstarted_datatypes}
19 ArrayFire provides one generic container object, the [array](\ref af::array)
20 on which functions and mathematical operations are performed. The `array`
21 can represent one of many different [basic data types](\ref af_dtype):
23 * [f32](\ref f32) real single-precision (`float`)
24 * [c32](\ref c32) complex single-precision (`cfloat`)
25 * [f64](\ref f64) real double-precision (`double`)
26 * [c64](\ref c64) complex double-precision (`cdouble`)
27 * [f16](\ref f16) real half-precision (`half_float::half`)
28 * [b8](\ref b8) 8-bit boolean values (`bool`)
29 * [s32](\ref s32) 32-bit signed integer (`int`)
30 * [u32](\ref u32) 32-bit unsigned integer (`unsigned`)
31 * [u8](\ref u8) 8-bit unsigned values (`unsigned char`)
32 * [s64](\ref s64) 64-bit signed integer (`intl`)
33 * [u64](\ref u64) 64-bit unsigned integer (`uintl`)
34 * [s16](\ref s16) 16-bit signed integer (`short`)
35 * [u16](\ref u16) 16-bit unsigned integer (`unsigned short`)
37 Most of these data types are supported on all modern GPUs; however, some
38 older devices may lack support for double precision arrays. In this case,
39 a runtime error will be generated when the array is constructed.
41 If not specified otherwise, `array`s are created as single precision floating
42 point numbers (`f32`).
44 # Creating and populating an ArrayFire array {#getting_started_af_arrays}
46 ArrayFire [array](\ref af::array)s represent memory stored on the device.
47 As such, creation and population of an array will consume memory on the device
48 which cannot freed until the `array` object goes out of scope. As device memory
49 allocation can be expensive, ArrayFire also includes a memory manager which
50 will re-use device memory whenever possible.
52 Arrays can be created using one of the [array constructors](\ref af::array).
53 Below we show how to create 1D, 2D, and 3D arrays with uninitialized values:
55 \snippet test/getting_started.cpp ex_getting_started_constructors
57 However, uninitialized memory is likely not useful in your application.
58 ArrayFire provides several convenient functions for creating arrays that contain
59 pre-populated values including constants, uniform random numbers, uniform
60 normally distributed numbers, and the identity matrix:
62 \snippet test/getting_started.cpp ex_getting_started_gen
64 A complete list of ArrayFire functions that automatically generate data
65 on the device may be found on the [functions to create arrays](\ref data_mat)
66 page. As stated above, the default data type for arrays is [f32](\ref f32) (a
67 32-bit floating point number) unless specified otherwise.
69 ArrayFire `array`s may also be populated from data found on the host.
72 \snippet test/getting_started.cpp ex_getting_started_init
74 ArrayFire also supports array initialization from memory already on the GPU.
75 For example, with CUDA one can populate an `array` directly using a call
78 \snippet test/getting_started.cpp ex_getting_started_dev_ptr
80 Similar functionality exists for OpenCL too. If you wish to intermingle
81 ArrayFire with CUDA or OpenCL code, we suggest you consult the
82 [CUDA interoperability](\ref interop_cuda) or
83 [OpenCL interoperability](\ref interop_opencl) pages for detailed instructions.
85 # ArrayFire array contents, dimensions, and properties {#getting_started_array_properties}
87 ArrayFire provides several functions to determine various aspects of arrays.
88 This includes functions to print the contents, query the dimensions, and
89 determine various other aspects of arrays.
91 The [af_print](\ref af_print) function can be used to print arrays that
92 have already been generated or any expression involving arrays:
94 \snippet test/getting_started.cpp ex_getting_started_print
96 The dimensions of an array may be determined using either a
97 [dim4](\ref af::dim4) object or by accessing the dimensions directly using the
98 [dims()](\ref af::array::dims) and [numdims()](\ref af::array::numdims)
101 \snippet test/getting_started.cpp ex_getting_started_dims
103 In addition to dimensions, arrays also carry several properties including
104 methods to determine the underlying type and size (in bytes). You can even
105 determine whether the array is empty, real/complex, a row/column, or a scalar
108 \snippet test/getting_started.cpp ex_getting_started_prop
110 For further information on these capabilities, we suggest you consult the
111 full documentation on the [array](\ref af::array).
113 # Writing mathematical expressions in ArrayFire {#getting_started_writing_math}
115 ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that
116 converts expressions using arrays into the smallest number of CUDA/OpenCL
117 kernels. For most operations on arrays, ArrayFire functions like a vector library.
118 That means that an element-wise operation, like `c[i] = a[i] + b[i]` in C,
119 would be written more concisely without indexing, like `c = a + b`.
120 When there are multiple expressions involving arrays, ArrayFire's JIT engine
121 will merge them together. This "kernel fusion" technology not only decreases
122 the number of kernel calls, but, more importantly, avoids extraneous global
124 Our JIT functionality extends across C/C++ function boundaries and only ends
125 when a non-JIT function is encountered or a synchronization operation is
126 explicitly called by the code.
128 ArrayFire provides [hundreds of functions](\ref arith_mat) for element-wise
129 operations. All of the standard operators (e.g. +,-,\*,/) are supported
130 as are most transcendental functions (sin, cos, log, sqrt, etc.).
131 Here are a few examples:
133 \snippet test/getting_started.cpp ex_getting_started_arith
135 To see the complete list of functions please consult the documentation on
136 [mathematical](\ref mathfunc_mat), [linear algebra](\ref linalg_mat),
137 [signal processing](\ref signal_mat), and [statistics](\ref stats_mat).
139 # Mathematical constants {#getting_started_constants}
141 ArrayFire contains several platform-independent constants, like
142 [Pi](\ref af::Pi), [NaN](\ref af::NaN), and [Inf](\ref af::Inf).
143 If ArrayFire does not have a constant you need, you can create your own
144 using the [af::constant](\ref af::constant) array constructor.
146 Constants can be used in all of ArrayFire's functions. Below we demonstrate
147 their use in element selection and a mathematical expression:
149 \snippet test/getting_started.cpp ex_getting_started_constants
151 Please note that our constants may, at times, conflict with macro definitions
152 in standard header files. When this occurs, please refer to our constants
153 using the `af::` namespace.
155 # Indexing {#getting_started_indexing}
157 Like all functions in ArrayFire, indexing is also executed in parallel on the
158 OpenCL/CUDA devices. Because of this, indexing becomes part of a JIT operation
159 and is accomplished using parentheses instead of square brackets (i.e. as `A(0)`
160 instead of `A[0]`). To index `af::array`s you may use one or a combination of
161 the following functions:
164 * [seq()](\ref af::seq) representing a linear sequence
165 * [end](\ref af::end) representing the last element of a dimension
166 * [span](\ref af::span) representing the entire dimension
167 * [row(i)](\ref af::array::row) or [col(i)](\ref af::array::col) specifying a single row/column
168 * [rows(first,last)](\ref af::array::rows) or [cols(first,last)](\ref af::array::cols)
169 specifying a span of rows or columns
171 Please see the [indexing page](\ref indexing) for several examples of how to
174 # Getting access to ArrayFire array memory on the host and device {#getting_started_memory_access}
176 Memory in `af::array`s may be accessed using the [host()](\ref af::array::host)
177 and [device()](\ref af::array::device) functions.
178 The `host` function *copies* the data from the device and makes it available
179 in a C-style array on the host. As such, it is up to the developer to manage
180 any memory returned by `host`.
181 The `device` function returns a pointer/reference to device memory for
182 interoperability with external CUDA/OpenCL kernels. As this memory belongs to
183 ArrayFire, the programmer should not attempt to free/deallocate the pointer.
184 For example, here is how we can interact with both OpenCL and CUDA:
186 \snippet test/getting_started.cpp ex_getting_started_ptr
188 ArrayFire also provides several helper functions for creating `af::array`s from
189 OpenCL `cl_mem` references and `cl::Buffer` objects. See the `include/af/opencl.h`
190 file for further information.
192 Lastly, if you want only the first value from an `af::array` you can use
193 get it using the [scalar()](\ref af::array::scalar) function:
195 \snippet test/getting_started.cpp ex_getting_started_scalar
197 # Bitwise operators {#getting_started_bitwise_operators}
199 In addition to supporting standard mathematical functions, arrays
200 that contain integer data types also support bitwise operators including
203 \snippet test/getting_started.cpp ex_getting_started_bit
205 # Using the ArrayFire API in C and C++ {#gettingstarted_api_usage}
207 The ArrayFire API is wrapped into a unified C/C++ header. To use the library
208 simply include the `arrayfire.h` header file and start coding!
210 ## Sample using the C API
212 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
213 #include <arrayfire.h>
214 // Generate random data and sum and print the result
217 // generate random values
220 dim_t dims[] = {10000};
221 af_randu(&a, n_dims, dims, f32);
223 // sum all the values
225 af_sum_all(&result, 0, a);
226 printf("sum: %g\n", result);
230 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232 ## Sample using the C++ API
234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
235 #include <arrayfire.h>
236 // Generate random data, sum and print the result.
239 // Generate 10,000 random values
240 af::array a = af::randu(10000);
242 // Sum the values and copy the result to the CPU:
243 double sum = af::sum<float>(a);
245 printf("sum: %g\n", sum);
248 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
250 # What to read next? {#getting_started_next_steps}
252 Now that you have a general introduction to ArrayFire, where do you go from
253 here? In particular you might find these documents useful
255 * [Building an ArrayFire program on Linux](\ref using_on_linux)
256 * [Building an Arrayfire program on Windows](\ref using_on_windows)
257 * [Timing ArrayFire code](\ref timing)
261 # Where to go for help? {#getting_started_help}
263 * Google Groups: https://groups.google.com/forum/#!forum/arrayfire-users
264 * ArrayFire Services: [Consulting](http://arrayfire.com/consulting/) | [Support](http://arrayfire.com/support/) | [Training](http://arrayfire.com/training/)
265 * ArrayFire Blogs: http://arrayfire.com/blog/
266 * Email: <mailto:technical@arrayfire.com>