schedule_model.hpp 10.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
Paul's avatar
Paul committed
24
25
#ifndef MIGRAPHX_GUARD_SCHEDULE_MODEL_HPP
#define MIGRAPHX_GUARD_SCHEDULE_MODEL_HPP
mei-ye's avatar
mei-ye committed
26
27
28
29
30
31
32
33

#include <cassert>
#include <string>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>

Paul's avatar
Paul committed
34
#include <migraphx/config.hpp>
mei-ye's avatar
mei-ye committed
35
#include <migraphx/instruction_ref.hpp>
Paul's avatar
Paul committed
36
#include <vector>
mei-ye's avatar
mei-ye committed
37
38
39
40

namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {

Shucai Xiao's avatar
Shucai Xiao committed
41
struct module;
Paul's avatar
Paul committed
42
struct operation;
mei-ye's avatar
mei-ye committed
43
44
45

#ifdef DOXYGEN

Paul's avatar
Paul committed
46
47
/// An interface for target-dependent model for the scheduler
struct schedule_model
mei-ye's avatar
mei-ye committed
48
{
Paul's avatar
Paul committed
49
50
51
    /// Get the number of concurrent instruction allowed
    std::size_t concurrency() const;
    /// Schedule a concurrent instruction
52
    void sched(module& m, instruction_ref ins, std::size_t n) const;
Paul's avatar
Paul committed
53
    // Insert necessary waits before an instruction
54
    void wait(module& m, instruction_ref ins, std::size_t wait_id) const;
Paul's avatar
Paul committed
55
    // Insert necessary records after an instruction
56
    void record(module& m, instruction_ref ins, std::size_t wait_id) const;
Paul's avatar
Paul committed
57
58
    /// Compute weights for an operation
    std::size_t weight(const operation& op) const;
mei-ye's avatar
mei-ye committed
59
60
61
62
};

#else

63
64
65
#ifdef TYPE_ERASED_DECLARATION

// Type-erased interface for:
66
struct MIGRAPHX_EXPORT schedule_model
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{
    //
    std::size_t concurrency() const;
    //
    void sched(module& m, instruction_ref ins, std::size_t n) const;
    //
    void wait(module& m, instruction_ref ins, std::size_t wait_id) const;
    //
    void record(module& m, instruction_ref ins, std::size_t wait_id) const;
    //
    std::size_t weight(const operation& op) const;
};

#else
mei-ye's avatar
mei-ye committed
81

Paul's avatar
Paul committed
82
struct schedule_model
mei-ye's avatar
mei-ye committed
83
84
{
    // Constructors
Paul's avatar
Paul committed
85
    schedule_model() = default;
mei-ye's avatar
mei-ye committed
86
87

    template <typename PrivateDetailTypeErasedT>
Paul's avatar
Paul committed
88
    schedule_model(PrivateDetailTypeErasedT value)
mei-ye's avatar
mei-ye committed
89
90
91
92
93
94
95
96
97
        : private_detail_te_handle_mem_var(
              std::make_shared<private_detail_te_handle_type<
                  typename std::remove_reference<PrivateDetailTypeErasedT>::type>>(
                  std::forward<PrivateDetailTypeErasedT>(value)))
    {
    }

    // Assignment
    template <typename PrivateDetailTypeErasedT>
Paul's avatar
Paul committed
98
    schedule_model& operator=(PrivateDetailTypeErasedT value)
mei-ye's avatar
mei-ye committed
99
    {
Paul Fultz II's avatar
Paul Fultz II committed
100
101
        using std::swap;
        auto* derived = this->any_cast<PrivateDetailTypeErasedT>();
102
        if(derived and private_detail_te_handle_mem_var.use_count() == 1)
Paul Fultz II's avatar
Paul Fultz II committed
103
104
105
106
107
108
109
110
        {
            *derived = std::forward<PrivateDetailTypeErasedT>(value);
        }
        else
        {
            schedule_model rhs(value);
            swap(private_detail_te_handle_mem_var, rhs.private_detail_te_handle_mem_var);
        }
mei-ye's avatar
mei-ye committed
111
112
113
114
115
116
117
        return *this;
    }

    // Cast
    template <typename PrivateDetailTypeErasedT>
    PrivateDetailTypeErasedT* any_cast()
    {
Paul Fultz II's avatar
Paul Fultz II committed
118
        return this->type_id() == typeid(PrivateDetailTypeErasedT)
mei-ye's avatar
mei-ye committed
119
120
121
122
123
124
125
126
127
128
                   ? std::addressof(static_cast<private_detail_te_handle_type<
                                        typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
                                        private_detail_te_get_handle())
                                        .private_detail_te_value)
                   : nullptr;
    }

    template <typename PrivateDetailTypeErasedT>
    const typename std::remove_cv<PrivateDetailTypeErasedT>::type* any_cast() const
    {
Paul Fultz II's avatar
Paul Fultz II committed
129
        return this->type_id() == typeid(PrivateDetailTypeErasedT)
mei-ye's avatar
mei-ye committed
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
                   ? std::addressof(static_cast<const private_detail_te_handle_type<
                                        typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
                                        private_detail_te_get_handle())
                                        .private_detail_te_value)
                   : nullptr;
    }

    const std::type_info& type_id() const
    {
        if(private_detail_te_handle_empty())
            return typeid(std::nullptr_t);
        else
            return private_detail_te_get_handle().type();
    }

Paul's avatar
Paul committed
145
    std::size_t concurrency() const
mei-ye's avatar
mei-ye committed
146
147
    {
        assert((*this).private_detail_te_handle_mem_var);
Paul's avatar
Paul committed
148
        return (*this).private_detail_te_get_handle().concurrency();
mei-ye's avatar
mei-ye committed
149
150
    }

151
    void sched(module& m, instruction_ref ins, std::size_t n) const
mei-ye's avatar
mei-ye committed
152
153
    {
        assert((*this).private_detail_te_handle_mem_var);
154
        (*this).private_detail_te_get_handle().sched(m, ins, n);
mei-ye's avatar
mei-ye committed
155
156
    }

157
    void wait(module& m, instruction_ref ins, std::size_t wait_id) const
mei-ye's avatar
mei-ye committed
158
159
    {
        assert((*this).private_detail_te_handle_mem_var);
160
        (*this).private_detail_te_get_handle().wait(m, ins, wait_id);
mei-ye's avatar
mei-ye committed
161
162
    }

163
    void record(module& m, instruction_ref ins, std::size_t wait_id) const
mei-ye's avatar
mei-ye committed
164
165
    {
        assert((*this).private_detail_te_handle_mem_var);
166
        (*this).private_detail_te_get_handle().record(m, ins, wait_id);
mei-ye's avatar
mei-ye committed
167
168
    }

Paul's avatar
Paul committed
169
170
171
172
173
174
175
176
    std::size_t weight(const operation& op) const
    {
        assert((*this).private_detail_te_handle_mem_var);
        return (*this).private_detail_te_get_handle().weight(op);
    }

    friend bool is_shared(const schedule_model& private_detail_x,
                          const schedule_model& private_detail_y)
mei-ye's avatar
mei-ye committed
177
178
179
180
181
182
183
184
185
186
187
188
    {
        return private_detail_x.private_detail_te_handle_mem_var ==
               private_detail_y.private_detail_te_handle_mem_var;
    }

    private:
    struct private_detail_te_handle_base_type
    {
        virtual ~private_detail_te_handle_base_type() {}
        virtual std::shared_ptr<private_detail_te_handle_base_type> clone() const = 0;
        virtual const std::type_info& type() const                                = 0;

189
        virtual std::size_t concurrency() const                                        = 0;
190
191
192
        virtual void sched(module& m, instruction_ref ins, std::size_t n) const        = 0;
        virtual void wait(module& m, instruction_ref ins, std::size_t wait_id) const   = 0;
        virtual void record(module& m, instruction_ref ins, std::size_t wait_id) const = 0;
193
        virtual std::size_t weight(const operation& op) const                          = 0;
mei-ye's avatar
mei-ye committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    };

    template <typename PrivateDetailTypeErasedT>
    struct private_detail_te_handle_type : private_detail_te_handle_base_type
    {
        template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
        private_detail_te_handle_type(
            PrivateDetailTypeErasedT value,
            typename std::enable_if<std::is_reference<PrivateDetailTypeErasedU>::value>::type* =
                nullptr)
            : private_detail_te_value(value)
        {
        }

        template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
        private_detail_te_handle_type(
            PrivateDetailTypeErasedT value,
211
            typename std::enable_if<not std::is_reference<PrivateDetailTypeErasedU>::value,
mei-ye's avatar
mei-ye committed
212
213
214
215
216
217
218
219
220
221
222
223
                                    int>::type* = nullptr) noexcept
            : private_detail_te_value(std::move(value))
        {
        }

        std::shared_ptr<private_detail_te_handle_base_type> clone() const override
        {
            return std::make_shared<private_detail_te_handle_type>(private_detail_te_value);
        }

        const std::type_info& type() const override { return typeid(private_detail_te_value); }

Paul's avatar
Paul committed
224
225
        std::size_t concurrency() const override { return private_detail_te_value.concurrency(); }

226
        void sched(module& m, instruction_ref ins, std::size_t n) const override
mei-ye's avatar
mei-ye committed
227
228
        {

229
            private_detail_te_value.sched(m, ins, n);
mei-ye's avatar
mei-ye committed
230
231
        }

232
        void wait(module& m, instruction_ref ins, std::size_t wait_id) const override
mei-ye's avatar
mei-ye committed
233
234
        {

235
            private_detail_te_value.wait(m, ins, wait_id);
mei-ye's avatar
mei-ye committed
236
237
        }

238
        void record(module& m, instruction_ref ins, std::size_t wait_id) const override
mei-ye's avatar
mei-ye committed
239
240
        {

241
            private_detail_te_value.record(m, ins, wait_id);
mei-ye's avatar
mei-ye committed
242
243
        }

Paul's avatar
Paul committed
244
        std::size_t weight(const operation& op) const override
mei-ye's avatar
mei-ye committed
245
246
        {

Paul's avatar
Paul committed
247
            return private_detail_te_value.weight(op);
mei-ye's avatar
mei-ye committed
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
        }

        PrivateDetailTypeErasedT private_detail_te_value;
    };

    template <typename PrivateDetailTypeErasedT>
    struct private_detail_te_handle_type<std::reference_wrapper<PrivateDetailTypeErasedT>>
        : private_detail_te_handle_type<PrivateDetailTypeErasedT&>
    {
        private_detail_te_handle_type(std::reference_wrapper<PrivateDetailTypeErasedT> ref)
            : private_detail_te_handle_type<PrivateDetailTypeErasedT&>(ref.get())
        {
        }
    };

    bool private_detail_te_handle_empty() const
    {
        return private_detail_te_handle_mem_var == nullptr;
    }

    const private_detail_te_handle_base_type& private_detail_te_get_handle() const
    {
        assert(private_detail_te_handle_mem_var != nullptr);
        return *private_detail_te_handle_mem_var;
    }

    private_detail_te_handle_base_type& private_detail_te_get_handle()
    {
        assert(private_detail_te_handle_mem_var != nullptr);
277
        if(private_detail_te_handle_mem_var.use_count() > 1)
mei-ye's avatar
mei-ye committed
278
279
280
281
282
283
284
285
            private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone();
        return *private_detail_te_handle_mem_var;
    }

    std::shared_ptr<private_detail_te_handle_base_type> private_detail_te_handle_mem_var;
};

template <typename ValueType>
Paul's avatar
Paul committed
286
inline const ValueType* any_cast(const schedule_model* x)
mei-ye's avatar
mei-ye committed
287
288
289
290
291
{
    return x->any_cast<ValueType>();
}

template <typename ValueType>
Paul's avatar
Paul committed
292
inline ValueType* any_cast(schedule_model* x)
mei-ye's avatar
mei-ye committed
293
294
295
296
297
{
    return x->any_cast<ValueType>();
}

template <typename ValueType>
Paul's avatar
Paul committed
298
inline ValueType& any_cast(schedule_model& x)
mei-ye's avatar
mei-ye committed
299
300
301
302
303
304
305
306
{
    auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
    if(y == nullptr)
        throw std::bad_cast();
    return *y;
}

template <typename ValueType>
Paul's avatar
Paul committed
307
inline const ValueType& any_cast(const schedule_model& x)
mei-ye's avatar
mei-ye committed
308
309
310
311
312
313
{
    const auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
    if(y == nullptr)
        throw std::bad_cast();
    return *y;
}
314
#endif
mei-ye's avatar
mei-ye committed
315
316

#endif
Paul's avatar
Paul committed
317

mei-ye's avatar
mei-ye committed
318
319
320
321
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx

#endif