oneAPI Deep Neural Network Library (oneDNN)  1.95.0
Performance library for Deep Learning
example_utils.h
1 /*******************************************************************************
2 * Copyright 2019-2020 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_H
18 #define EXAMPLE_UTILS_H
19 
20 #include <assert.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "dnnl.h"
27 #include "dnnl_debug.h"
28 
29 #define COMPLAIN_DNNL_ERROR_AND_EXIT(what, status) \
30  do { \
31  printf("[%s:%d] `%s` returns oneDNN error: %s.\n", __FILE__, __LINE__, \
32  what, dnnl_status2str(status)); \
33  printf("Example failed.\n"); \
34  exit(1); \
35  } while (0)
36 
37 #define COMPLAIN_EXAMPLE_ERROR_AND_EXIT(complain_fmt, ...) \
38  do { \
39  printf("[%s:%d] Error in the example: " complain_fmt ".\n", __FILE__, \
40  __LINE__, __VA_ARGS__); \
41  printf("Example failed.\n"); \
42  exit(2); \
43  } while (0)
44 
45 static dnnl_engine_kind_t validate_engine_kind(dnnl_engine_kind_t akind) {
46  // Checking if a GPU exists on the machine
47  if (akind == dnnl_gpu) {
49  printf("Application couldn't find GPU, please run with CPU "
50  "instead.\n");
51  exit(0);
52  }
53  }
54  return akind;
55 }
56 
57 #define CHECK(f) \
58  do { \
59  dnnl_status_t s_ = f; \
60  if (s_ != dnnl_success) COMPLAIN_DNNL_ERROR_AND_EXIT(#f, s_); \
61  } while (0)
62 
63 static inline dnnl_engine_kind_t parse_engine_kind(int argc, char **argv) {
64  // Returns default engine kind, i.e. CPU, if none given
65  if (argc == 1) {
66  return validate_engine_kind(dnnl_cpu);
67  } else if (argc == 2) {
68  // Checking the engine type, i.e. CPU or GPU
69  char *engine_kind_str = argv[1];
70  if (!strcmp(engine_kind_str, "cpu")) {
71  return validate_engine_kind(dnnl_cpu);
72  } else if (!strcmp(engine_kind_str, "gpu")) {
73  return validate_engine_kind(dnnl_gpu);
74  }
75  }
76 
77  // If all above fails, the example should be run properly
78  COMPLAIN_EXAMPLE_ERROR_AND_EXIT(
79  "inappropriate engine kind.\n"
80  "Please run the example like this: %s [cpu|gpu].",
81  argv[0]);
82 }
83 
84 static inline const char *engine_kind2str_upper(dnnl_engine_kind_t kind) {
85  if (kind == dnnl_cpu) return "CPU";
86  if (kind == dnnl_gpu) return "GPU";
87  return "<Unknown engine>";
88 }
89 
90 // Read from memory, write to handle
91 static inline void read_from_dnnl_memory(void *handle, dnnl_memory_t mem) {
92  dnnl_engine_t eng;
93  dnnl_engine_kind_t eng_kind;
94  const dnnl_memory_desc_t *md;
95 
96  CHECK(dnnl_memory_get_engine(mem, &eng));
97  CHECK(dnnl_engine_get_kind(eng, &eng_kind));
98  CHECK(dnnl_memory_get_memory_desc(mem, &md));
99  size_t bytes = dnnl_memory_desc_get_size(md);
100 
101 #if DNNL_WITH_SYCL
102  bool is_cpu_sycl
103  = (DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL && eng_kind == dnnl_cpu);
104  bool is_gpu_sycl
105  = (DNNL_GPU_RUNTIME == DNNL_RUNTIME_SYCL && eng_kind == dnnl_gpu);
106  if (is_cpu_sycl || is_gpu_sycl) {
107  void *mapped_ptr = NULL;
108  CHECK(dnnl_memory_map_data(mem, &mapped_ptr));
109  if (mapped_ptr) {
110  for (size_t i = 0; i < bytes; ++i) {
111  ((char *)handle)[i] = ((char *)mapped_ptr)[i];
112  }
113  }
114  CHECK(dnnl_memory_unmap_data(mem, mapped_ptr));
115  return;
116  }
117 #endif
118 
119 #if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL
120  if (eng_kind == dnnl_gpu) {
121  dnnl_stream_t s;
122  cl_command_queue q;
123  cl_mem m;
124 
125  CHECK(dnnl_memory_get_ocl_mem_object(mem, &m));
127  CHECK(dnnl_stream_get_ocl_command_queue(s, &q));
128 
129  cl_int ret = clEnqueueReadBuffer(
130  q, m, CL_TRUE, 0, bytes, handle, 0, NULL, NULL);
131  if (ret != CL_SUCCESS)
132  COMPLAIN_EXAMPLE_ERROR_AND_EXIT(
133  "clEnqueueReadBuffer failed (status code: %d)", ret);
134 
136  }
137 #endif
138 
139  if (eng_kind == dnnl_cpu) {
140  void *ptr = NULL;
141  CHECK(dnnl_memory_get_data_handle(mem, &ptr));
142  if (ptr) {
143  for (size_t i = 0; i < bytes; ++i) {
144  ((char *)handle)[i] = ((char *)ptr)[i];
145  }
146  }
147  return;
148  }
149 
150  assert(!"not expected");
151 }
152 
153 // Read from handle, write to memory
154 static inline void write_to_dnnl_memory(void *handle, dnnl_memory_t mem) {
155  dnnl_engine_t eng;
156  dnnl_engine_kind_t eng_kind;
157  const dnnl_memory_desc_t *md;
158 
159  CHECK(dnnl_memory_get_engine(mem, &eng));
160  CHECK(dnnl_engine_get_kind(eng, &eng_kind));
161  CHECK(dnnl_memory_get_memory_desc(mem, &md));
162  size_t bytes = dnnl_memory_desc_get_size(md);
163 
164 #if DNNL_WITH_SYCL
165  bool is_cpu_sycl
166  = (DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL && eng_kind == dnnl_cpu);
167  bool is_gpu_sycl
168  = (DNNL_GPU_RUNTIME == DNNL_RUNTIME_SYCL && eng_kind == dnnl_gpu);
169  if (is_cpu_sycl || is_gpu_sycl) {
170  void *mapped_ptr = NULL;
171  CHECK(dnnl_memory_map_data(mem, &mapped_ptr));
172  if (mapped_ptr) {
173  for (size_t i = 0; i < bytes; ++i) {
174  ((char *)mapped_ptr)[i] = ((char *)handle)[i];
175  }
176  }
177  CHECK(dnnl_memory_unmap_data(mem, mapped_ptr));
178  return;
179  }
180 #endif
181 
182 #if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL
183  if (eng_kind == dnnl_gpu) {
184  dnnl_stream_t s;
185  cl_command_queue q;
186  cl_mem m;
187 
188  CHECK(dnnl_memory_get_ocl_mem_object(mem, &m));
190  CHECK(dnnl_stream_get_ocl_command_queue(s, &q));
191 
192  cl_int ret = clEnqueueWriteBuffer(
193  q, m, CL_TRUE, 0, bytes, handle, 0, NULL, NULL);
194  if (ret != CL_SUCCESS)
195  COMPLAIN_EXAMPLE_ERROR_AND_EXIT(
196  "clEnqueueWriteBuffer failed (status code: %d)", ret);
197 
199  return;
200  }
201 #endif
202 
203  if (eng_kind == dnnl_cpu) {
204  void *ptr = NULL;
205  CHECK(dnnl_memory_get_data_handle(mem, &ptr));
206  if (ptr) {
207  for (size_t i = 0; i < bytes; ++i) {
208  ((char *)ptr)[i] = ((char *)handle)[i];
209  }
210  }
211  return;
212  }
213 
214  assert(!"not expected");
215 }
216 
217 #endif
dnnl_memory
dnnl_memory_get_ocl_mem_object
dnnl_status_t DNNL_API dnnl_memory_get_ocl_mem_object(const_dnnl_memory_t memory, cl_mem *mem_object)
Returns an OpenCL memory object associated with a memory object.
dnnl_engine
An opaque structure to describe an engine.
dnnl_memory_desc_get_size
size_t DNNL_API dnnl_memory_desc_get_size(const dnnl_memory_desc_t *memory_desc)
Returns the size of a memory descriptor.
dnnl_engine_get_kind
dnnl_status_t DNNL_API dnnl_engine_get_kind(dnnl_engine_t engine, dnnl_engine_kind_t *kind)
Returns the kind of an engine.
dnnl_gpu
@ dnnl_gpu
GPU engine.
Definition: dnnl_types.h:1743
dnnl_memory_unmap_data
dnnl_status_t DNNL_API dnnl_memory_unmap_data(const_dnnl_memory_t memory, void *mapped_ptr)
Unmaps a memory object and writes back any changes made to the previously mapped memory buffer.
DNNL_RUNTIME_SYCL
#define DNNL_RUNTIME_SYCL
SYCL runtime.
Definition: dnnl_types.h:2213
dnnl_stream_destroy
dnnl_status_t DNNL_API dnnl_stream_destroy(dnnl_stream_t stream)
Destroys an execution stream.
dnnl_engine_kind_t
dnnl_engine_kind_t
Kinds of engines.
Definition: dnnl_types.h:1737
dnnl_memory_get_data_handle
dnnl_status_t DNNL_API dnnl_memory_get_data_handle(const_dnnl_memory_t memory, void **handle)
Returns memory object's data handle.
dnnl_stream_create
dnnl_status_t DNNL_API dnnl_stream_create(dnnl_stream_t *stream, dnnl_engine_t engine, unsigned flags)
Creates an execution stream.
dnnl_memory_get_memory_desc
dnnl_status_t DNNL_API dnnl_memory_get_memory_desc(const_dnnl_memory_t memory, const dnnl_memory_desc_t **memory_desc)
Returns the memory descriptor for a memory object.
dnnl_stream_default_flags
@ dnnl_stream_default_flags
Default stream configuration.
Definition: dnnl_types.h:2171
dnnl_memory_get_engine
dnnl_status_t DNNL_API dnnl_memory_get_engine(const_dnnl_memory_t memory, dnnl_engine_t *engine)
Returns the engine of a memory object.
dnnl_engine_get_count
size_t DNNL_API dnnl_engine_get_count(dnnl_engine_kind_t kind)
Returns the number of engines of a particular kind.
dnnl_memory_map_data
dnnl_status_t DNNL_API dnnl_memory_map_data(const_dnnl_memory_t memory, void **mapped_ptr)
Maps a memory object and returns a host-side pointer to a memory buffer with a copy of its contents.
dnnl_stream_get_ocl_command_queue
dnnl_status_t DNNL_API dnnl_stream_get_ocl_command_queue(dnnl_stream_t stream, cl_command_queue *queue)
Returns the OpenCL command queue associated with an execution stream.
dnnl_debug.h
dnnl_cpu
@ dnnl_cpu
CPU engine.
Definition: dnnl_types.h:1741
dnnl_memory_desc_t
Memory descriptor.
Definition: dnnl_types.h:1140
dnnl.h
dnnl_stream