coo_interface.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2012 inria
  4. *
  5. * StarPU 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. * StarPU 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. #include <starpu.h>
  17. #include <common/fxt.h>
  18. #include <datawizard/memalloc.h>
  19. static int
  20. copy_any_to_any(void *src_interface, unsigned src_node,
  21. void *dst_interface, unsigned dst_node, void *async_data)
  22. {
  23. size_t size = 0;
  24. struct starpu_coo_interface *src_coo, *dst_coo;
  25. int ret = 0;
  26. src_coo = (struct starpu_coo_interface *) src_interface;
  27. dst_coo = (struct starpu_coo_interface *) dst_interface;
  28. size = src_coo->n_values * sizeof(src_coo->columns[0]);
  29. if (starpu_interface_copy(
  30. (uintptr_t) src_coo->columns, 0, src_node,
  31. (uintptr_t) dst_coo->columns, 0, dst_node,
  32. size, async_data))
  33. ret = -EAGAIN;
  34. /* sizeof(src_coo->columns[0]) == sizeof(src_coo->rows[0]) */
  35. if (starpu_interface_copy(
  36. (uintptr_t) src_coo->rows, 0, src_node,
  37. (uintptr_t) dst_coo->rows, 0, dst_node,
  38. size, async_data))
  39. ret = -EAGAIN;
  40. size = src_coo->n_values * src_coo->elemsize;
  41. if (starpu_interface_copy(
  42. src_coo->values, 0, src_node,
  43. dst_coo->values, 0, dst_node,
  44. size, async_data))
  45. ret = -EAGAIN;
  46. _STARPU_TRACE_DATA_COPY(src_node, dst_node,
  47. src_coo->n_values *
  48. (2 * sizeof(src_coo->rows[0]) + src_coo->elemsize));
  49. return ret;
  50. }
  51. static const struct starpu_data_copy_methods coo_copy_data_methods =
  52. {
  53. .any_to_any = copy_any_to_any,
  54. };
  55. static void
  56. register_coo_handle(starpu_data_handle_t handle, unsigned home_node,
  57. void *data_interface)
  58. {
  59. struct starpu_coo_interface *coo_interface =
  60. (struct starpu_coo_interface *) data_interface;
  61. unsigned node;
  62. for (node = 0; node < STARPU_MAXNODES; node++)
  63. {
  64. struct starpu_coo_interface *local_interface;
  65. local_interface = (struct starpu_coo_interface *)
  66. starpu_data_get_interface_on_node(handle, node);
  67. if (node == home_node)
  68. {
  69. local_interface->values = coo_interface->values;
  70. local_interface->columns = coo_interface->columns;
  71. local_interface->rows = coo_interface->rows;
  72. }
  73. else
  74. {
  75. local_interface->values = 0;
  76. local_interface->columns = 0;
  77. local_interface->rows = 0;
  78. }
  79. local_interface->id = coo_interface->id;
  80. local_interface->nx = coo_interface->nx;
  81. local_interface->ny = coo_interface->ny;
  82. local_interface->n_values = coo_interface->n_values;
  83. local_interface->elemsize = coo_interface->elemsize;
  84. }
  85. }
  86. static starpu_ssize_t
  87. allocate_coo_buffer_on_node(void *data_interface, unsigned dst_node)
  88. {
  89. uint32_t *addr_columns = NULL;
  90. uint32_t *addr_rows = NULL;
  91. uintptr_t addr_values = 0;
  92. struct starpu_coo_interface *coo_interface =
  93. (struct starpu_coo_interface *) data_interface;
  94. uint32_t n_values = coo_interface->n_values;
  95. size_t elemsize = coo_interface->elemsize;
  96. addr_columns = (void*) starpu_malloc_on_node(dst_node, n_values * sizeof(coo_interface->columns[0]));
  97. if (STARPU_UNLIKELY(addr_columns == NULL))
  98. goto fail_columns;
  99. addr_rows = (void*) starpu_malloc_on_node(dst_node, n_values * sizeof(coo_interface->rows[0]));
  100. if (STARPU_UNLIKELY(addr_rows == NULL))
  101. goto fail_rows;
  102. addr_values = starpu_malloc_on_node(dst_node, n_values * elemsize);
  103. if (STARPU_UNLIKELY(addr_values == (uintptr_t) NULL))
  104. goto fail_values;
  105. coo_interface->columns = addr_columns;
  106. coo_interface->rows = addr_rows;
  107. coo_interface->values = addr_values;
  108. return n_values * (sizeof(coo_interface->columns[0]) + sizeof(coo_interface->rows[0]) + elemsize);
  109. fail_values:
  110. starpu_free_on_node(dst_node, (uintptr_t) addr_rows, n_values * sizeof(coo_interface->rows[0]));
  111. fail_rows:
  112. starpu_free_on_node(dst_node, (uintptr_t) addr_columns, n_values * sizeof(coo_interface->columns[0]));
  113. fail_columns:
  114. return -ENOMEM;
  115. }
  116. static void
  117. free_coo_buffer_on_node(void *data_interface, unsigned node)
  118. {
  119. struct starpu_coo_interface *coo_interface = (struct starpu_coo_interface *) data_interface;
  120. uint32_t n_values = coo_interface->n_values;
  121. size_t elemsize = coo_interface->elemsize;
  122. starpu_free_on_node(node, (uintptr_t) coo_interface->columns, n_values * sizeof(coo_interface->columns[0]));
  123. starpu_free_on_node(node, (uintptr_t) coo_interface->rows, n_values * sizeof(coo_interface->rows[0]));
  124. starpu_free_on_node(node, coo_interface->values, n_values * elemsize);
  125. }
  126. static size_t
  127. coo_interface_get_size(starpu_data_handle_t handle)
  128. {
  129. struct starpu_coo_interface *coo_interface;
  130. coo_interface = (struct starpu_coo_interface *)
  131. starpu_data_get_interface_on_node(handle, STARPU_MAIN_RAM);
  132. return coo_interface->nx * coo_interface->ny * coo_interface->elemsize;
  133. }
  134. static uint32_t
  135. coo_interface_footprint(starpu_data_handle_t handle)
  136. {
  137. struct starpu_coo_interface *coo_interface;
  138. coo_interface = (struct starpu_coo_interface *)
  139. starpu_data_get_interface_on_node(handle, STARPU_MAIN_RAM);
  140. return starpu_hash_crc32c_be(coo_interface->nx * coo_interface->ny, 0);
  141. }
  142. static int
  143. coo_compare(void *a, void *b)
  144. {
  145. struct starpu_coo_interface *coo_a, *coo_b;
  146. coo_a = (struct starpu_coo_interface *) a;
  147. coo_b = (struct starpu_coo_interface *) b;
  148. return (coo_a->nx == coo_b->nx &&
  149. coo_a->ny == coo_b->ny &&
  150. coo_a->n_values == coo_b->n_values &&
  151. coo_a->elemsize == coo_b->elemsize);
  152. }
  153. static void
  154. display_coo_interface(starpu_data_handle_t handle, FILE *f)
  155. {
  156. struct starpu_coo_interface *coo_interface =
  157. coo_interface = (struct starpu_coo_interface *)
  158. starpu_data_get_interface_on_node(handle, STARPU_MAIN_RAM);
  159. fprintf(f, "%u\t%u", coo_interface->nx, coo_interface->ny);
  160. }
  161. static ssize_t describe(void *data_interface, char *buf, size_t size)
  162. {
  163. struct starpu_coo_interface *coo = (struct starpu_coo_interface *) data_interface;
  164. return snprintf(buf, size, "M%ux%ux%ux%u",
  165. (unsigned) coo->nx,
  166. (unsigned) coo->ny,
  167. (unsigned) coo->n_values,
  168. (unsigned) coo->elemsize);
  169. }
  170. struct starpu_data_interface_ops starpu_interface_coo_ops =
  171. {
  172. .register_data_handle = register_coo_handle,
  173. .allocate_data_on_node = allocate_coo_buffer_on_node,
  174. .handle_to_pointer = NULL,
  175. .free_data_on_node = free_coo_buffer_on_node,
  176. .copy_methods = &coo_copy_data_methods,
  177. .get_size = coo_interface_get_size,
  178. .footprint = coo_interface_footprint,
  179. .compare = coo_compare,
  180. .interfaceid = STARPU_COO_INTERFACE_ID,
  181. .interface_size = sizeof(struct starpu_coo_interface),
  182. .display = display_coo_interface,
  183. .describe = describe
  184. };
  185. void
  186. starpu_coo_data_register(starpu_data_handle_t *handleptr, unsigned home_node,
  187. uint32_t nx, uint32_t ny, uint32_t n_values,
  188. uint32_t *columns, uint32_t *rows,
  189. uintptr_t values, size_t elemsize)
  190. {
  191. struct starpu_coo_interface coo_interface =
  192. {
  193. .id = STARPU_COO_INTERFACE_ID,
  194. .values = values,
  195. .columns = columns,
  196. .rows = rows,
  197. .nx = nx,
  198. .ny = ny,
  199. .n_values = n_values,
  200. .elemsize = elemsize,
  201. };
  202. starpu_data_register(handleptr, home_node, &coo_interface,
  203. &starpu_interface_coo_ops);
  204. }