Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 20 additions & 14 deletions include/cilk/reducer
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,36 @@
#include <cstddef>
#include <functional>

typedef std::function<void(void *)> __cilk_identity_fn;
typedef std::function<void(void *, void *)> __cilk_reduce_fn;
namespace cilk {

struct __reducer_base {
__reducer_base();
virtual ~__reducer_base();
typedef std::function<void(void *)> identity_fn;
typedef std::function<void(void *, void *)> reduce_fn;

struct reducer_base {
protected:
reducer_base();
public:
virtual ~reducer_base();
// All of the following methods may be called concurrently.
virtual std::size_t size() const = 0;
// Return the __reducer_base subobject of a newly constructed object.
virtual __reducer_base *identity(void *view) = 0;
virtual std::size_t view_size() const = 0;
// Return the reducer_base subobject of a newly constructed object.
virtual reducer_base *identity(void *view) = 0;
// Merge r into l. The destructor for r will be called after reduce.
virtual void reduce(__reducer_base *l, __reducer_base *r) = 0;
virtual void reduce(reducer_base *l, reducer_base *r) = 0;
};

struct __reducer_callbacks {
struct reducer_callbacks {
std::size_t size;
__cilk_identity_fn identity;
__cilk_reduce_fn reduce;
identity_fn identity;
reduce_fn reduce;
};

extern "C" __reducer_base *__hyper_lookup_class(const __reducer_base *)
}

extern "C" cilk::reducer_base *__hyper_lookup_class(const cilk::reducer_base *)
__attribute__((nonnull, returns_nonnull));

extern "C" void *__hyper_lookup_internal_1(void *, const __reducer_callbacks &)
extern "C" void *__hyper_lookup_internal_1(void *, const cilk::reducer_callbacks &)
__attribute__((nonnull, returns_nonnull));

#endif // _CILK_REDUCER_
20 changes: 14 additions & 6 deletions runtime/cilk-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
#endif
#endif

namespace cilk {
struct reducer_base;
struct reducer_callbacks;
}

using cilk::reducer_base;
using cilk::reducer_callbacks;

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -70,8 +78,8 @@ get_worker_from_stack(const __cilkrts_stack_frame *sf) {
}

CHEETAH_INTERNAL
__reducer_base *
internal_reducer_lookup(__cilkrts_worker *w, __reducer_base *key);
reducer_base *
internal_reducer_lookup(__cilkrts_worker *w, reducer_base *key);
CHEETAH_INTERNAL
void internal_reducer_remove(__cilkrts_worker *w, void *key);

Expand Down Expand Up @@ -99,7 +107,7 @@ __cilkrts_pop_ext_stack(__cilkrts_worker *w, size_t size) {
/*
* All the data needed to properly handle a thrown exception.
*/
struct closure_exception final : public __reducer_base {
struct closure_exception final : public reducer_base {
char *exn = nullptr;
/* Canonical frame address (CFA) of the call-stack frame from which an
exception was rethrown. Used to ensure that the rethrown exception
Expand All @@ -113,9 +121,9 @@ struct closure_exception final : public __reducer_base {
currently running. */
cilk_fiber *throwing_fiber = nullptr;

virtual __reducer_base *identity(void *) override;
virtual void reduce(__reducer_base *, __reducer_base *) override;
virtual std::size_t size() const override { return sizeof *this; }
virtual reducer_base *identity(void *) override;
virtual void reduce(reducer_base *, reducer_base *) override;
virtual std::size_t view_size() const override { return sizeof *this; }
};

// Reducer structure for handling exceptions thrown in parallel.
Expand Down
8 changes: 5 additions & 3 deletions runtime/cilk2c_inlined.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <atomic>
#include <unwind.h>

using cilk::reducer_base;
using cilk::reducer_callbacks;

// Suppress -Wmissing-variable-declarations for this variable.
alignas(__cilkrts_stack_frame) extern size_t __cilkrts_stack_frame_align;
Expand All @@ -48,7 +50,7 @@ unsigned __cilkrts_get_worker_number(void) {
return 0;
}

__reducer_base *__cilkrts_reducer_lookup_0(__reducer_base *key) {
reducer_base *__cilkrts_reducer_lookup_0(reducer_base *key) {
// If we're outside a cilkified region, then the key is the view.
if (__cilkrts_status.need_to_cilkify)
return key;
Expand All @@ -57,14 +59,14 @@ __reducer_base *__cilkrts_reducer_lookup_0(__reducer_base *key) {
if (__builtin_expect(!!b, true)) {
// Return the reducer_base subobject of the existing view.
// get_if is used instead of get because no exceptions are allowed
return *std::get_if<__reducer_base *>(&b->data.extra);
return *std::get_if<reducer_base *>(&b->data.extra);
}

return __cilkrts_insert_new_view_0(table, key);
}

void *__cilkrts_reducer_lookup_1(void *key,
const __reducer_callbacks &callbacks) {
const reducer_callbacks &callbacks) {
// If we're outside a cilkified region, then the key is the view.
if (__cilkrts_status.need_to_cilkify)
return key;
Expand Down
17 changes: 11 additions & 6 deletions runtime/cilk2c_inlined.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@

struct __cilkrts_stack_frame;
struct __cilkrts_worker;
struct __reducer_base;
struct __reducer_callbacks;
namespace cilk {
struct reducer_base;
struct reducer_callbacks;
}

using cilk::reducer_base;
using cilk::reducer_callbacks;

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -83,18 +88,18 @@ void __cilk_sync(__cilkrts_stack_frame *sf);
// exception that needs to be handled locally.
void __cilk_sync_nothrow(__cilkrts_stack_frame *sf);

__reducer_base *__cilkrts_reducer_lookup_0(__reducer_base *key)
reducer_base *__cilkrts_reducer_lookup_0(reducer_base *key)
__attribute__((nonnull, returns_nonnull));
void *__cilkrts_reducer_lookup_1(void *key, const __reducer_callbacks &)
void *__cilkrts_reducer_lookup_1(void *key, const reducer_callbacks &)
__attribute__((nonnull, returns_nonnull));
void *__cilkrts_reducer_lookup_2(void *key, size_t size,
__cilk_c_identity_fn *id,
__cilk_c_reduce_fn *reduce)
__attribute__((nonnull, returns_nonnull));

void __cilkrts_reducer_register_0(__reducer_base *key) __CILKRTS_NOTHROW;
void __cilkrts_reducer_register_0(reducer_base *key) __CILKRTS_NOTHROW;
void __cilkrts_reducer_register_1(void *key,
__reducer_callbacks *) __CILKRTS_NOTHROW;
reducer_callbacks *) __CILKRTS_NOTHROW;
void __cilkrts_reducer_register_2(void *key,
__cilk_c_reduce_fn *reduce) __CILKRTS_NOTHROW;

Expand Down
8 changes: 6 additions & 2 deletions runtime/hyperobject_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@
// - Problem: Need a way to keep track of whether the view in a
// reducer_data is storing a pointer to the view or the view itself.

namespace cilk {

struct reducer_data {
void *view = nullptr;
std::variant<
__reducer_base *,
const __cilk_reduce_fn *,
reducer_base *,
const reduce_fn *,
__cilk_c_reduce_fn *
> extra;
};

}

#endif /* _HYPEROBJECT_BASE */
34 changes: 19 additions & 15 deletions runtime/local-hypertable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include <cstdint>
#include <cstdlib>

using cilk::reducer_base;
using cilk::reducer_callbacks;
using cilk::reduce_fn;

static void make_tombstone(uintptr_t *key) { *key = KEY_DELETED; }

// Constant used to determine the target maximum load factor. The
Expand Down Expand Up @@ -335,12 +339,12 @@ bool insert_hyperobject(hyper_table *table, bucket b) noexcept {
return false;
}

__reducer_base *__cilkrts_insert_new_view_0(hyper_table *table,
__reducer_base *key) {
reducer_base *__cilkrts_insert_new_view_0(hyper_table *table,
reducer_base *key) {
// Create a new view and initialize it with the identity function.
size_t size = key->size();
size_t size = key->view_size();
void *new_view = cilk_aligned_alloc(64, round_size_to_alignment(64, size));
__reducer_base *base = key->identity(new_view);
reducer_base *base = key->identity(new_view);
// Insert the new view into the local hypertable.
bucket new_bucket = {.key = (uintptr_t)key,
.data = {.view = new_view, .extra = base}};
Expand All @@ -351,7 +355,7 @@ __reducer_base *__cilkrts_insert_new_view_0(hyper_table *table,
}

void *__cilkrts_insert_new_view_1(hyper_table *table, uintptr_t key,
const __reducer_callbacks &callbacks) {
const reducer_callbacks &callbacks) {
// Create a new view and initialize it with the identity function.
void *new_view =
cilk_aligned_alloc(64, round_size_to_alignment(64, callbacks.size));
Expand Down Expand Up @@ -441,7 +445,7 @@ hyper_table *merge_two_hts(hyper_table *__restrict left,
} else {
bucket::reduce(&b, dst_bucket);
dst_bucket->data = b.data;
b.data.extra = (__reducer_base *)nullptr;
b.data.extra = (reducer_base *)nullptr;
b.data.view = nullptr;
}
}
Expand All @@ -456,21 +460,21 @@ hyper_table *merge_two_hts(hyper_table *__restrict left,
void bucket::reduce(bucket *left, bucket *right) {
assert(left->data.extra.index() == right->data.extra.index());
void *left_view = left->data.view, *right_view = right->data.view;
if (std::holds_alternative<__reducer_base *>(left->data.extra)) {
__reducer_base *leftmost =
static_cast<__reducer_base *>(reinterpret_cast<void *>(left->key));
__reducer_base *left_r = std::get<__reducer_base *>(left->data.extra);
__reducer_base *right_r = std::get<__reducer_base *>(right->data.extra);
if (std::holds_alternative<reducer_base *>(left->data.extra)) {
reducer_base *leftmost =
static_cast<reducer_base *>(reinterpret_cast<void *>(left->key));
reducer_base *left_r = std::get<reducer_base *>(left->data.extra);
reducer_base *right_r = std::get<reducer_base *>(right->data.extra);
leftmost->reduce(left_r, right_r);
right_r->~__reducer_base();
} else if (std::holds_alternative<const __cilk_reduce_fn *>(
right_r->~reducer_base();
} else if (std::holds_alternative<const reduce_fn *>(
left->data.extra)) {
(*std::get<const __cilk_reduce_fn *>(left->data.extra))(left_view,
(*std::get<const reduce_fn *>(left->data.extra))(left_view,
right_view);
} else {
std::get<__cilk_c_reduce_fn *>(left->data.extra)(left_view, right_view);
}
right->data.extra = (__reducer_base *)nullptr;
right->data.extra = (reducer_base *)nullptr;
right->data.view = nullptr;
free(right_view);
}
10 changes: 7 additions & 3 deletions runtime/local-hypertable.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <cstdint>
#include <cstdlib>

using cilk::reducer_base;
using cilk::reducer_callbacks;
using cilk::reducer_data;

typedef uint32_t index_t;

// Helper methods for testing and setting keys.
Expand Down Expand Up @@ -233,13 +237,13 @@ static inline bucket *find_hyperobject(hyper_table *table, uintptr_t key) {
}

CHEETAH_API
__reducer_base *__cilkrts_insert_new_view_0(hyper_table *table,
__reducer_base *key)
reducer_base *__cilkrts_insert_new_view_0(hyper_table *table,
reducer_base *key)
__attribute__((nonnull, returns_nonnull));

CHEETAH_API
void *__cilkrts_insert_new_view_1(hyper_table *table, uintptr_t key,
const __reducer_callbacks &callbacks)
const reducer_callbacks &callbacks)
__attribute__((nonnull, returns_nonnull));

CHEETAH_API
Expand Down
17 changes: 10 additions & 7 deletions runtime/local-reducer-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
#include "local-reducer-api.h"
#include "rts-config.h"

using cilk::reducer_base;
using cilk::reducer_callbacks;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

__reducer_base::__reducer_base() {
reducer_base::reducer_base() {
// This would be a great place to register the reducer,
// but doing so would break the equivalence between
// leftmost view and dynamic views. The derived class
// identity operation would need to pass a flag to this
// constructor to suppress registration.
}

__reducer_base::~__reducer_base() {}
reducer_base::~reducer_base() {}

static void reducer_register(bucket &b) __CILKRTS_NOTHROW {
struct hyper_table *table =
Expand All @@ -24,13 +27,13 @@ static void reducer_register(bucket &b) __CILKRTS_NOTHROW {
CILK_ASSERT(success && "Failed to register reducer.");
}

void __cilkrts_reducer_register_0(__reducer_base *key) __CILKRTS_NOTHROW {
void __cilkrts_reducer_register_0(reducer_base *key) __CILKRTS_NOTHROW {
bucket b{.key = (uintptr_t)key, .data = {.view = nullptr, .extra = key}};
reducer_register(b);
}

void __cilkrts_reducer_register_1(void *key,
__reducer_callbacks *cb) __CILKRTS_NOTHROW {
reducer_callbacks *cb) __CILKRTS_NOTHROW {
bucket b{
.key = (uintptr_t)key,
.data = {.view = key, .extra = &cb->reduce},
Expand Down Expand Up @@ -58,14 +61,14 @@ void __cilkrts_reducer_unregister(void *key) noexcept {
#pragma clang diagnostic pop

CHEETAH_INTERNAL
__reducer_base *internal_reducer_lookup(__cilkrts_worker *w,
__reducer_base *key) {
reducer_base *internal_reducer_lookup(__cilkrts_worker *w,
reducer_base *key) {
struct hyper_table *table = get_local_hyper_table(w);
bucket *b = find_hyperobject(table, (uintptr_t)key);
if (__builtin_expect(!!b, true)) {
CILK_ASSERT_POINTER_EQUAL(key, (void *)b->key);
// Return the existing view.
return std::get<__reducer_base *>(b->data.extra);
return std::get<reducer_base *>(b->data.extra);
}

return __cilkrts_insert_new_view_0(table, key);
Expand Down
8 changes: 5 additions & 3 deletions runtime/personality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <functional>
#include <unwind.h>

using cilk::reducer_base;

static struct closure_exception exception_reducer;

typedef _Unwind_Reason_Code (*__personality_routine)(
Expand Down Expand Up @@ -48,12 +50,12 @@ bool exception_reducer_is_empty() noexcept {
}

// Identity method for the exception reducer.
__reducer_base *closure_exception::identity(void *v) {
reducer_base *closure_exception::identity(void *v) {
return new (v) closure_exception;
}

// Reduce method for the exception reducer.
void closure_exception::reduce(__reducer_base *l, __reducer_base *r) {
void closure_exception::reduce(reducer_base *l, reducer_base *r) {
closure_exception *lex = static_cast<closure_exception *>(l);
closure_exception *rex = static_cast<closure_exception *>(r);
if (lex->exn == nullptr) {
Expand Down Expand Up @@ -92,7 +94,7 @@ closure_exception *get_exception_reducer_or_null(__cilkrts_worker *w) noexcept {
if (b) {
CILK_ASSERT_POINTER_EQUAL(key, (void *)b->key);
// Return the existing view.
__reducer_base *base = std::get<__reducer_base *>(b->data.extra);
reducer_base *base = std::get<reducer_base *>(b->data.extra);
return static_cast<closure_exception *>(base);
}
// No view was found. Don't create a new reducer view; just return NULL.
Expand Down
Loading