diff --git a/include/fmpi_mpi.h b/include/fmpi_mpi.h deleted file mode 100644 index 90ede0ef77c6a490e39ebde4d4b580075cd42a75..0000000000000000000000000000000000000000 --- a/include/fmpi_mpi.h +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: 0BSD -/*! - * @file - * @license{ - * BSD Zero Clause License - * - * 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_MPI_H_20211219234201 -#define FMPI_MPI_H_20211219234201 -/*============================================================================== - INCLUDE -==============================================================================*/ -// C Standard Library -// External -#include <mpi.h> // MPI_MAX_PROCESSOR_NAME -// Internal -/*============================================================================== - STRUCT -==============================================================================*/ -struct fmpi_mpi_ctx { - int rank; - int size; - char cpu_name[MPI_MAX_PROCESSOR_NAME]; - int cpu_name_length; - int root; - int futhark_err_class; - int futhark_err_code; -}; -struct fmpi_ctx; -/*============================================================================== - PUBLIC FUNCTION -==============================================================================*/ -struct fmpi_mpi_ctx * fmpi_mpi_init(int * argc, char ** argv[]); -void fmpi_mpi_exit(struct fmpi_mpi_ctx * ctx); -void fmpi_mpi_abort(struct fmpi_mpi_ctx * ctx); -_Bool fmpi_mpi_is_root(const struct fmpi_mpi_ctx * const ctx); -_Bool fmpi_mpi_has_error(struct fmpi_mpi_ctx * const ctx, int err_id, const char * const func_name); -_Bool fmpi_mpi_is_initialized(struct fmpi_mpi_ctx * const ctx); -_Bool fmpi_mpi_is_finalized(struct fmpi_mpi_ctx * const ctx); -struct fmpi_mpi_ctx * fmpi_mpi_create(int root); -void fmpi_mpi_destroy(struct fmpi_mpi_ctx ** const ctx); -void fmpi_mpi_ctx_print(const struct fmpi_mpi_ctx * const ctx); -/*============================================================================== - GUARD -==============================================================================*/ -#endif // FMPI_MPI_H_20211219234201 diff --git a/include/internal/fmpi_mpi.h b/include/internal/fmpi_mpi.h new file mode 100644 index 0000000000000000000000000000000000000000..cfb97a4a484f25e8a183ec066cf2fe90a4148a63 --- /dev/null +++ b/include/internal/fmpi_mpi.h @@ -0,0 +1,166 @@ +// 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_MPI_H_20211219234201 +#define FMPI_MPI_H_20211219234201 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +// External +#include <mpi.h> // MPI_MAX_PROCESSOR_NAME +// Internal +#include "fmpi_error.h" +/*============================================================================== + STRUCT +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_mpi_ctx +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @example{ + * TODO + * } + */ +typedef struct fmpi_mpi_ctx { + int rank; //!< TODO + int size; //!< TODO + char cpu_name[MPI_MAX_PROCESSOR_NAME]; //!< TODO + int cpu_name_length; //!< TODO + int root; //!< TODO + int futhark_err_class; //!< TODO + int futhark_err_code; //!< TODO + const struct fmpi_error_handler * err_handler; //!< TODO +} fmpi_mpi_ctx; +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_mpi_init() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] argc : TODO + * @param[in] argv : TODO + * @param[in] err_handler : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +struct fmpi_mpi_ctx * fmpi_mpi_init( + int * argc, char ** argv[], const struct fmpi_error_handler * err_handler +); +/*------------------------------------------------------------------------------ + fmpi_mpi_exit() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +int fmpi_mpi_exit(struct fmpi_mpi_ctx ** ctx); +/*------------------------------------------------------------------------------ + fmpi_mpi_is_root() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +_Bool fmpi_mpi_is_root(const struct fmpi_mpi_ctx * const ctx); +/*------------------------------------------------------------------------------ + fmpi_mpi_check_error() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * @param[in] err_id : TODO + * @param[in] func : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +_Bool fmpi_mpi_check_error( + const struct fmpi_mpi_ctx * ctx, int err_id, const char * func +); +/*------------------------------------------------------------------------------ + fmpi_mpi_ctx_print() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +void fmpi_mpi_ctx_print(const struct fmpi_mpi_ctx * ctx); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_MPI_H_20211219234201 diff --git a/src/fmpi_mpi.c b/src/fmpi_mpi.c index cc78b479be9f67ae9b2d6cd5a839b322e34aba3e..9ba26be0ee9dcd84af149a9a6a45e1956b5b9807 100644 --- a/src/fmpi_mpi.c +++ b/src/fmpi_mpi.c @@ -4,6 +4,8 @@ * @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. * @@ -20,89 +22,81 @@ INCLUDE ==============================================================================*/ // Own header -#include "fmpi_mpi.h" +#include "internal/fmpi_mpi.h" // C Standard Library #include <assert.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> // External #include <mpi.h> // Internal -#include "fmpi_ctx.h" +#include "internal/fmpi_error.h" /*============================================================================== DEFINE ==============================================================================*/ -#define FMPI_MPI_RANK_ROOT_DEFAULT 0 +#define FMPI_MPI_ROOT 0 +/*============================================================================== + MACRO +==============================================================================*/ +#define FMPI_RAISE_MPI_ERROR(ctx, ...) \ +do { \ + if((ctx)->err_handler != NULL) { \ + FMPI_RAISE_ERROR((ctx)->err_handler, "MPI", __VA_ARGS__); \ + } \ +} while(0) /*============================================================================== PUBLIC FUNCTION ==============================================================================*/ /*------------------------------------------------------------------------------ fmpi_mpi_init() ------------------------------------------------------------------------------*/ -struct fmpi_mpi_ctx * fmpi_mpi_init(int * argc, char ** argv[]) -{ - struct fmpi_mpi_ctx * ctx = fmpi_mpi_create(FMPI_MPI_RANK_ROOT_DEFAULT); +struct fmpi_mpi_ctx * fmpi_mpi_init( + int * const argc, char *** const argv, + const struct fmpi_error_handler * const err_handler +){ + struct fmpi_mpi_ctx * ctx = malloc(sizeof(*ctx)); if(ctx == NULL) { - fprintf(stderr, "fmpi_mpi_create() failed!\n"); + if(err_handler != NULL) { + FMPI_RAISE_ERROR(err_handler, "MPI", "malloc(fmpi_mpi_ctx) failed!"); + } return NULL; } + ctx->root = FMPI_MPI_ROOT; + ctx->err_handler = (err_handler != NULL) ? err_handler : NULL; int err_id = MPI_Init(argc, argv); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Init()")) { - fmpi_mpi_destroy(&ctx); return NULL; + if(fmpi_mpi_check_error(ctx, err_id, "MPI_Init") == true) { + return ctx; } + err_id = MPI_Comm_rank(MPI_COMM_WORLD, &ctx->rank); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Comm_rank()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } + fmpi_mpi_check_error(ctx, err_id, "MPI_Comm_rank"); + err_id = MPI_Comm_size(MPI_COMM_WORLD, &ctx->size); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Comm_size()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } - // `size` is used with `malloc()` and `malloc(0)` is implementation-defined. + fmpi_mpi_check_error(ctx, err_id, "MPI_Comm_size"); + // `ctx->size` is used with `malloc()` and `malloc(0)` is implementation-defined. assert(ctx->size > 0); + err_id = MPI_Get_processor_name(ctx->cpu_name, &ctx->cpu_name_length); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Get_processor_name()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } - err_id = MPI_Add_error_class(&ctx->futhark_err_class); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Get_processor_name()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } - err_id = MPI_Add_error_code(ctx->futhark_err_class, &ctx->futhark_err_code); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Get_processor_name()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } - err_id = MPI_Add_error_string(ctx->futhark_err_code, ""); - if(fmpi_mpi_has_error(ctx, err_id, "MPI_Get_processor_name()")) { - fmpi_mpi_destroy(&ctx); return NULL; - } + fmpi_mpi_check_error(ctx, err_id, "MPI_Get_processor_name"); + return ctx; } /*------------------------------------------------------------------------------ fmpi_mpi_exit() ------------------------------------------------------------------------------*/ -void fmpi_mpi_exit(struct fmpi_mpi_ctx * ctx) +int fmpi_mpi_exit(struct fmpi_mpi_ctx ** const ctx) { - if(ctx != NULL) { - fmpi_mpi_destroy(&ctx); - } - if(fmpi_mpi_is_initialized(ctx) && !fmpi_mpi_is_finalized(ctx)) { - const int err_id = MPI_Finalize(); - fmpi_mpi_has_error(ctx, err_id, "MPI_Finalize()"); - } -} -/*------------------------------------------------------------------------------ - fmpi_mpi_abort() -------------------------------------------------------------------------------*/ -void fmpi_mpi_abort(struct fmpi_mpi_ctx * ctx) -{ - if(ctx != NULL) { - fmpi_mpi_destroy(&ctx); - } - if(fmpi_mpi_is_initialized(ctx) && !fmpi_mpi_is_finalized(ctx)) { - MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN); + assert(ctx != NULL); + assert(*ctx != NULL); + + int err_id = MPI_Finalize(); + if(fmpi_mpi_check_error(*ctx, err_id, "MPI_Finalize") == true) { + err_id = -1; } + free(*ctx); *ctx = NULL; + return err_id; } /*------------------------------------------------------------------------------ fmpi_mpi_is_root() @@ -113,70 +107,24 @@ _Bool fmpi_mpi_is_root(const struct fmpi_mpi_ctx * const ctx) return ctx->rank == ctx->root; } /*------------------------------------------------------------------------------ - fmpi_mpi_has_error() + fmpi_mpi_check_error() ------------------------------------------------------------------------------*/ -_Bool fmpi_mpi_has_error(struct fmpi_mpi_ctx * const ctx, int err_id, const char * const func_name) -{ - int rank = -1; - if(ctx != NULL) { - rank = ctx->rank; - } +_Bool fmpi_mpi_check_error( + const struct fmpi_mpi_ctx * ctx, int err_id, const char * const func +){ + assert(ctx != NULL); + assert(func != NULL); if(err_id != MPI_SUCCESS) { - char err_array[MPI_MAX_ERROR_STRING] = {0}; + char err_str[MPI_MAX_ERROR_STRING] = {'\0'}; int err_str_len = 0; - const int err_str_id = MPI_Error_string(err_id, err_array, &err_str_len); - if(err_str_id != MPI_SUCCESS) { - fprintf(stderr, "[MPI ERROR rank=%d] MPI_Error_string() failed!\n", rank); + err_id = MPI_Error_string(err_id, err_str, &err_str_len); + if(err_id != MPI_SUCCESS) { + FMPI_RAISE_MPI_ERROR(ctx, "MPI_Error_string() failed!"); } - const char * err_str = err_str_id == MPI_SUCCESS ? err_array : ""; - fprintf(stderr, "[MPI ERROR rank=%d] %s failed!: %s\n", rank, func_name, err_str); - return 1; + FMPI_RAISE_MPI_ERROR(ctx, "%s() failed! %s", func, err_str); + return true; } - return 0; -} -/*------------------------------------------------------------------------------ - fmpi_mpi_is_initialized() -------------------------------------------------------------------------------*/ -_Bool fmpi_mpi_is_initialized(struct fmpi_mpi_ctx * const ctx) -{ - int is_initialized = 0; - const int err_id = MPI_Initialized(&is_initialized); - fmpi_mpi_has_error(ctx, err_id, "MPI_Initialized()"); - return is_initialized; -} -/*------------------------------------------------------------------------------ - fmpi_mpi_is_finalized() -------------------------------------------------------------------------------*/ -_Bool fmpi_mpi_is_finalized(struct fmpi_mpi_ctx * const ctx) -{ - int is_finalized = 0; - const int err_id = MPI_Finalized(&is_finalized); - fmpi_mpi_has_error(ctx, err_id, "MPI_Finalized()"); - return is_finalized; -} -/*------------------------------------------------------------------------------ - fmpi_mpi_create() -------------------------------------------------------------------------------*/ -struct fmpi_mpi_ctx * fmpi_mpi_create(int root) -{ - struct fmpi_mpi_ctx * ctx = malloc(sizeof(*ctx)); - if(ctx == NULL) { - fprintf(stderr, "malloc(fmpi_mpi_ctx) failed!\n"); - return NULL; - } - ctx->root = root; - return ctx; -} -/*------------------------------------------------------------------------------ - fmpi_mpi_destroy() -------------------------------------------------------------------------------*/ -void fmpi_mpi_destroy(struct fmpi_mpi_ctx ** const ctx) -{ - assert(ctx != NULL); - assert(*ctx != NULL); - - free((*ctx)); - (*ctx) = NULL; + return false; } /*------------------------------------------------------------------------------ fmpi_mpi_ctx_print() @@ -184,7 +132,6 @@ void fmpi_mpi_destroy(struct fmpi_mpi_ctx ** const ctx) void fmpi_mpi_ctx_print(const struct fmpi_mpi_ctx * const ctx) { assert(ctx != NULL); - printf("MPI size: %d\n", ctx->size); printf("MPI rank: %d\n", ctx->rank); printf("MPI CPU name: %s\n", ctx->cpu_name);