Commit 546b4279 authored by limm's avatar limm
Browse files

add csrc and mmdeploy module

parent 502f4fb9
Pipeline #2810 canceled with stages
// Copyright (c) OpenMMLab. All rights reserved.
// Modified from
// https://github.com/brycelelbach/wg21_p2300_std_execution/blob/main/include/execution.hpp
#ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ENSURE_STARTED_H_
#define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ENSURE_STARTED_H_
#include "concepts.h"
#include "utility.h"
namespace mmdeploy {
namespace __ensure_started {
struct _OperationBase {
void (*notify_)(_OperationBase*);
};
template <typename SharedState>
struct _Receiver {
struct type;
};
template <typename SharedState>
using receiver_t = typename _Receiver<SharedState>::type;
template <typename SharedState>
struct _Receiver<SharedState>::type {
std::shared_ptr<SharedState> shared_state_;
template <typename... As>
friend void tag_invoke(set_value_t, type&& self, As&&... as) noexcept {
assert(self.shared_state_);
self.shared_state_->data_.emplace((As &&) as...);
self.shared_state_->_Notify();
self.shared_state_.reset();
}
};
template <typename Sender>
struct _SharedState {
std::optional<completion_signatures_of_t<Sender>> data_;
// std::optional<connect_result_t<Sender, receiver_t<_SharedState>>> op_state2_;
std::optional<__conv_proxy<connect_result_t<Sender, receiver_t<_SharedState>>>> op_state2_proxy_;
std::atomic<void*> awaiting_{nullptr};
void _Notify() noexcept {
void* const completion_state = static_cast<void*>(this);
void* old = awaiting_.exchange(completion_state, std::memory_order_acq_rel);
auto* op_state = static_cast<_OperationBase*>(old);
if (op_state != nullptr) {
op_state->notify_(op_state);
}
}
};
template <typename Sender, typename Receiver>
struct _Operation {
struct type;
};
template <typename Sender, typename Receiver>
using Operation = typename _Operation<Sender, remove_cvref_t<Receiver>>::type;
template <typename Sender, typename Receiver>
struct _Operation<Sender, Receiver>::type : public _OperationBase {
Receiver receiver_;
std::shared_ptr<_SharedState<Sender>> shared_state_;
type(Receiver&& receiver, std::shared_ptr<_SharedState<Sender>> shared_state)
: _OperationBase{_Notify},
receiver_(std::move(receiver)),
shared_state_(std::move(shared_state)) {}
static void _Notify(_OperationBase* self) noexcept {
auto op_state = static_cast<type*>(self);
std::apply(
[&](auto&&... vals) -> void {
SetValue(std::move(op_state->receiver_), (decltype(vals)&&)vals...);
},
*op_state->shared_state_->data_);
}
friend void tag_invoke(start_t, type& self) {
auto shared_state = self.shared_state_.get();
std::atomic<void*>& awaiting = shared_state->awaiting_;
void* const completion_state = static_cast<void*>(shared_state);
void* old = awaiting.load(std::memory_order_acquire);
// TODO: cancel the loop by replacing `compare_exchange_weak` with `compare_exchange_strong`
do {
if (old == completion_state) {
_Notify(&self);
return;
}
} while (awaiting.compare_exchange_weak(old, static_cast<void*>(&self),
std::memory_order_release, std::memory_order_acquire));
}
};
template <typename Sender>
struct _Sender {
struct type;
};
template <typename Sender>
using sender_t = typename _Sender<remove_cvref_t<Sender>>::type;
template <typename Sender>
struct _Sender<Sender>::type {
using value_types = completion_signatures_of_t<Sender>;
using SharedState = _SharedState<Sender>;
std::shared_ptr<SharedState> shared_state_;
template <typename Sndr, std::enable_if_t<!std::is_same_v<remove_cvref_t<Sndr>, type>, int> = 0>
explicit type(Sndr&& sender) : shared_state_(std::make_shared<SharedState>()) {
shared_state_->op_state2_proxy_.emplace(
[&] { return Connect((Sndr &&) sender, receiver_t<SharedState>{shared_state_}); });
Start(**shared_state_->op_state2_proxy_);
// Start(shared_state_->op_state2_.emplace(
// __conv{[&] { return Connect((Sndr &&) sender, receiver_t<SharedState>{shared_state_});
// }}));
}
template <typename Self, typename Receiver, _decays_to<Self, type, int> = 0>
friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver)
-> Operation<Sender, Receiver> {
return {(Receiver &&) receiver, std::move(self.shared_state_)};
}
};
struct ensure_started_t {
template <typename Sender,
std::enable_if_t<_is_sender<Sender> &&
_tag_invocable_with_completion_scheduler<ensure_started_t, Sender>,
int> = 0>
auto operator()(Sender&& sender) const {
auto scheduler = GetCompletionScheduler(sender);
return tag_invoke(ensure_started_t{}, std::move(scheduler), (Sender &&) sender);
}
template <
typename Sender,
std::enable_if_t<_is_sender<Sender> &&
!_tag_invocable_with_completion_scheduler<ensure_started_t, Sender> &&
tag_invocable<ensure_started_t, Sender>,
int> = 0>
auto operator()(Sender&& sender) const {
return tag_invoke(ensure_started_t{}, (Sender &&) sender);
}
template <
typename Sender,
std::enable_if_t<_is_sender<Sender> &&
!_tag_invocable_with_completion_scheduler<ensure_started_t, Sender> &&
!tag_invocable<ensure_started_t, Sender>,
int> = 0>
sender_t<Sender> operator()(Sender&& sender) const {
return sender_t<Sender>{(Sender &&) sender};
}
};
} // namespace __ensure_started
using __ensure_started::ensure_started_t;
inline constexpr ensure_started_t EnsureStarted{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ENSURE_STARTED_H_
// Copyright (c) OpenMMLab. All rights reserved.
// Modified from
// https://github.com/brycelelbach/wg21_p2300_std_execution/blob/main/include/execution.hpp
#ifndef MMDEPLOY_CSRC_EXECUTION_EXECUTE_H_
#define MMDEPLOY_CSRC_EXECUTION_EXECUTE_H_
#include "mmdeploy/execution/start_detached.h"
#include "mmdeploy/execution/then.h"
#include "mmdeploy/execution/utility.h"
namespace mmdeploy {
namespace _execute {
struct execute_t {
template <typename Scheduler, typename Func,
std::enable_if_t<tag_invocable<execute_t, Scheduler, Func>, int> = 0>
void operator()(Scheduler&& scheduler, Func func) const {
return tag_invoke(*this, (Scheduler &&) scheduler, std::move(func));
}
template <typename Scheduler, typename Func,
std::enable_if_t<!tag_invocable<execute_t, Scheduler, Func>, int> = 0>
void operator()(Scheduler&& scheduler, Func func) const {
return StartDetached(Then(Schedule((Scheduler &&) scheduler), std::move(func)));
}
};
} // namespace _execute
using _execute::execute_t;
inline constexpr execute_t Execute{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXECUTION_EXECUTE_H_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_H_
#define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_H_
#include <atomic>
#include <cassert>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <optional>
#include <thread>
#include <variant>
#include "bulk.h"
#include "dynamic_batch.h"
#include "ensure_started.h"
#include "execute.h"
#include "just.h"
#include "let_value.h"
#include "on.h"
#include "run_loop.h"
#include "split.h"
#include "start_detached.h"
#include "submit.h"
#include "sync_wait.h"
#include "then.h"
#include "transfer.h"
#include "transfer_just.h"
#include "utility.h"
#include "when_all.h"
#endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_H_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_EXECUTION_EXPAND_H_
#define MMDEPLOY_CSRC_EXECUTION_EXPAND_H_
#include "closure.h"
#include "concepts.h"
#include "utility.h"
namespace mmdeploy {
namespace _expand {
template <typename Sender, typename Receiver>
struct _Receiver {
struct type {
Receiver receiver_;
template <class Tuple>
friend void tag_invoke(set_value_t, type&& self, Tuple&& tup) noexcept {
std::apply(
[&](auto&&... args) {
SetValue((Receiver &&) self.receiver_, (decltype(args)&&)args...);
},
(Tuple &&) tup);
}
};
};
template <typename Sender, typename Receiver>
using receiver_t = typename _Receiver<Sender, remove_cvref_t<Receiver>>::type;
template <typename Sender>
struct _Sender {
struct type {
using value_types = std::tuple_element_t<0, completion_signatures_of_t<Sender>>;
Sender sender_;
template <typename Self, typename Receiver, _decays_to<Self, type, bool> = true>
friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver) {
return Connect(((Self &&) self).sender_,
receiver_t<Sender, Receiver>{(Receiver &&) receiver});
}
};
};
template <typename Sender>
using sender_t = typename _Sender<remove_cvref_t<Sender>>::type;
struct expand_t {
template <typename Sender, std::enable_if_t<_is_sender<Sender>, int> = 0>
auto operator()(Sender&& sender) const {
return sender_t<Sender>{(Sender &&) sender};
}
_BinderBack<expand_t> operator()() const { return {{}, {}, {}}; }
};
} // namespace _expand
using _expand::expand_t;
inline constexpr expand_t Expand{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXECUTION_EXPAND_H_
// Copyright (c) OpenMMLab. All rights reserved.
// Modified from
// https://github.com/brycelelbach/wg21_p2300_std_execution/blob/main/include/execution.hpp
#ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_JUST_H_
#define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_JUST_H_
#include <tuple>
#include "concepts.h"
#include "utility.h"
namespace mmdeploy {
namespace __just {
template <typename Receiver, typename... Ts>
struct _Operation {
struct type;
};
template <typename Receiver, typename... Ts>
using operation_t = typename _Operation<remove_cvref_t<Receiver>, Ts...>::type;
template <typename Receiver, typename... Ts>
struct _Operation<Receiver, Ts...>::type {
std::tuple<Ts...> values_;
Receiver receiver_;
friend void tag_invoke(start_t, type& op_state) noexcept {
std::apply(
[&](Ts&... ts) -> void { SetValue(std::move(op_state.receiver_), std::move(ts)...); },
op_state.values_);
}
};
template <typename... Ts>
struct _Sender {
struct type;
};
template <typename... Ts>
using sender_t = typename _Sender<std::decay_t<Ts>...>::type;
template <typename... Ts>
struct _Sender<Ts...>::type {
using value_types = std::tuple<Ts...>;
value_types values_;
template <typename Receiver>
friend operation_t<Receiver, Ts...> tag_invoke(connect_t, const type& self, Receiver&& receiver) {
return {self.values_, (Receiver &&) receiver};
}
template <typename Receiver>
friend operation_t<Receiver, Ts...> tag_invoke(connect_t, type&& self, Receiver&& receiver) {
return {std::move(self).values_, (Receiver &&) receiver};
}
};
struct just_t {
template <typename... Ts>
sender_t<Ts...> operator()(Ts&&... ts) const {
return {{(Ts &&) ts...}};
}
};
} // namespace __just
using __just::just_t;
inline constexpr just_t Just{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_JUST_H_
// Copyright (c) OpenMMLab. All rights reserved.
#ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_LET_VALUE_H_
#define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_LET_VALUE_H_
#include <optional>
#include "utility.h"
namespace mmdeploy {
namespace __let_value {
template <typename T>
using __decay_ref = std::decay_t<T>&;
template <typename Func, typename... As>
using __result_sender_t = __call_result_t<Func, __decay_ref<As>...>;
template <typename Func, typename Tuple>
struct __value_type {};
template <typename Func, typename... As>
struct __value_type<Func, std::tuple<As...>> {
using type = __result_sender_t<Func, As...>;
};
template <typename Func, typename Tuple>
using __value_type_t = typename __value_type<Func, Tuple>::type;
template <typename CvrefSender, typename Receiver, typename Fun>
struct _Storage {
using Sender = remove_cvref_t<CvrefSender>;
using operation_t =
connect_result_t<__value_type_t<Fun, completion_signatures_of_t<Sender>>, Receiver>;
std::optional<completion_signatures_of_t<Sender>> args_;
// workaround for MSVC v142 toolset, copy elision does not work here
std::optional<__conv_proxy<operation_t>> proxy_;
};
template <typename CvrefSender, typename Receiver, typename Func>
struct _Operation {
struct type;
};
template <typename CvrefSender, typename Receiver, typename Func>
using operation_t = typename _Operation<CvrefSender, remove_cvref_t<Receiver>, Func>::type;
template <typename CvrefSender, typename Receiver, typename Func>
struct _Receiver {
struct type;
};
template <typename CvrefSender, typename Receiver, typename Func>
using receiver_t = typename _Receiver<CvrefSender, Receiver, Func>::type;
template <typename CvrefSender, typename Receiver, typename Func>
struct _Receiver<CvrefSender, Receiver, Func>::type {
operation_t<CvrefSender, Receiver, Func>* op_state_;
template <typename... As>
friend void tag_invoke(set_value_t, type&& self, As&&... as) noexcept {
auto* op_state = self.op_state_;
auto& args = op_state->storage_.args_.emplace((As &&) as...);
op_state->storage_.proxy_.emplace([&] {
return Connect(std::apply(std::move(op_state->func_), args), std::move(op_state->receiver_));
});
Start(**op_state->storage_.proxy_);
}
};
template <typename CvrefSender, typename Receiver, typename Func>
struct _Operation<CvrefSender, Receiver, Func>::type {
using _receiver_t = receiver_t<CvrefSender, Receiver, Func>;
friend void tag_invoke(start_t, type& self) noexcept { Start(self.op_state2_); }
template <typename Receiver2>
type(CvrefSender&& sender, Receiver2&& receiver, Func func)
: op_state2_(Connect((CvrefSender &&) sender, _receiver_t{this})),
receiver_((Receiver2 &&) receiver),
func_(std::move(func)) {}
connect_result_t<CvrefSender, _receiver_t> op_state2_;
Receiver receiver_;
Func func_;
_Storage<CvrefSender, Receiver, Func> storage_;
};
template <typename Sender, typename Func>
struct _Sender {
struct type;
};
template <typename Sender, typename Func>
using sender_t = typename _Sender<remove_cvref_t<Sender>, Func>::type;
template <typename Sender, typename Func>
struct _Sender<Sender, Func>::type {
template <typename Self, typename Receiver>
using _operation_t = operation_t<_copy_cvref_t<Self, Sender>, Receiver, Func>;
using value_types =
completion_signatures_of_t<__value_type_t<Func, completion_signatures_of_t<Sender>>>;
template <typename Self, typename Receiver, _decays_to<Self, type, int> = 0>
friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver)
-> _operation_t<Self, Receiver> {
return _operation_t<Self, Receiver>{((Self &&) self).sender_, (Receiver &&) receiver,
((Self &&) self).func_};
}
Sender sender_;
Func func_;
};
using std::enable_if_t;
struct let_value_t {
template <typename Sender, typename Func,
enable_if_t<_is_sender<Sender> &&
_tag_invocable_with_completion_scheduler<let_value_t, Sender, Func>,
int> = 0>
auto operator()(Sender&& sender, Func func) const {
auto scheduler = GetCompletionScheduler(sender);
return tag_invoke(let_value_t{}, std::move(scheduler), (Sender &&) sender, std::move(func));
}
template <typename Sender, typename Func,
enable_if_t<_is_sender<Sender> &&
_tag_invocable_with_completion_scheduler<let_value_t, Sender, Func> &&
tag_invocable<let_value_t, Sender, Func>,
int> = 0>
auto operator()(Sender&& sender, Func func) const {
return tag_invoke(let_value_t{}, (Sender &&) sender, std::move(func));
}
template <typename Sender, typename Func,
enable_if_t<_is_sender<Sender> &&
!_tag_invocable_with_completion_scheduler<let_value_t, Sender, Func> &&
!tag_invocable<let_value_t, Sender>,
int> = 0>
sender_t<Sender, Func> operator()(Sender&& sender, Func func) const {
return {(Sender &&) sender, std::move(func)};
}
template <typename Func>
_BinderBack<let_value_t, Func> operator()(Func func) const {
return {{}, {}, {std::move(func)}};
}
};
} // namespace __let_value
using __let_value::let_value_t;
inline constexpr let_value_t LetValue{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_LET_VALUE_H_
// Copyright (c) OpenMMLab. All rights reserved.
// Modified from
// https://github.com/brycelelbach/wg21_p2300_std_execution/blob/main/include/execution.hpp
#ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ON_H_
#define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ON_H_
#include <variant>
#include "utility.h"
namespace mmdeploy {
namespace __on {
template <typename Scheduler, typename Sender, typename Receiver>
struct _Operation {
struct type;
};
template <typename Scheduler, typename Sender, typename Receiver>
using operation_t = typename _Operation<Scheduler, Sender, Receiver>::type;
template <typename Scheduler, typename Sender, typename Receiver>
struct _ReceiverRef {
struct type;
};
template <typename Scheduler, typename Sender, typename Receiver>
using receiver_ref_t = typename _ReceiverRef<Scheduler, Sender, Receiver>::type;
template <typename Scheduler, typename Sender, typename Receiver>
struct _ReceiverRef<Scheduler, Sender, Receiver>::type {
operation_t<Scheduler, Sender, Receiver>* op_state_;
template <typename... Args>
friend void tag_invoke(set_value_t, type&& self, Args&&... args) noexcept {
SetValue((Receiver &&) self.op_state_->receiver_, ((Args &&) args)...);
}
};
template <typename Scheduler, typename Sender, typename Receiver>
struct _Receiver {
struct type;
};
template <typename Scheduler, typename Sender, typename Receiver>
using receiver_t = typename _Receiver<Scheduler, Sender, Receiver>::type;
template <typename Scheduler, typename Sender, typename Receiver>
struct _Receiver<Scheduler, Sender, Receiver>::type {
operation_t<Scheduler, Sender, Receiver>* op_state_;
using _receiver_ref_t = receiver_ref_t<Scheduler, Sender, Receiver>;
friend void tag_invoke(set_value_t, type&& self) noexcept {
auto op_state = self.op_state_;
Start(op_state->data_.template emplace<1>(
Connect((Sender &&) op_state->sender_, _receiver_ref_t{op_state})));
}
};
template <typename Scheduler, typename Sender, typename Receiver>
struct _Operation<Scheduler, Sender, Receiver>::type {
using _receiver_t = receiver_t<Scheduler, Sender, Receiver>;
using _receiver_ref_t = receiver_ref_t<Scheduler, Sender, Receiver>;
template <class Sender2, class Receiver2>
type(Scheduler scheduler, Sender2&& sender, Receiver2&& receiver)
: data_(std::in_place_index<0>, Connect(Schedule(scheduler), _receiver_t{this})),
scheduler_(scheduler),
sender_((Sender2 &&) sender),
receiver_((Receiver2 &&) receiver) {}
friend void tag_invoke(start_t, type& self) { Start(std::get<0>(self.data_)); }
std::variant<connect_result_t<schedule_result_t<Scheduler>, _receiver_t>,
connect_result_t<Sender, _receiver_ref_t>>
data_;
Scheduler scheduler_;
Sender sender_;
Receiver receiver_;
};
template <typename Scheduler, typename Sender>
struct _Sender {
struct type;
};
template <typename Scheduler, typename Sender>
using sender_t = typename _Sender<remove_cvref_t<Scheduler>, remove_cvref_t<Sender>>::type;
template <typename Scheduler, typename Sender>
struct _Sender<Scheduler, Sender>::type {
using value_types = completion_signatures_of_t<Sender>;
Scheduler scheduler_;
Sender sender_;
template <typename Receiver>
using _operation_t = operation_t<Scheduler, Sender, remove_cvref_t<Receiver>>;
template <typename Self, typename Receiver, _decays_to<Self, type, int> = 0>
friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver) -> _operation_t<Receiver> {
return {((Self &&) self).scheduler_, ((Self &&) self).sender_, (Receiver &&) receiver};
}
};
struct on_t {
template <typename Scheduler, typename Sender,
std::enable_if_t<_is_sender<Sender> && tag_invocable<on_t, Scheduler, Sender>, int> = 0>
auto operator()(Scheduler&& scheduler, Sender&& sender) const
-> tag_invoke_result_t<on_t, Scheduler, Sender> {
return tag_invoke(on_t{}, (Scheduler &&) scheduler, (Sender &&) sender);
}
template <
typename Scheduler, typename Sender,
std::enable_if_t<_is_sender<Sender> && !tag_invocable<on_t, Scheduler, Sender>, int> = 0>
sender_t<Scheduler, Sender> operator()(Scheduler&& scheduler, Sender&& sender) const {
return {(Scheduler &&) scheduler, (Sender &&) sender};
}
};
} // namespace __on
using __on::on_t;
inline constexpr on_t On{};
} // namespace mmdeploy
#endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ON_H_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment