parallel_code.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010-2014, 2016 Université de Bordeaux
  4. * Copyright (C) 2010-2015 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. #include <starpu.h>
  18. #include <omp.h>
  19. #ifdef STARPU_QUICK_CHECK
  20. #define NTASKS 64
  21. #else
  22. #define NTASKS 10
  23. #endif
  24. int tasks_executed[2];
  25. int parallel_code(unsigned *sched_ctx)
  26. {
  27. int i;
  28. int t = 0;
  29. int *cpuids = NULL;
  30. int ncpuids = 0;
  31. starpu_sched_ctx_get_available_cpuids(*sched_ctx, &cpuids, &ncpuids);
  32. // printf("execute task of %d threads \n", ncpuids);
  33. #pragma omp parallel num_threads(ncpuids)
  34. {
  35. starpu_sched_ctx_bind_current_thread_to_cpuid(cpuids[omp_get_thread_num()]);
  36. // printf("cpu = %d ctx%d nth = %d\n", sched_getcpu(), sched_ctx, omp_get_num_threads());
  37. #pragma omp for
  38. for(i = 0; i < NTASKS; i++)
  39. t++;
  40. }
  41. free(cpuids);
  42. tasks_executed[*sched_ctx-1] = t;
  43. return t;
  44. }
  45. static void sched_ctx_func(void *descr[] STARPU_ATTRIBUTE_UNUSED, void *arg)
  46. {
  47. int w = starpu_worker_get_id();
  48. unsigned *sched_ctx = (unsigned*)arg;
  49. int n = parallel_code(sched_ctx);
  50. printf("w %d executed %d it \n", w, n);
  51. }
  52. static struct starpu_codelet sched_ctx_codelet =
  53. {
  54. .cpu_funcs = {sched_ctx_func},
  55. .model = NULL,
  56. .nbuffers = 0,
  57. .name = "sched_ctx"
  58. };
  59. void *th(void* p)
  60. {
  61. unsigned* sched_ctx = (unsigned*)p;
  62. tasks_executed[*sched_ctx-1] = 0;
  63. //here the return of parallel code could be used (as a void*)
  64. starpu_sched_ctx_exec_parallel_code((void*)parallel_code, p, *sched_ctx);
  65. return &tasks_executed[*sched_ctx-1];
  66. }
  67. int main(int argc, char **argv)
  68. {
  69. tasks_executed[0] = 0;
  70. tasks_executed[1] = 0;
  71. int ntasks = NTASKS;
  72. int ret, j, k;
  73. ret = starpu_init(NULL);
  74. if (ret == -ENODEV)
  75. return 77;
  76. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  77. int nprocs1 = 1;
  78. int nprocs2 = 1;
  79. int *procs1, *procs2;
  80. #ifdef STARPU_USE_CPU
  81. unsigned ncpus = starpu_cpu_worker_get_count();
  82. procs1 = (int*)malloc(ncpus*sizeof(int));
  83. procs2 = (int*)malloc(ncpus*sizeof(int));
  84. starpu_worker_get_ids_by_type(STARPU_CPU_WORKER, procs1, ncpus);
  85. nprocs1 = ncpus/2;
  86. nprocs2 = nprocs1;
  87. k = 0;
  88. for(j = nprocs1; j < nprocs1+nprocs2; j++)
  89. procs2[k++] = j;
  90. #else
  91. procs1 = (int*)malloc(nprocs1*sizeof(int));
  92. procs2 = (int*)malloc(nprocs2*sizeof(int));
  93. procs1[0] = 0;
  94. procs2[0] = 0;
  95. #endif
  96. if (nprocs1 < 4)
  97. {
  98. /* Not enough procs */
  99. starpu_shutdown();
  100. return 77;
  101. }
  102. /*create contexts however you want*/
  103. unsigned sched_ctx1 = starpu_sched_ctx_create(procs1, nprocs1, "ctx1", STARPU_SCHED_CTX_POLICY_NAME, "dmda", 0);
  104. unsigned sched_ctx2 = starpu_sched_ctx_create(procs2, nprocs2, "ctx2", STARPU_SCHED_CTX_POLICY_NAME, "dmda", 0);
  105. /*indicate what to do with the resources when context 2 finishes (it depends on your application)*/
  106. // starpu_sched_ctx_set_inheritor(sched_ctx2, sched_ctx1);
  107. int nprocs3 = nprocs1/2;
  108. int nprocs4 = nprocs1/2;
  109. int nprocs5 = nprocs2/2;
  110. int nprocs6 = nprocs2/2;
  111. int procs3[nprocs3];
  112. int procs4[nprocs4];
  113. int procs5[nprocs5];
  114. int procs6[nprocs6];
  115. k = 0;
  116. for(j = 0; j < nprocs3; j++)
  117. procs3[k++] = procs1[j];
  118. k = 0;
  119. for(j = nprocs3; j < nprocs3+nprocs4; j++)
  120. procs4[k++] = procs1[j];
  121. k = 0;
  122. for(j = 0; j < nprocs5; j++)
  123. procs5[k++] = procs2[j];
  124. k = 0;
  125. for(j = nprocs5; j < nprocs5+nprocs6; j++)
  126. procs6[k++] = procs2[j];
  127. int master3 = starpu_sched_ctx_book_workers_for_task(sched_ctx1, procs3, nprocs3);
  128. int master4 = starpu_sched_ctx_book_workers_for_task(sched_ctx1, procs4, nprocs4);
  129. int master5 = starpu_sched_ctx_book_workers_for_task(sched_ctx2, procs5, nprocs5);
  130. int master6 = starpu_sched_ctx_book_workers_for_task(sched_ctx2, procs6, nprocs6);
  131. /* int master1 = starpu_sched_ctx_book_workers_for_task(procs1, nprocs1); */
  132. /* int master2 = starpu_sched_ctx_book_workers_for_task(procs2, nprocs2); */
  133. int i;
  134. for (i = 0; i < ntasks; i++)
  135. {
  136. struct starpu_task *task = starpu_task_create();
  137. task->cl = &sched_ctx_codelet;
  138. task->cl_arg = &sched_ctx1;
  139. /*submit tasks to context*/
  140. ret = starpu_task_submit_to_ctx(task,sched_ctx1);
  141. if (ret == -ENODEV) goto enodev;
  142. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
  143. }
  144. for (i = 0; i < ntasks; i++)
  145. {
  146. struct starpu_task *task = starpu_task_create();
  147. task->cl = &sched_ctx_codelet;
  148. task->cl_arg = &sched_ctx2;
  149. /*submit tasks to context*/
  150. ret = starpu_task_submit_to_ctx(task,sched_ctx2);
  151. if (ret == -ENODEV) goto enodev;
  152. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
  153. }
  154. /* tell starpu when you finished submitting tasks to this context
  155. in order to allow moving resources from this context to the inheritor one
  156. when its corresponding tasks finished executing */
  157. enodev:
  158. /* wait for all tasks at the end*/
  159. starpu_task_wait_for_all();
  160. /* starpu_sched_ctx_unbook_workers_for_task(sched_ctx1, master1); */
  161. /* starpu_sched_ctx_unbook_workers_for_task(sched_ctx2, master2); */
  162. starpu_sched_ctx_unbook_workers_for_task(sched_ctx1, master3);
  163. starpu_sched_ctx_unbook_workers_for_task(sched_ctx1, master4);
  164. starpu_sched_ctx_unbook_workers_for_task(sched_ctx2, master5);
  165. starpu_sched_ctx_unbook_workers_for_task(sched_ctx2, master6);
  166. pthread_t mp[2];
  167. pthread_create(&mp[0], NULL, th, &sched_ctx1);
  168. pthread_create(&mp[1], NULL, th, &sched_ctx2);
  169. pthread_join(mp[0], NULL);
  170. pthread_join(mp[1], NULL);
  171. starpu_sched_ctx_delete(sched_ctx1);
  172. starpu_sched_ctx_delete(sched_ctx2);
  173. printf("ctx%d: tasks starpu executed %d out of %d\n", sched_ctx1, tasks_executed[0], NTASKS);
  174. printf("ctx%d: tasks starpu executed %d out of %d\n", sched_ctx2, tasks_executed[1], NTASKS);
  175. starpu_shutdown();
  176. return (ret == -ENODEV ? 77 : 0);
  177. }