hello_world.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2012 Inria
  4. * Copyright (C) 2009-2011,2014-2015 Université de Bordeaux
  5. * Copyright (C) 2010-2013,2015,2017 CNRS
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. /*
  19. * This examples demonstrates how to construct and submit a task to StarPU and
  20. * more precisely:
  21. * - how to allocate a new task structure (starpu_task_create)
  22. * - how to describe a multi-versionned computational kernel (ie. a codelet)
  23. * - how to pass an argument to the codelet (task->cl_arg)
  24. * - how to declare a callback function that is called once the task has been
  25. * executed
  26. * - how to specify if starpu_task_submit is a blocking or non-blocking
  27. * operation (task->synchronous)
  28. */
  29. #include <stdio.h>
  30. #include <stdint.h>
  31. #include <starpu.h>
  32. #define FPRINTF(ofile, fmt, ...) do { if (!getenv("STARPU_SSILENT")) {fprintf(ofile, fmt, ## __VA_ARGS__); }} while(0)
  33. /* When the task is done, task->callback_func(task->callback_arg) is called. Any
  34. * callback function must have the prototype void (*)(void *).
  35. * NB: Callback are NOT allowed to perform potentially blocking operations */
  36. void callback_func(void *callback_arg)
  37. {
  38. FPRINTF(stdout, "Callback function got argument %p\n", callback_arg);
  39. }
  40. /* Every implementation of a codelet must have this prototype, the first
  41. * argument (buffers) describes the buffers/streams that are managed by the
  42. * DSM; the second arguments references read-only data that is passed as an
  43. * argument of the codelet (task->cl_arg). Here, "buffers" is unused as there
  44. * are no data input/output managed by the DSM (cl.nbuffers = 0) */
  45. struct params
  46. {
  47. int i;
  48. float f;
  49. };
  50. void cpu_func(void *buffers[], void *cl_arg)
  51. {
  52. (void)buffers;
  53. struct params *params = (struct params *) cl_arg;
  54. FPRINTF(stdout, "Hello world (params = {%i, %f} )\n", params->i, params->f);
  55. }
  56. int main(void)
  57. {
  58. struct starpu_codelet cl;
  59. struct starpu_task *task;
  60. struct params params = {1, 2.0f};
  61. int ret;
  62. /* initialize StarPU : passing a NULL argument means that we use
  63. * default configuration for the scheduling policies and the number of
  64. * processors/accelerators */
  65. ret = starpu_init(NULL);
  66. if (ret == -ENODEV)
  67. return 77;
  68. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  69. /* create a new task that is non-blocking by default : the task is not
  70. * submitted to the scheduler until the starpu_task_submit function is
  71. * called */
  72. task = starpu_task_create();
  73. starpu_codelet_init(&cl);
  74. /* this codelet may only be executed on a CPU, and its cpu
  75. * implementation is function "cpu_func" */
  76. cl.cpu_funcs[0] = cpu_func;
  77. cl.cpu_funcs_name[0] = "cpu_func";
  78. /* the codelet does not manipulate any data that is managed
  79. * by our DSM */
  80. cl.nbuffers = 0;
  81. cl.name="hello";
  82. /* the task uses codelet "cl" */
  83. task->cl = &cl;
  84. /* It is possible to pass buffers that are not managed by the DSM to the
  85. * kernels: the second argument of the "cpu_func" function is a pointer to a
  86. * buffer that contains information for the codelet (cl_arg stands for
  87. * codelet argument). In the case of accelerators, it is possible that
  88. * the codelet is given a pointer to a copy of that buffer: this buffer
  89. * is read-only so that any modification is not passed to other copies
  90. * of the buffer. For this reason, a buffer passed as a codelet
  91. * argument (cl_arg) is NOT a valid synchronization medium! */
  92. task->cl_arg = &params;
  93. task->cl_arg_size = sizeof(params);
  94. /* once the task has been executed, callback_func(0x42)
  95. * will be called on a CPU */
  96. task->callback_func = callback_func;
  97. task->callback_arg = (void*) (uintptr_t) 0x42;
  98. /* starpu_task_submit will be a blocking call */
  99. task->synchronous = 1;
  100. /* submit the task to StarPU */
  101. ret = starpu_task_submit(task);
  102. if (ret == -ENODEV) goto enodev;
  103. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
  104. /* terminate StarPU: statistics and other debug outputs are not
  105. * guaranteed to be generated unless this function is called. Once it
  106. * is called, it is not possible to submit tasks anymore, and the user
  107. * is responsible for making sure all tasks have already been executed:
  108. * calling starpu_shutdown() before the termination of all the tasks
  109. * results in an undefined behaviour */
  110. starpu_shutdown();
  111. return 0;
  112. enodev:
  113. starpu_shutdown();
  114. return 77;
  115. }