Deep Neural Network Library (DNNL)  1.90.1
Performance library for Deep Learning
example_utils.hpp
1 /*******************************************************************************
2 * Copyright 2019 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16 
17 #ifndef EXAMPLE_UTILS_HPP
18 #define EXAMPLE_UTILS_HPP
19 
20 #include <algorithm>
21 #include <assert.h>
22 #include <iostream>
23 #include <stdlib.h>
24 #include <string>
25 
26 #include "dnnl.hpp"
27 
28 dnnl::engine::kind validate_engine_kind(dnnl::engine::kind akind) {
29  // Checking if a GPU exists on the machine
30  if (akind == dnnl::engine::kind::gpu) {
32  std::cerr << "Application couldn't find GPU, please run with "
33  "CPU instead. Thanks!\n";
34  exit(0);
35  }
36  }
37  return akind;
38 }
39 
40 dnnl::engine::kind parse_engine_kind(
41  int argc, char **argv, int extra_args = 0) {
42  // Returns default engine kind, i.e. CPU, if none given
43  if (argc == 1) {
44  return validate_engine_kind(dnnl::engine::kind::cpu);
45  } else if (argc <= extra_args + 2) {
46  std::string engine_kind_str = argv[1];
47  // Checking the engine type, i.e. CPU or GPU
48  if (engine_kind_str == "cpu") {
49  return validate_engine_kind(dnnl::engine::kind::cpu);
50  } else if (engine_kind_str == "gpu") {
51  return validate_engine_kind(dnnl::engine::kind::gpu);
52  }
53  }
54 
55  // If all above fails, the example should be ran properly
56  std::cerr << "Please run example like this" << argv[0] << " cpu|gpu";
57  if (extra_args) { std::cerr << " [extra arguments]"; }
58  std::cerr << "\n";
59  exit(1);
60 }
61 
62 // Read from memory, write to handle
63 inline void read_from_dnnl_memory(void *handle, dnnl::memory &mem) {
64  dnnl::engine eng = mem.get_engine();
65  size_t size = mem.get_desc().get_size();
66 
67 #if DNNL_WITH_SYCL
68  bool is_cpu_sycl = (DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL
69  && eng.get_kind() == dnnl::engine::kind::cpu);
70  bool is_gpu_sycl = (DNNL_GPU_RUNTIME == DNNL_RUNTIME_SYCL
71  && eng.get_kind() == dnnl::engine::kind::gpu);
72  if (is_cpu_sycl || is_gpu_sycl) {
73 #ifdef DNNL_USE_SYCL_BUFFERS
74  auto buffer = mem.get_sycl_buffer<uint8_t>();
75  auto src = buffer.get_access<cl::sycl::access::mode::read>();
76  uint8_t *src_ptr = src.get_pointer();
77 #elif defined(DNNL_USE_DPCPP_USM)
78  uint8_t *src_ptr = (uint8_t *)mem.get_data_handle();
79 #else
80 #error "Not expected"
81 #endif
82  if (!handle || !src_ptr) {
83  std::cerr << "memory is NULL"
84  << "\n";
85  return;
86  }
87  for (size_t i = 0; i < size; ++i)
88  ((uint8_t *)handle)[i] = src_ptr[i];
89  return;
90  }
91 #endif
92 #if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL
93  if (eng.get_kind() == dnnl::engine::kind::gpu) {
94  dnnl::stream s(eng);
95  cl_command_queue q = s.get_ocl_command_queue();
96  cl_mem m = mem.get_ocl_mem_object();
97 
98  cl_int ret = clEnqueueReadBuffer(
99  q, m, CL_TRUE, 0, size, handle, 0, NULL, NULL);
100  if (ret != CL_SUCCESS)
101  throw std::runtime_error("clEnqueueReadBuffer failed. Status Code: "
102  + std::to_string(ret) + "\n");
103  return;
104  }
105 #endif
106 
107  if (eng.get_kind() == dnnl::engine::kind::cpu) {
108  uint8_t *src = static_cast<uint8_t *>(mem.get_data_handle());
109  if (!handle || !src) {
110  std::cerr << "memory is NULL"
111  << "\n";
112  return;
113  }
114  for (size_t i = 0; i < size; ++i)
115  ((uint8_t *)handle)[i] = src[i];
116  return;
117  }
118 
119  assert(!"not expected");
120 }
121 
122 // Read from handle, write to memory
123 inline void write_to_dnnl_memory(void *handle, dnnl::memory &mem) {
124  dnnl::engine eng = mem.get_engine();
125  size_t size = mem.get_desc().get_size();
126 
127 #if DNNL_WITH_SYCL
128  bool is_cpu_sycl = (DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL
129  && eng.get_kind() == dnnl::engine::kind::cpu);
130  bool is_gpu_sycl = (DNNL_GPU_RUNTIME == DNNL_RUNTIME_SYCL
131  && eng.get_kind() == dnnl::engine::kind::gpu);
132  if (is_cpu_sycl || is_gpu_sycl) {
133 #ifdef DNNL_USE_SYCL_BUFFERS
134  auto buffer = mem.get_sycl_buffer<uint8_t>();
135  auto dst = buffer.get_access<cl::sycl::access::mode::write>();
136  uint8_t *dst_ptr = dst.get_pointer();
137 #elif defined(DNNL_USE_DPCPP_USM)
138  uint8_t *dst_ptr = (uint8_t *)mem.get_data_handle();
139 #else
140 #error "Not expected"
141 #endif
142  if (!dst_ptr || !handle) {
143  std::cerr << "memory is NULL"
144  << "\n";
145  return;
146  }
147  for (size_t i = 0; i < size; ++i)
148  dst_ptr[i] = ((uint8_t *)handle)[i];
149  return;
150  }
151 #endif
152 #if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL
153  if (eng.get_kind() == dnnl::engine::kind::gpu) {
154  dnnl::stream s(eng);
155  cl_command_queue q = s.get_ocl_command_queue();
156  cl_mem m = mem.get_ocl_mem_object();
157 
158  cl_int ret = clEnqueueWriteBuffer(
159  q, m, CL_TRUE, 0, size, handle, 0, NULL, NULL);
160  if (ret != CL_SUCCESS)
161  throw std::runtime_error(
162  "clEnqueueWriteBuffer failed. Status Code: "
163  + std::to_string(ret) + "\n");
164  return;
165  }
166 #endif
167 
168  if (eng.get_kind() == dnnl::engine::kind::cpu) {
169  uint8_t *dst = static_cast<uint8_t *>(mem.get_data_handle());
170  if (!dst || !handle) {
171  std::cerr << "memory is NULL"
172  << "\n";
173  return;
174  }
175  for (size_t i = 0; i < size; ++i)
176  dst[i] = ((uint8_t *)handle)[i];
177  return;
178  }
179 
180  assert(!"not expected");
181 }
182 
183 #endif
void * get_data_handle() const
Returns a handle of the data contained in the memory.
Definition: dnnl.hpp:1561
static size_t get_count(kind akind)
Returns the number of engines of a certain kind.
Definition: dnnl.hpp:851
C++ API.
kind get_kind() const
Returns the kind of the engine.
Definition: dnnl.hpp:906
An execution engine.
Definition: dnnl.hpp:832
cl::sycl::buffer< T, ndims > get_sycl_buffer(size_t *offset=nullptr) const
Returns the underlying SYCL buffer object.
Definition: dnnl.hpp:1631
kind
Kinds of engines.
Definition: dnnl.hpp:837
engine get_engine() const
Returns the engine of the memory.
Definition: dnnl.hpp:1551
Memory that describes the data.
Definition: dnnl.hpp:1071
desc get_desc() const
Returns the descriptor of the memory.
Definition: dnnl.hpp:1543
cl_mem get_ocl_mem_object() const
Returns the OpenCL memory object associated with the memory.
Definition: dnnl.hpp:1611
size_t get_size() const
Returns the number of bytes required to allocate the memory described including the padding area...
Definition: dnnl.hpp:1478
An execution stream.
Definition: dnnl.hpp:976