From 82938e88d621908a59121ecae93c4db5a039e322 Mon Sep 17 00:00:00 2001 From: "raphael.bach" <raphael.bach@etu.hesge.ch> Date: Mon, 20 Dec 2021 16:24:02 +0100 Subject: [PATCH] Well no atomic commits for this project I guess --- Doxyfile | 4 +- Makefile | 10 +- external/cpl/cpl_type.h | 11 ++ external/cpl/cpl_util.h | 3 + futharkmpi_fut.fut | 7 - include/fmpi.h | 38 +++++ include/fmpi_ctx.h | 50 ++++++ include/fmpi_futhark.h | 71 ++++++++ include/{futharkmpi.h => fmpi_mpi.h} | 42 ++--- include/fmpi_reduce.h | 59 +++++++ include/internal/fmpi_futhark_internal.h | 59 +++++++ include/internal/fmpi_generic.h | 141 ++++++++++++++++ include/internal/fmpi_reduce_internal.h | 51 ++++++ makefiles/tools.mk | 11 +- notes | 49 ++++++ src/fmpi_ctx.c | 135 +++++++++++++++ src/fmpi_futhark.c | 145 ++++++++++++++++ src/fmpi_mpi.c | 194 ++++++++++++++++++++++ src/fmpi_reduce.c | 83 +++++++++ src/futhark/fmpi_c_types.fut | 49 ++++++ src/futhark/fmpi_fut.fut | 17 ++ src/futhark/fmpi_module_reduce.fut | 33 ++++ src/futhark/fmpi_reduce.fut | 10 ++ src/futharkmpi.c | 203 ----------------------- src/main.c | 48 +++--- tool/gen_futhark.py | 51 +++++- types | 13 -- 27 files changed, 1288 insertions(+), 299 deletions(-) delete mode 100644 futharkmpi_fut.fut create mode 100644 include/fmpi.h create mode 100644 include/fmpi_ctx.h create mode 100644 include/fmpi_futhark.h rename include/{futharkmpi.h => fmpi_mpi.h} (62%) create mode 100644 include/fmpi_reduce.h create mode 100644 include/internal/fmpi_futhark_internal.h create mode 100644 include/internal/fmpi_generic.h create mode 100644 include/internal/fmpi_reduce_internal.h create mode 100644 notes create mode 100644 src/fmpi_ctx.c create mode 100644 src/fmpi_futhark.c create mode 100644 src/fmpi_mpi.c create mode 100644 src/fmpi_reduce.c create mode 100644 src/futhark/fmpi_c_types.fut create mode 100644 src/futhark/fmpi_fut.fut create mode 100644 src/futhark/fmpi_module_reduce.fut create mode 100644 src/futhark/fmpi_reduce.fut delete mode 100644 src/futharkmpi.c delete mode 100644 types diff --git a/Doxyfile b/Doxyfile index b9a1128..5879167 100644 --- a/Doxyfile +++ b/Doxyfile @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Fuhtarkmpi" +PROJECT_NAME = "Futharkmpi" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -969,7 +969,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = dep +EXCLUDE = build EXCLUDE += include/generated EXCLUDE += include/impl EXCLUDE += test diff --git a/Makefile b/Makefile index aed4cca..021ab97 100644 --- a/Makefile +++ b/Makefile @@ -23,12 +23,12 @@ CC_ERROR := $(filter-out -pedantic-errors,$(CC_ERROR)) include $(MAKEFILE_PATH)/targets.mk .PHONY: futharkc -futharkc: src/futharkmpi_fut.c +futharkc: src/fmpi_fut.c -src/futharkmpi_fut.c: futharkmpi_fut.fut - futhark c futharkmpi_fut.fut --library - mv futharkmpi_fut.h $(INC_PATH) - mv futharkmpi_fut.c $(SRC_PATH) +src/fmpi_fut.c: src/futhark/fmpi_fut.fut + futhark c src/futhark/fmpi_fut.fut --library + mv src/futhark/fmpi_fut.h $(INC_PATH)/internal + mv src/futhark/fmpi_fut.c $(SRC_PATH) # Call the program with `mpirun` RUN_CMD := $(RUN_CMD:%=mpirun %) diff --git a/external/cpl/cpl_type.h b/external/cpl/cpl_type.h index 56b22e2..6eea237 100644 --- a/external/cpl/cpl_type.h +++ b/external/cpl/cpl_type.h @@ -728,6 +728,17 @@ #define CPL_TYPE_SCALAR_ABBR \ CPL_TYPE_ARITHMETIC_ABBR, \ CPL_TYPE_ARITHMETIC_PTR_ABBR + +#define CPL_TYPE_PFMT_int8_t PRIi8 +#define CPL_TYPE_PFMT_int16_t PRIi16 +#define CPL_TYPE_PFMT_int32_t PRIi32 +#define CPL_TYPE_PFMT_int64_t PRIi64 +#define CPL_TYPE_PFMT_uint8_t PRIu8 +#define CPL_TYPE_PFMT_uint16_t PRIu16 +#define CPL_TYPE_PFMT_uint32_t PRIu32 +#define CPL_TYPE_PFMT_uint64_t PRIu64 +#define CPL_TYPE_PFMT_float "f" +#define CPL_TYPE_PFMT_double "f" /*============================================================================== GUARD ==============================================================================*/ diff --git a/external/cpl/cpl_util.h b/external/cpl/cpl_util.h index 5e51022..b81e514 100644 --- a/external/cpl/cpl_util.h +++ b/external/cpl/cpl_util.h @@ -45,6 +45,9 @@ * } */ #define CPL_DEFER(M, ...) M(__VA_ARGS__) + +#define CPL_STRINGIFY(...) CPL_STRINGIFY_RAW(__VA_ARGS__) +#define CPL_STRINGIFY_RAW(...) #__VA_ARGS__ /*============================================================================== GUARD ==============================================================================*/ diff --git a/futharkmpi_fut.fut b/futharkmpi_fut.fut deleted file mode 100644 index 97bbe35..0000000 --- a/futharkmpi_fut.fut +++ /dev/null @@ -1,7 +0,0 @@ -import "./futharkmpi_reduce" --- Reduce Range -entry reduce_range_add (a: f64) (b: f64): f64 = f64.i64 (reduce (+) 0 (i64.f64 a ... i64.f64 b)) -entry reduce_range_mul (a: f64) (b: f64): f64 = f64.i64 (reduce (*) 1 (i64.f64 a ... i64.f64 b)) --- Reduce Array -entry reduce_array_add (xs: []f64): f64 = reduce (+) 0 xs -entry reduce_array_mul (xs: []f64): f64 = reduce (*) 1 xs diff --git a/include/fmpi.h b/include/fmpi.h new file mode 100644 index 0000000..682ff2d --- /dev/null +++ b/include/fmpi.h @@ -0,0 +1,38 @@ +// 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_H_20211124145123 +#define FMPI_H_20211124145123 +/*============================================================================== + INCLUDE +==============================================================================*/ +// Internal +#include "fmpi_ctx.h" +#include "fmpi_futhark.h" +#include "fmpi_mpi.h" +#include "fmpi_reduce.h" +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_H_20211124145123 diff --git a/include/fmpi_ctx.h b/include/fmpi_ctx.h new file mode 100644 index 0000000..9a0c582 --- /dev/null +++ b/include/fmpi_ctx.h @@ -0,0 +1,50 @@ +// 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_INIT_H_20211218002623 +#define FMPI_INIT_H_20211218002623 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +// External +// Internal +/*============================================================================== + STRUCT +==============================================================================*/ +struct fmpi_ctx { + struct fmpi_mpi_ctx * mpi; + struct futhark_context_config * futhark_cfg; + struct futhark_context * futhark; +}; +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +struct fmpi_ctx * fmpi_init(int * argc, char ** argv[]); +void fmpi_exit(struct fmpi_ctx * ctx); +_Noreturn void fmpi_abort(struct fmpi_ctx * ctx); +struct fmpi_ctx * fmpi_ctx_create(void); +void fmpi_ctx_destroy(struct fmpi_ctx ** const ctx); +void fmpi_ctx_print(const struct fmpi_ctx * const ctx); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_INIT_H_20211218002623 diff --git a/include/fmpi_futhark.h b/include/fmpi_futhark.h new file mode 100644 index 0000000..c7bf37d --- /dev/null +++ b/include/fmpi_futhark.h @@ -0,0 +1,71 @@ +// 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/futharkmpi.h b/include/fmpi_mpi.h similarity index 62% rename from include/futharkmpi.h rename to include/fmpi_mpi.h index d30a8c5..90ede0e 100644 --- a/include/futharkmpi.h +++ b/include/fmpi_mpi.h @@ -19,48 +19,42 @@ /*============================================================================== GUARD ==============================================================================*/ -#ifndef FUTHARKMPI_H_20211124145123 -#define FUTHARKMPI_H_20211124145123 +#ifndef FMPI_MPI_H_20211219234201 +#define FMPI_MPI_H_20211219234201 /*============================================================================== INCLUDE ==============================================================================*/ // C Standard Library // External -#include <mpi.h> +#include <mpi.h> // MPI_MAX_PROCESSOR_NAME // Internal -#include "futharkmpi_fut.h" -/*============================================================================== - DEFINE -==============================================================================*/ -#define FUTHARKMPI_ADD 0 -#define FUTHARKMPI_MUL 1 /*============================================================================== STRUCT ==============================================================================*/ -struct mpi_ctx { +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 futharkmpi_ctx { - struct mpi_ctx mpi; - struct futhark_context_config * futhark_cfg; - struct futhark_context * futhark; -}; +struct fmpi_ctx; /*============================================================================== PUBLIC FUNCTION ==============================================================================*/ -struct futharkmpi_ctx * futharkmpi_init(int * argc, char ** argv[]); -void futharkmpi_exit(struct futharkmpi_ctx * ctx); -void futharkmpi_print_ctx(struct futharkmpi_ctx * ctx); -double futharkmpi_reduce_mul(struct futharkmpi_ctx * ctx, void * src, MPI_Datatype type); -double futharkmpi_local_range_reduce_add(struct futharkmpi_ctx * ctx, double a, double b); -double futharkmpi_local_range_reduce_mul(struct futharkmpi_ctx * ctx, double a, double b); -double futharkmpi_local_array_reduce_mul(struct futharkmpi_ctx * ctx, double * array); +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 // FUTHARKMPI_H_20211124145123 +#endif // FMPI_MPI_H_20211219234201 diff --git a/include/fmpi_reduce.h b/include/fmpi_reduce.h new file mode 100644 index 0000000..353f338 --- /dev/null +++ b/include/fmpi_reduce.h @@ -0,0 +1,59 @@ +// 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_REDUCE_H_20211218002000 +#define FMPI_REDUCE_H_20211218002000 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +// External +// Internal +#include "fmpi_ctx.h" +#include "internal/fmpi_reduce_internal.h" +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_local_reduce_prod() +------------------------------------------------------------------------------*/ +/** + * Return the locally computed product of all elements in an \p{array}. + * + * @param[in,out] ctx : Pointer to a fmpi_ctx structure. + * @param[in] array : Array to reduce. + * @param[in] length : Length of the \p{array}. + * + * @return The product of all elements in \p{array}. + * + * @warning + * - \p{ctx} must be a valid pointer allocated with fmpi_init(). + * - \p{array} must not be `NULL`. + */ +#define fmpi_local_reduce_prod(ctx, array, length) \ + FMPI_GENERIC_FUNC(array, local_reduce_prod, FMPI_REDUCE_PROD_TYPES)(ctx, array, length) + +#define fmpi_reduce_prod(ctx, array) \ + FMPI_GENERIC_FUNC(array, reduce_prod, FMPI_REDUCE_PROD_TYPES)(ctx, array) +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_REDUCE_H_20211218002000 diff --git a/include/internal/fmpi_futhark_internal.h b/include/internal/fmpi_futhark_internal.h new file mode 100644 index 0000000..824c88b --- /dev/null +++ b/include/internal/fmpi_futhark_internal.h @@ -0,0 +1,59 @@ +// 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_INTERNAL_H_20211219235241 +#define FMPI_FUTHARK_INTERNAL_H_20211219235241 +/*============================================================================== + INCLUDE +==============================================================================*/ +// Internal +#include "fmpi_ctx.h" +#include "fmpi_generic.h" +/*============================================================================== + MACRO +==============================================================================*/ +#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) + +FMPI_DECLARE_FUNC( + FMPI_PROTO_NEW_1D, FMPI_FUTHARK_TYPES +); +FMPI_DECLARE_FUNC( + FMPI_PROTO_FREE_1D, FMPI_FUTHARK_TYPES +); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_FUTHARK_INTERNAL_H_20211219235241 diff --git a/include/internal/fmpi_generic.h b/include/internal/fmpi_generic.h new file mode 100644 index 0000000..40d0edf --- /dev/null +++ b/include/internal/fmpi_generic.h @@ -0,0 +1,141 @@ +// 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_GENERIC_H_20211201184118 +#define FMPI_GENERIC_H_20211201184118 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +#include <inttypes.h> +#include <stdint.h> +// External +#include "../external/cpl/cpl_concat.h" +#include "../external/cpl/cpl_logic.h" +#include "../external/cpl/cpl_map.h" +#include "../external/cpl/cpl_token.h" +#include "../external/cpl/cpl_type.h" +#include "../external/cpl/cpl_util.h" +// Internal +/*============================================================================== + TYPEDEF +==============================================================================*/ +// Match C type name with Futhark type name +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +//typedef _Bool bool; +/*============================================================================== + MACRO +==============================================================================*/ +#define FMPI_TYPE_SIGNED \ + i8, \ + i16, \ + i32, \ + i64 + +#define FMPI_TYPE_UNSIGNED \ + u8, \ + u16, \ + u32, \ + u64 + +#define FMPI_TYPE_INTEGER \ + FMPI_TYPE_SIGNED, \ + FMPI_TYPE_UNSIGNED + +#define FMPI_TYPE_FLOATING \ + f32, \ + f64 + +#define FMPI_TYPE_REAL \ + FMPI_TYPE_INTEGER, \ + FMPI_TYPE_FLOATING + +#define FMPI_TYPE_BOOLEAN \ + bool + +#define FMPI_TYPE_ALL \ + FMPI_TYPE_REAL, \ + FMPI_TYPE_BOOLEAN + +#define FMPI_DEFAULT_VALUE_i8 0 +#define FMPI_DEFAULT_VALUE_i16 0 +#define FMPI_DEFAULT_VALUE_i32 0 +#define FMPI_DEFAULT_VALUE_i64 0 +#define FMPI_DEFAULT_VALUE_u8 0 +#define FMPI_DEFAULT_VALUE_u16 0 +#define FMPI_DEFAULT_VALUE_u32 0 +#define FMPI_DEFAULT_VALUE_u64 0 +#define FMPI_DEFAULT_VALUE_f32 0.0f +#define FMPI_DEFAULT_VALUE_f64 0.0 +//#define FMPI_DEFAULT_VALUE_bool false + +#define FMPI_PFMT(T) \ + CPL_CONCAT_2(CPL_TYPE_PFMT_, T) + +#define FMPI_MPI_DATATYPE_i8 MPI_INT8_T +#define FMPI_MPI_DATATYPE_i16 MPI_INT16_T +#define FMPI_MPI_DATATYPE_i32 MPI_INT32_T +#define FMPI_MPI_DATATYPE_i64 MPI_INT64_T +#define FMPI_MPI_DATATYPE_u8 MPI_UINT8_T +#define FMPI_MPI_DATATYPE_u16 MPI_UINT16_T +#define FMPI_MPI_DATATYPE_u32 MPI_UINT32_T +#define FMPI_MPI_DATATYPE_u64 MPI_UINT64_T +#define FMPI_MPI_DATATYPE_f32 MPI_FLOAT +#define FMPI_MPI_DATATYPE_f64 MPI_DOUBLE +//#define FMPI_MPI_DATATYPE_bool MPI_C_BOOL + +#define FMPI_GENERIC_ASSOC(FUNC, TYPE) \ + TYPE : fmpi_##FUNC##_##TYPE + +#define FMPI_GENERIC_ASSOC_FUTHARK(FUNC, DIM, TYPE) \ + TYPE : fmpi_##FUNC##_##TYPE##_##DIM + +#define FMPI_GENERIC_FUNC(CTR_EXPR, FUNC, ...) \ + _Generic((*CTR_EXPR), default: 0, \ + CPL_MAP_FIXED(FMPI_GENERIC_ASSOC, CPL_COMMA, (FUNC), __VA_ARGS__)\ + ) + +#define FMPI_GENERIC_FUNC_FUTHARK(CTR_EXPR, FUNC, DIM, ...) \ + _Generic((*CTR_EXPR), default: 0, \ + CPL_MAP_FIXED(FMPI_GENERIC_ASSOC_FUTHARK, CPL_COMMA, (FUNC, DIM), __VA_ARGS__)\ + ) + +#define FMPI_DECLARE_FUNC(FUNC, ...) \ + CPL_MAP(FUNC, CPL_SEMICOLON, __VA_ARGS__) + +#define FMPI_DEFINE_FUNC(FUNC, ...) \ + CPL_MAP(FUNC, CPL_EMPTY, __VA_ARGS__) +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_GENERIC_H_20211201184118 diff --git a/include/internal/fmpi_reduce_internal.h b/include/internal/fmpi_reduce_internal.h new file mode 100644 index 0000000..968c106 --- /dev/null +++ b/include/internal/fmpi_reduce_internal.h @@ -0,0 +1,51 @@ +// 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_REDUCE_IMPL_H_20211218005919 +#define FMPI_REDUCE_IMPL_H_20211218005919 +/*============================================================================== + INCLUDE +==============================================================================*/ +// Internal +#include "fmpi_ctx.h" +#include "fmpi_generic.h" +/*============================================================================== + MACRO +==============================================================================*/ +#define FMPI_REDUCE_PROD_TYPES \ + FMPI_TYPE_REAL + +#define FMPI_PROTO_LOCAL_REDUCE_PROD(T) \ + T fmpi_local_reduce_prod_##T(struct fmpi_ctx * const ctx, T * const array, int length) + +#define FMPI_PROTO_REDUCE_PROD(T) \ + T fmpi_reduce_prod_##T(struct fmpi_ctx * const ctx, T * const array) + +FMPI_DECLARE_FUNC( + FMPI_PROTO_LOCAL_REDUCE_PROD, FMPI_REDUCE_PROD_TYPES +); +FMPI_DECLARE_FUNC( + FMPI_PROTO_REDUCE_PROD, FMPI_REDUCE_PROD_TYPES +); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // FMPI_REDUCE_IMPL_H_20211218005919 diff --git a/makefiles/tools.mk b/makefiles/tools.mk index 5b08745..8c7882a 100644 --- a/makefiles/tools.mk +++ b/makefiles/tools.mk @@ -55,15 +55,8 @@ endif ################################################################################ # Output path for data generated by doxygen [R] DOXYGEN_PATH_OUT = $(DOC_PATH)/doxygen -# Executable name [R] -LD_LIBRARY_PATH += /home/user1/app/llvm-project/lib -DOXYGEN_EXEC := LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) doxygen -# Doxygen command ran by the `doc` target [+] -DOXYGEN_CMD = $(DOXYGEN_EXEC) -ifneq ($(shell which $(DOXYGEN_EXEC)),) -#DOC_CMD += $(DOXYGEN_CMD) -#DOC_DIR_DEPS += $(DOXYGEN_PATH_OUT) -endif +DOC_DIR_DEPS += $(DOXYGEN_PATH_OUT) +DOC_CMD += doxygen ################################################################################ # GCOV ################################################################################ diff --git a/notes b/notes new file mode 100644 index 0000000..f65e4bb --- /dev/null +++ b/notes @@ -0,0 +1,49 @@ +========== FUTHARK ============================================================= +Return code: + - 0 on success + - non-zero or NULL on failure + +futhark_context_get_error(): + - Returned string must be free() manually + +futhark_context_free() + - futhark_context_sync() must be called right before + +futhark_new_*(): + - Asynchronous -> futhark_context_sync() must be called before using the + return value. + +futhark_values_*() + - Asynchronous -> futhark_context_sync() must be called before using the + return value. + +futhark_entry_*() + - Asynchronous -> futhark_context_sync() must be called before using the + return value. + - Check return code of both futhark_entry_*() AND futhark_context_sync() + +========== MPI ================================================================= +MPI_Error_class(): + - Thread-safe + - Can be called before MPI is initialized + - Can be called after MPI is finalized + +MPI_Error_string(): + - Thread-safe + - Can be called before MPI is initialized + - Can be called after MPI is finalized + +========== MISC ================================================================ + MPI | C | Futhark +-------------+----------+--------- +MPI_C_BOOL | _Bool | bool +MPI_INT8_T | int8_t | i8 +MPI_INT16_T | int16_t | i16 +MPI_INT32_T | int32_t | i32 +MPI_INT64_T | int64_t | i64 +MPI_UINT8_T | uint8_t | u8 +MPI_UINT16_T | uint16_t | u16 +MPI_UINT32_T | uint32_t | u32 +MPI_UINT64_T | uint64_t | u64 +MPI_FLOAT | float | f32 +MPI_DOUBLE | double | f64 diff --git a/src/fmpi_ctx.c b/src/fmpi_ctx.c new file mode 100644 index 0000000..c55cfcf --- /dev/null +++ b/src/fmpi_ctx.c @@ -0,0 +1,135 @@ +// 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. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_ctx.h" +// C Standard Library +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +// Internal +#include "fmpi_futhark.h" +#include "fmpi_mpi.h" +#include "internal/fmpi_fut.h" +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + fmpi_init() +------------------------------------------------------------------------------*/ +struct fmpi_ctx * fmpi_init(int * argc, char ** argv[]) +{ + struct fmpi_ctx * ctx = fmpi_ctx_create(); + if(ctx == NULL) { + fprintf(stderr, "fmpi_ctx_create(fmpi_ctx) failed!\n"); + return NULL; + } + + ctx->mpi = fmpi_mpi_init(argc, argv); + if(ctx->mpi == NULL) { + fprintf(stderr, "fmpi_mpi_init() failed!\n"); + fmpi_ctx_destroy(&ctx); + return NULL; + } + + const int err_id = fmpi_futhark_init(ctx); + if(err_id != MPI_SUCCESS) { + fprintf(stderr, "fmpi_futhark_init() failed!\n"); + fmpi_ctx_destroy(&ctx); + return NULL; + } + return ctx; +} +/*------------------------------------------------------------------------------ + fmpi_exit() +------------------------------------------------------------------------------*/ +void fmpi_exit(struct fmpi_ctx * ctx) +{ + assert(ctx != NULL); + + fmpi_futhark_exit(ctx); + fmpi_mpi_destroy(&ctx->mpi); + fmpi_mpi_exit(ctx->mpi); + fmpi_ctx_destroy(&ctx); +} +/*------------------------------------------------------------------------------ + fmpi_abort() +------------------------------------------------------------------------------*/ +_Noreturn void fmpi_abort(struct fmpi_ctx * ctx) +{ + if(ctx != NULL) { + fmpi_futhark_exit(ctx); + fmpi_mpi_destroy(&ctx->mpi); + fmpi_ctx_destroy(&ctx); + } + fmpi_mpi_abort(NULL); + abort(); +} +/*------------------------------------------------------------------------------ + fmpi_ctx_create() +------------------------------------------------------------------------------*/ +struct fmpi_ctx * fmpi_ctx_create(void) +{ + struct fmpi_ctx * ctx = malloc(sizeof(*ctx)); + if(ctx == NULL) { + fprintf(stderr, "malloc(fmpi_ctx) failed!\n"); + return NULL; + } + ctx->mpi = NULL; + ctx->futhark_cfg = NULL; + ctx->futhark = NULL; + return ctx; +} +/*------------------------------------------------------------------------------ + fmpi_ctx_create() +------------------------------------------------------------------------------*/ +void fmpi_ctx_destroy(struct fmpi_ctx ** const ctx) +{ + assert(ctx != NULL); + assert(*ctx != NULL); + + if((*ctx)->futhark_cfg != NULL && (*ctx)->futhark != NULL) { + fmpi_futhark_exit(*ctx); + } + /*if((*ctx)->mpi != NULL) { + fmpi_mpi_exit(*ctx); + }*/ + free((*ctx)->mpi); + (*ctx)->mpi = NULL; + free(*ctx); + *ctx = NULL; +} +/*------------------------------------------------------------------------------ + fmpi_ctx_print() +------------------------------------------------------------------------------*/ +void fmpi_ctx_print(const struct fmpi_ctx * const ctx) +{ + assert(ctx != NULL); + + if(ctx->mpi != NULL) { + fmpi_mpi_ctx_print(ctx->mpi); + } +} +/*============================================================================== + PRIVATE FUNCTION +==============================================================================*/ diff --git a/src/fmpi_futhark.c b/src/fmpi_futhark.c new file mode 100644 index 0000000..b3d84d4 --- /dev/null +++ b/src/fmpi_futhark.c @@ -0,0 +1,145 @@ +// 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. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_futhark.h" +// C Standard Library +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#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" +/*============================================================================== + STRUCT +==============================================================================*/ +/*============================================================================== + 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; + } + 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; + } + return MPI_SUCCESS; +} +/*------------------------------------------------------------------------------ + fmpi_futhark_exit() +------------------------------------------------------------------------------*/ +void fmpi_futhark_exit(struct fmpi_ctx * const ctx) +{ + assert(ctx != NULL); + assert(ctx->futhark_cfg != NULL); + assert(ctx->futhark != NULL); + + fmpi_futhark_sync(ctx); + futhark_context_free(ctx->futhark); + ctx->futhark = NULL; + futhark_context_config_free(ctx->futhark_cfg); + ctx->futhark_cfg = NULL; +} +/*------------------------------------------------------------------------------ + 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) +{ + 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; + } + return 0; +} +/*------------------------------------------------------------------------------ + fmpi_futhark_abort_on_error() +------------------------------------------------------------------------------*/ +void fmpi_futhark_abort_on_error(struct fmpi_ctx * ctx, const char * const func_name) +{ + assert(ctx != NULL); + if(fmpi_futhark_has_error(ctx, func_name)) { + fmpi_abort(ctx); + } +} +/*------------------------------------------------------------------------------ + 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())); \ +} + +FMPI_DEFINE_FUNC(FMPI_DEFINE_NEW_1D, FMPI_FUTHARK_TYPES) +FMPI_DEFINE_FUNC(FMPI_DEFINE_FREE_1D, FMPI_FUTHARK_TYPES) diff --git a/src/fmpi_mpi.c b/src/fmpi_mpi.c new file mode 100644 index 0000000..cc78b47 --- /dev/null +++ b/src/fmpi_mpi.c @@ -0,0 +1,194 @@ +// 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. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_mpi.h" +// C Standard Library +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +// External +#include <mpi.h> +// Internal +#include "fmpi_ctx.h" +/*============================================================================== + DEFINE +==============================================================================*/ +#define FMPI_MPI_RANK_ROOT_DEFAULT 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); + if(ctx == NULL) { + fprintf(stderr, "fmpi_mpi_create() failed!\n"); + return NULL; + } + + int err_id = MPI_Init(argc, argv); + if(fmpi_mpi_has_error(ctx, err_id, "MPI_Init()")) { + fmpi_mpi_destroy(&ctx); return NULL; + } + 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; + } + 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. + 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; + } + 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) +{ + 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); + } +} +/*------------------------------------------------------------------------------ + fmpi_mpi_is_root() +------------------------------------------------------------------------------*/ +_Bool fmpi_mpi_is_root(const struct fmpi_mpi_ctx * const ctx) +{ + assert(ctx != NULL); + return ctx->rank == ctx->root; +} +/*------------------------------------------------------------------------------ + fmpi_mpi_has_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; + } + if(err_id != MPI_SUCCESS) { + char err_array[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; + } + 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; +} +/*------------------------------------------------------------------------------ + fmpi_mpi_ctx_print() +------------------------------------------------------------------------------*/ +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); + printf("MPI root: %s\n", ctx->cpu_name); + printf("MPI futhark error class: %d\n", ctx->futhark_err_class); + printf("MPI futhark error code: %d\n", ctx->futhark_err_code); +} diff --git a/src/fmpi_reduce.c b/src/fmpi_reduce.c new file mode 100644 index 0000000..2eca439 --- /dev/null +++ b/src/fmpi_reduce.c @@ -0,0 +1,83 @@ +// 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. + * } + */ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "fmpi_reduce.h" +// C Standard Library +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +// Internal +#include "fmpi_futhark.h" +#include "fmpi_mpi.h" +#include "internal/fmpi_fut.h" +#include "internal/fmpi_generic.h" +/*============================================================================== + STRUCT +==============================================================================*/ +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +#define FMPI_DEFINE_LOCAL_REDUCE_PROD(T) \ +FMPI_PROTO_LOCAL_REDUCE_PROD(T) \ +{ \ + assert(ctx != NULL); \ + assert(array != NULL); \ + \ + struct futhark_##T##_1d * xs = fmpi_new_##T##_1d(ctx, array, length);\ + T result = FMPI_DEFAULT_VALUE_##T; \ + futhark_entry_reduce_prod_##T(ctx->futhark, &result, xs); \ + fmpi_futhark_abort_on_error(ctx, CPL_STRINGIFY(futhark_entry_reduce_prod_##T())); \ + fmpi_futhark_sync(ctx); \ + fmpi_free_##T##_1d(ctx, xs); \ + return result; \ +} + +#define FMPI_DEFINE_REDUCE_PROD(T) \ +FMPI_PROTO_REDUCE_PROD(T) \ +{ \ + assert(ctx != NULL); \ + assert(array != NULL); \ + \ + T result = FMPI_DEFAULT_VALUE_##T; \ + /*! @cast MPI uses `int` for `size`. */ \ + /* Casting `int` to `size_t` should be safe if the value isn't negative. */ \ + /* This is asserted in`fmpi_init()`.*/ \ + T * fact_global = malloc((size_t)ctx->mpi->size * sizeof(*fact_global)); \ + if(fact_global == NULL) { \ + fprintf(stderr, "malloc(fact_global) failed!\n"); \ + } \ + int err_id = MPI_Gather(array, 1, FMPI_MPI_DATATYPE_##T, fact_global, 1, FMPI_MPI_DATATYPE_##T, ctx->mpi->root, MPI_COMM_WORLD); \ + if(fmpi_mpi_has_error(ctx->mpi, err_id, "MPI_Gather()")) { \ + free(fact_global); \ + fmpi_abort(ctx); \ + } \ + if(fmpi_mpi_is_root(ctx->mpi)) { \ + result = fmpi_local_reduce_prod_##T(ctx, fact_global, ctx->mpi->size); \ + } \ + free(fact_global); \ + return result; \ +} + +FMPI_DEFINE_FUNC(FMPI_DEFINE_LOCAL_REDUCE_PROD, FMPI_REDUCE_PROD_TYPES) +FMPI_DEFINE_FUNC(FMPI_DEFINE_REDUCE_PROD, FMPI_REDUCE_PROD_TYPES) diff --git a/src/futhark/fmpi_c_types.fut b/src/futhark/fmpi_c_types.fut new file mode 100644 index 0000000..c8fe63e --- /dev/null +++ b/src/futhark/fmpi_c_types.fut @@ -0,0 +1,49 @@ +-- SPDX-License-Identifier: 0BSD +-- +-- @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. +-- } +entry make_futhark_i8_1d (xs: []i8): i8 = 0 +entry make_futhark_i8_2d (xs: [][]i8): i8 = 0 +entry make_futhark_i8_3d (xs: [][][]i8): i8 = 0 +entry make_futhark_i16_1d (xs: []i16): i16 = 0 +entry make_futhark_i16_2d (xs: [][]i16): i16 = 0 +entry make_futhark_i16_3d (xs: [][][]i16): i16 = 0 +entry make_futhark_i32_1d (xs: []i32): i32 = 0 +entry make_futhark_i32_2d (xs: [][]i32): i32 = 0 +entry make_futhark_i32_3d (xs: [][][]i32): i32 = 0 +entry make_futhark_i64_1d (xs: []i64): i64 = 0 +entry make_futhark_i64_2d (xs: [][]i64): i64 = 0 +entry make_futhark_i64_3d (xs: [][][]i64): i64 = 0 +entry make_futhark_u8_1d (xs: []u8): u8 = 0 +entry make_futhark_u8_2d (xs: [][]u8): u8 = 0 +entry make_futhark_u8_3d (xs: [][][]u8): u8 = 0 +entry make_futhark_u16_1d (xs: []u16): u16 = 0 +entry make_futhark_u16_2d (xs: [][]u16): u16 = 0 +entry make_futhark_u16_3d (xs: [][][]u16): u16 = 0 +entry make_futhark_u32_1d (xs: []u32): u32 = 0 +entry make_futhark_u32_2d (xs: [][]u32): u32 = 0 +entry make_futhark_u32_3d (xs: [][][]u32): u32 = 0 +entry make_futhark_u64_1d (xs: []u64): u64 = 0 +entry make_futhark_u64_2d (xs: [][]u64): u64 = 0 +entry make_futhark_u64_3d (xs: [][][]u64): u64 = 0 +entry make_futhark_f32_1d (xs: []f32): f32 = 0 +entry make_futhark_f32_2d (xs: [][]f32): f32 = 0 +entry make_futhark_f32_3d (xs: [][][]f32): f32 = 0 +entry make_futhark_f64_1d (xs: []f64): f64 = 0 +entry make_futhark_f64_2d (xs: [][]f64): f64 = 0 +entry make_futhark_f64_3d (xs: [][][]f64): f64 = 0 +entry make_futhark_bool_1d (xs: []bool): bool = true +entry make_futhark_bool_2d (xs: [][]bool): bool = true +entry make_futhark_bool_3d (xs: [][][]bool): bool = true diff --git a/src/futhark/fmpi_fut.fut b/src/futhark/fmpi_fut.fut new file mode 100644 index 0000000..ed1e76b --- /dev/null +++ b/src/futhark/fmpi_fut.fut @@ -0,0 +1,17 @@ +--import "futharkmpi_reduce" +-- Reduce Range +entry reduce_range_add (a: f64) (b: f64): f64 = f64.i64 (reduce (+) 0 (i64.f64 a ... i64.f64 b)) +entry reduce_range_prod (a: f64) (b: f64): f64 = f64.i64 (reduce (*) 1 (i64.f64 a ... i64.f64 b)) +-- Reduce Array +entry reduce_array_add (xs: []f64): f64 = reduce (+) 0 xs + +entry reduce_prod_i8 (xs: []i8): i8 = i8.product xs +entry reduce_prod_i16 (xs: []i16): i16 = i16.product xs +entry reduce_prod_i32 (xs: []i32): i32 = i32.product xs +entry reduce_prod_i64 (xs: []i64): i64 = i64.product xs +entry reduce_prod_u8 (xs: []u8): u8 = u8.product xs +entry reduce_prod_u16 (xs: []u16): u16 = u16.product xs +entry reduce_prod_u32 (xs: []u32): u32 = u32.product xs +entry reduce_prod_u64 (xs: []u64): u64 = u64.product xs +entry reduce_prod_f32 (xs: []f32): f32 = f32.product xs +entry reduce_prod_f64 (xs: []f64): f64 = f64.product xs diff --git a/src/futhark/fmpi_module_reduce.fut b/src/futhark/fmpi_module_reduce.fut new file mode 100644 index 0000000..7a0fb8d --- /dev/null +++ b/src/futhark/fmpi_module_reduce.fut @@ -0,0 +1,33 @@ +-- Default operations for MPI_Reduce() +-- See https://www.open-mpi.org/doc/current/man3/MPI_Reduce.3.php#sect10 +local module type local_reduce = { + type t + val sum [n]: [n]t -> t + val prod [n]: [n]t -> t + val min [n]: [n]t -> t + val max [n]: [n]t -> t +} + +module module_reduce (T: numeric): local_reduce with t = T.t = { + type t = T.t + let sum [n] (xs: [n]t): t = T.sum xs + let prod [n] (xs: [n]t): t = T.product xs + let min [n] (xs: [n]t): t = T.minimum xs + let max [n] (xs: [n]t): t = T.maximum xs +} + + +-- #[generic=all] +--entry reduce_sum (xs: []f64): f64 = f64.sum xs +--entry reduce_prod (xs: []f64): f64 = f64.product xs +--entry reduce_min (xs: []f64): f64 = f64.minimum xs +--entry reduce_max (xs: []f64): f64 = f64.maximum xs +-- #[generic=integer] +--entry reduce_band (xs: []i64): i64 = reduce (&) 1 xs +--entry reduce_bor (xs: []i64): i64 = reduce (|) 0 xs +--entry reduce_bxor (xs: []i64): i64 reduce (^) xs +--entry reduce_land (xs: []bool): bool = bool.i32 5 +--MPI_LOR logical or +--MPI_LXOR logical xor +--MPI_MAXLOC max value and location +--MPI_MINLOC min value and location diff --git a/src/futhark/fmpi_reduce.fut b/src/futhark/fmpi_reduce.fut new file mode 100644 index 0000000..2feec6c --- /dev/null +++ b/src/futhark/fmpi_reduce.fut @@ -0,0 +1,10 @@ +entry reduce_prod_i8 (xs: []i8): i8 = i8.product xs +entry reduce_prod_i16 (xs: []i16): i16 = i16.product xs +entry reduce_prod_i32 (xs: []i32): i32 = i32.product xs +entry reduce_prod_i64 (xs: []i64): i64 = i64.product xs +entry reduce_prod_u8 (xs: []u8): u8 = u8.product xs +entry reduce_prod_u16 (xs: []u16): u16 = u16.product xs +entry reduce_prod_u32 (xs: []u32): u32 = u32.product xs +entry reduce_prod_u64 (xs: []u64): u64 = u64.product xs +entry reduce_prod_f32 (xs: []f32): f32 = f32.product xs +entry reduce_prod_f64 (xs: []f64): f64 = f64.product xs diff --git a/src/futharkmpi.c b/src/futharkmpi.c deleted file mode 100644 index 5592257..0000000 --- a/src/futharkmpi.c +++ /dev/null @@ -1,203 +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. - * } - */ -/*============================================================================== - INCLUDE -==============================================================================*/ -// Own header -#include "futharkmpi.h" -// C Standard Library -#include <assert.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -// External -#include <mpi.h> -// Internal -#include "futharkmpi_fut.h" -/*============================================================================== - DEFINE -==============================================================================*/ -#define FUTHARKMPI_RANK_ROOT 0 -/*============================================================================== - STRUCT -==============================================================================*/ -extern struct futhark_context_config * futhark_context_config_new(void); -extern void futhark_context_config_free(struct futhark_context_config * cfg); -extern struct futhark_context * futhark_context_new(struct futhark_context_config * cfg); -extern void futhark_context_free(struct futhark_context * ctx); -extern int futhark_context_sync(struct futhark_context * ctx); -extern char * futhark_context_get_error(struct futhark_context * ctx); -/*============================================================================== - PUBLIC FUNCTION -==============================================================================*/ -struct futharkmpi_ctx * futharkmpi_init(int * argc, char ** argv[]) -{ - struct futharkmpi_ctx * ctx = malloc(sizeof(*ctx)); - if(ctx == NULL) { - fprintf(stderr, "malloc(futharkmpi_ctx) failed!\n"); - return NULL; - } - - int err = MPI_Init(argc, argv); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Init() failed!\n"); - goto abort; - } - - int size = 0; - err = MPI_Comm_size(MPI_COMM_WORLD, &size); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Comm_size() failed!\n"); - goto abort; - } - // `size` is used with `malloc()` and `malloc(0)` is implementation-defined. - assert(size > 0); - ctx->mpi.size = size; - - int rank = 0; - err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Comm_rank() failed!\n"); - goto abort; - } - ctx->mpi.rank = rank; - - int cpu_name_length = 0; - err = MPI_Get_processor_name(ctx->mpi.cpu_name, &cpu_name_length); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Get_processor_name() failed!\n"); - goto abort; - } - ctx->mpi.cpu_name_length = cpu_name_length; - - ctx->mpi.root = FUTHARKMPI_RANK_ROOT; - - struct futhark_context_config * futhark_cfg = futhark_context_config_new(); - if(futhark_cfg == NULL) { - fprintf(stderr, "futhark_context_config_new() failed!\n"); - goto abort; - } - ctx->futhark_cfg = futhark_cfg; - - struct futhark_context * futhark_ctx = futhark_context_new(futhark_cfg); - char * error = futhark_context_get_error(futhark_ctx); - if(futhark_ctx == NULL || error != NULL) { - fprintf(stderr, "futhark_context_new() failed!: %s\n", error); - futhark_context_sync(futhark_ctx); - futhark_context_free(futhark_ctx); - futhark_context_config_free(futhark_cfg); - goto abort; - } - ctx->futhark = futhark_ctx; - return ctx; - -abort: - err = MPI_Abort(MPI_COMM_WORLD, err); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Abort() failed!\n"); - } - err = MPI_Finalize(); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Finalize() failed!\n"); - } - return NULL; -} -void futharkmpi_exit(struct futharkmpi_ctx * ctx) -{ - assert(ctx != NULL); - - futhark_context_sync(ctx->futhark); - futhark_context_free(ctx->futhark); - futhark_context_config_free(ctx->futhark_cfg); - - int err = MPI_Finalize(); - if(err != MPI_SUCCESS) { - fprintf(stderr, "MPI_Finalize() failed!\n"); - } - free(ctx); -} -void futharkmpi_print_ctx(struct futharkmpi_ctx * ctx) -{ - assert(ctx != NULL); - - printf("MPI size: %d\n", ctx->mpi.size); - printf("MPI rank: %d\n", ctx->mpi.rank); - printf("MPI CPU name: %s\n", ctx->mpi.cpu_name); -} -double futharkmpi_reduce_mul(struct futharkmpi_ctx * ctx, void * src, MPI_Datatype type) -{ - assert(ctx != NULL); - assert(src != NULL); - - double result = 0.0; - /*! @cast MPI uses `int` for `size`. Casting `int` to `size_t` should be - * safe if the value isn't negative. This is asserted in`futharkmpi_init()`. - */ - double * fact_global = malloc((size_t)ctx->mpi.size * sizeof(*fact_global)); - MPI_Gather(src, 1, type, fact_global, 1, type, ctx->mpi.root, MPI_COMM_WORLD); - if(ctx->mpi.rank == ctx->mpi.root) { - result = futharkmpi_local_array_reduce_mul(ctx, fact_global); - //printf("rank=%d fact_global=%f\n", ctx->mpi.rank, result); - //memcpy(dest, &fact_global, sizeof(fact_global)); - } - free(fact_global); - return result; -} -double futharkmpi_local_range_reduce_add(struct futharkmpi_ctx * ctx, double a, double b) -{ - assert(ctx != NULL); - - double result = 0.0; - int err = futhark_entry_reduce_range_add(ctx->futhark, &result, a, b); - if(err != 0) { - fprintf(stderr, "futhark_entry_reduce_add() failed!: %s\n", futhark_context_get_error(ctx->futhark)); - } - return result; -} -double futharkmpi_local_range_reduce_mul(struct futharkmpi_ctx * ctx, double a, double b) -{ - assert(ctx != NULL); - - double result = 0.0; - int err = futhark_entry_reduce_range_mul(ctx->futhark, &result, a, b); - if(err != 0) { - fprintf(stderr, "futhark_entry_reduce_mul() failed!: %s\n", futhark_context_get_error(ctx->futhark)); - } - return result; -} -double futharkmpi_local_array_reduce_mul(struct futharkmpi_ctx * ctx, double * array) -{ - assert(ctx != NULL); - assert(array != NULL); - - struct futhark_f64_1d * x_arr = futhark_new_f64_1d(ctx->futhark, array, 4); - double result = 0.0; - int err = futhark_entry_reduce_array_mul(ctx->futhark, &result, x_arr); - futhark_context_sync(ctx->futhark); - if(err != 0) { - fprintf(stderr, "futhark_entry_reduce_mul() failed!: %s\n", futhark_context_get_error(ctx->futhark)); - } - return result; -} - - /*for(int i = 0; i < 4; i++) { - printf("fact_global=%f src=%f\n", fact_global, fact_local[i]); - fact_global *= fact_local[i]; - }*/ diff --git a/src/main.c b/src/main.c index e61445d..37221b3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,41 +1,31 @@ - -#include "futharkmpi.h" +#include "fmpi.h" #include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> -#include <mpi.h> - -double fact_chunk(double x, int length); +#define ARRAY_SIZE 16 +#define T double int main(int argc, char * argv[]) { - struct futharkmpi_ctx * ctx = futharkmpi_init(&argc, &argv); + struct fmpi_ctx * ctx = fmpi_init(&argc, &argv); if(ctx == NULL) { - fprintf(stderr, "futharkmpi_init() failed!\n"); - return EXIT_FAILURE; + fprintf(stderr, "fmpi_init() failed!\n"); + fmpi_abort(NULL); } - const double a = (ctx->mpi.rank * ctx->mpi.size) + 1; - const double b = a + ctx->mpi.size - 1; - double fact_local = futharkmpi_local_range_reduce_mul(ctx, a, b); - double fact_global = futharkmpi_reduce_mul(ctx, &fact_local, MPI_DOUBLE); - printf("rank=%d fact_local=%f\n", ctx->mpi.rank, fact_local); - if(ctx->mpi.rank == ctx->mpi.root) { - printf("rank=%d fact_global=%f\n", ctx->mpi.rank, fact_global); - } else { + if(fmpi_mpi_is_root(ctx->mpi)) { + fmpi_ctx_print(ctx); } - futharkmpi_exit(ctx); - return EXIT_SUCCESS; -} - -double fact_chunk(double x, int length) -{ - double result = x; - for(double i = 1; i < length; i++) { - result *= x + i; + const size_t start = (size_t)(ctx->mpi->rank * ctx->mpi->size); + T array[ARRAY_SIZE] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + }; + T fact_local = fmpi_local_reduce_prod(ctx, (array+start), ARRAY_SIZE/ctx->mpi->size); + printf("rank=%d fact_local=%"FMPI_PFMT(T)"\n", ctx->mpi->rank, fact_local); + T fact_global = fmpi_reduce_prod(ctx, &fact_local); + if(fmpi_mpi_is_root(ctx->mpi)) { + printf("rank=%d fact_global=%"FMPI_PFMT(T)"\n", ctx->mpi->rank, fact_global); } - return result; + fmpi_exit(ctx); + return EXIT_SUCCESS; } - - //printf("rank=%d a=%f b=%f fact_chunk=%f\n", ctx->mpi.rank, a, b, fact_local); - //futharkmpi_print_ctx(ctx); diff --git a/tool/gen_futhark.py b/tool/gen_futhark.py index 64bb5ce..e99e197 100644 --- a/tool/gen_futhark.py +++ b/tool/gen_futhark.py @@ -17,7 +17,7 @@ # PERFORMANCE OF THIS SOFTWARE. # } -license_str = """\ +LICENSE_STR = """\ -- SPDX-License-Identifier: 0BSD -- -- @license{ @@ -36,15 +36,52 @@ license_str = """\ -- } """ +OUTPUT_PATH = './' +INPUT_PATH = OUTPUT_PATH DIM_MAX = 3 +FUTHARK_TYPE_LIST = [ + 'i8', 'i16', 'i32', 'i64', + 'u8', 'u16', 'u32', 'u64', + 'f32', 'f64', 'bool' +] +C_TYPE_LIST = [ + 'int8_t', 'int16_t', 'int32_t', 'int64_t', + 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', + 'float', 'double', '_Bool' +] +TYPE_LIST_LENGTH = len(FUTHARK_TYPE_LIST) -def main(args): - f = open('./futharkmpi_c_types.fut', 'w') - f.write(license_str) - type_list = ['i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'bool'] - for type in type_list: +def futharkmpi_c_types(): + str = '' + for type in TYPE_LIST: for i in range (1, DIM_MAX+1): - f.write('entry make_futhark_{type}_{dim}d (xs: {array}{type}): {type} = 0\n'.format(type = type, dim = i, array = i * "[]")) + str += 'entry make_futhark_{type}_{dim}d (xs: {array}{type}): {type} = 0\n'.format(type = type, dim = i, array = i * "[]") + return str + +def futharkmpi_reduce(): + str = 'import "{path}"\n\n'.format(path=INPUT_PATH + 'futharkmpi_module_reduce') + func_list = ['sum', 'prod', 'min', 'max'] + for i in range(TYPE_LIST_LENGTH): + str += 'module reduce_{type} = module_reduce {type}\n'.format(type = FUTHARK_TYPE_LIST[i]) + for func in func_list: + str += 'entry reduce_{func}_{ctype} = reduce_{ftype}.{func}\n'.format(func = func, ctype = C_TYPE_LIST[i], ftype = FUTHARK_TYPE_LIST[i]) + return str + +## +# Create a file and write generated code to it. +# +# @param generator : A function returning a string containing the generated +# code. Its name is used as a prefix for the file name. +def generate_file(generator): + file_name = generator.__name__ + '.fut' + with open(OUTPUT_PATH + file_name, 'w') as fd: + fd.write(LICENSE_STR) + fd.write(generator()) + +def main(args): + generator_list = [futharkmpi_reduce] + for generator in generator_list: + generate_file(generator) return 0 if __name__ == '__main__': diff --git a/types b/types deleted file mode 100644 index c828f7d..0000000 --- a/types +++ /dev/null @@ -1,13 +0,0 @@ - MPI | C | Futhark --------------+----------+--------- -MPI_C_BOOL | _Bool | bool -MPI_INT8_T | int8_t | i8 -MPI_INT16_T | int16_t | i16 -MPI_INT32_T | int32_t | i32 -MPI_INT64_T | int64_t | i64 -MPI_UINT8_T | uint8_t | u8 -MPI_UINT16_T | uint16_t | u16 -MPI_UINT32_T | uint32_t | u32 -MPI_UINT64_T | uint64_t | u64 -MPI_FLOAT | float | f32 -MPI_DOUBLE | double | f64 -- GitLab