Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone Maybe: refactor Variant, Optional, Maybe and more #6820

Merged
merged 71 commits into from
Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
45aba9b
refactor maybe: add variant
PragmaTwice Nov 9, 2021
7010891
maybe: add optional and tests
PragmaTwice Nov 11, 2021
ae926b5
maybe: add hash for optional & variant; support NullOpt for both opti…
PragmaTwice Nov 12, 2021
67be133
maybe: more notes
PragmaTwice Nov 13, 2021
30e2a0b
maybe: binary search impl for Variant::Visit
PragmaTwice Nov 13, 2021
e41efcf
maybe: add more relational operator to optional & variant
PragmaTwice Nov 18, 2021
cb9f4bb
maybe: add nonstd::string_view
PragmaTwice Nov 18, 2021
01be3c7
maybe: fix construct of optional & variant
PragmaTwice Nov 18, 2021
42ecdc1
maybe: support comparision for optional & variant
PragmaTwice Nov 19, 2021
fdbbadc
maybe: add monadic operations for optional
PragmaTwice Nov 19, 2021
f46a1bd
maybe: add error traits
PragmaTwice Nov 23, 2021
a07112f
maybe: add JUST and Maybe
PragmaTwice Nov 23, 2021
620c681
maybe: remove useless comment
PragmaTwice Nov 23, 2021
61fc090
maybe: add more test
PragmaTwice Nov 24, 2021
ee0666f
maybe: customizable JUST
PragmaTwice Nov 24, 2021
0e90621
maybe: add Map and Bind (AndThen) to Maybe
PragmaTwice Nov 24, 2021
eac99c1
maybe: re-design JustConfig
PragmaTwice Nov 26, 2021
faf244d
maybe: rename xxxT to xxxS
PragmaTwice Nov 26, 2021
12699a5
maybe: fix method names
PragmaTwice Nov 26, 2021
2b2545e
Merge branch 'master' of github.com:oneflow-Inc/oneflow into maybe
PragmaTwice Nov 26, 2021
405e709
maybe: add maybe to cmake
PragmaTwice Nov 26, 2021
31476a7
maybe: fix error traits
PragmaTwice Nov 29, 2021
0b89912
maybe: rename fields & add aggregate type checking
PragmaTwice Nov 29, 2021
605633a
maybe: move string_view to new file
PragmaTwice Nov 29, 2021
af6eb1e
maybe: rename fields for optional and error
PragmaTwice Nov 29, 2021
f905b2b
maybe: new Value (no index checking, protected method) and Get (has c…
PragmaTwice Nov 29, 2021
74be59d
maybe: remove DefaultArgument
PragmaTwice Nov 29, 2021
477899f
maybe: fix non aggregate type construct in optional
PragmaTwice Dec 1, 2021
98e9918
maybe: fix method names for error
PragmaTwice Dec 7, 2021
40a38e6
maybe: fix internal macro
PragmaTwice Dec 7, 2021
a3e801e
just: rename JustConfig to JustTraits
PragmaTwice Dec 9, 2021
30150be
just: add expect_false
PragmaTwice Dec 9, 2021
bad7191
Merge branch 'master' into maybe
PragmaTwice Dec 9, 2021
9a116fb
maybe: use nodiscard
PragmaTwice Dec 11, 2021
044272c
Merge branch 'maybe' of github.com:PragmaTwice/oneflow into maybe
PragmaTwice Dec 11, 2021
7aa6a7f
maybe: add more nodiscard
PragmaTwice Dec 11, 2021
d846de0
maybe: rename JUST_OPT to OPT_JUST
PragmaTwice Dec 13, 2021
d5d1c73
error: add static_assert for StackedError
PragmaTwice Jan 26, 2022
a609951
Merge branch 'master' into maybe
PragmaTwice Jan 26, 2022
a89d78c
error: add assert for NoStackError
PragmaTwice Jan 26, 2022
d472efc
import string_view using FetchContent
PragmaTwice Jan 26, 2022
d9c480e
format cpp
PragmaTwice Jan 26, 2022
aabce86
Merge branch 'master' into maybe
PragmaTwice Jan 26, 2022
5497208
fix typo
PragmaTwice Jan 26, 2022
f3a76e2
optional: fix storage
PragmaTwice Jan 26, 2022
94373df
optional: fix static assert
PragmaTwice Jan 26, 2022
288f6f9
optional: more test
PragmaTwice Jan 26, 2022
2a95c92
format
PragmaTwice Jan 26, 2022
ca580b2
Merge branch 'master' into maybe
PragmaTwice Jan 26, 2022
fc42a18
Merge branch 'maybe' of github.com:PragmaTwice/oneflow into maybe
PragmaTwice Jan 26, 2022
5b64921
Merge branch 'master' into maybe
PragmaTwice Jan 26, 2022
f9fe09a
Merge branch 'master' into maybe
oneflow-ci-bot Jan 26, 2022
0638a07
Merge remote-tracking branch 'origin/master' into maybe
PragmaTwice Jan 26, 2022
808c4e6
Merge branch 'master' into maybe
oneflow-ci-bot Jan 26, 2022
e359b7d
upgrade clang-tidy in ci
daquexian Jan 27, 2022
ff7fc40
Merge branch 'maybe' of github.com:PragmaTwice/oneflow into maybe
PragmaTwice Jan 27, 2022
01626bd
Merge remote-tracking branch 'origin/upgrade_clang_tidy' into maybe
PragmaTwice Jan 27, 2022
984c3f0
fix optional<scalar> init & fix unit test in clang build
PragmaTwice Jan 27, 2022
1c80328
Merge branch 'master' into maybe
PragmaTwice Jan 27, 2022
496bf4a
fix test
PragmaTwice Jan 27, 2022
a097165
Merge branch 'master' into maybe
PragmaTwice Jan 27, 2022
cd1313c
Merge branch 'maybe' of github.com:PragmaTwice/oneflow into maybe
PragmaTwice Jan 27, 2022
5dfa010
format
PragmaTwice Jan 28, 2022
b529569
fix test
PragmaTwice Jan 28, 2022
9784cdb
Merge branch 'master' into maybe
PragmaTwice Jan 28, 2022
1d4a0d5
fix test
PragmaTwice Jan 28, 2022
bfa68a8
Merge branch 'maybe' of github.com:PragmaTwice/oneflow into maybe
PragmaTwice Jan 28, 2022
58fb904
format
PragmaTwice Jan 28, 2022
034638e
Merge branch 'master' into maybe
oneflow-ci-bot Jan 28, 2022
4d45ae0
Merge branch 'master' into maybe
oneflow-ci-bot Jan 28, 2022
3ec6159
Merge branch 'master' into maybe
oneflow-ci-bot Jan 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cmake/oneflow.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@ foreach(oneflow_hdr_to_be_expanded ${oneflow_all_hdr_to_be_expanded})
set_source_files_properties(${oneflow_all_hdr_expanded} PROPERTIES GENERATED TRUE)
endforeach()

file(GLOB_RECURSE oneflow_all_src "${PROJECT_SOURCE_DIR}/oneflow/core/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/user/*.*" "${PROJECT_SOURCE_DIR}/oneflow/api/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/extension/python/*.*")
file(
GLOB_RECURSE
oneflow_all_src
"${PROJECT_SOURCE_DIR}/oneflow/core/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/user/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/api/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/maybe/*.*"
"${PROJECT_SOURCE_DIR}/oneflow/extension/python/*.*")
if(WITH_XLA OR WITH_TENSORRT OR WITH_OPENVINO)
file(GLOB_RECURSE oneflow_xrt_src "${PROJECT_SOURCE_DIR}/oneflow/xrt/*.*")
if(NOT WITH_XLA)
Expand Down
4 changes: 3 additions & 1 deletion cmake/third_party.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ if(RPC_BACKEND MATCHES "GRPC")
endif()
include(flatbuffers)
include(lz4)
include(string_view)

if(WITH_XLA)
include(tensorflow)
Expand Down Expand Up @@ -145,7 +146,8 @@ set(oneflow_third_party_libs
${CMAKE_THREAD_LIBS_INIT}
${FLATBUFFERS_STATIC_LIBRARIES}
${LZ4_STATIC_LIBRARIES}
nlohmann_json::nlohmann_json)
nlohmann_json::nlohmann_json
string-view-lite)
if(WITH_ONEDNN)
set(oneflow_third_party_libs ${oneflow_third_party_libs} ${ONEDNN_STATIC_LIBRARIES})
endif()
Expand Down
9 changes: 9 additions & 0 deletions cmake/third_party/string_view.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include(FetchContent)

set_mirror_url_with_hash(
string_view_URL "https://github.com/martinmoene/string-view-lite/archive/refs/tags/v1.6.0.tar.gz"
2bdbfa2def2d460e3f78ee9846ece943)

FetchContent_Declare(string_view URL ${string_view_URL} URL_HASH MD5=${string_view_URL_HASH})

FetchContent_MakeAvailable(string_view)
20 changes: 17 additions & 3 deletions oneflow/maybe/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,30 @@ limitations under the License.
#if !__is_identifier(__is_aggregate)
#define OF_MAYBE_HAS_IS_AGGREGATE
#endif
#elif __has_builtin(__is_aggregate)
#else
#if __has_builtin(__is_aggregate)
#define OF_MAYBE_HAS_IS_AGGREGATE
#endif
#endif

#ifdef OF_MAYBE_HAS_IS_AGGREGATE
#define OF_MAYBE_IS_AGGREGATE(...) __is_aggregate(__VA_ARGS__)
#define OF_MAYBE_IS_AGGREGATE(...) (__is_aggregate(__VA_ARGS__))
#else
// decay to POD checking if no such builtin (because implementing __is_aggregate need reflection)
#define OF_MAYBE_IS_AGGREGATE(...) \
std::is_standard_layout<__VA_ARGS__>::value&& std::is_trivial<__VA_ARGS__>::value
(std::is_standard_layout<__VA_ARGS__>::value && std::is_trivial<__VA_ARGS__>::value)
#endif

// `__builtin_expect` exists at least since GCC 4 / Clang 3
#define OF_MAYBE_EXPECT_FALSE(x) (__builtin_expect((x), 0))

#if __has_cpp_attribute(nodiscard)
#define OF_MAYBE_NODISCARD_FUNC [[nodiscard]]
#define OF_MAYBE_NODISCARD_TYPE [[nodiscard]]
#elif __has_attribute(warn_unused_result)
#define OF_MAYBE_NODISCARD_FUNC \
__attribute__((warn_unused_result)) // or [[gnu::warn_unused_result]]
#define OF_MAYBE_NODISCARD_TYPE
#endif

#endif // ONEFLOW_MAYBE_CONFIG_H_
283 changes: 283 additions & 0 deletions oneflow/maybe/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
/*
Copyright 2020 The OneFlow Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#ifndef ONEFLOW_MAYBE_ERROR_H_
#define ONEFLOW_MAYBE_ERROR_H_

#include <cstddef>
#include <cstdlib>
#include <memory>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <iostream>

#include "utility.h"
#include "type_traits.h"
#include "string_view.h"

namespace oneflow {

namespace maybe {

namespace details {

template<typename D>
struct ErrorStackFromContainerBase {
lixinqi marked this conversation as resolved.
Show resolved Hide resolved
private:
using Derived = D;

auto& Stack() { return static_cast<Derived*>(this)->GetStack(); }

const auto& Stack() const { return static_cast<const Derived*>(this)->GetStack(); }

public:
std::size_t StackSize() const { return Stack().size(); }

template<typename... Args>
void PushStack(Args&&... args) {
auto& s = Stack();
s.emplace(s.end(), std::forward<Args>(args)...);
}

template<typename T = Derived>
const typename T::StackType::value_type& StackElem(std::size_t index) const {
return Stack()[index];
}

auto StackBegin() const { return Stack().begin(); }
auto StackEnd() const { return Stack().end(); }
};

} // namespace details

template<typename T>
struct StackedErrorTraits {
StackedErrorTraits() = delete;

using ErrorType = typename T::ErrorType;
using StackEntryType = typename T::StackEntryType;

template<
typename U,
std::enable_if_t<
std::is_same<T, RemoveCVRef<U>>::value
&& std::is_same<ErrorType, RemoveCVRef<decltype(std::declval<U>().Error())>>::value,
int> = 0>
static decltype(auto) Error(U&& se) {
return se.Error();
}

static std::size_t StackSize(const T& se) { return se.StackSize(); }

static ConstRefExceptVoid<StackEntryType> StackElem(const T& se, std::size_t index) {
return se.StackElem(index);
}

template<typename U, typename... Args,
std::enable_if_t<std::is_same<T, RemoveCVRef<U>>::value, int> = 0>
static void PushStack(U&& se, Args&&... args) {
se.PushStack(std::forward<Args>(args)...);
}

template<typename U, std::enable_if_t<std::is_same<T, RemoveCVRef<U>>::value, int> = 0>
static std::string Dump(U&& se) {
return se.Dump();
}

template<typename U, std::enable_if_t<std::is_same<T, RemoveCVRef<U>>::value, int> = 0>
[[noreturn]] static void Abort(U&& se) {
se.Abort();
}
};

template<typename T>
struct StackedErrorTraits<std::unique_ptr<T>> {
StackedErrorTraits() = delete;

using PointedTraits = StackedErrorTraits<T>;

using ValueType = std::unique_ptr<T>;

using ErrorType = typename PointedTraits::ErrorType;
using StackEntryType = typename PointedTraits::StackEntryType;

template<typename U, std::enable_if_t<std::is_same<ValueType, RemoveCVRef<U>>::value, int> = 0>
static decltype(auto) Error(U&& se) {
return PointedTraits::Error(*se);
}

static std::size_t StackSize(const ValueType& se) { return PointedTraits::StackSize(*se); }

static ConstRefExceptVoid<StackEntryType> StackElem(const T& se, std::size_t index) {
return PointedTraits::StackElem(*se, index);
}

template<typename U, typename... Args,
std::enable_if_t<std::is_same<ValueType, RemoveCVRef<U>>::value, int> = 0>
static void PushStack(U&& se, Args&&... args) {
PointedTraits::PushStack(*se, std::forward<Args>(args)...);
}

template<typename U, std::enable_if_t<std::is_same<ValueType, RemoveCVRef<U>>::value, int> = 0>
static std::string Dump(U&& se) {
return PointedTraits::Dump(*se);
}

template<typename U, std::enable_if_t<std::is_same<ValueType, RemoveCVRef<U>>::value, int> = 0>
[[noreturn]] static void Abort(U&& se) {
PointedTraits::Abort(*se);
}
};

// simple implementation for some customization points
namespace simple {

template<typename T>
struct MessageFormatTrait;

template<>
struct MessageFormatTrait<std::string> {
template<typename Code, typename... Args>
static std::string Format(Code&& code, Args&&... args) {
if (sizeof...(args) > 0) {
std::stringstream res;

res << code << ": ";
[[maybe_unused]] int dummy[] = {(res << args, 0)...};

return res.str();
} else {
return code;
}
}
};

template<>
struct MessageFormatTrait<StringView> {
template<typename Code>
static StringView Format(Code&& code) {
return code;
}
};

template<typename Message, typename MessageFormatTraits = MessageFormatTrait<Message>>
struct ErrorStackEntry {
StringView filename;
std::size_t lineno;
StringView function;
Message message;

template<typename... Args>
ErrorStackEntry(StringView filename, std::size_t lineno, StringView function, Args&&... args)
: filename(filename),
lineno(lineno),
function(function),
message(MessageFormatTraits::Format(std::forward<Args>(args)...)) {}
};

template<typename E, typename M = std::string>
PragmaTwice marked this conversation as resolved.
Show resolved Hide resolved
struct StackedError : details::ErrorStackFromContainerBase<StackedError<E, M>> {
public:
using ErrorType = E;
using StackMessage = M;
using StackEntryType = ErrorStackEntry<StackMessage>;
using StackType = std::vector<StackEntryType>;
using BaseType = details::ErrorStackFromContainerBase<StackedError<E, M>>;

static_assert(!std::is_reference<E>::value, "the underlying value type cannot be reference");

StackedError(ErrorType error) // NOLINT(google-explicit-constructor)
: error_(std::move(error)) {}

ErrorType& Error() { return error_; }
const ErrorType& Error() const { return error_; }

std::string Dump() {
std::stringstream res;
res << "error occurred: " << error_ << std::endl;
for (const auto& elem : stack_) {
res << "from " << elem.function << " in " << elem.filename << ":" << elem.lineno << ": "
<< elem.message << std::endl;
}

return res.str();
}

[[noreturn]] void Abort() {
lixinqi marked this conversation as resolved.
Show resolved Hide resolved
std::cerr << "error occurred: " << error_ << std::endl;
for (const auto& elem : stack_) {
std::cerr << "from " << elem.function << " in " << elem.filename << ":" << elem.lineno << ": "
<< elem.message << std::endl;
}
std::abort();
}

private:
ErrorType error_;
StackType stack_;

StackType& GetStack() { return stack_; }

const StackType& GetStack() const { return stack_; }

friend BaseType;
};

template<typename E>
struct NoStackError {
using ErrorType = E;
using StackEntryType = void;

static_assert(!std::is_reference<E>::value, "the underlying value type cannot be reference");

NoStackError(ErrorType error) // NOLINT(google-explicit-constructor)
: error_(std::move(error)) {}

ErrorType& Error() { return error_; }
const ErrorType& Error() const { return error_; }

std::size_t StackSize() const { return 0; }

void StackElem(std::size_t) const {}

template<typename... Args>
void PushStack(Args&&... args) {}

std::string Dump() {
std::stringstream res;
res << error_ << std::endl;

return res.str();
}

[[noreturn]] void Abort() {
std::cerr << error_ << std::endl;
std::abort();
}

private:
ErrorType error_;
};

} // namespace simple

} // namespace maybe

} // namespace oneflow

#endif // ONEFLOW_MAYBE_ERROR_H_
Loading