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
30namespace dnnl {
31namespace impl {
32namespace cpu {
33
34class cpu_memory_storage_t : public memory_storage_t {
35public:
36 cpu_memory_storage_t(engine_t *engine)
37 : memory_storage_t(engine), data_(nullptr, release) {}
38
39 status_t get_data_handle(void **handle) const override {
40 *handle = data_.get();
41 return status::success;
42 }
43
44 status_t set_data_handle(void *handle) override {
45 data_ = decltype(data_)(handle, release);
46 return status::success;
47 }
48
49 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
63 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
70 bool is_host_accessible() const override { return true; }
71
72 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
80 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
87protected:
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
95private:
96 std::unique_ptr<void, void (*)(void *)> data_;
97
98 DNNL_DISALLOW_COPY_AND_ASSIGN(cpu_memory_storage_t);
99
100 static void release(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