DPNP C++ backend kernel library 0.20.0dev0
Data Parallel Extension for NumPy*
Loading...
Searching...
No Matches
dpnpc_memory_adapter.hpp
1//*****************************************************************************
2// Copyright (c) 2016, Intel Corporation
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7// - Redistributions of source code must retain the above copyright notice,
8// this list of conditions and the following disclaimer.
9// - Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12// - Neither the name of the copyright holder nor the names of its contributors
13// may be used to endorse or promote products derived from this software
14// without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26// THE POSSIBILITY OF SUCH DAMAGE.
27//*****************************************************************************
28
29#pragma once
30#ifndef DPNP_MEMORY_ADAPTER_H // Cython compatibility
31#define DPNP_MEMORY_ADAPTER_H
32
33#include "dpnp_utils.hpp"
34#include "queue_sycl.hpp"
35
47template <typename _DataType>
49{
50 DPCTLSyclQueueRef queue_ref;
51 sycl::queue queue;
52 void *aux_ptr = nullptr;
53 void *orig_ptr =
54 nullptr;
55 size_t size_in_bytes = 0;
56 bool allocated = false;
58 bool target_no_queue = false;
60 bool copy_back = false;
62 const bool verbose = false;
63 std::vector<sycl::event> deps;
64
65public:
66 DPNPC_ptr_adapter() = delete;
67
68 DPNPC_ptr_adapter(DPCTLSyclQueueRef q_ref,
69 const void *src_ptr,
70 const size_t size,
71 bool target_no_sycl = false,
72 bool copy_back_request = false)
73 {
74 queue_ref = q_ref;
75 queue = *(reinterpret_cast<sycl::queue *>(queue_ref));
76 target_no_queue = target_no_sycl;
77 copy_back = copy_back_request;
78 orig_ptr = const_cast<void *>(src_ptr);
79 size_in_bytes = size * sizeof(_DataType);
80 deps = std::vector<sycl::event>{};
81
82 // enum class alloc { host = 0, device = 1, shared = 2, unknown = 3 };
83 sycl::usm::alloc src_ptr_type = sycl::usm::alloc::unknown;
84 src_ptr_type = sycl::get_pointer_type(src_ptr, queue.get_context());
85 if (verbose) {
86 std::cerr << "DPNPC_ptr_converter:";
87 std::cerr << "\n\t target_no_queue=" << target_no_queue;
88 std::cerr << "\n\t copy_back=" << copy_back;
89 std::cerr << "\n\t pointer=" << src_ptr;
90 std::cerr << "\n\t size=" << size;
91 std::cerr << "\n\t size_in_bytes=" << size_in_bytes;
92 std::cerr << "\n\t pointer type=" << (long)src_ptr_type;
93 std::cerr << "\n\t queue inorder=" << queue.is_in_order();
94 std::cerr << "\n\t queue device is_cpu="
95 << queue.get_device().is_cpu();
96 std::cerr << "\n\t queue device is_gpu="
97 << queue.get_device().is_gpu();
98 std::cerr << "\n\t queue device is_accelerator="
99 << queue.get_device().is_accelerator();
100 std::cerr << std::endl;
101 }
102
103 if (is_memcpy_required(src_ptr_type)) {
104 aux_ptr = dpnp_memory_alloc_c(queue_ref, size_in_bytes);
105 dpnp_memory_memcpy_c(queue_ref, aux_ptr, src_ptr, size_in_bytes);
106 allocated = true;
107 if (verbose) {
108 std::cerr << "DPNPC_ptr_converter::alloc and copy memory"
109 << " from=" << src_ptr << " to=" << aux_ptr
110 << " size_in_bytes=" << size_in_bytes << std::endl;
111 }
112 }
113 else {
114 aux_ptr = const_cast<void *>(src_ptr);
115 }
116 }
117
119 {
120 if (allocated) {
121 if (verbose) {
122 std::cerr << "DPNPC_ptr_converter::free_memory at=" << aux_ptr
123 << std::endl;
124 }
125
126 sycl::event::wait(deps);
127
128 if (copy_back) {
129 copy_data_back();
130 }
131
132 dpnp_memory_free_c(queue_ref, aux_ptr);
133 }
134 }
135
136 bool is_memcpy_required(sycl::usm::alloc src_ptr_type)
137 {
138 if (target_no_queue || queue.get_device().is_gpu()) {
139 if (src_ptr_type == sycl::usm::alloc::unknown) {
140 return true;
141 }
142 else if (target_no_queue &&
143 src_ptr_type == sycl::usm::alloc::device) {
144 return true;
145 }
146 }
147
148 return false;
149 }
150
151 _DataType *get_ptr() const
152 {
153 return reinterpret_cast<_DataType *>(aux_ptr);
154 }
155
156 void copy_data_back() const
157 {
158 if (verbose) {
159 std::cerr << "DPNPC_ptr_converter::copy_data_back:"
160 << " from=" << aux_ptr << " to=" << orig_ptr
161 << " size_in_bytes=" << size_in_bytes << std::endl;
162 }
163
164 dpnp_memory_memcpy_c(queue_ref, orig_ptr, aux_ptr, size_in_bytes);
165 }
166
167 void depends_on(const std::vector<sycl::event> &new_deps)
168 {
169 assert(allocated);
170 deps.insert(std::end(deps), std::begin(new_deps), std::end(new_deps));
171 }
172
173 void depends_on(const sycl::event &new_dep)
174 {
175 assert(allocated);
176 deps.push_back(new_dep);
177 }
178};
179
180#endif // DPNP_MEMORY_ADAPTER_H
Adapter for the memory given by parameters in the DPNPC functions.
char * dpnp_memory_alloc_c(DPCTLSyclQueueRef q_ref, size_t size_in_bytes)
SYCL queue memory allocation.