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

Refactor `fmpi_mpi` module

parent 69208110
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.
*
......@@ -28,32 +30,136 @@
// External
#include <mpi.h> // MPI_MAX_PROCESSOR_NAME
// Internal
#include "fmpi_error.h"
/*==============================================================================
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;
/*------------------------------------------------------------------------------
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
==============================================================================*/
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);
/*------------------------------------------------------------------------------
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);
_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);
/*------------------------------------------------------------------------------
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
==============================================================================*/
......
......@@ -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)
{
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)
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)) {
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);
}
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;
}
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;
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!");
}
ctx->root = root;
return ctx;
FMPI_RAISE_MPI_ERROR(ctx, "%s() failed! %s", func, err_str);
return true;
}
/*------------------------------------------------------------------------------
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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment