starpu_util.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * StarPU
  3. * Copyright (C) Université Bordeaux 1, CNRS 2008-2010 (see AUTHORS file)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #ifndef __STARPU_UTIL_H__
  17. #define __STARPU_UTIL_H__
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <assert.h>
  22. #include <starpu_config.h>
  23. #include <starpu_task.h>
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. #define STARPU_POISON_PTR ((void *)0xdeadbeef)
  28. #define STARPU_MIN(a,b) ((a)<(b)?(a):(b))
  29. #define STARPU_MAX(a,b) ((a)<(b)?(b):(a))
  30. #ifdef STARPU_NO_ASSERT
  31. #define STARPU_ASSERT(x) do {} while(0);
  32. #else
  33. # if defined(__CUDACC__) && defined(STARPU_HAVE_WINDOWS)
  34. # define STARPU_ASSERT(x) do { if (!(x)) *(int*)NULL = 0; } while(0)
  35. # else
  36. # define STARPU_ASSERT(x) assert(x)
  37. # endif
  38. #endif
  39. #define STARPU_ABORT() abort()
  40. #define STARPU_UNLIKELY(expr) (__builtin_expect(!!(expr),0))
  41. #define STARPU_LIKELY(expr) (__builtin_expect(!!(expr),1))
  42. #ifdef __GNUC__
  43. # define STARPU_ATTRIBUTE_UNUSED __attribute__((unused))
  44. #else
  45. # define STARPU_ATTRIBUTE_UNUSED
  46. #endif
  47. #if defined(__i386__) || defined(__x86_64__)
  48. static inline unsigned starpu_cmpxchg(unsigned *ptr, unsigned old, unsigned next) {
  49. __asm__ __volatile__("lock cmpxchgl %2,%1": "+a" (old), "+m" (*ptr) : "q" (next) : "memory");
  50. return old;
  51. }
  52. static inline unsigned starpu_xchg(unsigned *ptr, unsigned next) {
  53. /* Note: xchg is always locked already */
  54. __asm__ __volatile__("xchgl %1,%0": "+m" (*ptr), "+q" (next) : : "memory");
  55. return next;
  56. }
  57. #define STARPU_HAVE_XCHG
  58. #endif
  59. #define STARPU_ATOMIC_SOMETHING(name,expr) \
  60. static inline unsigned starpu_atomic_##name(unsigned *ptr, unsigned value) { \
  61. unsigned old, next; \
  62. while (1) { \
  63. old = *ptr; \
  64. next = expr; \
  65. if (starpu_cmpxchg(ptr, old, next) == old) \
  66. break; \
  67. }; \
  68. return expr; \
  69. }
  70. #ifdef STARPU_HAVE_SYNC_FETCH_AND_ADD
  71. #define STARPU_ATOMIC_ADD(ptr, value) (__sync_fetch_and_add ((ptr), (value)) + (value))
  72. #elif defined(STARPU_HAVE_XCHG)
  73. STARPU_ATOMIC_SOMETHING(add, old + value)
  74. #define STARPU_ATOMIC_ADD(ptr, value) starpu_atomic_add(ptr, value)
  75. #endif
  76. #ifdef STARPU_HAVE_SYNC_FETCH_AND_OR
  77. #define STARPU_ATOMIC_OR(ptr, value) (__sync_fetch_and_or ((ptr), (value)))
  78. #elif defined(STARPU_HAVE_XCHG)
  79. STARPU_ATOMIC_SOMETHING(or, old | value)
  80. #define STARPU_ATOMIC_OR(ptr, value) starpu_atomic_or(ptr, value)
  81. #endif
  82. #ifdef STARPU_HAVE_SYNC_BOOL_COMPARE_AND_SWAP
  83. #define STARPU_BOOL_COMPARE_AND_SWAP(ptr, old, value) (__sync_bool_compare_and_swap ((ptr), (old), (value)))
  84. #elif defined(STARPU_HAVE_XCHG)
  85. #define STARPU_BOOL_COMPARE_AND_SWAP(ptr, old, value) (starpu_cmpxchg((ptr), (old), (value)) == (old))
  86. #endif
  87. #ifdef STARPU_HAVE_SYNC_LOCK_TEST_AND_SET
  88. #define STARPU_TEST_AND_SET(ptr, value) (__sync_lock_test_and_set ((ptr), (value)))
  89. #define STARPU_RELEASE(ptr) (__sync_lock_release ((ptr)))
  90. #elif defined(STARPU_HAVE_XCHG)
  91. #define STARPU_TEST_AND_SET(ptr, value) (starpu_xchg((ptr), (value)))
  92. #define STARPU_RELEASE(ptr) (starpu_xchg((ptr), 0))
  93. #endif
  94. #ifdef STARPU_HAVE_SYNC_SYNCHRONIZE
  95. #define STARPU_SYNCHRONIZE() __sync_synchronize()
  96. #elif defined(__i386__)
  97. #define STARPU_SYNCHRONIZE() __asm__ __volatile__("lock; addl $0,0(%%esp)" ::: "memory")
  98. #elif defined(__x86_64__)
  99. #define STARPU_SYNCHRONIZE() __asm__ __volatile__("mfence" ::: "memory")
  100. #elif defined(__ppc__) || defined(__ppc64__)
  101. #define STARPU_SYNCHRONIZE() __asm__ __volatile__("sync" ::: "memory")
  102. #endif
  103. static inline int starpu_get_env_number(const char *str)
  104. {
  105. char *strval;
  106. strval = getenv(str);
  107. if (strval) {
  108. /* the env variable was actually set */
  109. unsigned val;
  110. char *check;
  111. val = (int)strtol(strval, &check, 10);
  112. STARPU_ASSERT(strcmp(check, "\0") == 0);
  113. //fprintf(stderr, "ENV %s WAS %d\n", str, val);
  114. return val;
  115. }
  116. else {
  117. /* there is no such env variable */
  118. //fprintf("There was no %s ENV\n", str);
  119. return -1;
  120. }
  121. }
  122. /* Add an event in the execution trace if FxT is enabled */
  123. void starpu_trace_user_event(unsigned code);
  124. /* Some helper functions for application using CUBLAS kernels */
  125. void starpu_helper_cublas_init(void);
  126. void starpu_helper_cublas_shutdown(void);
  127. /* Call func(arg) on every worker matching the "where" mask (eg.
  128. * STARPU_CUDA|STARPU_CPU to execute the function on every CPU and every CUDA
  129. * device). This function is synchronous, but the different workers may execute
  130. * the function in parallel.
  131. * */
  132. void starpu_execute_on_each_worker(void (*func)(void *), void *arg, uint32_t where);
  133. /* This creates (and submits) an empty task that unlocks a tag once all its
  134. * dependencies are fulfilled. */
  135. void starpu_create_sync_task(starpu_tag_t sync_tag, unsigned ndeps, starpu_tag_t *deps,
  136. void (*callback)(void *), void *callback_arg);
  137. /* Constants used by the starpu_insert_task helper to determine the different types of argument */
  138. #define STARPU_VALUE (1<<3) /* Pointer to a constant value */
  139. #define STARPU_CALLBACK (1<<4) /* Callback function */
  140. #define STARPU_CALLBACK_ARG (1<<5) /* Argument of the callback function (of type void *) */
  141. #define STARPU_PRIORITY (1<<6) /* Priority associated to the task */
  142. /* Wrapper to create a task. TODO document this interface */
  143. void starpu_insert_task(starpu_codelet *cl, ...);
  144. /* Retrieve the arguments of type STARPU_VALUE associated to a task
  145. * automatically created using starpu_insert_task. */
  146. void starpu_unpack_cl_args(void *cl_arg, ...);
  147. #ifdef __cplusplus
  148. }
  149. #endif
  150. #endif // __STARPU_UTIL_H__