diff --git a/include/fmpi_core.h b/include/fmpi_core.h
index 40e985c212ad72eb5688b53b4123d4f7493e3d61..10664ddaff56a8d9ac93f510cf7dfda8b8ff4ab9 100644
--- a/include/fmpi_core.h
+++ b/include/fmpi_core.h
@@ -150,12 +150,12 @@ do { \
     FMPI_REGISTER_SYNC_TASK()
 ------------------------------------------------------------------------------*/
 #define FMPI_REGISTER_SYNC_TASK(ctx, func, stencil, ...) \
-    FMPI_TASK_REGISTER_IMPL(func, sync, ctx, stencil, __VA_ARGS__)
+    FMPI_TASK_REGISTER_SYNC_IMPL(func, ctx, stencil, __VA_ARGS__)
 /*------------------------------------------------------------------------------
     FMPI_REGISTER_ASYNC_TASK()
 ------------------------------------------------------------------------------*/
 #define FMPI_REGISTER_ASYNC_TASK(ctx, func, stencil, ...) \
-    FMPI_TASK_REGISTER_IMPL(func, async, ctx, stencil, __VA_ARGS__)
+    FMPI_TASK_REGISTER_ASYNC_IMPL(func, ctx, stencil, __VA_ARGS__)
 /*==============================================================================
     GUARD
 ==============================================================================*/
diff --git a/include/fmpi_task.h b/include/fmpi_task.h
index 39e26cad537fb3f28fadee7ef3896c3425f0dae5..9967f7db60d3bc2612df4816a026419392ee9ac6 100644
--- a/include/fmpi_task.h
+++ b/include/fmpi_task.h
@@ -116,7 +116,7 @@ typedef struct fmpi_task {
     PUBLIC FUNCTION
 ==============================================================================*/
 /*------------------------------------------------------------------------------
-    fmpi_task_register_sync()
+    fmpi_task_register()
 ------------------------------------------------------------------------------*/
 /**
  * TODO
@@ -136,16 +136,10 @@ typedef struct fmpi_task {
  *  TODO
  * }
  */
-struct fmpi_task fmpi_task_register_sync(
+struct fmpi_task fmpi_task_register(
     struct fmpi_ctx * ctx, fmpi_task_func func, const char * name,
-    struct fmpi_stencil stencil, const struct fmpi_task_args * args
-);
-/*------------------------------------------------------------------------------
-    fmpi_task_register_async()
-------------------------------------------------------------------------------*/
-struct fmpi_task fmpi_task_register_async(
-    struct fmpi_ctx * ctx, fmpi_task_func func, const char * name,
-    struct fmpi_stencil stencil, const struct fmpi_task_args * args
+    enum fmpi_task_type type, struct fmpi_stencil stencil,
+    const struct fmpi_task_args * args
 );
 /*------------------------------------------------------------------------------
     fmpi_task_run_sync()
diff --git a/include/internal/generic/fmpi_task_generic.h b/include/internal/generic/fmpi_task_generic.h
index f1624e7dc1155b6f3b2789b2ed6aa96118566cb9..350abd0e6db958d73fcbdf5480892b0bf9e2e6eb 100644
--- a/include/internal/generic/fmpi_task_generic.h
+++ b/include/internal/generic/fmpi_task_generic.h
@@ -73,18 +73,22 @@ _Pragma("GCC diagnostic warning \"-Wincompatible-pointer-types\"")\
         return futhark_entry_##FUNC(ctx, out, FMPI_PRIV_TASK_ARGS_##N(args_in));  \
     }
 
-#define FMPI_TASK_REGISTER_IMPL(FUNC, TYPE, ctx, stencil, ...) \
+#define FMPI_TASK_REGISTER_SYNC_IMPL(FUNC, ctx, stencil, ...) \
     FMPI_PRIV_TASK_CONCAT(FMPI_PRIV_TASK_REGISTER_, CPL_ARG_COUNT(__VA_ARGS__)) \
-    (FUNC, TYPE, ctx, stencil ,__VA_ARGS__)
+    (FUNC, ctx, FMPI_TASK_TYPE_SYNC, stencil ,__VA_ARGS__)
 
-#define FMPI_PRIV_TASK_REGISTER_1(FUNC, TYPE, ctx, stencil, arg_out) \
-    fmpi_task_register_##TYPE((ctx), FUNC##_0, #FUNC, (stencil), &(struct fmpi_task_args){ \
+#define FMPI_TASK_REGISTER_ASYNC_IMPL(FUNC, ctx, stencil, ...) \
+    FMPI_PRIV_TASK_CONCAT(FMPI_PRIV_TASK_REGISTER_, CPL_ARG_COUNT(__VA_ARGS__)) \
+    (FUNC, ctx, FMPI_TASK_TYPE_ASYNC, stencil ,__VA_ARGS__)
+
+#define FMPI_PRIV_TASK_REGISTER_1(FUNC, ctx, type, stencil, arg_out) \
+    fmpi_task_register((ctx), FUNC##_0, #FUNC, (type), (stencil), &(struct fmpi_task_args){ \
         .out = (arg_out), \
         .cnt = 0 \
     })
 
-#define FMPI_PRIV_TASK_REGISTER_N(N, FUNC, TYPE, ctx, stencil, arg_out, ...) \
-    fmpi_task_register_##TYPE((ctx), FUNC##_##N, #FUNC, (stencil), &(struct fmpi_task_args){ \
+#define FMPI_PRIV_TASK_REGISTER_N(N, FUNC, ctx, type, stencil, arg_out, ...) \
+    fmpi_task_register((ctx), FUNC##_##N, #FUNC, (type), (stencil), &(struct fmpi_task_args){ \
         .in = {__VA_ARGS__}, \
         .out = (arg_out), \
         .cnt = N \
diff --git a/src/fmpi_task.c b/src/fmpi_task.c
index f7b6503b7769d2f0585ce9e8cafb7f3dfd7b2f59..2845ae351d7a0d17c745b92c191123762e662107 100644
--- a/src/fmpi_task.c
+++ b/src/fmpi_task.c
@@ -40,21 +40,22 @@
     PUBLIC FUNCTION DEFINITION
 ==============================================================================*/
 /*------------------------------------------------------------------------------
-    fmpi_task_register_sync()
+    fmpi_task_register()
 ------------------------------------------------------------------------------*/
-struct fmpi_task fmpi_task_register_sync(
+struct fmpi_task fmpi_task_register(
     struct fmpi_ctx * const ctx, const fmpi_task_func func,
-    const char * const name, const struct fmpi_stencil stencil,
-    const struct fmpi_task_args * const args
+    const char * const name, const enum fmpi_task_type type,
+    const struct fmpi_stencil stencil, const struct fmpi_task_args * const args
 ){
     assert(ctx != NULL);
     assert(ctx->task_cnt < FMPI_TASK_MAX);
     assert(name != NULL);
     assert(args != NULL);
+
     struct fmpi_task task = {
         .func = func,
         .name = name,
-        .type = FMPI_TASK_TYPE_SYNC,
+        .type = type,
         .args = *args,
         .stencil = stencil
     };
@@ -63,58 +64,33 @@ struct fmpi_task fmpi_task_register_sync(
         const struct fmpi_data * const data = (stencil.type != FMPI_STENCIL_NONE)
             ? &task.domains[i].halo
             : &task.domains[i].inner;
+        void * gpu_data = NULL;
+        const char * func_name = NULL;
+        if(task.type == FMPI_TASK_TYPE_SYNC) {
         //! @todo Could fmpi_futhark_new_data_async() be called here instead?
-        void * gpu_data = fmpi_futhark_new_data_sync(
-            ctx->fut, data->raw, data->type.base, data->dim_cnt,
-            data->dim_len[0], data->dim_len[1], data->dim_len[2]
-        );
-        if(gpu_data == NULL) {
-            FMPI_RAISE_ERROR(ctx->err_handler, "FMPI",
-                "fmpi_futhark_new_data_sync() failed!"
+            gpu_data = fmpi_futhark_new_data_sync(
+                ctx->fut, data->raw, data->type.base, data->dim_cnt,
+                data->dim_len[0], data->dim_len[1], data->dim_len[2]
             );
+            func_name = "fmpi_futhark_new_data_sync";
+        } else {
+            gpu_data = fmpi_futhark_new_data_async(
+                ctx->fut, data->raw, data->type.base, data->dim_cnt,
+                data->dim_len[0], data->dim_len[1], data->dim_len[2]
+            );
+            func_name = "fmpi_futhark_new_data_async";
         }
-        task.args.in[i].gpu = gpu_data;
-    }
-    ctx->tasks[ctx->task_cnt++] = task;
-    fmpi_futhark_sync(ctx->fut);
-    return task;
-}
-/*------------------------------------------------------------------------------
-    fmpi_task_register_async()
-------------------------------------------------------------------------------*/
-struct fmpi_task fmpi_task_register_async(
-    struct fmpi_ctx * const ctx, const fmpi_task_func func,
-    const char * const name, const struct fmpi_stencil stencil,
-    const struct fmpi_task_args * const args
-){
-    assert(ctx != NULL);
-    assert(ctx->task_cnt < FMPI_TASK_MAX);
-    assert(name != NULL);
-    assert(args != NULL);
-    struct fmpi_task task = {
-        .func = func,
-        .name = name,
-        .type = FMPI_TASK_TYPE_ASYNC,
-        .args = *args,
-        .stencil = stencil
-    };
-    for(size_t i = 0; i < task.args.cnt; i++) {
-        task.domains[i] = fmpi_new_domain(ctx, &args->in[i], stencil);
-        const struct fmpi_data * const data = (stencil.type != FMPI_STENCIL_NONE)
-            ? &task.domains[i].halo
-            : &task.domains[i].inner;
-        void * gpu_data = fmpi_futhark_new_data_async(
-            ctx->fut, data->raw, data->type.base, data->dim_cnt,
-            data->dim_len[0], data->dim_len[1], data->dim_len[2]
-        );
         if(gpu_data == NULL) {
             FMPI_RAISE_ERROR(ctx->err_handler, "FMPI",
-                "fmpi_futhark_new_data_async() failed!"
+                "%s() failed!", func_name
             );
         }
         task.args.in[i].gpu = gpu_data;
     }
     ctx->tasks[ctx->task_cnt++] = task;
+    if(task.type == FMPI_TASK_TYPE_SYNC) {
+        fmpi_futhark_sync(ctx->fut);
+    }
     return task;
 }
 /*------------------------------------------------------------------------------