From 29990ab017f94999ac616654542d9cbe134f0265 Mon Sep 17 00:00:00 2001 From: Guillaume Mercier Date: Wed, 6 Mar 2024 20:33:17 +0100 Subject: [PATCH] - New interface for pthreads. - The former layout interface is kept for now but will be removed in a forthcoming clean-up Signed-off-by: Guillaume Mercier --- include/quo-vadis-thread.h | 65 +++++++++++++++++++--------- src/quo-vadis-thread.cc | 83 +++++++++++++++++++++++++++--------- src/qvi-thread.cc | 2 +- tests/CMakeLists.txt | 53 ++++++++++++----------- tests/test-progress-thread.c | 50 +--------------------- 5 files changed, 137 insertions(+), 116 deletions(-) diff --git a/include/quo-vadis-thread.h b/include/quo-vadis-thread.h index b8471427..f5f3d8c6 100644 --- a/include/quo-vadis-thread.h +++ b/include/quo-vadis-thread.h @@ -53,6 +53,51 @@ typedef enum qv_policy_s { QV_POLICY_CHOOSE } qv_policy_t; + +/** + * Creates a thread context. + */ +int +qv_thread_context_create( + qv_context_t **ctx +); + + +/** + * Frees resources associated with a context created by + * qv_thread_context_create(). + */ +int +qv_thread_context_free( + qv_context_t *ctx +); + + +#ifndef USE_LAYOUTS +typedef struct { + qv_context_t *ctx; + qv_scope_t *scope; + void *(*thread_routine)(void *); + void *arg; +} qv_thread_args_t; + + +void * +qv_thread_routine( + void * arg +); + + +int +qv_pthread_create( + pthread_t *thread, + pthread_attr_t *attr, + void *(*thread_routine)(void *arg), + void *arg, + qv_context_t *ctx, + qv_scope_t *scope +); +#else /** * Layout for fine-grain binding * with default behaviour @@ -93,25 +138,6 @@ typedef struct { int num_th; } qv_thread_args_t; - -/** - * Creates a thread context. - */ -int -qv_thread_context_create( - qv_context_t **ctx -); - - -/** - * Frees resources associated with a context created by - * qv_thread_context_create(). - */ -int -qv_thread_context_free( - qv_context_t *ctx -); - int qv_thread_layout_create( qv_context_t *ctx, @@ -160,6 +186,7 @@ qv_thread_layout_set_stride( qv_layout_t *layout, int stride ); +#endif // USE_LAYOUTS #ifdef __cplusplus diff --git a/src/quo-vadis-thread.cc b/src/quo-vadis-thread.cc index 0c39bd1b..518d34b5 100644 --- a/src/quo-vadis-thread.cc +++ b/src/quo-vadis-thread.cc @@ -89,32 +89,76 @@ qv_thread_context_create( return rc; } +#ifndef USE_LAYOUTS +//New interface +void * +qv_thread_routine( + void * arg +) { + qv_thread_args_t *arg_ptr = (qv_thread_args_t *) arg; + // fprintf(stdout,"qv_thread_routine: ctx=%p scope=%p\n", qvp->ctx, qvp->scope); + + int rc = qv_bind_push(arg_ptr->ctx, arg_ptr->scope); + if (rc != QV_SUCCESS) { + // char const *ers = "qv_bind_push() failed"; + // qvi_test_panic("%s (rc=%s)", ers, qv_strerr(rc)); + pthread_exit(NULL); + } + + void *ret = arg_ptr->thread_routine(arg_ptr->arg); + + // Free memory allocated in qv_pthread_create + //free(arg_ptr); + delete arg_ptr; + pthread_exit(ret); +} + +int +qv_pthread_create( + pthread_t *thread, + pthread_attr_t *attr, + void *(*thread_routine)(void *arg), + void *arg, + qv_context_t *ctx, + qv_scope_t *scope +) { + // Memory will be freed in qv_thread_routine to avoid memory leaks + qv_thread_args_t *arg_ptr = qvi_new qv_thread_args_t(); + //(qv_thread_args_t *)malloc(sizeof(qv_thread_args_t)); + arg_ptr->ctx = ctx; + arg_ptr->scope = scope; + arg_ptr->thread_routine = thread_routine; + arg_ptr->arg = arg; + + // fprintf(stdout,"qv_pthread_create: ctx=%p scope=%p\n", ctx, scope); + return pthread_create(thread, attr, qv_thread_routine, arg_ptr); +} +#else // USE_LAYOUTS +// Layout interface int qv_thread_layout_create( // use hwpool if necessary qv_context_t *ctx, qv_layout_params_t params, qv_layout_t **layout -) -{ - int rc = QV_SUCCESS; - qv_layout_t *ilay = qvi_new qv_layout_t(); +) { + int rc = QV_SUCCESS; + qv_layout_t *ilay = qvi_new qv_layout_t(); - ilay->hwl = qvi_rmi_client_hwloc_get(ctx->rmi); - ilay->hw_topo = qvi_hwloc_get_topo_obj(ilay->hwl); - ilay->params = params; - ilay->ctx = ctx; - memset(&ilay->cached_info,0,sizeof(qv_layout_cached_info_t)); - ilay->is_cached = 0; + ilay->hwl = qvi_rmi_client_hwloc_get(ctx->rmi); + ilay->hw_topo = qvi_hwloc_get_topo_obj(ilay->hwl); + ilay->params = params; + ilay->ctx = ctx; + memset(&ilay->cached_info,0,sizeof(qv_layout_cached_info_t)); + ilay->is_cached = 0; - *layout = ilay; - return rc; + *layout = ilay; + return rc; } int qv_thread_layout_free( qv_layout_t *layout -) -{ +){ int rc = QV_SUCCESS; if (!layout) { @@ -134,8 +178,7 @@ int qv_thread_layout_set_policy( qv_layout_t *layout, qv_policy_t policy -) -{ +) { int rc = QV_SUCCESS; if (!layout) { @@ -153,8 +196,7 @@ int qv_thread_layout_set_obj_type( qv_layout_t *layout, qv_hw_obj_type_t obj_type -) -{ +) { int rc = QV_SUCCESS; if (!layout) { @@ -172,8 +214,7 @@ int qv_thread_layout_set_stride( qv_layout_t *layout, int stride -) -{ +) { int rc = QV_SUCCESS; if (!layout) { @@ -381,7 +422,7 @@ qv_thread_args_set( return rc; } - +#endif // USE_LAYOUTS /* * vim: ft=cpp ts=4 sts=4 sw=4 expandtab diff --git a/src/qvi-thread.cc b/src/qvi-thread.cc index 6925f3a6..5d38cc73 100644 --- a/src/qvi-thread.cc +++ b/src/qvi-thread.cc @@ -586,7 +586,7 @@ static int qvi_get_subgroup_info( idx2++; *new_id = (idx2 - idx); -#pragma omp barrier // to prevent the quickest hread to remove data before all others have used it +#pragma omp barrier // to prevent the quickest thread to remove data before all others have used it #pragma omp single delete [] lptr; return QV_SUCCESS; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cadbe406..80b6348d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -215,6 +215,7 @@ if(MPI_FOUND) target_link_libraries( test-progress-thread + quo-vadis quo-vadis-mpi ) @@ -263,18 +264,18 @@ if(MPI_FOUND) ############################# HYBRID TESTS (PThreads) ########################## ################################################################################ - add_executable( - test-mpi-pthreads-layout - qvi-test-common.h - test-mpi-pthreads-layout.c - ) + #add_executable( + #test-mpi-pthreads-layout + #qvi-test-common.h + #test-mpi-pthreads-layout.c + #) - target_link_libraries( - test-mpi-pthreads-layout - quo-vadis - quo-vadis-mpi - ) + #target_link_libraries( + #test-mpi-pthreads-layout + #quo-vadis + #quo-vadis-mpi + #) ############################# HYBRID TESTS (OpenMP) ############################ ################################################################################ @@ -292,19 +293,19 @@ if(MPI_FOUND) OpenMP::OpenMP_C ) - add_executable( - test-mpi-threads-layout - qvi-test-common.h - test-mpi-threads-layout.c - ) + #add_executable( + # test-mpi-threads-layout + # qvi-test-common.h + # test-mpi-threads-layout.c + #) - target_link_libraries( - test-mpi-threads-layout - quo-vadis - quo-vadis-mpi - OpenMP::OpenMP_C - ) + #target_link_libraries( + # test-mpi-threads-layout + # quo-vadis + # quo-vadis-mpi + # OpenMP::OpenMP_C + #) endif() endif() @@ -376,7 +377,7 @@ if(MPI_FOUND) test-mpi-api test-mpi-getdev test-mpi-scopes - test-mpi-pthreads-layout + #test-mpi-pthreads-layout PROPERTIES LINKER_LANGUAGE C ) @@ -385,10 +386,10 @@ if(MPI_FOUND) test-mpi-threads PROPERTIES LINKER_LANGUAGE C ) - set_target_properties( - test-mpi-threads-layout - PROPERTIES LINKER_LANGUAGE C - ) + #set_target_properties( + # test-mpi-threads-layout + # PROPERTIES LINKER_LANGUAGE C + #) endif() endif() diff --git a/tests/test-progress-thread.c b/tests/test-progress-thread.c index 464fa260..1f888dfe 100644 --- a/tests/test-progress-thread.c +++ b/tests/test-progress-thread.c @@ -2,57 +2,9 @@ #include #include #include "quo-vadis-mpi.h" +#include "quo-vadis-thread.h" #include "qvi-test-common.h" - -/* - * It would be nice to have these defined as part of QV. - * It would simplify usage and avoid errors. - */ - -typedef struct { - qv_context_t *ctx; - qv_scope_t *scope; - void *(*thread_routine)(void *); - void *arg; -} qv_thread_args_t; - -void *qv_thread_routine(void * arg) -{ - qv_thread_args_t *qvp = (qv_thread_args_t *) arg; - // printf("qv_thread_routine: ctx=%p scope=%p\n", qvp->ctx, qvp->scope); - - int rc = qv_bind_push(qvp->ctx, qvp->scope); - if (rc != QV_SUCCESS) { - char const *ers = "qv_bind_push() failed"; - qvi_test_panic("%s (rc=%s)", ers, qv_strerr(rc)); - } - - qvp->thread_routine(qvp->arg); - - /* Memory allocated in qv_pthread_create */ - free(qvp); - - pthread_exit(NULL); -} - -int qv_pthread_create(pthread_t *thread, pthread_attr_t *attr, - void *(*thread_routine)(void *arg), void *arg, - qv_context_t *ctx, qv_scope_t *scope) -{ - /* Memory will be freed in qv_thread_routine to avoid - a memory leak */ - qv_thread_args_t *qv_thargs = malloc(sizeof(qv_thread_args_t)); - qv_thargs->ctx = ctx; - qv_thargs->scope = scope; - qv_thargs->thread_routine = thread_routine; - qv_thargs->arg = arg; - - // printf("qv_pthread_create: ctx=%p scope=%p\n", ctx, scope); - return pthread_create(thread, attr, qv_thread_routine, qv_thargs); -} - - /* * QV Todo: *