浏览代码

Factorize data packing and export it as starpu_codelet_pack_arg_init, starpu_codelet_pack_arg, starpu_codelet_pack_arg_fini

Samuel Thibault 7 年之前
父节点
当前提交
592323f354
共有 3 个文件被更改,包括 92 次插入73 次删除
  1. 20 1
      doc/doxygen/chapters/api/insert_task.doxy
  2. 14 2
      include/starpu_task_util.h
  3. 58 70
      src/util/starpu_task_insert_utils.c

+ 20 - 1
doc/doxygen/chapters/api/insert_task.doxy

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010-2017                                CNRS
- * Copyright (C) 2009-2011,2014-2016                      Université de Bordeaux
+ * Copyright (C) 2009-2011,2014-2016,2018                 Université de Bordeaux
  * Copyright (C) 2011-2012                                Inria
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -162,6 +162,25 @@ Pack arguments of type ::STARPU_VALUE into a buffer which can be
 given to a codelet and later unpacked with the function
 starpu_codelet_unpack_args().
 
+Instead of calling starpu_codelet_pack_args(), one can also call
+starpu_codelet_pack_arg_init(), then starpu_codelet_pack_arg() for each
+data, then starpu_codelet_pack_arg_fini().
+
+\fn void starpu_codelet_pack_arg_init(struct starpu_codelet_pack_arg *state)
+\ingroup API_Insert_Task
+Initiaze struct starpu_codelet_pack_arg before calling starpu_codelet_pack_arg and
+starpu_codelet_pack_arg_fini. This will simply initialize the content of the structure.
+
+\fn void starpu_codelet_pack_arg(struct starpu_codelet_pack_arg *state, void *ptr, size_t ptr_size)
+Pack one argument into struct starpu_codelet_pack_arg state. That structure
+has to be initialized before with starpu_codelet_pack_arg_init, and after all
+starpu_codelet_pack_arg calls performed, starpu_codelet_pack_arg_fini has to be
+used to get the cl_arg and cl_arg_size to be put in the task.
+
+\fn void starpu_codelet_pack_arg_fini(struct starpu_codelet_pack_arg *state, void **cl_arg, size_t *cl_arg_size)
+\ingroup API_Insert_Task
+Finish packing data, after calling starpu_codelet_pack_arg_init once and starpu_codelet_pack_arg several times.
+
 \fn void starpu_codelet_unpack_args(void *cl_arg, ...)
 \ingroup API_Insert_Task
 Retrieve the arguments of type ::STARPU_VALUE associated to a

+ 14 - 2
include/starpu_task_util.h

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2014                                Inria
  * Copyright (C) 2010-2017                                CNRS
- * Copyright (C) 2010-2015                                Université de Bordeaux
+ * Copyright (C) 2010-2015, 2018                          Université de Bordeaux
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -70,9 +70,21 @@ int starpu_task_insert(struct starpu_codelet *cl, ...);
 /* the function starpu_insert_task has the same semantics as starpu_task_insert, it is kept to avoid breaking old codes */
 int starpu_insert_task(struct starpu_codelet *cl, ...);
 
+void starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, ...);
+
+struct starpu_codelet_pack_arg {
+	char *arg_buffer;
+	size_t arg_buffer_size;
+	size_t current_offset;
+	int nargs;
+};
+
+void starpu_codelet_pack_arg_init(struct starpu_codelet_pack_arg *state);
+void starpu_codelet_pack_arg(struct starpu_codelet_pack_arg *state, const void *ptr, size_t ptr_size);
+void starpu_codelet_pack_arg_fini(struct starpu_codelet_pack_arg *state, void **cl_arg, size_t *cl_arg_size);
+
 void starpu_codelet_unpack_args(void *cl_arg, ...);
 void starpu_codelet_unpack_args_and_copyleft(void *cl_arg, void *buffer, size_t buffer_size, ...);
-void starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, ...);
 
 #ifdef __cplusplus
 }

+ 58 - 70
src/util/starpu_task_insert_utils.c

@@ -21,31 +21,56 @@
 #include <common/utils.h>
 #include <core/task.h>
 
-static void _starpu_pack_arguments(size_t *current_offset, size_t *arg_buffer_size_, char **arg_buffer_, void *ptr, size_t ptr_size)
+void starpu_codelet_pack_arg_init(struct starpu_codelet_pack_arg *state)
 {
-	if (*current_offset + sizeof(ptr_size) + ptr_size > *arg_buffer_size_)
+	state->arg_buffer = NULL;
+	state->arg_buffer_size = 0;
+	state->current_offset = sizeof(int);
+	state->nargs = 0;
+}
+
+void starpu_codelet_pack_arg(struct starpu_codelet_pack_arg *state, const void *ptr, size_t ptr_size)
+{
+	STARPU_ASSERT_MSG(state->current_offset >= sizeof(int), "struct starpu_codelet_pack_arg has to be initialized with starpu_codelet_pack_arg_init");
+	if (state->current_offset + sizeof(ptr_size) + ptr_size > state->arg_buffer_size)
 	{
-		if (*arg_buffer_size_ == 0)
-			*arg_buffer_size_ = 128 + sizeof(ptr_size) + ptr_size;
+		if (state->arg_buffer_size == 0)
+			state->arg_buffer_size = 128 + sizeof(ptr_size) + ptr_size;
 		else
-			*arg_buffer_size_ = 2 * *arg_buffer_size_ + sizeof(ptr_size) + ptr_size;
-		_STARPU_REALLOC(*arg_buffer_, *arg_buffer_size_);
+			state->arg_buffer_size = 2 * state->arg_buffer_size + sizeof(ptr_size) + ptr_size;
+		_STARPU_REALLOC(state->arg_buffer, state->arg_buffer_size);
+	}
+	memcpy(state->arg_buffer+state->current_offset, (void *)&ptr_size, sizeof(ptr_size));
+	state->current_offset += sizeof(ptr_size);
+
+	memcpy(state->arg_buffer+state->current_offset, ptr, ptr_size);
+	state->current_offset += ptr_size;
+	STARPU_ASSERT(state->current_offset <= state->arg_buffer_size);
+	state->nargs++;
+}
+
+void starpu_codelet_pack_arg_fini(struct starpu_codelet_pack_arg *state, void **cl_arg, size_t *cl_arg_size)
+{
+	if (state->nargs)
+	{
+		memcpy(state->arg_buffer, &state->nargs, sizeof(state->nargs));
+	}
+	else
+	{
+		free(state->arg_buffer);
+		state->arg_buffer = NULL;
 	}
-	memcpy(*arg_buffer_+*current_offset, (void *)&ptr_size, sizeof(ptr_size));
-	*current_offset += sizeof(ptr_size);
 
-	memcpy(*arg_buffer_+*current_offset, ptr, ptr_size);
-	*current_offset += ptr_size;
-	STARPU_ASSERT(*current_offset <= *arg_buffer_size_);
+	*cl_arg = state->arg_buffer;
+	*cl_arg_size = state->arg_buffer_size;
 }
 
 int _starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, va_list varg_list)
 {
 	int arg_type;
-	int nargs = 0;
-	char *_arg_buffer = NULL; // We would like a void* but we use a char* to allow pointer arithmetic
-	size_t _arg_buffer_size = 0;
-	size_t current_offset = sizeof(nargs);
+
+	struct starpu_codelet_pack_arg state;
+	starpu_codelet_pack_arg_init(&state);
 
 	while((arg_type = va_arg(varg_list, int)) != 0)
 	{
@@ -69,8 +94,7 @@ int _starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, va_lis
 			void *ptr = va_arg(varg_list, void *);
 			size_t ptr_size = va_arg(varg_list, size_t);
 
-			nargs++;
-			_starpu_pack_arguments(&current_offset, &_arg_buffer_size, &_arg_buffer, ptr, ptr_size);
+			starpu_codelet_pack_arg(&state, ptr, ptr_size);
 		}
 		else if (arg_type==STARPU_CL_ARGS)
 		{
@@ -174,18 +198,7 @@ int _starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, va_lis
 		}
 	}
 
-	if (nargs)
-	{
-		memcpy(_arg_buffer, (int *)&nargs, sizeof(nargs));
-	}
-	else
-	{
-		free(_arg_buffer);
-		_arg_buffer = NULL;
-	}
-
-	*arg_buffer = _arg_buffer;
-	*arg_buffer_size = _arg_buffer_size;
+	starpu_codelet_pack_arg_fini(&state, arg_buffer, arg_buffer_size);
 	return 0;
 }
 
@@ -304,11 +317,7 @@ static inline void starpu_task_insert_process_data_mode_array_arg(struct starpu_
 int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *task, va_list varg_list)
 {
 	int arg_type;
-	char *arg_buffer_ = NULL;
-	size_t arg_buffer_size_ = 0;
-	size_t current_offset = sizeof(int);
 	int current_buffer;
-	int nargs = 0;
 	int allocated_buffers = 0;
 	unsigned ndeps = 0;
 	struct starpu_task **task_deps_array = NULL;
@@ -318,6 +327,9 @@ int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *ta
 	task->cl = cl;
 	current_buffer = 0;
 
+	struct starpu_codelet_pack_arg state;
+	starpu_codelet_pack_arg_init(&state);
+
 	while((arg_type = va_arg(varg_list, int)) != 0)
 	{
 		if (arg_type & STARPU_R || arg_type & STARPU_W || arg_type & STARPU_SCRATCH || arg_type & STARPU_REDUX)
@@ -344,9 +356,7 @@ int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *ta
 		{
 			void *ptr = va_arg(varg_list, void *);
 			size_t ptr_size = va_arg(varg_list, size_t);
-
-			nargs++;
-			_starpu_pack_arguments(&current_offset, &arg_buffer_size_, &arg_buffer_, ptr, ptr_size);
+			starpu_codelet_pack_arg(&state, ptr, ptr_size);
 		}
 		else if (arg_type==STARPU_CL_ARGS)
 		{
@@ -489,23 +499,13 @@ int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *ta
 		}
 	}
 
-	if (nargs)
-	{
-		if (task->cl_arg != NULL)
-		{
+	if (state.nargs) {
+		if (task->cl_arg != NULL) {
 			_STARPU_DISP("Parameters STARPU_CL_ARGS and STARPU_VALUE cannot be used in the same call\n");
-			free(arg_buffer_);
-			arg_buffer_ = NULL;
+			free(state.arg_buffer);
 			return -EINVAL;
 		}
-		memcpy(arg_buffer_, (int *)&nargs, sizeof(nargs));
-		task->cl_arg = arg_buffer_;
-		task->cl_arg_size = arg_buffer_size_;
-	}
-	else
-	{
-		free(arg_buffer_);
-		arg_buffer_ = NULL;
+		starpu_codelet_pack_arg_fini(&state, &task->cl_arg, &task->cl_arg_size);
 	}
 
 	if (task_deps_array)
@@ -520,17 +520,16 @@ int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *ta
 int _fstarpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *task, void **arglist)
 {
 	int arg_i = 0;
-	char *arg_buffer_ = NULL;
-	size_t arg_buffer_size_ = 0;
-	size_t current_offset = sizeof(int);
 	int current_buffer = 0;
-	int nargs = 0;
 	int allocated_buffers = 0;
 	unsigned ndeps = 0;
 	struct starpu_task **task_deps_array = NULL;
 
 	_STARPU_TRACE_TASK_BUILD_START();
 
+	struct starpu_codelet_pack_arg state;
+	starpu_codelet_pack_arg_init(&state);
+
 	task->cl = cl;
 	task->name = NULL;
 	task->cl_arg_free = 1;
@@ -568,8 +567,7 @@ int _fstarpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *t
 			void *ptr = arglist[arg_i];
 			arg_i++;
 			size_t ptr_size = (size_t)(intptr_t)arglist[arg_i];
-			nargs++;
-			_starpu_pack_arguments(&current_offset, &arg_buffer_size_, &arg_buffer_, ptr, ptr_size);
+			starpu_codelet_pack_arg(&state, ptr, ptr_size);
 		}
 		else if (arg_type == STARPU_CL_ARGS)
 		{
@@ -734,23 +732,13 @@ int _fstarpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *t
 		}
 	}
 
-	if (nargs)
-	{
-		if (task->cl_arg != NULL)
-		{
+	if (state.nargs) {
+		if (task->cl_arg != NULL) {
 			_STARPU_DISP("Parameters STARPU_CL_ARGS and STARPU_VALUE cannot be used in the same call\n");
-			free(arg_buffer_);
-			arg_buffer_ = NULL;
+			free(state.arg_buffer);
 			return -EINVAL;
 		}
-		memcpy(arg_buffer_, (int *)&nargs, sizeof(nargs));
-		task->cl_arg = arg_buffer_;
-		task->cl_arg_size = arg_buffer_size_;
-	}
-	else
-	{
-		free(arg_buffer_);
-		arg_buffer_ = NULL;
+		starpu_codelet_pack_arg_fini(&state, &task->cl_arg, &task->cl_arg_size);
 	}
 
 	if (task_deps_array)