This C++ API example demonstrates programming for Intel(R) Processor Graphics with OpenCL* extensions API in oneDNN.
#include <iostream>
#include <numeric>
#include <stdexcept>
#include <CL/cl.h>
#include "oneapi/dnnl/dnnl_ocl.hpp"
#include "example_utils.hpp"
using namespace std;
#define OCL_CHECK(x) \
do { \
cl_int s = (x); \
if (s != CL_SUCCESS) { \
std::cout << "[" << __FILE__ << ":" << __LINE__ << "] '" << #x \
<< "' failed (status code: " << s << ")." << std::endl; \
exit(1); \
} \
} while (0)
cl_kernel create_init_opencl_kernel(
cl_context ocl_ctx, const char *kernel_name, const char *ocl_code) {
cl_int err;
const char *sources[] = {ocl_code};
cl_program ocl_program
= clCreateProgramWithSource(ocl_ctx, 1, sources, nullptr, &err);
OCL_CHECK(err);
OCL_CHECK(
clBuildProgram(ocl_program, 0, nullptr, nullptr, nullptr, nullptr));
cl_kernel ocl_kernel = clCreateKernel(ocl_program, kernel_name, &err);
OCL_CHECK(err);
OCL_CHECK(clReleaseProgram(ocl_program));
return ocl_kernel;
}
void gpu_opencl_interop_tutorial() {
const size_t N = std::accumulate(tz_dims.begin(), tz_dims.end(), (size_t)1,
std::multiplies<size_t>());
memory::desc mem_d(
memory mem(mem_d, eng);
const char *ocl_code
= "__kernel void init(__global float *data) {"
" int id = get_global_id(0);"
" data[id] = (id % 2) ? -id : id;"
"}";
const char *kernel_name = "init";
cl_kernel ocl_init_kernel = create_init_opencl_kernel(
OCL_CHECK(clSetKernelArg(ocl_init_kernel, 0, sizeof(ocl_buf), &ocl_buf));
OCL_CHECK(clEnqueueNDRangeKernel(ocl_queue, ocl_init_kernel, 1, nullptr, &N,
nullptr, 0, nullptr, nullptr));
auto relu_d = eltwise_forward::desc(
auto relu_pd = eltwise_forward::primitive_desc(relu_d, eng);
auto relu = eltwise_forward(relu_pd);
strm.wait();
std::vector<float> mem_data(N);
read_from_dnnl_memory(mem_data.data(), mem);
for (size_t i = 0; i < N; i++) {
float expected = (i % 2) ? 0.0f : (float)i;
if (mem_data[i] != expected) {
std::cout << "Expect " << expected << " but got " << mem_data[i]
<< "." << std::endl;
throw std::logic_error("Accuracy check failed.");
}
}
OCL_CHECK(clReleaseKernel(ocl_init_kernel));
}
int main(int argc, char **argv) {
return handle_example_errors(
}
@ eltwise_relu
Elementwise: rectified linear unit (ReLU)
@ forward
Forward data propagation, alias for dnnl::prop_kind::forward_training.
#define DNNL_ARG_DST
A special mnemonic for destination argument for primitives that have a single destination.
Definition: dnnl_types.h:2376
#define DNNL_ARG_SRC
A special mnemonic for source argument for primitives that have a single source.
Definition: dnnl_types.h:2352
cl_command_queue get_command_queue(const stream &astream)
Returns OpenCL queue object associated with the execution stream.
Definition: dnnl_ocl.hpp:108
cl_context get_context(const engine &aengine)
Returns OpenCL context associated with the engine.
Definition: dnnl_ocl.hpp:72
cl_mem get_mem_object(const memory &amemory)
Returns the OpenCL memory object associated with the memory object.
Definition: dnnl_ocl.hpp:120
oneDNN namespace
Definition: dnnl.hpp:74
@ nchw
4D CNN activations tensor; an alias for dnnl::memory::format_tag::abcd
@ f32
32-bit/single-precision floating point.
std::vector< dim > dims
Vector of dimensions.
Definition: dnnl.hpp:1131
An execution stream.
Definition: dnnl.hpp:1001