1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
Getting Started {#gettingstarted}
===============
[TOC]
# Supported data types {#gettingstarted_datatypes}
There is one generic [array](\ref af::array) container object while the
underlying data may be one of various [basic types](\ref af::af_dtype):
* [b8](\ref b8) 8-bit boolean values (`bool`)
* [f32](\ref f32) real single-precision (`float`)
* [c32](\ref c32) complex single-precision (`cfloat`)
* [s32](\ref s32) 32-bit signed integer (`int`)
* [u32](\ref u32) 32-bit unsigned integer (`unsigned`)
* [f64](\ref f64) real double-precision (`double`)
* [c64](\ref c64) complex double-precision (`cdouble`)
* [s64](\ref s64) 64-bit signed integer (`intl`)
* [u64](\ref u64) 64-bit unsigned integer (`uintl`)
* [s16](\ref s16) 16-bit signed integer (`short`)
* [u16](\ref u16) 16-bit unsigned integer (`unsigned short`)
Older devices may not support double precision operations.
# Creating and populating an ArrayFire array {#getting_started_af_arrays}
ArrayFire [array](\ref af::array)s always exist on the device. They
may be populated with data using an ArrayFire function, or filled with data
found on the host. For example:
\snippet test/getting_started.cpp ex_getting_started_gen
A complete list of ArrayFire functions that automatically generate data
on the device may be found on the [functions to create arrays](\ref data_mat)
page. The default data type for arrays is [f32](\ref f32) (a
32-bit floating point number) unless specified otherwise.
ArrayFire arrays may also be populated from data found on the host.
For example:
\snippet test/getting_started.cpp ex_getting_started_init
ArrayFire also supports array initialization from a device pointer.
For example ArrayFire can be populated directly by a call to `cudaMemcpy`
\snippet test/getting_started.cpp ex_getting_started_dev_ptr
# ArrayFire array contents, dimensions, and properties {#getting_started_array_properties}
The [af_print](\ref af::af_print) function can be used to print arrays that
have already been generated or an expression involving arrays:
\snippet test/getting_started.cpp ex_getting_started_print
ArrayFire provides several convenient methods for accessing the dimensions.
You may use either a [dim4](\ref af::dim4) object or access the dimensions
directly using the [dims()](\ref af::array::dims) and
[numdims()](\ref af::array::numdims) functions:
\snippet test/getting_started.cpp ex_getting_started_dims
Arrays also provide functions to determine their properties including:
\snippet test/getting_started.cpp ex_getting_started_prop
# Writing mathematical expressions in ArrayFire {#getting_started_writing_math}
Most of ArrayFire's functions operate on an element-wise basis.
This means that function like `c[i] = a[i] + b[i]` could simply be written
as `c = a + b`.
ArrayFire has an intelligent runtime JIT compliation engine which converts
array expressions into the smallest number of OpenCL/CUDA kernels.
This "kernel fusion" technology not only decreases the number of kernel calls,
but, more importantly, avoids extraneous global memory operations.
Our JIT functionality extends across C/C++ function boundaries and only ends
when a non-JIT function is encountered or a synchronization operation is
explicitly called by the code.
ArrayFire has [hundreds of functions](\ref arith_mat) for element-wise
arithmetic. Here are a few examples:
\snippet test/getting_started.cpp ex_getting_started_arith
# Mathematical constants {#getting_started_constants}
ArrayFire contains several platform-independent constants, like
[Pi](\ref af::Pi), [NaN](\ref af::NaN), and [Inf](\ref af::Inf).
If ArrayFire does not have a constant you need, you can create your own
using the [af::constant](\ref af::constant) array constructor.
Constants can be used in all of ArrayFire's functions. Below we demonstrate
their use in element selection and a mathematical expression:
\snippet test/getting_started.cpp ex_getting_started_constants
Please note that our constants may, at times, conflict with macro definitions
in standard header files. When this occurs, please refer to our constants
using the `af::` namespace.
# Indexing {#getting_started_indexing}
Like all functions in ArrayFire, indexing is also executed in parallel on
the OpenCL/CUDA device.
Because of this, indexing becomes part of a JIT operation and is accomplished
using parentheses instead of square brackets (i.e. as `A(0)` instead of `A[0]`).
To index `af::array`s you may use one or a combination of the following functions:
* integer scalars
* [seq()](\ref af::seq) representing a linear sequence
* [end](\ref af::end) representing the last element of a dimension
* [span](\ref af::span) representing the entire dimension
* [row(i)](\ref af::array::row) or [col(i)](\ref af::array::col) specifying a single row/column
* [rows(first,last)](\ref af::array::rows) or [cols(first,last)](\ref af::array::cols)
specifying a span of rows or columns
Please see the [indexing page](\ref indexing) for several examples of how to
use these functions.
# Getting access to ArrayFire array memory on the host and device {#getting_started_memory_access}
Memory in `af::array`s may be accessed using the [host()](\ref af::array::host)
and device()](\ref af::array::device) functions.
The `host` function *copies* the data from the device and makes it available
in a C-style array on the host.
The `device` function returns a pointer to device memory for interoperability
with external CUDA/OpenCL kernels.
For example, here is how we can interact with both OpenCL and CUDA:
\snippet test/getting_started.cpp ex_getting_started_ptr
ArrayFire also provides several helper functions for creating `af::array`s from
OpenCL `cl_mem` references and `cl::Buffer` objects. See the `include/af/opencl.h`
file for further information.
Lastly, if you want only the first value from an `af::array` you can use
get it using the [scalar()](\ref af::array::scalar) function:
\snippet test/getting_started.cpp ex_getting_started_scalar
# Bitwise operators {#getting_started_bitwise_operators}
In addition to supporting standard mathematical functions, `af::array`s
that contain integer data types also support bitwise operators including
and, or, and shift:
\snippet test/getting_started.cpp ex_getting_started_bit
# Using the ArrayFire API in C and C++ {#gettingstarted_api_usage}
The ArrayFire API is wrapped into a unified C/C++ header. To use the library
simply include the `arrayfire.h` header file and start coding!
## Sample using the C API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
#include <arrayfire.h>
// Generate random data and sum and print the result
int main(void)
{
// generate random values
int n = 10000;
af_array a;
af_randu(&a, n);
// sum all the values
float result;
af_sum_all(&result, a, 0);
printf("sum: %g\n", sum);
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Sample using the C++ API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
#include <arrayfire.h>
// Generate random data, sum and print the result.
int main(void)
{
// Generate 10,000 random values
af::array a = af::randu(10000);
// Sum the values and copy the result to the CPU:
double sum = af::sum<float>(a);
printf("sum: %g\n", sum);
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# What to read next? {#getting_started_next_steps}
Now that you have a general introduction to ArrayFire, where do you go from
here? In particular you might find these documents useful
* [Building an ArrayFire program on Linux](\ref using_on_linux)
* [Building an Arrayfire program on Windows](\ref using_on_windows)
* [Timing ArrayFire code](\ref timing)
# Where to go for help? {#getting_started_help}
* Google Groups: https://groups.google.com/forum/#!forum/arrayfire-users
* ArrayFire Services: [Consulting](http://arrayfire.com/consulting/) | [Support](http://arrayfire.com/support/) | [Training](http://arrayfire.com/training/)
* ArrayFire Blogs: http://arrayfire.com/blog/
* Email: <mailto:technical@arrayfire.com>
|