在《玩转 ArrayFire:04 初识 array(一)》中,我们已经了解到 ArrayFire 的一些具体用法,在这一篇中,我们将继续学习 ArrayFire 的更多用法。
像 ArrayFire 中的所有函数一样,索引也可以在 OpenCL/CUDA 设备上并行执行。因此,索引成为 JIT 操作的一部分,并且是使用圆括号而不是方括号来完成的(即作为(0)而不是[0])。要索引 af:: array ,你可以使用以下函数中的一个或一个组合:
array 中的内存可以使用 host() 和 device() 函数访问。host 函数从设备复制数据,并使其在主机上的 C 风格数组中可用。因此,由开发人员管理主机返回的内存。device 函数返回一个指向设备内存的指针/引用,用于与外部 CUDA/OpenCL 内核的互操作性。由于该内存属于 ArrayFire,程序员不应该试图释放/释放该指针。例如,下面是我们如何与 OpenCL 和 CUDA 交互:
// Create an array consisting of 3 random numbers
array a = randu(3, f32);
// Copy an array on the device to the host:
float * host_a = a.host<float>();
// access the host data as a normal array
printf("host_a[2] = %g\n", host_a[2]); // last element
// and free memory using delete:
delete[] host_a;
// Get access to the device memory for a CUDA kernel
float * d_cuda = a.device<float>(); // no need to free this
float value;
cudaMemcpy(&value, d_cuda + 2, sizeof(float), cudaMemcpyDeviceToHost);
printf("d_cuda[2] = %g\n", value);
a.unlock(); // unlock to allow garbage collection if necessary
// Because OpenCL uses references rather than pointers, accessing memory
// is similar, but has a somewhat clunky syntax. For the C-API
cl_mem d_opencl = (cl_mem) a.device<float>();
// for the C++ API, you can just wrap this object into a cl::Buffer
// after calling clRetainMemObject.
ArrayFire 还提供了几个辅助函数,用于从OpenCL cl_mem 引用和 cl::Buffer 对象处创建 af::array。更多信息请参阅 include/af/opencl.h 文件。
最后,如果你只想要 af::array 的第一个值,你可以使用 scalar()函数得到它:
array a = randu(3);
float val = a.scalar<float>();
printf("scalar value: %g\n", val)
除了支持标准数学函数外,包含整型数据类型的 array 还支持按位运算符,包括与、或、异或:
int h_A[] = {
1, 1, 0, 0, 4, 0, 0, 2, 0};
int h_B[] = {
1, 0, 1, 0, 1, 0, 1, 1, 1};
array A = array(3, 3, h_A), B = array(3, 3, h_B);
af_print(A); af_print(B);
array A_and_B = A & B; af_print(A_and_B);
array A_or_B = A | B; af_print(A_or_B);
array A_xor_B = A ^ B; af_print(A_xor_B);
ArrayFire API被包装在一个统一的 C/C++ 头文件中。要使用这个库,只需包含 arrayfire.h 头文件并开始编码!
这是使用 C API 的示例:
#include
// 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", result);
return 0;
}
这是使用 C++ API 的示例:
#include
// 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;
}