Skip to content
Snippets Groups Projects
Verified Commit 120d7b16 authored by raphael.bach's avatar raphael.bach
Browse files

Refactor `fmpi_futhark` module

parent 5f54ebce
No related branches found
No related tags found
No related merge requests found
......@@ -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.
*
......@@ -25,19 +27,87 @@
INCLUDE
==============================================================================*/
// C Standard Library
// External
// Internal
#include "internal/fmpi_futhark_internal.h"
#include "fmpi_error.h"
#include "generic/fmpi_futhark_generic.h"
/*==============================================================================
STRUCT
==============================================================================*/
struct fmpi_ctx;
/*------------------------------------------------------------------------------
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
==============================================================================*/
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_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()
------------------------------------------------------------------------------*/
......@@ -46,8 +116,7 @@ void fmpi_futhark_sync(struct fmpi_ctx * const ctx);
* 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.
* @param[in] func : Function name.
*
* @return
* - `true` if an error is detected.
......@@ -55,16 +124,56 @@ void fmpi_futhark_sync(struct fmpi_ctx * const ctx);
*
* @warning
* - \p{ctx} must be a valid pointer allocated with fmpi_init().
* - \p{func_name} must not be `NULL`.
* - \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
* }
*/
_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)
#define fmpi_futhark_free_1d(ctx, array, length) \
FMPI_GENERIC_FUNC(array, free_1d, FMPI_FUTHARK_TYPES)(ctx, array)
/*==============================================================================
GUARD
==============================================================================*/
......
......@@ -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
==============================================================================*/
......
......@@ -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;
}
/*------------------------------------------------------------------------------
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()");
futhark_context_free((*ctx)->ctx);
futhark_context_config_free((*ctx)->cfg);
free(*ctx); *ctx = NULL;
return err_id;
}
/*------------------------------------------------------------------------------
fmpi_futhark_has_error()
fmpi_futhark_sync()
------------------------------------------------------------------------------*/
_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) \
{ \
#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 * 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) \
{ \
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);\
futhark_free_##T##_1d(ctx->futhark, array); \
fmpi_futhark_abort_on_error(ctx, CPL_STRINGIFY(futhark_free_##T##_1d())); \
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)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment