1 /*******************************************************************************
2 * Copyright 2019-2021 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 CPU_CPU_MEMORY_STORAGE_HPP
18 #define CPU_CPU_MEMORY_STORAGE_HPP
19 
20 #include <memory>
21 
22 #include "common/c_types_map.hpp"
23 #include "common/memory.hpp"
24 #include "common/memory_storage.hpp"
25 #include "common/stream.hpp"
26 #include "common/utils.hpp"
27 
28 #include "cpu/platform.hpp"
29 
30 namespace dnnl {
31 namespace impl {
32 namespace cpu {
33 
34 class cpu_memory_storage_t : public memory_storage_t {
35 public:
cpu_memory_storage_t(engine_t * engine)36     cpu_memory_storage_t(engine_t *engine)
37         : memory_storage_t(engine), data_(nullptr, release) {}
38 
get_data_handle(void ** handle) const39     status_t get_data_handle(void **handle) const override {
40         *handle = data_.get();
41         return status::success;
42     }
43 
set_data_handle(void * handle)44     status_t set_data_handle(void *handle) override {
45         data_ = decltype(data_)(handle, release);
46         return status::success;
47     }
48 
map_data(void ** mapped_ptr,stream_t * stream,size_t size) const49     status_t map_data(
50             void **mapped_ptr, stream_t *stream, size_t size) const override {
51         UNUSED(size);
52         // This function is called for non-SYCL CPU engines only, where the
53         // runtime_kind is constant for a specific build, and engine_kind is
54         // only cpu. However, at the same time, the stream engine and memory
55         // object engine may have different memory locations. Therefore, at
56         // most, we need to ensure that the indexes of these engines are
57         // identical.
58         if (stream != nullptr && stream->engine()->index() != engine()->index())
59             return status::invalid_arguments;
60         return get_data_handle(mapped_ptr);
61     }
62 
unmap_data(void * mapped_ptr,stream_t * stream) const63     status_t unmap_data(void *mapped_ptr, stream_t *stream) const override {
64         UNUSED(mapped_ptr);
65         if (stream != nullptr && stream->engine()->index() != engine()->index())
66             return status::invalid_arguments;
67         return status::success;
68     }
69 
is_host_accessible() const70     bool is_host_accessible() const override { return true; }
71 
get_sub_storage(size_t offset,size_t size) const72     std::unique_ptr<memory_storage_t> get_sub_storage(
73             size_t offset, size_t size) const override {
74         void *sub_ptr = reinterpret_cast<uint8_t *>(data_.get()) + offset;
75         auto sub_storage = new cpu_memory_storage_t(this->engine());
76         sub_storage->init(memory_flags_t::use_runtime_ptr, size, sub_ptr);
77         return std::unique_ptr<memory_storage_t>(sub_storage);
78     }
79 
clone() const80     std::unique_ptr<memory_storage_t> clone() const override {
81         auto storage = new cpu_memory_storage_t(engine());
82         if (storage)
83             storage->init(memory_flags_t::use_runtime_ptr, 0, data_.get());
84         return std::unique_ptr<memory_storage_t>(storage);
85     }
86 
87 protected:
init_allocate(size_t size)88     status_t init_allocate(size_t size) override {
89         void *ptr = malloc(size, platform::get_cache_line_size());
90         if (!ptr) return status::out_of_memory;
91         data_ = decltype(data_)(ptr, destroy);
92         return status::success;
93     }
94 
95 private:
96     std::unique_ptr<void, void (*)(void *)> data_;
97 
98     DNNL_DISALLOW_COPY_AND_ASSIGN(cpu_memory_storage_t);
99 
release(void * ptr)100     static void release(void *ptr) {}
destroy(void * ptr)101     static void destroy(void *ptr) { free(ptr); }
102 };
103 
104 } // namespace cpu
105 } // namespace impl
106 } // namespace dnnl
107 
108 #endif
109