1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/*!
21 * \file src/relay/collage/cost.h
22 * \brief Represents the estimated cost of a candidate partition.
23 */
24#ifndef TVM_RELAY_COLLAGE_COST_H_
25#define TVM_RELAY_COLLAGE_COST_H_
26
27#include <tvm/runtime/logging.h>
28
29#include <cmath>
30#include <limits>
31#include <string>
32
33namespace tvm {
34namespace relay {
35namespace collage {
36
37/*!
38 * \brief The assumed cost for a candidate partition. Generally average execution time in seconds.
39 * However other cost functions are possible, for example to introduce a penalty for high memory
40 * use, etc.
41 */
42class Cost {
43 public:
44 Cost() = delete;
45
46 static Cost Zero() { return Cost(0.0); }
47
48 /*!
49 * \brief Returns the distinguished 'invalid' cost signaling a candidate partition is not
50 * supported by the intended target, for example because the sub-graph has an unsupported operator
51 * or the intermediate memory required exceeds some system limit.
52 */
53 static Cost Invalid() { return Cost(std::numeric_limits<double>::infinity()); }
54
55 bool is_invalid() const { return std::isinf(value_) && value_ > 0.0; }
56
57 /*!
58 * \brief Returns the distinguished 'unknown' cost, signaling fixed priorities should be used to
59 * choose the best partitions. This can be used to disable tuning and fallback to fixed rules,
60 * much as TVM will use an un-tuned kernel if no tuning records are available.
61 */
62 static Cost Unknown() { return Cost(std::numeric_limits<double>::quiet_NaN()); }
63
64 bool is_unknown() const { return std::isnan(value_); }
65
66 /*! \brief Returns cost with given finite, non-negative value. */
67 static Cost Value(double value) {
68 ICHECK(!std::isnan(value) && !std::isinf(value) && value >= 0.0);
69 return Cost(value);
70 }
71
72 bool is_value() const { return !std::isnan(value_) && !std::isinf(value_); }
73
74 double value() const {
75 ICHECK(is_value());
76 return value_;
77 }
78
79 /*! \brief Return true if the less-than relation is defined for this and that. */
80 bool are_comparable(Cost that) const { return !std::isnan(value_) && !std::isnan(that.value_); }
81
82 /*! \brief Returns sum of this and that. */
83 Cost operator+(Cost that) const { return Cost(value_ + that.value_); }
84
85 /*! \brief Returns difference of this and that. */
86 Cost operator-(Cost that) const { return Cost(value_ - that.value_); }
87
88 /*! \brief Returns true if this is cheaper than that, assuming they are comparable. */
89 bool operator<(Cost that) const { return value_ < that.value_; }
90
91 std::string ToString() const;
92
93 private:
94 explicit Cost(double value) : value_(value) {}
95
96 /*!
97 * \brief Non-negative value or:
98 * - +inf if candidate partition is not feasible.
99 * - NaN if candidate partition has an unknown cost (priority may be used to break ties).
100 */
101 double value_ = 0.0;
102};
103
104} // namespace collage
105} // namespace relay
106} // namespace tvm
107
108#endif // TVM_RELAY_COLLAGE_COST_H_
109