From c0dd2a5b04f436872b84c3ab3994268bebb2d8d9 Mon Sep 17 00:00:00 2001 From: "raphael.bach" <raphael.bach@etu.hesge.ch> Date: Sat, 14 May 2022 20:44:16 +0200 Subject: [PATCH] Add `fmpi_task` module --- include/fmpi_core.h | 114 +++++++++++++++++++++++++ include/fmpi_task.h | 201 ++++++++++++++++++++++++++++++++++++++++++++ src/fmpi_core.c | 77 +++++++++++++++++ src/fmpi_task.c | 59 +++++++++++++ 4 files changed, 451 insertions(+) create mode 100644 include/fmpi_core.h create mode 100644 include/fmpi_task.h create mode 100644 src/fmpi_core.c create mode 100644 src/fmpi_task.c diff --git a/include/fmpi_core.h b/include/fmpi_core.h new file mode 100644 index 0000000..798833e --- /dev/null +++ b/include/fmpi_core.h @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: 0BSD +/*! + * @file + * @license{ + * BSD Zero Clause License + * + * Copyright (c) 2022 by Raphael Bach + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * } + */ +/*============================================================================== + GUARD +==============================================================================*/ +#ifndef FMPI_CORE_H_20211231181158 +#define FMPI_CORE_H_20211231181158 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +// Internal +#include "internal/fmpi_ctx.h" +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_init() +------------------------------------------------------------------------------*/ +/** + * Initializes the fmpi library. + * + * @param[in,out] argc : A pointer to the `argc` parameter of `main()`. + * @param[in,out] argv : A triple pointer to the `argv` parameter of `main()`. + * + * @return + * - @success: A pointer to a newly allocated `fmpi_ctx`. + * - @failure: `NULL`. + * + * @example{ + * struct fmpi_ctx * ctx = fmpi_init(&argc, &argv); + * if(ctx == NULL) { + * fprintf(stderr, "fmpi_init() failed!\n"); + * fmpi_abort(NULL); + * } + * } + */ +struct fmpi_ctx * fmpi_init(int * argc, char ** argv[]); +/*------------------------------------------------------------------------------ + fmpi_exit() +------------------------------------------------------------------------------*/ +/** + * Exits the fmpi library and sets \p{ctx} to `NULL` after freeing it. + * + * @param[in,out] ctx : A double pointer to a valid `fmpi_ctx` allocated with + * `fmpi_init()`. + * + * @return + * - @success: `0`. + * - @failure: A non-zero value. + * + * @warning + * - \b [UB] \p{ctx} must not be `NULL`. + * - \b [UB] \p{*ctx} must not be `NULL`. + * + * @example{ + * struct fmpi_ctx * ctx = fmpi_init(&argc, &argv); + * if(fmpi_exit(ctx) != 0) { + * fprintf(stderr, "fmpi_exit() failed!\n"); + * } + * } + */ +int fmpi_exit(struct fmpi_ctx ** const ctx); +/*------------------------------------------------------------------------------ + fmpi_abort() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @example{ + * TODO + * } + */ +_Noreturn void fmpi_abort(void); +/*------------------------------------------------------------------------------ + fmpi_is_root() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : A pointer to a fmpi_ctx. + * + * @return TODO + * + * @warning + * - \b [UB] \p{ctx} must not be `NULL`. + * + * @example{ + * TODO + * } + */ +_Bool fmpi_is_root(const struct fmpi_ctx * ctx); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_CORE_H_20211231181158 diff --git a/include/fmpi_task.h b/include/fmpi_task.h new file mode 100644 index 0000000..0f64e55 --- /dev/null +++ b/include/fmpi_task.h @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: 0BSD +/*! + * @file + * @license{ + * BSD Zero Clause License + * + * Copyright (c) 2022 by Raphael Bach + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * } + */ +/*============================================================================== + GUARD +==============================================================================*/ +#ifndef FMPI_TASK_H_20220513032517 +#define FMPI_TASK_H_20220513032517 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +#include <stddef.h> +// External +// Internal +#include "fmpi_data.h" +#include "internal/fmpi_ctx.h" +/*============================================================================== + DEFINE +==============================================================================*/ +/** + * Maximum number of arguments that can be passed to a task. + */ +#define FMPI_TASK_ARGS_CNT_MAX 32 +/*============================================================================== + TYPE +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_task_args +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @example{ + * TODO + * } + */ +typedef struct fmpi_task_args { + struct fmpi_data in[FMPI_TASK_ARGS_CNT_MAX]; //!< TODO + struct fmpi_data out; //!< TODO + size_t cnt; //!< TODO +} fmpi_task_args; +/*------------------------------------------------------------------------------ + fmpi_task_func +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : A pointer to a fmpi_ctx. + * @param[in] args : A pointer to a fmpi_task_args. + * + * @return Nothing. + * + * @warning + * - \b [UB] \p{ctx} must not be `NULL`. + * - \b [UB] \p{args} must not be `NULL`. + * + * @example{ + * TODO + * } + */ +typedef void (*fmpi_task_func)( + const struct fmpi_ctx * ctx, const struct fmpi_task_args * args +); +/*------------------------------------------------------------------------------ + fmpi_task +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @example{ + * TODO + * } + */ +typedef struct fmpi_task { + fmpi_task_func func; //!< TODO + struct fmpi_task_args args; //!< TODO +} fmpi_task; +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_task_register() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : A pointer to a fmpi_ctx. + * @param[in] func : A function with a fmpi_task_func signature. + * @param[in] args : A pointer to a fmpi_task_args. + * + * @return A fmpi_task structure. + * + * @warning + * - \b [UB] \p{ctx} must not be `NULL`. + * - \b [UB] \p{func} must not be `NULL`. + * - \b [UB] \p{args} must not be `NULL`. + * + * @example{ + * TODO + * } + */ +struct fmpi_task fmpi_task_register( + const struct fmpi_ctx * ctx, const fmpi_task_func func, + const struct fmpi_task_args * args +); +/*------------------------------------------------------------------------------ + fmpi_task_run() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : A pointer to a fmpi_ctx. + * @param[in] task : A pointer to a fmpi_task. + * + * @return Nothing. + * + * @warning + * - \b [UB] \p{ctx} must not be `NULL`. + * - \b [UB] \p{task} must not be `NULL`. + * + * @example{ + * TODO + * } + */ +void fmpi_task_run(const struct fmpi_ctx * ctx, const struct fmpi_task * task); +/*============================================================================== + MACRO +==============================================================================*/ +/*------------------------------------------------------------------------------ + FMPI_TASK_FUTHARK_SYNC() +------------------------------------------------------------------------------*/ +/** + * Declares and defines a task running a `futhark` function synchronously. + * + * @param[in] task_name : The name to give to this task. + * @param[in] func : A pointer to a futhark function. + * + * @return Nothing. + * + * @warning + * - \b [UB] \p{func} must not be `NULL`. + * + * @example{ + * FMPI_TASK_FUTHARK_SYNC(fut_array_sum, futhark_entry_array_sum) + * } + */ +#define FMPI_TASK_FUTHARK_SYNC(task_name, func) \ +void task_name(const struct fmpi_ctx * ctx, const struct fmpi_task_args * args); \ +void task_name(const struct fmpi_ctx * const ctx, const struct fmpi_task_args * const args) { \ + assert(ctx != NULL); \ + assert(args != NULL); \ + func(ctx->fut->ctx, args->out.start, args->in[0].start); \ + fmpi_futhark_sync(ctx->fut); \ +} +/*------------------------------------------------------------------------------ + FMPI_TASK_FUTHARK_ASYNC() +------------------------------------------------------------------------------*/ +/** + * Declares and defines a task running a `futhark` function asynchronously. + * + * @param[in] task_name : The name to give to this task. + * @param[in] func : A pointer to a futhark function. + * + * @return Nothing. + * + * @warning + * - \b [UB] \p{func} must not be `NULL`. + * + * @example{ + * FMPI_TASK_FUTHARK_ASYNC(fut_array_sum, futhark_entry_array_sum) + * } + */ +#define FMPI_TASK_FUTHARK_ASYNC(task_name, func) \ +void task_name(const struct fmpi_ctx * ctx, const struct fmpi_task_args * args); \ +void task_name(const struct fmpi_ctx * const ctx, const struct fmpi_task_args * const args) { \ + assert(ctx != NULL); \ + assert(args != NULL); \ + func(ctx->fut->ctx, args->out.start, args->in[0].start); \ +} +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_TASK_H_20220513032517 diff --git a/src/fmpi_core.c b/src/fmpi_core.c new file mode 100644 index 0000000..64ed212 --- /dev/null +++ b/src/fmpi_core.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: 0BSD +/*! + * @file + * @license{ + * BSD Zero Clause License + * + * Copyright (c) 2022 by Raphael Bach + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_core.h" +// C Standard Library +#include <assert.h> +#include <stdio.h> // fprintf() +#include <stdlib.h> // NULL, +// External +#include <mpi.h> +// Internal +#include "internal/fmpi_ctx.h" +#include "internal/fmpi_futhark.h" +#include "internal/fmpi_mpi.h" +/*============================================================================== + STRUCT +==============================================================================*/ +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_init() +------------------------------------------------------------------------------*/ +struct fmpi_ctx * fmpi_init(int * const argc, char *** const argv) +{ + struct fmpi_ctx * ctx = fmpi_ctx_create(argc, argv); + if(ctx == NULL) { + fprintf(stderr, "fmpi_ctx_create() failed!\n"); + return NULL; + } + return ctx; +} +/*------------------------------------------------------------------------------ + fmpi_exit() +------------------------------------------------------------------------------*/ +int fmpi_exit(struct fmpi_ctx ** const ctx) +{ + assert(ctx != NULL); + return fmpi_ctx_destroy(ctx); +} +/*------------------------------------------------------------------------------ + fmpi_abort() +------------------------------------------------------------------------------*/ +_Noreturn void fmpi_abort(void) +{ + MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN); + abort(); +} +/*------------------------------------------------------------------------------ + fmpi_is_root() +------------------------------------------------------------------------------*/ +_Bool fmpi_is_root(const struct fmpi_ctx * ctx) +{ + assert(ctx != NULL); + return fmpi_mpi_is_root(ctx->mpi); +} diff --git a/src/fmpi_task.c b/src/fmpi_task.c new file mode 100644 index 0000000..c45237d --- /dev/null +++ b/src/fmpi_task.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: 0BSD +/*! + * @file + * @license{ + * BSD Zero Clause License + * + * Copyright (c) 2022 by Raphael Bach + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_task.h" +// C Standard Library +#include <assert.h> +#include <stdint.h> // int64_t +// Internal +#include "internal/fmpi_futhark.h" +#include "internal/fmpi_futhark_entry.h" +/*============================================================================== + PUBLIC FUNCTION DEFINITION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_task_run() +------------------------------------------------------------------------------*/ +struct fmpi_task fmpi_task_register( + const struct fmpi_ctx * const ctx, const fmpi_task_func func, + const struct fmpi_task_args * const args +){ + assert(ctx != NULL); + struct fmpi_task task = { + .func = func, + .args = *args + }; + for(size_t i = 0; i < args->cnt; i++) { + task.args.in[i].start = futhark_new_i64_1d(ctx->fut->ctx, args->in[i].start, (int64_t)args->in[i].dims_length[0]); + } + futhark_context_sync(ctx->fut->ctx); + return task; +} +void fmpi_task_run( + const struct fmpi_ctx * const ctx, const struct fmpi_task * const task +){ + assert(ctx != NULL); + assert(task != NULL); + task->func(ctx, &task->args); +} -- GitLab