hello_world_top.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010 Université de Bordeaux
  4. * Copyright (C) 2010, 2011, 2012, 2016, 2017 CNRS
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. /*
  18. * This examples demonstrates how to construct and submit a task to StarPU and
  19. * more precisely:
  20. * - how to allocate a new task structure (starpu_task_create)
  21. * - how to describe a multi-versionned computational kernel (ie. a codelet)
  22. * - how to pass an argument to the codelet (task->cl_arg)
  23. * - how to declare a callback function that is called once the task has been
  24. * executed
  25. * - how to specify if starpu_task_submit is a blocking or non-blocking
  26. * operation (task->synchronous)
  27. */
  28. #include <stdio.h>
  29. #include <stdint.h>
  30. #include <starpu.h>
  31. #include <stdlib.h>
  32. #include <time.h>
  33. /* Example of enum param */
  34. char* names[] = {"Paul", "Jean", "Jaques", "Alain", "Brian"};
  35. int names_len = 5;
  36. int name_selected=2; //must be between 0 and names_len-1
  37. /* Exemple of int param */
  38. int number_of_addition = 30;
  39. /* Exemple of bool param */
  40. int stop_after_5_task = 0;
  41. /* When the task is done, task->callback_func(task->callback_arg) is called. Any
  42. * callback function must have the prototype void (*)(void *).
  43. * NB: Callback are NOT allowed to perform potentially blocking operations */
  44. void callback_func(void *callback_arg)
  45. {
  46. printf("Callback function got argument %p\n", callback_arg);
  47. }
  48. /* Every implementation of a codelet must have this prototype, the first
  49. * argument (buffers) describes the buffers/streams that are managed by the
  50. * DSM; the second arguments references read-only data that is passed as an
  51. * argument of the codelet (task->cl_arg). Here, "buffers" is unused as there
  52. * are no data input/output managed by the DSM (cl.nbuffers = 0) */
  53. struct params
  54. {
  55. int i;
  56. float f;
  57. };
  58. void cpu_func(void *buffers[], void *cl_arg)
  59. {
  60. (void)buffers;
  61. struct params *params = (struct params *) cl_arg;
  62. //loosing time for top example...
  63. int sum = 0;
  64. int i = 0;
  65. while(i<number_of_addition*1000000)
  66. {
  67. sum+=rand();
  68. i++;
  69. }
  70. printf("Hello %s (params = {%i, %f} ) sum=%d\n",
  71. names[name_selected],
  72. params->i,
  73. params->f,
  74. sum);
  75. }
  76. void callback_name_changed(struct starpu_top_param* param)
  77. {
  78. (void)param;
  79. char* message = (char *) malloc(256);
  80. sprintf(message, "Name have been changed to %s", names[name_selected]);
  81. starpu_top_debug_log(message);
  82. free(message);
  83. }
  84. void callback_number_addition_changed(struct starpu_top_param* param)
  85. {
  86. (void)param;
  87. char* message = (char *) malloc(256);
  88. sprintf(message, "Number of addition is now %d", number_of_addition);
  89. starpu_top_debug_log(message);
  90. free(message);
  91. }
  92. struct starpu_codelet cl =
  93. {
  94. /* this codelet may only be executed on a CPU, and its cpu
  95. * implementation is function "cpu_func" */
  96. .cpu_funcs = {cpu_func},
  97. /* the codelet does not manipulate any data that is managed
  98. * by our DSM */
  99. .nbuffers = 0
  100. };
  101. int main(void)
  102. {
  103. int ret;
  104. srand ( time(NULL) );
  105. /* initialize StarPU : passing a NULL argument means that we use
  106. * default configuration for the scheduling policies and the number of
  107. * processors/accelerators */
  108. ret = starpu_init(NULL);
  109. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  110. /*init starpu_top*/
  111. struct starpu_top_data * loop_count =
  112. starpu_top_add_data_integer("Loop count", 0,124,1);
  113. struct starpu_top_data * remain_count =
  114. starpu_top_add_data_integer("Remaining loop", 0,124,1);
  115. struct starpu_top_data * midle_reach =
  116. starpu_top_add_data_boolean("Midle reached", 1);
  117. struct starpu_top_param* name =
  118. starpu_top_register_parameter_enum("Your name : ",
  119. &name_selected,
  120. names,
  121. names_len,
  122. callback_name_changed);
  123. struct starpu_top_param * number_of_addition_param =
  124. starpu_top_register_parameter_integer("Number of Millions of addition",
  125. &number_of_addition,
  126. 0,
  127. 50,
  128. callback_number_addition_changed);
  129. STARPU_ASSERT(number_of_addition_param != NULL);
  130. struct starpu_top_param * stop5_param =
  131. starpu_top_register_parameter_boolean("Stop after 5 task ?",
  132. &stop_after_5_task,
  133. NULL);
  134. STARPU_ASSERT(stop5_param != NULL);
  135. //all parameters are initialized, we can connect to UI
  136. starpu_top_init_and_wait("Serveur de test HelloWorld");
  137. //set "default value"
  138. starpu_top_update_data_boolean(midle_reach, 0);
  139. /* create a new task that is non-blocking by default : the task is not
  140. * submitted to the scheduler until the starpu_task_submit function is
  141. * called */
  142. /*
  143. * For this simple example, we make 124 iter
  144. */
  145. struct starpu_task *task[124];
  146. int i;
  147. for(i=0; i<124; i++)
  148. {
  149. starpu_top_update_data_integer(loop_count, i);
  150. starpu_top_update_data_integer(remain_count, 124-i);
  151. if(i==62)
  152. {
  153. starpu_top_update_data_boolean(midle_reach, 1);
  154. }
  155. if(i==25)
  156. {
  157. //changing name
  158. name_selected = 1;
  159. starpu_top_update_parameter(name);
  160. }
  161. if(i>4 && stop_after_5_task)
  162. {
  163. break;
  164. }
  165. task[i]=starpu_task_create();
  166. /* the task uses codelet "cl" */
  167. task[i]->cl = &cl;
  168. /* It is possible to pass buffers that are not managed by the DSM to the
  169. * kernels: the second argument of the "cpu_func" function is a pointer to a
  170. * buffer that contains information for the codelet (cl_arg stands for
  171. * codelet argument). In the case of accelerators, it is possible that
  172. * the codelet is given a pointer to a copy of that buffer: this buffer
  173. * is read-only so that any modification is not passed to other copies
  174. * of the buffer. For this reason, a buffer passed as a codelet
  175. * argument (cl_arg) is NOT a valid synchronization medium! */
  176. struct params params = { i, 2.0f };
  177. task[i]->cl_arg = &params;
  178. task[i]->cl_arg_size = sizeof(params);
  179. /* once the task has been executed, callback_func(0x42)
  180. * will be called on a CPU */
  181. task[i]->callback_func = callback_func;
  182. task[i]->callback_arg = (void*) (uintptr_t) 0x42;
  183. /* starpu_task_submit will be a blocking call */
  184. task[i]->synchronous = 1;
  185. /* submit the task to StarPU */
  186. if(number_of_addition==42)
  187. starpu_top_debug_lock("debug stop point because of 42 !");
  188. ret = starpu_task_submit(task[i]);
  189. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
  190. }
  191. /* terminate StarPU: statistics and other debug outputs are not
  192. * guaranteed to be generated unless this function is called. Once it
  193. * is called, it is not possible to submit tasks anymore, and the user
  194. * is responsible for making sure all tasks have already been executed:
  195. * calling starpu_shutdown() before the termination of all the tasks
  196. * results in an undefined behaviour */
  197. starpu_shutdown();
  198. return 0;
  199. }