From 780b3787e15484fae9cb8fa2a7dd19c0120d8338 Mon Sep 17 00:00:00 2001
From: PRUVOST Florent <florent.pruvost@inria.fr>
Date: Wed, 22 Apr 2020 17:43:03 +0200
Subject: [PATCH] Add execute_on_worker feature of starpu thanks to a new field
 `schedopt` in the runtime_request_s struct

---
 compute/ztile.c                               |   4 +-
 control/async.c                               | 136 ++++++++++++++++++
 control/async.h                               |   3 +
 control/chameleon_f90.f90                     |  45 ++++++
 include/chameleon.h                           |   6 +
 include/chameleon/constants.h                 |   5 +
 include/chameleon/runtime.h                   |  72 ++++++++++
 include/chameleon/runtime_struct.h            |   5 +-
 runtime/openmp/control/runtime_async.c        |  37 +++++
 runtime/openmp/control/runtime_control.c      |   3 +
 runtime/parsec/control/runtime_async.c        |  37 +++++
 runtime/quark/control/runtime_async.c         |  37 +++++
 runtime/quark/control/runtime_control.c       |   8 +-
 runtime/starpu/codelets/codelet_dzasum.c      |   3 +
 runtime/starpu/codelets/codelet_map.c         |   3 +
 runtime/starpu/codelets/codelet_zaxpy.c       |   3 +
 runtime/starpu/codelets/codelet_zbuild.c      |   3 +
 runtime/starpu/codelets/codelet_zgeadd.c      |   3 +
 runtime/starpu/codelets/codelet_zgelqt.c      |   3 +
 runtime/starpu/codelets/codelet_zgemm.c       |   3 +
 runtime/starpu/codelets/codelet_zgeqrt.c      |   3 +
 runtime/starpu/codelets/codelet_zgessm.c      |   3 +
 runtime/starpu/codelets/codelet_zgessq.c      |   3 +
 runtime/starpu/codelets/codelet_zgetrf.c      |   3 +
 .../starpu/codelets/codelet_zgetrf_incpiv.c   |   3 +
 .../starpu/codelets/codelet_zgetrf_nopiv.c    |   3 +
 runtime/starpu/codelets/codelet_zgram.c       |   3 +
 runtime/starpu/codelets/codelet_zhe2ge.c      |   3 +
 runtime/starpu/codelets/codelet_zhemm.c       |   3 +
 runtime/starpu/codelets/codelet_zher2k.c      |   3 +
 runtime/starpu/codelets/codelet_zherfb.c      |   3 +
 runtime/starpu/codelets/codelet_zherk.c       |   3 +
 runtime/starpu/codelets/codelet_zlacpy.c      |   3 +
 runtime/starpu/codelets/codelet_zlag2c.c      |   6 +
 runtime/starpu/codelets/codelet_zlange.c      |   6 +
 runtime/starpu/codelets/codelet_zlanhe.c      |   3 +
 runtime/starpu/codelets/codelet_zlansy.c      |   3 +
 runtime/starpu/codelets/codelet_zlantr.c      |   3 +
 runtime/starpu/codelets/codelet_zlascal.c     |   3 +
 runtime/starpu/codelets/codelet_zlaset.c      |   3 +
 runtime/starpu/codelets/codelet_zlaset2.c     |   3 +
 runtime/starpu/codelets/codelet_zlatro.c      |   3 +
 runtime/starpu/codelets/codelet_zlauum.c      |   3 +
 runtime/starpu/codelets/codelet_zplghe.c      |   3 +
 runtime/starpu/codelets/codelet_zplgsy.c      |   3 +
 runtime/starpu/codelets/codelet_zplrnt.c      |   3 +
 runtime/starpu/codelets/codelet_zplssq.c      |   5 +
 runtime/starpu/codelets/codelet_zpotrf.c      |   3 +
 runtime/starpu/codelets/codelet_zssssm.c      |   3 +
 runtime/starpu/codelets/codelet_zsymm.c       |   3 +
 runtime/starpu/codelets/codelet_zsyr2k.c      |   3 +
 runtime/starpu/codelets/codelet_zsyrk.c       |   3 +
 runtime/starpu/codelets/codelet_zsyssq.c      |   3 +
 .../starpu/codelets/codelet_zsytrf_nopiv.c    |   3 +
 runtime/starpu/codelets/codelet_ztplqt.c      |   3 +
 runtime/starpu/codelets/codelet_ztpmlqt.c     |   3 +
 runtime/starpu/codelets/codelet_ztpmqrt.c     |   3 +
 runtime/starpu/codelets/codelet_ztpqrt.c      |   3 +
 runtime/starpu/codelets/codelet_ztradd.c      |   3 +
 runtime/starpu/codelets/codelet_ztrasm.c      |   3 +
 runtime/starpu/codelets/codelet_ztrmm.c       |   3 +
 runtime/starpu/codelets/codelet_ztrsm.c       |   3 +
 runtime/starpu/codelets/codelet_ztrssq.c      |   3 +
 runtime/starpu/codelets/codelet_ztrtri.c      |   3 +
 .../starpu/codelets/codelet_ztsmlq_hetra1.c   |   3 +
 .../starpu/codelets/codelet_ztsmqr_hetra1.c   |   3 +
 runtime/starpu/codelets/codelet_ztstrf.c      |   3 +
 runtime/starpu/codelets/codelet_zunmlq.c      |   3 +
 runtime/starpu/codelets/codelet_zunmqr.c      |   3 +
 runtime/starpu/control/runtime_async.c        |  57 ++++++++
 runtime/starpu/control/runtime_control.c      |   3 +
 runtime/starpu/include/chameleon_starpu.h.in  |   5 +
 72 files changed, 634 insertions(+), 5 deletions(-)

diff --git a/compute/ztile.c b/compute/ztile.c
index b4c3b5367..74d85e06e 100644
--- a/compute/ztile.c
+++ b/compute/ztile.c
@@ -120,7 +120,7 @@ int CHAMELEON_zLap2Desc( cham_uplo_t uplo, CHAMELEON_Complex64_t *Af77, int LDA,
 {
     CHAM_context_t *chamctxt;
     RUNTIME_sequence_t *sequence = NULL;
-    RUNTIME_request_t request;
+    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
     CHAM_desc_t *B;
     int status;
 
@@ -204,7 +204,7 @@ int CHAMELEON_zDesc2Lap( cham_uplo_t uplo, CHAM_desc_t *A, CHAMELEON_Complex64_t
 {
     CHAM_context_t *chamctxt;
     RUNTIME_sequence_t *sequence = NULL;
-    RUNTIME_request_t request;
+    RUNTIME_request_t request = RUNTIME_REQUEST_INITIALIZER;
     CHAM_desc_t *B;
     int status;
 
diff --git a/control/async.c b/control/async.c
index 061572467..fc9c695a9 100644
--- a/control/async.c
+++ b/control/async.c
@@ -208,3 +208,139 @@ int CHAMELEON_Sequence_Flush(RUNTIME_sequence_t *sequence, RUNTIME_request_t *re
 
     return CHAMELEON_SUCCESS;
 }
+
+
+/**
+ *  Create a request
+ */
+int chameleon_request_create(CHAM_context_t *chamctxt, RUNTIME_request_t **request)
+{
+    if ((*request = malloc(sizeof(RUNTIME_request_t))) == NULL) {
+        chameleon_error("chameleon_request_create", "malloc() failed");
+        return CHAMELEON_ERR_OUT_OF_RESOURCES;
+    }
+
+    RUNTIME_request_create( chamctxt, *request );
+
+    (*request)->status = CHAMELEON_SUCCESS;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Destroy a request
+ */
+int chameleon_request_destroy(CHAM_context_t *chamctxt, RUNTIME_request_t *request)
+{
+    RUNTIME_request_destroy( chamctxt, request );
+    free(request);
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Set parameter for a request
+ */
+int chameleon_request_set(CHAM_context_t *chamctxt, RUNTIME_request_t *request, int param, int value)
+{
+    int status;
+    status = RUNTIME_request_set( chamctxt, request, param, value );
+    return status;
+}
+
+/**
+ *
+ * @ingroup Requests
+ *
+ *  CHAMELEON_Request_Create - Create a request.
+ *
+ ******************************************************************************
+ *
+ * @param[out] request
+ *          Identifies a request for a specific routine.
+ *
+ ******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ */
+int CHAMELEON_Request_Create(RUNTIME_request_t **request)
+{
+    CHAM_context_t *chamctxt;
+    int status;
+
+    chamctxt = chameleon_context_self();
+    if (chamctxt == NULL) {
+        chameleon_fatal_error("CHAMELEON_Request_Create", "CHAMELEON not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+    status = chameleon_request_create(chamctxt, request);
+    return status;
+}
+
+/**
+ *
+ * @ingroup Requests
+ *
+ *  CHAMELEON_Request_Destroy - Destroy a request.
+ *
+ ******************************************************************************
+ *
+ * @param[in] request
+ *          Identifies a request for a specific routine.
+ *
+ ******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ */
+int CHAMELEON_Request_Destroy(RUNTIME_request_t *request)
+{
+    CHAM_context_t *chamctxt;
+    int status;
+
+    chamctxt = chameleon_context_self();
+    if (chamctxt == NULL) {
+        chameleon_fatal_error("CHAMELEON_Request_Destroy", "CHAMELEON not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+    if (request == NULL) {
+        chameleon_fatal_error("CHAMELEON_Request_Destroy", "NULL request");
+        return CHAMELEON_ERR_UNALLOCATED;
+    }
+    status = chameleon_request_destroy(chamctxt, request);
+    return status;
+}
+
+/**
+ *
+ * @ingroup Requests
+ *
+ *  CHAMELEON_Request_Set - Set CHAMELEON parameter for a request.
+ *
+ *******************************************************************************
+ *
+ * @param[in] param
+ *          Feature to be enabled:
+ *          @arg CHAMELEON_REQUEST_WORKERID: force tasks execution on a specific worker id
+ *
+ * @param[in] value
+ *          Value of the parameter.
+ *
+ *******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ */
+int CHAMELEON_Request_Set( RUNTIME_request_t *request, int param, int value)
+{
+    CHAM_context_t *chamctxt;
+    int status;
+
+    chamctxt = chameleon_context_self();
+    if (chamctxt == NULL) {
+        chameleon_error("CHAMELEON_Request_Set", "CHAMELEON not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+
+    status = chameleon_request_set(chamctxt, request, param, value);
+    return status;
+}
\ No newline at end of file
diff --git a/control/async.h b/control/async.h
index be521ae68..5da5c1c6c 100644
--- a/control/async.h
+++ b/control/async.h
@@ -33,6 +33,9 @@ int chameleon_request_fail     (RUNTIME_sequence_t *sequence, RUNTIME_request_t
 int chameleon_sequence_create  (CHAM_context_t *CHAMELEON, RUNTIME_sequence_t **sequence);
 int chameleon_sequence_destroy (CHAM_context_t *CHAMELEON, RUNTIME_sequence_t *sequence);
 int chameleon_sequence_wait    (CHAM_context_t *CHAMELEON, RUNTIME_sequence_t *sequence);
+int chameleon_request_create   (CHAM_context_t *CHAMELEON, RUNTIME_request_t **request);
+int chameleon_request_destroy  (CHAM_context_t *CHAMELEON, RUNTIME_request_t *request);
+int chameleon_request_set      (CHAM_context_t *chamctxt, RUNTIME_request_t *request, int param, int value);
 
 #ifdef __cplusplus
 }
diff --git a/control/chameleon_f90.f90 b/control/chameleon_f90.f90
index db2b926fc..587be5698 100644
--- a/control/chameleon_f90.f90
+++ b/control/chameleon_f90.f90
@@ -310,6 +310,35 @@ module chameleon
          end function CHAMELEON_Sequence_Flush_c
       end interface
 
+      interface
+         function CHAMELEON_Request_Create_c(req) &
+          & bind(c, name='CHAMELEON_Request_Create')
+            use iso_c_binding
+            integer(kind=c_int) :: CHAMELEON_Request_Create_c
+            type(c_ptr) :: req
+         end function CHAMELEON_Request_Create_c
+      end interface
+
+      interface
+         function CHAMELEON_Request_Destroy_c(req) &
+          & bind(c, name='CHAMELEON_Request_Destroy')
+            use iso_c_binding
+            integer(kind=c_int) :: CHAMELEON_Request_Destroy_c
+            type(c_ptr), value :: req
+         end function CHAMELEON_Request_Destroy_c
+      end interface
+
+      interface
+         function CHAMELEON_Request_Set_c(req, param, pval) &
+          & bind(c, name='CHAMELEON_Request_Set')
+            use iso_c_binding
+            integer(kind=c_int) :: CHAMELEON_Request_Set_c
+            type(c_ptr) :: req
+            integer(kind=c_int), value :: param
+            integer(kind=c_int), value :: pval
+         end function CHAMELEON_Request_Set_c
+      end interface
+
       interface chameleon_lapack_to_tile
          module procedure chameleon_lapack_to_tile_s
          module procedure chameleon_lapack_to_tile_d
@@ -591,4 +620,20 @@ module chameleon
       info = chameleon_sequence_flush_c(sequence,request)
    end subroutine chameleon_sequence_flush
 
+   subroutine chameleon_request_create(request,info)
+      use iso_c_binding
+      implicit none
+      type(c_ptr), intent(out) :: request
+      integer(kind=c_int), intent(out) :: info
+      info = chameleon_request_create_c(request)
+   end subroutine chameleon_request_create
+
+   subroutine chameleon_request_destroy(request,info)
+      use iso_c_binding
+      implicit none
+      type(c_ptr), intent(in) :: request
+      integer(kind=c_int), intent(out) :: info
+      info = chameleon_request_destroy_c(request)
+   end subroutine chameleon_request_destroy
+
 end module chameleon
diff --git a/include/chameleon.h b/include/chameleon.h
index 953bd31cd..ac4c8a8ca 100644
--- a/include/chameleon.h
+++ b/include/chameleon.h
@@ -145,6 +145,12 @@ void CHAMELEON_user_tag_size(int, int);
 int CHAMELEON_Sequence_Create  (RUNTIME_sequence_t **sequence);
 int CHAMELEON_Sequence_Destroy (RUNTIME_sequence_t *sequence);
 int CHAMELEON_Sequence_Wait    (RUNTIME_sequence_t *sequence);
+int CHAMELEON_Sequence_Flush   (RUNTIME_sequence_t *sequence, RUNTIME_request_t *request);
+
+/* Requests */
+int CHAMELEON_Request_Create  (RUNTIME_request_t **request);
+int CHAMELEON_Request_Destroy (RUNTIME_request_t *request);
+int CHAMELEON_Request_Set     (RUNTIME_request_t *request, int param, int value);
 
 /**
  *
diff --git a/include/chameleon/constants.h b/include/chameleon/constants.h
index 47e45a1cb..a75a90706 100644
--- a/include/chameleon/constants.h
+++ b/include/chameleon/constants.h
@@ -216,6 +216,11 @@ typedef enum chameleon_store_e {
 #define CHAMELEON_TRANSLATION_MODE  7
 #define CHAMELEON_LOOKAHEAD         8
 
+/**
+ *  CHAMELEON constants - configuration parameters for a request
+ */
+#define CHAMELEON_REQUEST_WORKERID 1
+
 /**
  * @brief QR/LQ factorization trees
  */
diff --git a/include/chameleon/runtime.h b/include/chameleon/runtime.h
index ce2e5b5af..aac25cb7d 100644
--- a/include/chameleon/runtime.h
+++ b/include/chameleon/runtime.h
@@ -310,6 +310,78 @@ RUNTIME_sequence_flush( CHAM_context_t     *ctxt,
                         RUNTIME_request_t  *request,
                         int                 status );
 
+/**
+ * @}
+ *
+ * @name RUNTIME Asynchonous functionalities
+ * @{
+ *    These functions manage the request of tasks. A request is a subset of
+ *    related tasks belonging to a same procedure.
+ */
+
+/**
+ * @brief Create a request structure associated to a given context.
+ *
+ * @param[in] ctxt
+ *            The runtime context in which the request is created.
+ *
+ * @param[in,out] request
+ *            On entry the allocated runtime request structure, and on exit
+ *            the scheduler specifics for the request have been initialized.
+ *
+ * @retval CHAMELEON_SUCCESS on success.
+ * @retval CHAMELEON_ERR_OUT_OF_RESOURCES, if the request could not be created.
+ */
+int
+RUNTIME_request_create( CHAM_context_t    *ctxt,
+                        RUNTIME_request_t *request );
+
+/**
+ * @brief Destroy the request structure.
+ *
+ * @param[in] ctxt
+ *            The runtime context to which the request belongs.
+ *
+ * @param[in,out] request
+ *            On entry the request structure.
+ *            On exit, the scheduler specifics of the request have been
+ *            destroyed.
+ *
+ * @retval CHAMELEON_SUCCESS on success.
+ */
+int
+RUNTIME_request_destroy( CHAM_context_t    *ctxt,
+                         RUNTIME_request_t *request);
+
+/**
+ *  @brief RUNTIME_request_set - Set RUNTIME parameter for a request.
+ *
+ *******************************************************************************
+ *
+ * @param[in] ctxt
+ *            The runtime context to which the request belongs.
+ *
+ * @param[in,out] request
+ *            On entry the request structure.
+ *            On exit, the request structure modified.
+ *
+ * @param[in] param
+ *          Feature to be enabled:
+ *          @arg CHAMELEON_REQUEST_WORKERID: force tasks execution on a specific worker id
+ *
+ * @param[in] value
+ *          Value of the parameter.
+ *
+ *******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ */
+int
+RUNTIME_request_set( CHAM_context_t  *chamctxt,
+                     RUNTIME_request_t *request,
+                     int param, int value );
+
 /**
  * @}
  *
diff --git a/include/chameleon/runtime_struct.h b/include/chameleon/runtime_struct.h
index 44bc95e60..96a8c5cb7 100644
--- a/include/chameleon/runtime_struct.h
+++ b/include/chameleon/runtime_struct.h
@@ -41,13 +41,14 @@ typedef enum runtime_id_e {
  *
  */
 typedef struct runtime_request_s {
-    int       status;   /**< Return status registered by the tasks for the request */
+    int       status; /**< Return status registered by the tasks for the request */
+    void      *schedopt; /**< Specific runtime data pointer to handle the request */
 } RUNTIME_request_t;
 
 /**
  *  @brief Runtime request initializer
  */
-#define RUNTIME_REQUEST_INITIALIZER { 0 }
+#define RUNTIME_REQUEST_INITIALIZER { .status = 0, .schedopt = NULL }
 
 /**
  * @brief RUNTIME sequence structure
diff --git a/runtime/openmp/control/runtime_async.c b/runtime/openmp/control/runtime_async.c
index 7032ec2a9..42a1d52b1 100644
--- a/runtime/openmp/control/runtime_async.c
+++ b/runtime/openmp/control/runtime_async.c
@@ -69,3 +69,40 @@ void RUNTIME_sequence_flush( CHAM_context_t  *chamctxt,
     request->status = status;
     return;
 }
+
+/**
+ *  Create a request
+ */
+int RUNTIME_request_create( CHAM_context_t  *chamctxt,
+                            RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    request->schedopt = NULL;
+    request->status = CHAMELEON_SUCCESS;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Destroy a request
+ */
+int RUNTIME_request_destroy( CHAM_context_t  *chamctxt,
+                             RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    (void)request;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Set runtime parameter for a request
+ */
+int RUNTIME_request_set( CHAM_context_t  *chamctxt,
+                         RUNTIME_request_t *request,
+                         int param, int value )
+{
+    (void)chamctxt;
+    (void)request;
+    (void)param;
+    (void)value;
+    return CHAMELEON_SUCCESS;
+}
\ No newline at end of file
diff --git a/runtime/openmp/control/runtime_control.c b/runtime/openmp/control/runtime_control.c
index d07758f47..ec955ca19 100644
--- a/runtime/openmp/control/runtime_control.c
+++ b/runtime/openmp/control/runtime_control.c
@@ -38,6 +38,9 @@ int RUNTIME_init( CHAM_context_t *chamctxt,
         chameleon_warning( "RUNTIME_init_scheduler(OpenMP)", "Multi-threaded kernels are not supported for now");
     }
 
+    chamctxt->nworkers = ncpus;
+    chamctxt->nthreads_per_worker = nthreads_per_worker;
+
     return hres;
 }
 
diff --git a/runtime/parsec/control/runtime_async.c b/runtime/parsec/control/runtime_async.c
index 657b2078a..af5def990 100644
--- a/runtime/parsec/control/runtime_async.c
+++ b/runtime/parsec/control/runtime_async.c
@@ -83,3 +83,40 @@ void RUNTIME_sequence_flush( CHAM_context_t  *chamctxt,
     (void)chamctxt;
     return;
 }
+
+/**
+ *  Create a request
+ */
+int RUNTIME_request_create( CHAM_context_t  *chamctxt,
+                            RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    request->schedopt = NULL;
+    request->status = CHAMELEON_SUCCESS;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Destroy a request
+ */
+int RUNTIME_request_destroy( CHAM_context_t  *chamctxt,
+                             RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    (void)request;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Set runtime parameter for a request
+ */
+int RUNTIME_request_set( CHAM_context_t  *chamctxt,
+                         RUNTIME_request_t *request,
+                         int param, int value )
+{
+    (void)chamctxt;
+    (void)request;
+    (void)param;
+    (void)value;
+    return CHAMELEON_SUCCESS;
+}
\ No newline at end of file
diff --git a/runtime/quark/control/runtime_async.c b/runtime/quark/control/runtime_async.c
index f6f466f02..b008c5610 100644
--- a/runtime/quark/control/runtime_async.c
+++ b/runtime/quark/control/runtime_async.c
@@ -73,3 +73,40 @@ void RUNTIME_sequence_flush( CHAM_context_t  *chamctxt,
     QUARK_Sequence_Cancel( (Quark*)(chamctxt),
                            (Quark_Sequence *)(sequence->schedopt) );
 }
+
+/**
+ *  Create a request
+ */
+int RUNTIME_request_create( CHAM_context_t  *chamctxt,
+                            RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    request->schedopt = NULL;
+    request->status = CHAMELEON_SUCCESS;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Destroy a request
+ */
+int RUNTIME_request_destroy( CHAM_context_t  *chamctxt,
+                             RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    (void)request;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Set runtime parameter for a request
+ */
+int RUNTIME_request_set( CHAM_context_t  *chamctxt,
+                         RUNTIME_request_t *request,
+                         int param, int value )
+{
+    (void)chamctxt;
+    (void)request;
+    (void)param;
+    (void)value;
+    return CHAMELEON_SUCCESS;
+}
\ No newline at end of file
diff --git a/runtime/quark/control/runtime_control.c b/runtime/quark/control/runtime_control.c
index cfc447329..c8ab84585 100644
--- a/runtime/quark/control/runtime_control.c
+++ b/runtime/quark/control/runtime_control.c
@@ -29,7 +29,7 @@ int RUNTIME_init( CHAM_context_t *chamctxt,
                   int ncudas,
                   int nthreads_per_worker )
 {
-    int hres = 0;
+    int hres = -1;
     if ( ncudas > 0 ) {
         chameleon_warning( "RUNTIME_init_scheduler(quark)", "GPUs are not supported for now");
     }
@@ -40,6 +40,12 @@ int RUNTIME_init( CHAM_context_t *chamctxt,
 
     chamctxt->schedopt = (void*)QUARK_New( ncpus );
 
+    if(NULL != chamctxt->schedopt) {
+        chamctxt->nworkers = ncpus;
+        chamctxt->nthreads_per_worker = nthreads_per_worker;
+        hres = 0;
+    }
+
     return hres;
 }
 
diff --git a/runtime/starpu/codelets/codelet_dzasum.c b/runtime/starpu/codelets/codelet_dzasum.c
index 67df3e6ef..b88605ba1 100644
--- a/runtime/starpu/codelets/codelet_dzasum.c
+++ b/runtime/starpu/codelets/codelet_dzasum.c
@@ -53,6 +53,8 @@ void INSERT_TASK_dzasum( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_dzasum;
     void (*callback)(void*) = options->profiling ? cl_dzasum_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -69,6 +71,7 @@ void INSERT_TASK_dzasum( const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+         STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "dzasum",
 #endif
diff --git a/runtime/starpu/codelets/codelet_map.c b/runtime/starpu/codelets/codelet_map.c
index 347a76ed4..65dd72e33 100644
--- a/runtime/starpu/codelets/codelet_map.c
+++ b/runtime/starpu/codelets/codelet_map.c
@@ -48,6 +48,8 @@ void INSERT_TASK_map( const RUNTIME_option_t *options,
 
     struct starpu_codelet *codelet = &cl_map;
     void (*callback)(void*) = options->profiling ? cl_map_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -64,6 +66,7 @@ void INSERT_TASK_map( const RUNTIME_option_t *options,
         STARPU_VALUE,    &op_args,                sizeof(void*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "map",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zaxpy.c b/runtime/starpu/codelets/codelet_zaxpy.c
index f19b201be..88cf08e02 100644
--- a/runtime/starpu/codelets/codelet_zaxpy.c
+++ b/runtime/starpu/codelets/codelet_zaxpy.c
@@ -49,6 +49,8 @@ void INSERT_TASK_zaxpy( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zaxpy;
     void (*callback)(void*) = options->profiling ? cl_zaxpy_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -65,6 +67,7 @@ void INSERT_TASK_zaxpy( const RUNTIME_option_t *options,
             STARPU_VALUE,    &incB,                        sizeof(int),
             STARPU_PRIORITY, options->priority,
             STARPU_CALLBACK, callback,
+            STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
             STARPU_NAME, "zaxpy",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zbuild.c b/runtime/starpu/codelets/codelet_zbuild.c
index a99d48944..ad52e6452 100644
--- a/runtime/starpu/codelets/codelet_zbuild.c
+++ b/runtime/starpu/codelets/codelet_zbuild.c
@@ -61,6 +61,8 @@ CODELETS_CPU(zbuild, 1, cl_zbuild_cpu_func)
 
     struct starpu_codelet *codelet = &cl_zbuild;
     void (*callback)(void*) = options->profiling ? cl_zbuild_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
     int row_min, row_max, col_min, col_max;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
@@ -82,6 +84,7 @@ CODELETS_CPU(zbuild, 1, cl_zbuild_cpu_func)
         STARPU_VALUE,    &user_build_callback,          sizeof(void*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zbuild",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgeadd.c b/runtime/starpu/codelets/codelet_zgeadd.c
index 495a7273f..27ce15a01 100644
--- a/runtime/starpu/codelets/codelet_zgeadd.c
+++ b/runtime/starpu/codelets/codelet_zgeadd.c
@@ -146,6 +146,8 @@ void INSERT_TASK_zgeadd( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zgeadd;
     void (*callback)(void*) = options->profiling ? cl_zgeadd_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -163,6 +165,7 @@ void INSERT_TASK_zgeadd( const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgeadd",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgelqt.c b/runtime/starpu/codelets/codelet_zgelqt.c
index d918f8110..63d7b9ca3 100644
--- a/runtime/starpu/codelets/codelet_zgelqt.c
+++ b/runtime/starpu/codelets/codelet_zgelqt.c
@@ -66,6 +66,8 @@ void INSERT_TASK_zgelqt(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgelqt;
     void (*callback)(void*) = options->profiling ? cl_zgelqt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
     CHAMELEON_starpu_ws_t *h_work = (CHAMELEON_starpu_ws_t*)(options->ws_host);
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
@@ -86,6 +88,7 @@ void INSERT_TASK_zgelqt(const RUNTIME_option_t *options,
         STARPU_VALUE,    &h_work,            sizeof(CHAMELEON_starpu_ws_t *),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgelqt",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgemm.c b/runtime/starpu/codelets/codelet_zgemm.c
index 24b46d514..034136bed 100644
--- a/runtime/starpu/codelets/codelet_zgemm.c
+++ b/runtime/starpu/codelets/codelet_zgemm.c
@@ -111,6 +111,8 @@ void INSERT_TASK_zgemm(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgemm;
     void (*callback)(void*) = options->profiling ? cl_zgemm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -132,6 +134,7 @@ void INSERT_TASK_zgemm(const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgemm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgeqrt.c b/runtime/starpu/codelets/codelet_zgeqrt.c
index 962f28c33..9f1f407d5 100644
--- a/runtime/starpu/codelets/codelet_zgeqrt.c
+++ b/runtime/starpu/codelets/codelet_zgeqrt.c
@@ -67,6 +67,8 @@ void INSERT_TASK_zgeqrt(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgeqrt;
     void (*callback)(void*) = options->profiling ? cl_zgeqrt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
     CHAMELEON_starpu_ws_t *h_work = (CHAMELEON_starpu_ws_t*)(options->ws_host);
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
@@ -87,6 +89,7 @@ void INSERT_TASK_zgeqrt(const RUNTIME_option_t *options,
         STARPU_VALUE,    &h_work,            sizeof(CHAMELEON_starpu_ws_t *),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgeqrt",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgessm.c b/runtime/starpu/codelets/codelet_zgessm.c
index b93e04dd0..310e7e2b9 100644
--- a/runtime/starpu/codelets/codelet_zgessm.c
+++ b/runtime/starpu/codelets/codelet_zgessm.c
@@ -62,6 +62,8 @@ void INSERT_TASK_zgessm( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgessm;
     void (*callback)(void*) = options->profiling ? cl_zgessm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(L, Lm, Ln);
@@ -81,6 +83,7 @@ void INSERT_TASK_zgessm( const RUNTIME_option_t *options,
         STARPU_RW,            RTBLKADDR(A, CHAMELEON_Complex64_t, Am, An),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgessm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgessq.c b/runtime/starpu/codelets/codelet_zgessq.c
index 16ce38951..f22e28a24 100644
--- a/runtime/starpu/codelets/codelet_zgessq.c
+++ b/runtime/starpu/codelets/codelet_zgessq.c
@@ -52,6 +52,8 @@ void INSERT_TASK_zgessq( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zgessq;
     void (*callback)(void*) = options->profiling ? cl_zgessq_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -67,6 +69,7 @@ void INSERT_TASK_zgessq( const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(SCALESUMSQ, double, SCALESUMSQm, SCALESUMSQn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgessq",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgetrf.c b/runtime/starpu/codelets/codelet_zgetrf.c
index 90482b6f6..23e40e873 100644
--- a/runtime/starpu/codelets/codelet_zgetrf.c
+++ b/runtime/starpu/codelets/codelet_zgetrf.c
@@ -63,6 +63,8 @@ void INSERT_TASK_zgetrf( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgetrf;
     void (*callback)(void*) = options->profiling ? cl_zgetrf_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -80,6 +82,7 @@ void INSERT_TASK_zgetrf( const RUNTIME_option_t *options,
         STARPU_VALUE,    &(options->request),        sizeof(RUNTIME_request_t*),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgetrf",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgetrf_incpiv.c b/runtime/starpu/codelets/codelet_zgetrf_incpiv.c
index 720d94a37..4b2b788ba 100644
--- a/runtime/starpu/codelets/codelet_zgetrf_incpiv.c
+++ b/runtime/starpu/codelets/codelet_zgetrf_incpiv.c
@@ -68,6 +68,8 @@ void INSERT_TASK_zgetrf_incpiv(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgetrf_incpiv;
     void (*callback)(void*) = options->profiling ? cl_zgetrf_incpiv_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_starpu_ws_t *h_work = (CHAMELEON_starpu_ws_t*)(options->ws_host);
 
@@ -92,6 +94,7 @@ void INSERT_TASK_zgetrf_incpiv(const RUNTIME_option_t *options,
         STARPU_VALUE,    &(options->request),        sizeof(RUNTIME_request_t*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgetrf_incpiv",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgetrf_nopiv.c b/runtime/starpu/codelets/codelet_zgetrf_nopiv.c
index c32ebc253..776415a75 100644
--- a/runtime/starpu/codelets/codelet_zgetrf_nopiv.c
+++ b/runtime/starpu/codelets/codelet_zgetrf_nopiv.c
@@ -63,6 +63,8 @@ void INSERT_TASK_zgetrf_nopiv(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zgetrf_nopiv;
     void (*callback)(void*) = options->profiling ? cl_zgetrf_nopiv_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -79,6 +81,7 @@ void INSERT_TASK_zgetrf_nopiv(const RUNTIME_option_t *options,
         STARPU_VALUE,    &(options->request),        sizeof(RUNTIME_request_t*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgetrf_nopiv",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgram.c b/runtime/starpu/codelets/codelet_zgram.c
index a1c83f476..83643fc4f 100644
--- a/runtime/starpu/codelets/codelet_zgram.c
+++ b/runtime/starpu/codelets/codelet_zgram.c
@@ -55,6 +55,8 @@ void INSERT_TASK_zgram( const RUNTIME_option_t *options,
 {
   struct starpu_codelet *codelet = &cl_zgram;
   void (*callback)(void*) = options->profiling ? cl_zgram_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
   CHAMELEON_BEGIN_ACCESS_DECLARATION;
   CHAMELEON_ACCESS_R(Di, Dim, Din);
@@ -76,6 +78,7 @@ void INSERT_TASK_zgram( const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(A, double, Am, An),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zgram",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zhe2ge.c b/runtime/starpu/codelets/codelet_zhe2ge.c
index 6f01c7613..c7a24022b 100644
--- a/runtime/starpu/codelets/codelet_zhe2ge.c
+++ b/runtime/starpu/codelets/codelet_zhe2ge.c
@@ -58,6 +58,8 @@ void INSERT_TASK_zhe2ge(const RUNTIME_option_t *options,
     (void)mb;
     struct starpu_codelet *codelet = &cl_zhe2ge;
     void (*callback)(void*) = options->profiling ? cl_zhe2ge_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -73,6 +75,7 @@ void INSERT_TASK_zhe2ge(const RUNTIME_option_t *options,
         STARPU_W,             RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zhe2ge",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zhemm.c b/runtime/starpu/codelets/codelet_zhemm.c
index 31a2b87bf..b6a827896 100644
--- a/runtime/starpu/codelets/codelet_zhemm.c
+++ b/runtime/starpu/codelets/codelet_zhemm.c
@@ -110,6 +110,8 @@ void INSERT_TASK_zhemm(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zhemm;
     void (*callback)(void*) = options->profiling ? cl_zhemm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -130,6 +132,7 @@ void INSERT_TASK_zhemm(const RUNTIME_option_t *options,
         STARPU_RW,               RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zhemm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zher2k.c b/runtime/starpu/codelets/codelet_zher2k.c
index de32d9521..291fef279 100644
--- a/runtime/starpu/codelets/codelet_zher2k.c
+++ b/runtime/starpu/codelets/codelet_zher2k.c
@@ -107,6 +107,8 @@ INSERT_TASK_zher2k( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zher2k;
     void (*callback)(void*) = options->profiling ? cl_zher2k_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -127,6 +129,7 @@ INSERT_TASK_zher2k( const RUNTIME_option_t *options,
         STARPU_RW,                 RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zher2k",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zherfb.c b/runtime/starpu/codelets/codelet_zherfb.c
index e47bfa3cc..e967fdfd1 100644
--- a/runtime/starpu/codelets/codelet_zherfb.c
+++ b/runtime/starpu/codelets/codelet_zherfb.c
@@ -94,6 +94,8 @@ void INSERT_TASK_zherfb(const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zherfb;
     void (*callback)(void*) = options->profiling ? cl_zherfb_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -115,6 +117,7 @@ void INSERT_TASK_zherfb(const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zherfb",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zherk.c b/runtime/starpu/codelets/codelet_zherk.c
index d90885b26..6a8b17cd6 100644
--- a/runtime/starpu/codelets/codelet_zherk.c
+++ b/runtime/starpu/codelets/codelet_zherk.c
@@ -102,6 +102,8 @@ void INSERT_TASK_zherk(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zherk;
     void (*callback)(void*) = options->profiling ? cl_zherk_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -120,6 +122,7 @@ void INSERT_TASK_zherk(const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zherk",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlacpy.c b/runtime/starpu/codelets/codelet_zlacpy.c
index 144a38c56..5703507ed 100644
--- a/runtime/starpu/codelets/codelet_zlacpy.c
+++ b/runtime/starpu/codelets/codelet_zlacpy.c
@@ -67,6 +67,8 @@ void INSERT_TASK_zlacpyx( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zlacpy;
     void (*callback)(void*) = options->profiling ? cl_zlacpy_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R( A, Am, An );
@@ -84,6 +86,7 @@ void INSERT_TASK_zlacpyx( const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlacpy",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlag2c.c b/runtime/starpu/codelets/codelet_zlag2c.c
index 622aa424d..c3f44bc2a 100644
--- a/runtime/starpu/codelets/codelet_zlag2c.c
+++ b/runtime/starpu/codelets/codelet_zlag2c.c
@@ -60,6 +60,8 @@ void INSERT_TASK_zlag2c(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zlag2c;
     void (*callback)(void*) = options->profiling ? cl_zlag2c_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -74,6 +76,7 @@ void INSERT_TASK_zlag2c(const RUNTIME_option_t *options,
         STARPU_W,         RTBLKADDR(B, CHAMELEON_Complex32_t, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlag2c",
 #endif
@@ -110,6 +113,8 @@ void INSERT_TASK_clag2z(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_clag2z;
     void (*callback)(void*) = options->profiling ? cl_clag2z_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R( A, Am, An );
@@ -124,6 +129,7 @@ void INSERT_TASK_clag2z(const RUNTIME_option_t *options,
         STARPU_W,         RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "clag2z",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlange.c b/runtime/starpu/codelets/codelet_zlange.c
index aa1109617..23ca2f7cc 100644
--- a/runtime/starpu/codelets/codelet_zlange.c
+++ b/runtime/starpu/codelets/codelet_zlange.c
@@ -57,6 +57,8 @@ void INSERT_TASK_zlange( const RUNTIME_option_t *options,
     (void)NB;
     struct starpu_codelet *codelet = &cl_zlange;
     void (*callback)(void*) = options->profiling ? cl_zlange_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -73,6 +75,7 @@ void INSERT_TASK_zlange( const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlange",
 #endif
@@ -110,6 +113,8 @@ void INSERT_TASK_zlange_max(const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zlange_max;
     void (*callback)(void*) = options->profiling ? cl_zlange_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(  A, Am, An );
@@ -122,6 +127,7 @@ void INSERT_TASK_zlange_max(const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+         STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlange_max",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlanhe.c b/runtime/starpu/codelets/codelet_zlanhe.c
index c5bcc1496..f31fea4c4 100644
--- a/runtime/starpu/codelets/codelet_zlanhe.c
+++ b/runtime/starpu/codelets/codelet_zlanhe.c
@@ -56,6 +56,8 @@ void INSERT_TASK_zlanhe(const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zlanhe;
     void (*callback)(void*) = options->profiling ? cl_zlange_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -72,6 +74,7 @@ void INSERT_TASK_zlanhe(const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlanhe",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlansy.c b/runtime/starpu/codelets/codelet_zlansy.c
index e378fdc5f..0fb7e31ef 100644
--- a/runtime/starpu/codelets/codelet_zlansy.c
+++ b/runtime/starpu/codelets/codelet_zlansy.c
@@ -57,6 +57,8 @@ void INSERT_TASK_zlansy( const RUNTIME_option_t *options,
     (void)NB;
     struct starpu_codelet *codelet = &cl_zlansy;
     void (*callback)(void*) = options->profiling ? cl_zlange_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -73,6 +75,7 @@ void INSERT_TASK_zlansy( const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlansy",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlantr.c b/runtime/starpu/codelets/codelet_zlantr.c
index 8598eb4b6..f13dd13bb 100644
--- a/runtime/starpu/codelets/codelet_zlantr.c
+++ b/runtime/starpu/codelets/codelet_zlantr.c
@@ -53,6 +53,8 @@ void INSERT_TASK_zlantr( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zlantr;
     void (*callback)(void*) = options->profiling ? cl_zlange_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -71,6 +73,7 @@ void INSERT_TASK_zlantr( const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlantr",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlascal.c b/runtime/starpu/codelets/codelet_zlascal.c
index dbf072de1..0916e8aa5 100644
--- a/runtime/starpu/codelets/codelet_zlascal.c
+++ b/runtime/starpu/codelets/codelet_zlascal.c
@@ -54,6 +54,8 @@ void INSERT_TASK_zlascal(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zlascal;
     void (*callback)(void*) = options->profiling ? cl_zlascal_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -68,6 +70,7 @@ void INSERT_TASK_zlascal(const RUNTIME_option_t *options,
         STARPU_RW,         RTBLKADDR(A, CHAMELEON_Complex64_t, Am, An),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlascal",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlaset.c b/runtime/starpu/codelets/codelet_zlaset.c
index 71daf564b..df278acd9 100644
--- a/runtime/starpu/codelets/codelet_zlaset.c
+++ b/runtime/starpu/codelets/codelet_zlaset.c
@@ -56,6 +56,8 @@ void INSERT_TASK_zlaset(const RUNTIME_option_t *options,
 
     struct starpu_codelet *codelet = &cl_zlaset;
     void (*callback)(void*) = options->profiling ? cl_zlaset_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_W(A, Am, An);
@@ -71,6 +73,7 @@ void INSERT_TASK_zlaset(const RUNTIME_option_t *options,
         STARPU_W,      RTBLKADDR(A, CHAMELEON_Complex64_t, Am, An),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlaset",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlaset2.c b/runtime/starpu/codelets/codelet_zlaset2.c
index e6fb28558..61256da73 100644
--- a/runtime/starpu/codelets/codelet_zlaset2.c
+++ b/runtime/starpu/codelets/codelet_zlaset2.c
@@ -53,6 +53,8 @@ void INSERT_TASK_zlaset2(const RUNTIME_option_t *options,
 
     struct starpu_codelet *codelet = &cl_zlaset2;
     void (*callback)(void*) = options->profiling ? cl_zlaset2_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_W(A, Am, An);
@@ -67,6 +69,7 @@ void INSERT_TASK_zlaset2(const RUNTIME_option_t *options,
         STARPU_W,      RTBLKADDR(A, CHAMELEON_Complex64_t, Am, An),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlaset2",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlatro.c b/runtime/starpu/codelets/codelet_zlatro.c
index 86696064f..20ed9394c 100644
--- a/runtime/starpu/codelets/codelet_zlatro.c
+++ b/runtime/starpu/codelets/codelet_zlatro.c
@@ -63,6 +63,8 @@ void INSERT_TASK_zlatro( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zlatro;
     void (*callback)(void*) = NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -79,6 +81,7 @@ void INSERT_TASK_zlatro( const RUNTIME_option_t *options,
         STARPU_W,        RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlatro",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zlauum.c b/runtime/starpu/codelets/codelet_zlauum.c
index 4c7911c29..59d67ebf5 100644
--- a/runtime/starpu/codelets/codelet_zlauum.c
+++ b/runtime/starpu/codelets/codelet_zlauum.c
@@ -58,6 +58,8 @@ void INSERT_TASK_zlauum( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zlauum;
     void (*callback)(void*) = options->profiling ? cl_zlauum_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -70,6 +72,7 @@ void INSERT_TASK_zlauum( const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(A, CHAMELEON_Complex64_t, Am, An),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zlauum",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zplghe.c b/runtime/starpu/codelets/codelet_zplghe.c
index 5b75d6615..361ebc17e 100644
--- a/runtime/starpu/codelets/codelet_zplghe.c
+++ b/runtime/starpu/codelets/codelet_zplghe.c
@@ -59,6 +59,8 @@ void INSERT_TASK_zplghe( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zplghe;
     void (*callback)(void*) = options->profiling ? cl_zplghe_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_W(A, Am, An);
@@ -76,6 +78,7 @@ void INSERT_TASK_zplghe( const RUNTIME_option_t *options,
         STARPU_VALUE, &seed,   sizeof(unsigned long long int),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zplghe",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zplgsy.c b/runtime/starpu/codelets/codelet_zplgsy.c
index 5b79c6839..efc64b037 100644
--- a/runtime/starpu/codelets/codelet_zplgsy.c
+++ b/runtime/starpu/codelets/codelet_zplgsy.c
@@ -60,6 +60,8 @@ void INSERT_TASK_zplgsy( const RUNTIME_option_t *options,
 
     struct starpu_codelet *codelet = &cl_zplgsy;
     void (*callback)(void*) = options->profiling ? cl_zplgsy_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_W(A, Am, An);
@@ -77,6 +79,7 @@ void INSERT_TASK_zplgsy( const RUNTIME_option_t *options,
         STARPU_VALUE, &seed,   sizeof(unsigned long long int),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zplgsy",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zplrnt.c b/runtime/starpu/codelets/codelet_zplrnt.c
index 3f4297078..0d86aeff0 100644
--- a/runtime/starpu/codelets/codelet_zplrnt.c
+++ b/runtime/starpu/codelets/codelet_zplrnt.c
@@ -57,6 +57,8 @@ void INSERT_TASK_zplrnt( const RUNTIME_option_t *options,
 
     struct starpu_codelet *codelet = &cl_zplrnt;
     void (*callback)(void*) = options->profiling ? cl_zplrnt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_W(A, Am, An);
@@ -73,6 +75,7 @@ void INSERT_TASK_zplrnt( const RUNTIME_option_t *options,
         STARPU_VALUE, &seed,   sizeof(unsigned long long int),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zplrnt",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zplssq.c b/runtime/starpu/codelets/codelet_zplssq.c
index 65deb638f..b29f1d74e 100644
--- a/runtime/starpu/codelets/codelet_zplssq.c
+++ b/runtime/starpu/codelets/codelet_zplssq.c
@@ -57,6 +57,8 @@ void INSERT_TASK_zplssq( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zplssq;
     void (*callback)(void*) = options->profiling ? cl_zplssq_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(  IN,  INm,  INn  );
@@ -72,6 +74,7 @@ void INSERT_TASK_zplssq( const RUNTIME_option_t *options,
         STARPU_RW, RTBLKADDR( OUT, double, OUTm, OUTn ),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zplssq",
 #endif
@@ -105,6 +108,8 @@ void INSERT_TASK_zplssq2( const RUNTIME_option_t *options, int N,
 {
     struct starpu_codelet *codelet = &cl_zplssq2;
     void (*callback)(void*) = options->profiling ? cl_zplssq2_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW( RESULT, RESULTm, RESULTn );
diff --git a/runtime/starpu/codelets/codelet_zpotrf.c b/runtime/starpu/codelets/codelet_zpotrf.c
index b8b189375..de6c1886b 100644
--- a/runtime/starpu/codelets/codelet_zpotrf.c
+++ b/runtime/starpu/codelets/codelet_zpotrf.c
@@ -67,6 +67,8 @@ void INSERT_TASK_zpotrf(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zpotrf;
     void (*callback)(void*) = options->profiling ? cl_zpotrf_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -83,6 +85,7 @@ void INSERT_TASK_zpotrf(const RUNTIME_option_t *options,
         /* STARPU_SCRATCH,   options->ws_worker, */
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zpotrf",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zssssm.c b/runtime/starpu/codelets/codelet_zssssm.c
index 7a3caf86b..29ef312bd 100644
--- a/runtime/starpu/codelets/codelet_zssssm.c
+++ b/runtime/starpu/codelets/codelet_zssssm.c
@@ -67,6 +67,8 @@ void INSERT_TASK_zssssm( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zssssm;
     void (*callback)(void*) = options->profiling ? cl_zssssm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A1, A1m, A1n);
@@ -90,6 +92,7 @@ void INSERT_TASK_zssssm( const RUNTIME_option_t *options,
         STARPU_VALUE,          &IPIV,                      sizeof(int*),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zssssm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zsymm.c b/runtime/starpu/codelets/codelet_zsymm.c
index de2aeb22e..689be9b62 100644
--- a/runtime/starpu/codelets/codelet_zsymm.c
+++ b/runtime/starpu/codelets/codelet_zsymm.c
@@ -110,6 +110,8 @@ void INSERT_TASK_zsymm(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zsymm;
     void (*callback)(void*) = options->profiling ? cl_zsymm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -130,6 +132,7 @@ void INSERT_TASK_zsymm(const RUNTIME_option_t *options,
         STARPU_RW,               RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zsymm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zsyr2k.c b/runtime/starpu/codelets/codelet_zsyr2k.c
index 1da32daad..86037a377 100644
--- a/runtime/starpu/codelets/codelet_zsyr2k.c
+++ b/runtime/starpu/codelets/codelet_zsyr2k.c
@@ -106,6 +106,8 @@ void INSERT_TASK_zsyr2k(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zsyr2k;
     void (*callback)(void*) = options->profiling ? cl_zsyr2k_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -126,6 +128,7 @@ void INSERT_TASK_zsyr2k(const RUNTIME_option_t *options,
         STARPU_RW,                 RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zsyr2k",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zsyrk.c b/runtime/starpu/codelets/codelet_zsyrk.c
index d340e7a7d..66782975f 100644
--- a/runtime/starpu/codelets/codelet_zsyrk.c
+++ b/runtime/starpu/codelets/codelet_zsyrk.c
@@ -102,6 +102,8 @@ void INSERT_TASK_zsyrk(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zsyrk;
     void (*callback)(void*) = options->profiling ? cl_zsyrk_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -120,6 +122,7 @@ void INSERT_TASK_zsyrk(const RUNTIME_option_t *options,
         STARPU_RW,                 RTBLKADDR(C, CHAMELEON_Complex64_t, Cm, Cn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zsyrk",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zsyssq.c b/runtime/starpu/codelets/codelet_zsyssq.c
index 29283f0b5..951e60d1b 100644
--- a/runtime/starpu/codelets/codelet_zsyssq.c
+++ b/runtime/starpu/codelets/codelet_zsyssq.c
@@ -50,6 +50,8 @@ void INSERT_TASK_zsyssq( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zsyssq;
     void (*callback)(void*) = options->profiling ? cl_zgessq_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -65,6 +67,7 @@ void INSERT_TASK_zsyssq( const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(SCALESUMSQ, double, SCALESUMSQm, SCALESUMSQn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zsyssq",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zsytrf_nopiv.c b/runtime/starpu/codelets/codelet_zsytrf_nopiv.c
index 3293f977a..cbac3596e 100644
--- a/runtime/starpu/codelets/codelet_zsytrf_nopiv.c
+++ b/runtime/starpu/codelets/codelet_zsytrf_nopiv.c
@@ -54,6 +54,8 @@ void INSERT_TASK_zsytrf_nopiv( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_zsytrf_nopiv;
     void (*callback)(void*) = options->profiling ? cl_zsytrf_nopiv_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -68,6 +70,7 @@ void INSERT_TASK_zsytrf_nopiv( const RUNTIME_option_t *options,
         /* STARPU_SCRATCH,   options->ws_worker, */
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zsytrf_nopiv",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztplqt.c b/runtime/starpu/codelets/codelet_ztplqt.c
index 96f966b8a..0754c207f 100644
--- a/runtime/starpu/codelets/codelet_ztplqt.c
+++ b/runtime/starpu/codelets/codelet_ztplqt.c
@@ -58,6 +58,8 @@ void INSERT_TASK_ztplqt( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztplqt;
     void (*callback)(void*) = options->profiling ? cl_ztplqt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -78,6 +80,7 @@ void INSERT_TASK_ztplqt( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_USE_MPI)
         STARPU_EXECUTE_ON_NODE, B->get_rankof(B, Bm, Bn),
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztpmlqt.c b/runtime/starpu/codelets/codelet_ztpmlqt.c
index c62d453cc..92d9e3bac 100644
--- a/runtime/starpu/codelets/codelet_ztpmlqt.c
+++ b/runtime/starpu/codelets/codelet_ztpmlqt.c
@@ -104,6 +104,8 @@ void INSERT_TASK_ztpmlqt( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztpmlqt;
     void (*callback)(void*) = options->profiling ? cl_ztpmlqt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(V, Vm, Vn);
@@ -130,6 +132,7 @@ void INSERT_TASK_ztpmlqt( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_USE_MPI)
         STARPU_EXECUTE_ON_NODE, B->get_rankof(B, Bm, Bn),
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztpmqrt.c b/runtime/starpu/codelets/codelet_ztpmqrt.c
index 13fbfef66..c0da2c794 100644
--- a/runtime/starpu/codelets/codelet_ztpmqrt.c
+++ b/runtime/starpu/codelets/codelet_ztpmqrt.c
@@ -104,6 +104,8 @@ void INSERT_TASK_ztpmqrt( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztpmqrt;
     void (*callback)(void*) = options->profiling ? cl_ztpmqrt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(V, Vm, Vn);
@@ -130,6 +132,7 @@ void INSERT_TASK_ztpmqrt( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_USE_MPI)
         STARPU_EXECUTE_ON_NODE, B->get_rankof(B, Bm, Bn),
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztpqrt.c b/runtime/starpu/codelets/codelet_ztpqrt.c
index d6300f71e..596bb44a2 100644
--- a/runtime/starpu/codelets/codelet_ztpqrt.c
+++ b/runtime/starpu/codelets/codelet_ztpqrt.c
@@ -57,6 +57,8 @@ void INSERT_TASK_ztpqrt( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztpqrt;
     void (*callback)(void*) = options->profiling ? cl_ztpqrt_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -77,6 +79,7 @@ void INSERT_TASK_ztpqrt( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_USE_MPI)
         STARPU_EXECUTE_ON_NODE, B->get_rankof(B, Bm, Bn),
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztradd.c b/runtime/starpu/codelets/codelet_ztradd.c
index d23ce80eb..e19dd2636 100644
--- a/runtime/starpu/codelets/codelet_ztradd.c
+++ b/runtime/starpu/codelets/codelet_ztradd.c
@@ -114,6 +114,8 @@ void INSERT_TASK_ztradd( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztradd;
     void (*callback)(void*) = options->profiling ? cl_zgeadd_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -132,6 +134,7 @@ void INSERT_TASK_ztradd( const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztradd",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztrasm.c b/runtime/starpu/codelets/codelet_ztrasm.c
index d650d1973..527c7e44b 100644
--- a/runtime/starpu/codelets/codelet_ztrasm.c
+++ b/runtime/starpu/codelets/codelet_ztrasm.c
@@ -53,6 +53,8 @@ void INSERT_TASK_ztrasm( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztrasm;
     void (*callback)(void*) = options->profiling ? cl_ztrasm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -70,6 +72,7 @@ void INSERT_TASK_ztrasm( const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(B, double, Bm, Bn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztrasm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztrmm.c b/runtime/starpu/codelets/codelet_ztrmm.c
index 92eb37b92..a1d24cf95 100644
--- a/runtime/starpu/codelets/codelet_ztrmm.c
+++ b/runtime/starpu/codelets/codelet_ztrmm.c
@@ -105,6 +105,8 @@ void INSERT_TASK_ztrmm(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_ztrmm;
     void (*callback)(void*) = options->profiling ? cl_ztrmm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -124,6 +126,7 @@ void INSERT_TASK_ztrmm(const RUNTIME_option_t *options,
         STARPU_RW,                 RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,    options->priority,
         STARPU_CALLBACK,    callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztrmm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztrsm.c b/runtime/starpu/codelets/codelet_ztrsm.c
index 250f39fbb..f4ab40920 100644
--- a/runtime/starpu/codelets/codelet_ztrsm.c
+++ b/runtime/starpu/codelets/codelet_ztrsm.c
@@ -103,6 +103,8 @@ void INSERT_TASK_ztrsm(const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_ztrsm;
     void (*callback)(void*) = options->profiling ? cl_ztrsm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -122,6 +124,7 @@ void INSERT_TASK_ztrsm(const RUNTIME_option_t *options,
         STARPU_RW,        RTBLKADDR(B, CHAMELEON_Complex64_t, Bm, Bn),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztrsm",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztrssq.c b/runtime/starpu/codelets/codelet_ztrssq.c
index b92c02f70..d7ed201af 100644
--- a/runtime/starpu/codelets/codelet_ztrssq.c
+++ b/runtime/starpu/codelets/codelet_ztrssq.c
@@ -52,6 +52,8 @@ void INSERT_TASK_ztrssq( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztrssq;
     void (*callback)(void*) = options->profiling ? cl_ztrasm_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -68,6 +70,7 @@ void INSERT_TASK_ztrssq( const RUNTIME_option_t *options,
         STARPU_RW,       RTBLKADDR(SCALESUMSQ, double, SCALESUMSQm, SCALESUMSQn),
         STARPU_PRIORITY, options->priority,
         STARPU_CALLBACK, callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztrssq",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztrtri.c b/runtime/starpu/codelets/codelet_ztrtri.c
index 4c891806c..758542d88 100644
--- a/runtime/starpu/codelets/codelet_ztrtri.c
+++ b/runtime/starpu/codelets/codelet_ztrtri.c
@@ -68,6 +68,8 @@ void INSERT_TASK_ztrtri( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_ztrtri;
     void (*callback)(void*) = options->profiling ? cl_ztrtri_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_RW(A, Am, An);
@@ -84,6 +86,7 @@ void INSERT_TASK_ztrtri( const RUNTIME_option_t *options,
         STARPU_VALUE,    &(options->request),        sizeof(RUNTIME_request_t*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztrtri",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztsmlq_hetra1.c b/runtime/starpu/codelets/codelet_ztsmlq_hetra1.c
index d90d7742f..01704f33a 100644
--- a/runtime/starpu/codelets/codelet_ztsmlq_hetra1.c
+++ b/runtime/starpu/codelets/codelet_ztsmlq_hetra1.c
@@ -73,6 +73,8 @@ void INSERT_TASK_ztsmlq_hetra1( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztsmlq_hetra1;
     void (*callback)(void*) = options->profiling ? cl_ztsmlq_hetra1_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     int ldWORK = side == ChamLeft ? ib : nb;
 
@@ -101,6 +103,7 @@ void INSERT_TASK_ztsmlq_hetra1( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztsmlq_hetra1",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztsmqr_hetra1.c b/runtime/starpu/codelets/codelet_ztsmqr_hetra1.c
index 04adf4260..4c6b5229e 100644
--- a/runtime/starpu/codelets/codelet_ztsmqr_hetra1.c
+++ b/runtime/starpu/codelets/codelet_ztsmqr_hetra1.c
@@ -73,6 +73,8 @@ void INSERT_TASK_ztsmqr_hetra1( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_ztsmqr_hetra1;
     void (*callback)(void*) = options->profiling ? cl_ztsmqr_hetra1_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     int ldWORK = side == ChamLeft ? ib : nb;
 
@@ -101,6 +103,7 @@ void INSERT_TASK_ztsmqr_hetra1( const RUNTIME_option_t *options,
         STARPU_SCRATCH,   options->ws_worker,
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztsmqr_hetra1",
 #endif
diff --git a/runtime/starpu/codelets/codelet_ztstrf.c b/runtime/starpu/codelets/codelet_ztstrf.c
index 1caab2a06..32b3fb5ad 100644
--- a/runtime/starpu/codelets/codelet_ztstrf.c
+++ b/runtime/starpu/codelets/codelet_ztstrf.c
@@ -80,6 +80,8 @@ void INSERT_TASK_ztstrf( const RUNTIME_option_t *options,
     (void)nb;
     struct starpu_codelet *codelet = &cl_ztstrf;
     void (*callback)(void*) = options->profiling ? cl_ztstrf_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
     CHAMELEON_starpu_ws_t *d_work = (CHAMELEON_starpu_ws_t*)(options->ws_host);
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
@@ -107,6 +109,7 @@ void INSERT_TASK_ztstrf( const RUNTIME_option_t *options,
         STARPU_VALUE,    &(options->request),        sizeof(RUNTIME_request_t*),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "ztstrf",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zunmlq.c b/runtime/starpu/codelets/codelet_zunmlq.c
index 7ae725bdd..7f2b6b24f 100644
--- a/runtime/starpu/codelets/codelet_zunmlq.c
+++ b/runtime/starpu/codelets/codelet_zunmlq.c
@@ -106,6 +106,8 @@ void INSERT_TASK_zunmlq( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zunmlq;
     void (*callback)(void*) = options->profiling ? cl_zunmlq_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -129,6 +131,7 @@ void INSERT_TASK_zunmlq( const RUNTIME_option_t *options,
         STARPU_VALUE,    &nb,                sizeof(int),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zunmlq",
 #endif
diff --git a/runtime/starpu/codelets/codelet_zunmqr.c b/runtime/starpu/codelets/codelet_zunmqr.c
index 8ea66722b..de61f52c9 100644
--- a/runtime/starpu/codelets/codelet_zunmqr.c
+++ b/runtime/starpu/codelets/codelet_zunmqr.c
@@ -105,6 +105,8 @@ void INSERT_TASK_zunmqr( const RUNTIME_option_t *options,
 {
     struct starpu_codelet *codelet = &cl_zunmqr;
     void (*callback)(void*) = options->profiling ? cl_zunmqr_callback : NULL;
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(options->request->schedopt);
+    int workerid = (schedopt == NULL) ? -1 : schedopt->workerid;
 
     CHAMELEON_BEGIN_ACCESS_DECLARATION;
     CHAMELEON_ACCESS_R(A, Am, An);
@@ -128,6 +130,7 @@ void INSERT_TASK_zunmqr( const RUNTIME_option_t *options,
         STARPU_VALUE,    &nb,                sizeof(int),
         STARPU_PRIORITY,  options->priority,
         STARPU_CALLBACK,  callback,
+        STARPU_EXECUTE_ON_WORKER, workerid,
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
         STARPU_NAME, "zunmqr",
 #endif
diff --git a/runtime/starpu/control/runtime_async.c b/runtime/starpu/control/runtime_async.c
index ef2dbcc8b..3241acc15 100644
--- a/runtime/starpu/control/runtime_async.c
+++ b/runtime/starpu/control/runtime_async.c
@@ -76,3 +76,60 @@ void RUNTIME_sequence_flush( CHAM_context_t  *chamctxt,
     request->status = status;
     return;
 }
+
+/**
+ *  Create a request
+ */
+int RUNTIME_request_create( CHAM_context_t  *chamctxt,
+                            RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    /* allocate schedopt */
+    request->schedopt = (starpu_option_request_t*)malloc(sizeof(starpu_option_request_t));
+    /* initialize schedopt */
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(request->schedopt);
+    /* default is to not use "execute_on_a_specific_worker" i.e. -1 */
+    schedopt->workerid = -1;
+    request->status = CHAMELEON_SUCCESS;
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Destroy a request
+ */
+int RUNTIME_request_destroy( CHAM_context_t  *chamctxt,
+                             RUNTIME_request_t *request )
+{
+    (void)chamctxt;
+    free(request->schedopt);
+    return CHAMELEON_SUCCESS;
+}
+
+/**
+ *  Set runtime parameter for a request
+ */
+int RUNTIME_request_set( CHAM_context_t  *chamctxt,
+                         RUNTIME_request_t *request,
+                         int param, int value )
+{
+    if ( request->schedopt == NULL ) {
+        chameleon_error("RUNTIME_request_set", "request not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+    starpu_option_request_t* schedopt = (starpu_option_request_t *)(request->schedopt);
+
+    switch ( param ) {
+        case CHAMELEON_REQUEST_WORKERID:
+            if ( (value < -1) || (value >= chamctxt->nworkers) ) {
+                chameleon_error("RUNTIME_request_set", "workerid should be in [-1, NCPUS-1]");
+                return CHAMELEON_ERR_ILLEGAL_VALUE;
+            }
+            schedopt->workerid = value;
+            break;
+        default:
+            chameleon_error("RUNTIME_request_set", "unknown parameter");
+            return CHAMELEON_ERR_ILLEGAL_VALUE;
+    }
+
+    return CHAMELEON_SUCCESS;
+}
\ No newline at end of file
diff --git a/runtime/starpu/control/runtime_control.c b/runtime/starpu/control/runtime_control.c
index 9e29f90f8..69fe75a64 100644
--- a/runtime/starpu/control/runtime_control.c
+++ b/runtime/starpu/control/runtime_control.c
@@ -107,6 +107,9 @@ int RUNTIME_init( CHAM_context_t *chamctxt,
         chamctxt->parallel_enabled = CHAMELEON_FALSE;
 
         hres = chameleon_starpu_init( conf );
+
+        chamctxt->nworkers = ncpus;
+        chamctxt->nthreads_per_worker = nthreads_per_worker;
     }
     else {
         int worker;
diff --git a/runtime/starpu/include/chameleon_starpu.h.in b/runtime/starpu/include/chameleon_starpu.h.in
index 561666430..767c65f13 100644
--- a/runtime/starpu/include/chameleon_starpu.h.in
+++ b/runtime/starpu/include/chameleon_starpu.h.in
@@ -77,6 +77,11 @@
 
 typedef struct starpu_conf starpu_conf_t;
 
+/* Structure used to give some options during one request (procedure) */
+typedef struct starpu_option_request_s {
+    int workerid; // to force task execution on a specific workerid
+} starpu_option_request_t;
+
 /**/
 
 /*
-- 
GitLab