diff --git a/include/fmpi_futhark.h b/include/fmpi_futhark.h deleted file mode 100644 index c7bf37d886e79064f765f971f712a5a71c807128..0000000000000000000000000000000000000000 --- a/include/fmpi_futhark.h +++ /dev/null @@ -1,71 +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_FUTHARK_H_20211219234207 -#define FMPI_FUTHARK_H_20211219234207 -/*============================================================================== - INCLUDE -==============================================================================*/ -// C Standard Library -// External -// Internal -#include "internal/fmpi_futhark_internal.h" -/*============================================================================== - STRUCT -==============================================================================*/ -struct fmpi_ctx; -/*============================================================================== - PUBLIC FUNCTION -==============================================================================*/ -int fmpi_futhark_init(struct fmpi_ctx * const ctx); -void fmpi_futhark_exit(struct fmpi_ctx * const ctx); -void fmpi_futhark_sync(struct fmpi_ctx * const ctx); -/*------------------------------------------------------------------------------ - fmpi_futhark_has_error() -------------------------------------------------------------------------------*/ -/** - * Check if the last function called before calling - * fmpi_has_futhark_error() generated an error. - * - * @param[in,out] ctx : Pointer to a fmpi_ctx structure. - * @param[in] err_id : Error id returned by a futhark function. - * @param[in] func_name : Function name. - * - * @return - * - `true` if an error is detected. - * - `false` if no error was detected. - * - * @warning - * - \p{ctx} must be a valid pointer allocated with fmpi_init(). - * - \p{func_name} must not be `NULL`. - */ -_Bool fmpi_futhark_has_error(struct fmpi_ctx * const ctx, const char * const func_name); -void fmpi_futhark_abort_on_error(struct fmpi_ctx * ctx, const char * const func_name); - -#define fmpi_new_1d(ctx, array, length) \ - FMPI_GENERIC_FUNC_FUTHARK(array, new, 1d, FMPI_FUTHARK_TYPES)(ctx, array, length) - -#define fmpi_free_1d(ctx, array, length) \ - FMPI_GENERIC_FUNC_FUTHARK(array, free, 1d, FMPI_FUTHARK_TYPES)(ctx, array) -/*============================================================================== - GUARD -==============================================================================*/ -#endif // FMPI_FUTHARK_H_20211219234207 diff --git a/include/internal/fmpi_futhark.h b/include/internal/fmpi_futhark.h new file mode 100644 index 0000000000000000000000000000000000000000..c2b7e21306aac21b673164e4e510daf65dd8b6b0 --- /dev/null +++ b/include/internal/fmpi_futhark.h @@ -0,0 +1,180 @@ +// 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_FUTHARK_H_20211219234207 +#define FMPI_FUTHARK_H_20211219234207 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +// Internal +#include "fmpi_error.h" +#include "generic/fmpi_futhark_generic.h" +/*============================================================================== + STRUCT +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_futhark_ctx() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @example{ + * TODO + * } + */ +typedef struct fmpi_futhark_ctx { + struct futhark_context * ctx; //!< TODO + struct futhark_context_config * cfg; //!< TODO + const struct fmpi_error_handler * err_handler; //!< TODO +} fmpi_futhark_ctx; +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_futhark_init() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] err_handler : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +struct fmpi_futhark_ctx * fmpi_futhark_init(const struct fmpi_error_handler * err_handler); +/*------------------------------------------------------------------------------ + fmpi_futhark_exit() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +int fmpi_futhark_exit(struct fmpi_futhark_ctx ** ctx); +/*------------------------------------------------------------------------------ + fmpi_futhark_sync() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +int fmpi_futhark_sync(const struct fmpi_futhark_ctx * ctx); +/*------------------------------------------------------------------------------ + fmpi_futhark_has_error() +------------------------------------------------------------------------------*/ +/** + * Check if the last function called before calling + * fmpi_has_futhark_error() generated an error. + * + * @param[in,out] ctx : Pointer to a fmpi_ctx structure. + * @param[in] func : Function name. + * + * @return + * - `true` if an error is detected. + * - `false` if no error was detected. + * + * @warning + * - \p{ctx} must be a valid pointer allocated with fmpi_init(). + * - \p{func} must not be `NULL`. + */ +_Bool fmpi_futhark_check_error(const struct fmpi_futhark_ctx * ctx, const char * func); +/*============================================================================== + MACRO +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_futhark_init() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * @param[in] array : TODO + * @param[in] length : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +#define fmpi_futhark_new_1d(ctx, array, length) \ + FMPI_GENERIC_FUNC(array, new_1d, FMPI_FUTHARK_TYPES)(ctx, array, length) +/*------------------------------------------------------------------------------ + fmpi_futhark_init() +------------------------------------------------------------------------------*/ +/** + * TODO + * + * @param[in] ctx : TODO + * @param[in] array : TODO + * @param[in] length : TODO + * + * @return + * - @success: TODO + * - @failure: TODO + * + * @warning TODO + * + * @example{ + * TODO + * } + */ +#define fmpi_futhark_free_1d(ctx, array, length) \ + FMPI_GENERIC_FUNC(array, free_1d, FMPI_FUTHARK_TYPES)(ctx, array) +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_FUTHARK_H_20211219234207 diff --git a/include/internal/fmpi_futhark_internal.h b/include/internal/generic/fmpi_futhark_generic.h similarity index 58% rename from include/internal/fmpi_futhark_internal.h rename to include/internal/generic/fmpi_futhark_generic.h index 824c88b8f70512979357bb52e66aecc97993e388..4e112f2107599fd18e559bef8af6a4acf35d0e57 100644 --- a/include/internal/fmpi_futhark_internal.h +++ b/include/internal/generic/fmpi_futhark_generic.h @@ -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. * @@ -24,35 +26,29 @@ /*============================================================================== INCLUDE ==============================================================================*/ +// C Standard Library +#include <stddef.h> // size_t // Internal -#include "fmpi_ctx.h" #include "fmpi_generic.h" /*============================================================================== MACRO ==============================================================================*/ +struct fmpi_ctx; + #define FMPI_FUTHARK_TYPES \ FMPI_TYPE_REAL -#define FMPI_PROTO_NEW_1D(T) \ - struct futhark_##T##_1d * fmpi_new_##T##_1d(struct fmpi_ctx * ctx, const T * array, int length) -#define FMPI_PROTO_NEW_2D(T) \ - struct futhark_##T##_2d * fmpi_new_##T##_2d(struct fmpi_ctx * ctx, const T * array, int length) -#define FMPI_PROTO_NEW_3D(T) \ - struct futhark_##T##_3d * fmpi_new_##T##_3d(struct fmpi_ctx * ctx, const T * array, int length) - -#define FMPI_PROTO_FREE_1D(T) \ - void fmpi_free_##T##_1d(struct fmpi_ctx * ctx, struct futhark_##T##_1d * array) -#define FMPI_PROTO_FREE_2D(T) \ - void fmpi_free_##T##_2d(struct fmpi_ctx * ctx, struct futhark_##T##_2d * array) -#define FMPI_PROTO_FREE_3D(T) \ - void fmpi_free_##T##_3d(struct fmpi_ctx * ctx, struct futhark_##T##_3d * array) +#define FMPI_FUTHARK_DECLARATION(D, T) \ +struct futhark_##T##_##D##d * fmpi_futhark_new_##D##d_##T( \ + const struct fmpi_ctx * ctx, const T * array, size_t length \ +); \ +void fmpi_futhark_free_##D##d_##T( \ + const struct fmpi_ctx * ctx, struct futhark_##T##_##D##d * array \ +) -FMPI_DECLARE_FUNC( - FMPI_PROTO_NEW_1D, FMPI_FUTHARK_TYPES -); -FMPI_DECLARE_FUNC( - FMPI_PROTO_FREE_1D, FMPI_FUTHARK_TYPES -); +FMPI_DECLARE_DIM_FUNCS(FMPI_FUTHARK_DECLARATION, 1, FMPI_FUTHARK_TYPES); +FMPI_DECLARE_DIM_FUNCS(FMPI_FUTHARK_DECLARATION, 2, FMPI_FUTHARK_TYPES); +FMPI_DECLARE_DIM_FUNCS(FMPI_FUTHARK_DECLARATION, 3, FMPI_FUTHARK_TYPES); /*============================================================================== GUARD ==============================================================================*/ diff --git a/src/fmpi_futhark.c b/src/fmpi_futhark.c index b3d84d4c8fa00fef864bff3a8da1b8d7404289a2..874c91fe620ee8749ac9aae6a4f890fbcd02071b 100644 --- a/src/fmpi_futhark.c +++ b/src/fmpi_futhark.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,126 +22,133 @@ INCLUDE ==============================================================================*/ // Own header -#include "fmpi_futhark.h" +#include "internal/fmpi_futhark.h" // C Standard Library #include <assert.h> -#include <stdint.h> -#include <stdio.h> +#include <stdbool.h> +#include <stdint.h> // int64_t #include <stdlib.h> -#include <string.h> -// External // Internal -#include "fmpi_ctx.h" -#include "fmpi_mpi.h" -#include "internal/fmpi_fut.h" -#include "internal/fmpi_generic.h" +#include "internal/fmpi_ctx.h" +#include "internal/fmpi_futhark_entry.h" +#include "internal/generic/fmpi_generic.h" /*============================================================================== - STRUCT + MACRO ==============================================================================*/ +#define FMPI_RAISE_FUTHARK_ERROR(ctx, ...) \ +do { \ + if((ctx)->err_handler != NULL) { \ + FMPI_RAISE_ERROR((ctx)->err_handler, "FUTHARK", __VA_ARGS__); \ + } \ +} while(0) /*============================================================================== PUBLIC FUNCTION ==============================================================================*/ /*------------------------------------------------------------------------------ fmpi_futhark_init() ------------------------------------------------------------------------------*/ -int fmpi_futhark_init(struct fmpi_ctx * const ctx) -{ - assert(ctx != NULL); - assert(ctx->futhark == NULL); - assert(ctx->futhark_cfg == NULL); - - ctx->futhark_cfg = futhark_context_config_new(); - if(ctx->futhark_cfg == NULL) { - fprintf(stderr, "[FUTHARK ERROR rank=%d] futhark_context_config_new() failed!\n", ctx->mpi->rank); - return ctx->mpi->futhark_err_class; +struct fmpi_futhark_ctx * fmpi_futhark_init( + const struct fmpi_error_handler * const err_handler +){ + struct fmpi_futhark_ctx * ctx = malloc(sizeof(*ctx)); + if(ctx == NULL) { + if(err_handler != NULL) { + FMPI_RAISE_ERROR(err_handler, "FUTHARK", "malloc(fmpi_futhark_ctx) failed!"); + } + return NULL; + } + ctx->err_handler = (err_handler != NULL) ? err_handler : NULL; + ctx->cfg = futhark_context_config_new(); + if(ctx->cfg == NULL) { + FMPI_RAISE_FUTHARK_ERROR(ctx, "futhark_context_config_new() failed!"); + return ctx; + } + ctx->ctx = futhark_context_new(ctx->cfg); + // The doc says in case of error futhark_context_free() should be called + // anyway, implying that futhark_context_new() returns a non-null pointer + // even on error. + // The code generated by futhark 0.22 says otherwise by clearly returning + // NULL if malloc() fails. + if(ctx->ctx == NULL) { + FMPI_RAISE_FUTHARK_ERROR(ctx, "futhark_context_new() failed!"); + futhark_context_config_free(ctx->cfg); + return ctx; } - ctx->futhark = futhark_context_new(ctx->futhark_cfg); - char * err_ptr = futhark_context_get_error(ctx->futhark); - if(ctx->futhark == NULL || err_ptr != NULL) { - const char * err_str = err_ptr != NULL ? err_ptr : ""; - fprintf(stderr, "[FUTHARK ERROR rank=%d] futhark_context_new() failed! %s\n", ctx->mpi->rank, err_str); - futhark_context_free(ctx->futhark); - futhark_context_config_free(ctx->futhark_cfg); - free(ctx->futhark); - return ctx->mpi->futhark_err_class; + if(fmpi_futhark_check_error(ctx, "futhark_context_new") == true) { + fmpi_futhark_sync(ctx); + futhark_context_free(ctx->ctx); + futhark_context_config_free(ctx->cfg); } - return MPI_SUCCESS; + return ctx; } /*------------------------------------------------------------------------------ fmpi_futhark_exit() ------------------------------------------------------------------------------*/ -void fmpi_futhark_exit(struct fmpi_ctx * const ctx) +int fmpi_futhark_exit(struct fmpi_futhark_ctx ** const ctx) { assert(ctx != NULL); - assert(ctx->futhark_cfg != NULL); - assert(ctx->futhark != NULL); + assert(*ctx != NULL); - fmpi_futhark_sync(ctx); - futhark_context_free(ctx->futhark); - ctx->futhark = NULL; - futhark_context_config_free(ctx->futhark_cfg); - ctx->futhark_cfg = NULL; + int err_id = 0; + if(futhark_context_sync((*ctx)->ctx) != 0) { + err_id = -1; + } + futhark_context_free((*ctx)->ctx); + futhark_context_config_free((*ctx)->cfg); + free(*ctx); *ctx = NULL; + return err_id; } /*------------------------------------------------------------------------------ fmpi_futhark_sync() ------------------------------------------------------------------------------*/ -void fmpi_futhark_sync(struct fmpi_ctx * const ctx) -{ - assert(ctx != NULL); - futhark_context_sync(ctx->futhark); - fmpi_futhark_abort_on_error(ctx, "futhark_context_sync()"); -} -/*------------------------------------------------------------------------------ - fmpi_futhark_has_error() -------------------------------------------------------------------------------*/ -_Bool fmpi_futhark_has_error(struct fmpi_ctx * const ctx, const char * const func_name) +int fmpi_futhark_sync(const struct fmpi_futhark_ctx * const ctx) { assert(ctx != NULL); - - char * err_str = futhark_context_get_error(ctx->futhark); - if(err_str != NULL) { - const char * func_str = func_name != NULL ? func_name : "NO_NAME"; - fprintf(stderr, "[FUTHARK ERROR rank=%d] %s failed! %s\n", ctx->mpi->rank, func_str, err_str); - free(err_str); err_str = NULL; - return 1; + const int err = futhark_context_sync(ctx->ctx); + if(err != 0) { + fmpi_futhark_check_error(ctx, "futhark_context_sync"); + return -1; } return 0; } /*------------------------------------------------------------------------------ - fmpi_futhark_abort_on_error() + fmpi_futhark_check_error() ------------------------------------------------------------------------------*/ -void fmpi_futhark_abort_on_error(struct fmpi_ctx * ctx, const char * const func_name) -{ +_Bool fmpi_futhark_check_error( + const struct fmpi_futhark_ctx * const ctx, const char * const func +){ assert(ctx != NULL); - if(fmpi_futhark_has_error(ctx, func_name)) { - fmpi_abort(ctx); + assert(func != NULL); + char * err_str = futhark_context_get_error(ctx->ctx); + if(err_str != NULL) { + FMPI_RAISE_FUTHARK_ERROR(ctx, "%s() failed! %s", func, err_str); + free(err_str); err_str = NULL; + return true; } + return false; } -/*------------------------------------------------------------------------------ - fmpi_new_1d() -------------------------------------------------------------------------------*/ -#define FMPI_DEFINE_NEW_1D(T) \ -FMPI_PROTO_NEW_1D(T) \ -{ \ - assert(ctx != NULL); \ - assert(array != NULL); \ - struct futhark_##T##_1d * xs = futhark_new_##T##_1d(ctx->futhark, array, length); \ - fmpi_futhark_abort_on_error(ctx, CPL_STRINGIFY(futhark_new_##T##_1d())); \ - fmpi_futhark_sync(ctx);\ - return xs;\ -} -/*------------------------------------------------------------------------------ - fmpi_free_1d() -------------------------------------------------------------------------------*/ -#define FMPI_DEFINE_FREE_1D(T) \ -FMPI_PROTO_FREE_1D(T) \ -{ \ - assert(ctx != NULL); \ - assert(array != NULL); \ - fmpi_futhark_sync(ctx);\ - futhark_free_##T##_1d(ctx->futhark, array); \ - fmpi_futhark_abort_on_error(ctx, CPL_STRINGIFY(futhark_free_##T##_1d())); \ +#define FMPI_FUTHARK_DEFINITION(D, T) \ +struct futhark_##T##_1d * fmpi_futhark_new_1d_##T( \ + const struct fmpi_ctx * const ctx, const T * const array, const size_t length \ +){ \ + assert(ctx != NULL); \ + assert(array != NULL); \ + struct futhark_##T##_1d * data = futhark_new_##T##_1d(ctx->fut->ctx, array, (int64_t)length); \ + if(data == NULL) { \ + fmpi_futhark_check_error(ctx->fut, CPL_STRINGIFY(futhark_new_##T##_1d)); \ + } \ + fmpi_futhark_sync(ctx->fut);\ + return data;\ +}\ +void fmpi_futhark_free_1d_##T( \ + const struct fmpi_ctx * const ctx, struct futhark_##T##_1d * const array \ +){ \ + assert(ctx != NULL); \ + assert(array != NULL); \ + fmpi_futhark_sync(ctx->fut);\ + const int err = futhark_free_##T##_1d(ctx->fut->ctx, array); \ + if(err != 0) { \ + fmpi_futhark_check_error(ctx->fut, CPL_STRINGIFY(futhark_free_##T##_1d)); \ + } \ } - -FMPI_DEFINE_FUNC(FMPI_DEFINE_NEW_1D, FMPI_FUTHARK_TYPES) -FMPI_DEFINE_FUNC(FMPI_DEFINE_FREE_1D, FMPI_FUTHARK_TYPES) +FMPI_DEFINE_DIM_FUNCS(FMPI_FUTHARK_DEFINITION, -, FMPI_FUTHARK_TYPES)