diff --git a/include/internal/fmpi_futhark.h b/include/internal/fmpi_futhark.h
index 92688f779133b38af5eb84639ccc64aff620625d..1e09e3f06f7f3d2925c2d637cde04c2d9c1ef622 100644
--- a/include/internal/fmpi_futhark.h
+++ b/include/internal/fmpi_futhark.h
@@ -29,7 +29,8 @@
 // C Standard Library
 // Internal
 #include "fmpi_error.h"
-#include "generic/fmpi_futhark_generic.h"
+#include "internal/generic/fmpi_futhark_generic.h"
+#include "internal/generic/fmpi_type.h"
 /*==============================================================================
     STRUCT
 ==============================================================================*/
@@ -127,6 +128,13 @@ int fmpi_futhark_sync(const struct fmpi_futhark_ctx * ctx);
  * - \p{func} must not be `NULL`.
  */
 _Bool fmpi_futhark_check_error(const struct fmpi_futhark_ctx * ctx, const char * func);
+/*------------------------------------------------------------------------------
+    fmpi_futhark_new_data()
+------------------------------------------------------------------------------*/
+void * fmpi_futhark_new_data(
+    const struct fmpi_futhark_ctx * ctx, const void * data, enum fmpi_type type,
+    size_t dim_cnt, size_t x, size_t y, size_t z
+);
 /*==============================================================================
    MACRO
 ==============================================================================*/
diff --git a/include/internal/generic/fmpi_futhark_generic.h b/include/internal/generic/fmpi_futhark_generic.h
index f860bafe059ae8dbe77cb6bdaf709cb6b3bfd72c..29732ce2d22fbd357cdf2b7f30a334d4a466aaf6 100644
--- a/include/internal/generic/fmpi_futhark_generic.h
+++ b/include/internal/generic/fmpi_futhark_generic.h
@@ -28,7 +28,10 @@
 ==============================================================================*/
 // C Standard Library
 #include <stddef.h> // size_t
+// External
+#include "../../../external/cpl/cpl_map.h"
 // Internal
+#include "../fmpi_common.h"
 #include "fmpi_generic.h"
 /*==============================================================================
     MACRO
@@ -38,6 +41,12 @@ struct fmpi_futhark_ctx;
 #define FMPI_FUTHARK_TYPES \
     FMPI_TYPE_REAL
 
+#define FMPI_PRIV_FUTHARK_ARRAY_ENTRY(D, T) \
+    [FMPI_TYPE_##T * (FMPI_DIM_MAX) + ((D)-1)] = fmpi_futhark_new_##D##d_##T
+
+#define FMPI_FUTHARK_ARRAY_ENTRY_LIST(D) \
+    CPL_MAP_FIXED(FMPI_PRIV_FUTHARK_ARRAY_ENTRY, CPL_COMMA, (D), FMPI_FUTHARK_TYPES)
+
 #if defined(__GNUC__) || defined(__GNUG__)
     _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
     _Pragma("GCC diagnostic push")
@@ -62,11 +71,11 @@ struct fmpi_futhark_ctx;
     futhark_new_##T##_3d(ctx, array, (int64_t)(x), (int64_t)(y), (int64_t)(z));
 
 #define FMPI_FUTHARK_DECLARATION(D, T) \
-struct futhark_##T##_##D##d * fmpi_futhark_new_##D##d_##T( \
-    const struct fmpi_futhark_ctx * ctx, const T * array, size_t x, size_t y, size_t z \
+void * fmpi_futhark_new_##D##d_##T( \
+    const struct fmpi_futhark_ctx * ctx, const void * array, size_t x, size_t y, size_t z \
 ); \
 void fmpi_futhark_free_##D##d_##T( \
-    const struct fmpi_futhark_ctx * ctx, struct futhark_##T##_##D##d * array \
+    const struct fmpi_futhark_ctx * ctx, void * array \
 )
 
 FMPI_DECLARE_DIM_FUNCS(FMPI_FUTHARK_DECLARATION, 1, FMPI_FUTHARK_TYPES);
diff --git a/src/fmpi_futhark.c b/src/fmpi_futhark.c
index f5a23bdfcc9753ec2b8bb10dcf1c5d6d8ffc0d09..e49b554d1f4c5f4a9f5625b0c0c14807d5e7bca9 100644
--- a/src/fmpi_futhark.c
+++ b/src/fmpi_futhark.c
@@ -29,9 +29,22 @@
 #include <stdint.h> // int64_t
 #include <stdlib.h>
 // Internal
+#include "internal/fmpi_common.h"
 #include "internal/fmpi_ctx.h"
 #include "internal/fmpi_futhark_entry.h"
 #include "internal/generic/fmpi_generic.h"
+/*==============================================================================
+    STATIC
+==============================================================================*/
+typedef void * (*fmpi_futhark_new_data_func)(
+    const struct fmpi_futhark_ctx * ctx, const void * data,
+    size_t x, size_t y, size_t z
+);
+static const fmpi_futhark_new_data_func fmpi_futhark_new_data_func_list[] = {
+   FMPI_FUTHARK_ARRAY_ENTRY_LIST(1),
+   FMPI_FUTHARK_ARRAY_ENTRY_LIST(2),
+   FMPI_FUTHARK_ARRAY_ENTRY_LIST(3)
+};
 /*==============================================================================
     MACRO
 ==============================================================================*/
@@ -127,10 +140,25 @@ _Bool fmpi_futhark_check_error(
     }
     return false;
 }
+/*------------------------------------------------------------------------------
+    fmpi_futhark_new_data()
+------------------------------------------------------------------------------*/
+void * fmpi_futhark_new_data(
+    const struct fmpi_futhark_ctx * ctx, const void * const data,
+    const enum fmpi_type type, const size_t dim_cnt,
+    const size_t x, const size_t y, const size_t z
+){
+    assert(ctx != NULL);
+    assert(data != NULL);
+    assert(dim_cnt <= FMPI_DIM_MAX);
+    const size_t idx = (type * (FMPI_DIM_MAX) + ((dim_cnt)-1));
+    return fmpi_futhark_new_data_func_list[idx](ctx, data, x, y, z);
+}
 
 #define FMPI_FUTHARK_DEFINITION(D, T) \
-struct futhark_##T##_##D##d * fmpi_futhark_new_##D##d_##T( \
-    const struct fmpi_futhark_ctx * const ctx, const T * const array, size_t x, size_t y, size_t z \
+void * fmpi_futhark_new_##D##d_##T( \
+    const struct fmpi_futhark_ctx * const ctx, const void * const array, \
+    const size_t x, const size_t y, const size_t z \
 ){ \
     assert(ctx != NULL); \
     assert(array != NULL); \
@@ -142,7 +170,7 @@ struct futhark_##T##_##D##d * fmpi_futhark_new_##D##d_##T( \
     return data; \
 }\
 void fmpi_futhark_free_##D##d_##T( \
-    const struct fmpi_futhark_ctx * const ctx, struct futhark_##T##_##D##d * const array \
+    const struct fmpi_futhark_ctx * const ctx, void * const array \
 ){ \
     assert(ctx != NULL); \
     assert(array != NULL); \