Skip to content

Commit f3cb8c3

Browse files
dbortfacebook-github-bot
authored andcommitted
Remove custom implementations of optional and string_view
Summary: Now that we're using C++17, we don't need to maintain custom implementations of `optional` and `string_view`. The standard optional has an implicit ctor that causes ambiguities in some reduce_util.h functions. Add explicit overrides to resolve the ambiguities. Note that this is technically an API break, since exec_aten::optional is changing in a way that can break some existing code. There is no way to roll this out incrementally, though, and there should not be many examples of user code that would break because of this change. Differential Revision: D64634702
1 parent 4d7b294 commit f3cb8c3

File tree

4 files changed

+33
-727
lines changed

4 files changed

+33
-727
lines changed

kernels/portable/cpu/util/reduce_util.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,15 @@ size_t compute_reduced_out_size(
565565
bool keepdim,
566566
exec_aten::SizesType* sizes_arr);
567567

568+
inline size_t compute_reduced_out_size(
569+
const exec_aten::Tensor& in,
570+
int64_t dim,
571+
bool keepdim,
572+
exec_aten::SizesType* sizes_arr) {
573+
return compute_reduced_out_size(
574+
in, exec_aten::optional<int64_t>(dim), keepdim, sizes_arr);
575+
}
576+
568577
inline ssize_t compute_reduced_out_dim(
569578
const exec_aten::Tensor& in,
570579
const exec_aten::optional<int64_t>& dim,
@@ -588,6 +597,14 @@ inline ssize_t compute_reduced_out_dim(
588597
: 0);
589598
}
590599

600+
inline ssize_t compute_reduced_out_dim(
601+
const exec_aten::Tensor& in,
602+
int64_t dim,
603+
bool keepdim) {
604+
return compute_reduced_out_dim(
605+
in, exec_aten::optional<int64_t>(dim), keepdim);
606+
}
607+
591608
//
592609
// Resize out tensor of reduction op
593610
//
@@ -604,6 +621,15 @@ Error resize_reduction_out(
604621
bool keepdim,
605622
exec_aten::Tensor& out);
606623

624+
inline Error resize_reduction_out(
625+
const exec_aten::Tensor& in,
626+
int64_t dim,
627+
bool keepdim,
628+
exec_aten::Tensor& out) {
629+
return resize_reduction_out(
630+
in, exec_aten::optional<int64_t>(dim), keepdim, out);
631+
}
632+
607633
#ifndef USE_ATEN_LIB
608634
bool check_reduction_args(
609635
const Tensor& in,

runtime/core/exec_aten/exec_aten.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ using ArrayRef = torch::executor::ArrayRef<T>;
104104
template <typename T>
105105
using optional = torch::executor::optional<T>;
106106
using nullopt_t = torch::executor::nullopt_t;
107-
// NOLINTNEXTLINE(facebook-hte-NamespaceScopedStaticDeclaration)
108-
static constexpr nullopt_t nullopt{0};
107+
using torch::executor::nullopt;
109108
using ScalarType = torch::executor::ScalarType;
110109
using TensorList = ArrayRef<Tensor>;
111110
using Scalar = torch::executor::Scalar;

runtime/core/portable_type/optional.h

Lines changed: 4 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -8,175 +8,15 @@
88

99
#pragma once
1010

11-
#include <executorch/runtime/platform/assert.h>
12-
#include <new>
13-
#include <utility> // std::forward and other template magic checks
11+
#include <optional>
1412

1513
namespace executorch {
1614
namespace runtime {
1715
namespace etensor {
1816

19-
/// Used to indicate an optional type with uninitialized state.
20-
struct nullopt_t final {
21-
constexpr explicit nullopt_t(int32_t) {}
22-
};
23-
24-
/// A constant of type nullopt_t that is used to indicate an optional type with
25-
/// uninitialized state.
26-
constexpr nullopt_t nullopt{0};
27-
28-
/// Leaner optional class, subset of c10, std, and boost optional APIs.
29-
template <class T>
30-
class optional final {
31-
public:
32-
/// The type wrapped by the optional class.
33-
using value_type = T;
34-
35-
/// Constructs an optional object that does not contain a value.
36-
/* implicit */ optional() noexcept : storage_(trivial_init), init_(false) {}
37-
38-
/// Constructs an optional object that does not contain a value.
39-
/* implicit */ optional(nullopt_t) noexcept
40-
: storage_(trivial_init), init_(false) {}
41-
42-
/// Constructs an optional object that matches the state of v.
43-
/* implicit */ optional(const optional<T>& v)
44-
: storage_(trivial_init), init_(v.init_) {
45-
if (init_) {
46-
new (&storage_.value_) T(v.storage_.value_);
47-
}
48-
}
49-
50-
/// Constructs an optional object that contains the specified value.
51-
/* implicit */ optional(const T& v) : storage_(v), init_(true) {}
52-
53-
/// Constructs an optional object from v.
54-
/* implicit */ optional(optional<T>&& v) noexcept(
55-
std::is_nothrow_move_constructible<T>::value)
56-
: storage_(trivial_init), init_(v.init_) {
57-
if (init_) {
58-
new (&storage_.value_) T(std::forward<T>(v.storage_.value_));
59-
}
60-
}
61-
62-
/// Constructs an optional object that contains the specified value.
63-
/* implicit */ optional(T&& v) : storage_(std::forward<T>(v)), init_(true) {}
64-
65-
optional& operator=(const optional& rhs) {
66-
if (init_ && !rhs.init_) {
67-
clear();
68-
} else if (!init_ && rhs.init_) {
69-
init_ = true;
70-
new (&storage_.value_) T(rhs.storage_.value_);
71-
} else if (init_ && rhs.init_) {
72-
storage_.value_ = rhs.storage_.value_;
73-
}
74-
return *this;
75-
}
76-
77-
optional& operator=(optional&& rhs) noexcept(
78-
std::is_nothrow_move_assignable<T>::value &&
79-
std::is_nothrow_move_constructible<T>::value) {
80-
if (init_ && !rhs.init_) {
81-
clear();
82-
} else if (!init_ && rhs.init_) {
83-
init_ = true;
84-
new (&storage_.value_) T(std::forward<T>(rhs.storage_.value_));
85-
} else if (init_ && rhs.init_) {
86-
storage_.value_ = std::forward<T>(rhs.storage_.value_);
87-
}
88-
return *this;
89-
}
90-
91-
/// Destroys the stored value if there is one
92-
~optional() {
93-
if (init_) {
94-
storage_.value_.~T();
95-
}
96-
}
97-
98-
optional& operator=(nullopt_t) noexcept {
99-
clear();
100-
return *this;
101-
}
102-
103-
/// Returns true if the object contains a value, false otherwise
104-
explicit operator bool() const noexcept {
105-
return init_;
106-
}
107-
108-
/// Returns true if the object contains a value, false otherwise
109-
bool has_value() const noexcept {
110-
return init_;
111-
}
112-
113-
/// Returns a constant reference to the contained value. Calls ET_CHECK if
114-
/// the object does not contain a value.
115-
T const& value() const& {
116-
ET_CHECK(init_);
117-
return contained_val();
118-
}
119-
120-
/// Returns a mutable reference to the contained value. Calls ET_CHECK if the
121-
/// object does not contain a value.
122-
T& value() & {
123-
ET_CHECK(init_);
124-
return contained_val();
125-
}
126-
127-
/// Returns an rvalue of the contained value. Calls ET_CHECK if the object
128-
/// does not contain a value.
129-
T&& value() && {
130-
ET_CHECK(init_);
131-
return std::forward<T>(contained_val());
132-
}
133-
134-
private:
135-
// Used to invoke the dummy ctor of storage_t in the initializer lists of
136-
// optional_base as default ctor is implicitly deleted because T is nontrivial
137-
struct trivial_init_t {
138-
} trivial_init{};
139-
140-
/**
141-
* A wrapper type that lets us avoid constructing a T when there is no value.
142-
* If there is a value present, the optional class must destroy it.
143-
*/
144-
union storage_t {
145-
/// A small, trivially-constructable alternative to T.
146-
unsigned char dummy_;
147-
/// The constructed value itself, if optional::has_value_ is true.
148-
T value_;
149-
150-
/* implicit */ storage_t(trivial_init_t) {
151-
dummy_ = 0;
152-
}
153-
154-
template <class... Args>
155-
storage_t(Args&&... args) : value_(std::forward<Args>(args)...) {}
156-
157-
~storage_t() {}
158-
};
159-
160-
const T& contained_val() const& {
161-
return storage_.value_;
162-
}
163-
T&& contained_val() && {
164-
return std::move(storage_.value_);
165-
}
166-
T& contained_val() & {
167-
return storage_.value_;
168-
}
169-
170-
void clear() noexcept {
171-
if (init_) {
172-
storage_.value_.~T();
173-
}
174-
init_ = false;
175-
}
176-
177-
storage_t storage_;
178-
bool init_;
179-
};
17+
using std::nullopt;
18+
using std::nullopt_t;
19+
using std::optional;
18020

18121
} // namespace etensor
18222
} // namespace runtime

0 commit comments

Comments
 (0)