Skip to content

Commit

Permalink
- New interface for pthreads. (#79)
Browse files Browse the repository at this point in the history
- The former layout interface is kept for now but will be removed in a forthcoming clean-up

Signed-off-by: Guillaume Mercier <[email protected]>
  • Loading branch information
GuillaumeMercier authored Mar 6, 2024
1 parent 8b2a348 commit 6d70320
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 116 deletions.
65 changes: 46 additions & 19 deletions include/quo-vadis-thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -160,6 +186,7 @@ qv_thread_layout_set_stride(
qv_layout_t *layout,
int stride
);
#endif // USE_LAYOUTS


#ifdef __cplusplus
Expand Down
83 changes: 62 additions & 21 deletions src/quo-vadis-thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -134,8 +178,7 @@ int
qv_thread_layout_set_policy(
qv_layout_t *layout,
qv_policy_t policy
)
{
) {
int rc = QV_SUCCESS;

if (!layout) {
Expand All @@ -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) {
Expand All @@ -172,8 +214,7 @@ int
qv_thread_layout_set_stride(
qv_layout_t *layout,
int stride
)
{
) {
int rc = QV_SUCCESS;

if (!layout) {
Expand Down Expand Up @@ -381,7 +422,7 @@ qv_thread_args_set(
return rc;
}


#endif // USE_LAYOUTS

/*
* vim: ft=cpp ts=4 sts=4 sw=4 expandtab
Expand Down
2 changes: 1 addition & 1 deletion src/qvi-thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
53 changes: 27 additions & 26 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ if(MPI_FOUND)

target_link_libraries(
test-progress-thread
quo-vadis
quo-vadis-mpi
)

Expand Down Expand Up @@ -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) ############################
################################################################################
Expand All @@ -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()
Expand Down Expand Up @@ -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
)

Expand All @@ -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()

Expand Down
50 changes: 1 addition & 49 deletions tests/test-progress-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,9 @@
#include <stdio.h>
#include <pthread.h>
#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:
*
Expand Down

0 comments on commit 6d70320

Please sign in to comment.