Branch data Line data Source code
1 : : /* StarPU --- Runtime system for heterogeneous multicore architectures.
2 : : *
3 : : * Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
4 : : * Copyright (C) 2013 Centre National de la Recherche Scientifique
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 : : #include <starpu.h>
19 : :
20 : : /* XXX Why cant we dereference a handle without this one ? */
21 : : #include <core/sched_policy.h>
22 : :
23 : : #include <assert.h>
24 : :
25 : : #include "test_interfaces.h"
26 : : #include "../../helper.h"
27 : :
28 : : /*
29 : : * This is definitely note thrad-safe.
30 : : */
31 : : static struct test_config *current_config;
32 : :
33 : : /* TODO :
34 : : - OpenCL to OpenCL support
35 : : */
36 : :
37 : : static char *
38 : 126 : enum_to_string(int exit_code)
39 : : {
40 [ + - + - : 126 : switch (exit_code)
- - ]
41 : : {
42 : : case SUCCESS:
43 : 104 : return "Success";
44 : : case FAILURE:
45 : 0 : return "Failure";
46 : : case UNTESTED:
47 : 22 : return "Untested";
48 : : case TASK_CREATION_FAILURE:
49 : 0 : return "Task creation failed";
50 : : case TASK_SUBMISSION_FAILURE:
51 : 0 : return "Task submission failed";
52 : : default:
53 : 126 : assert(0);
54 : : }
55 : : }
56 : :
57 : : struct data_interface_test_summary
58 : : {
59 : : int success;
60 : :
61 : : /* Copy methods */
62 : : #ifdef STARPU_USE_CPU
63 : : int cpu_to_cpu;
64 : : #endif
65 : : #ifdef STARPU_USE_CUDA
66 : : int cpu_to_cuda;
67 : : int cuda_to_cuda;
68 : : int cuda_to_cpu;
69 : : int cpu_to_cuda_async;
70 : : int cuda_to_cpu_async;
71 : : int cuda_to_cuda_async;
72 : : #endif
73 : : #ifdef STARPU_USE_OPENCL
74 : : int cpu_to_opencl;
75 : : int opencl_to_cpu;
76 : : int cpu_to_opencl_async;
77 : : int opencl_to_cpu_async;
78 : : #endif
79 : :
80 : : /* Other stuff */
81 : : int compare;
82 : : #ifdef STARPU_USE_CPU
83 : : int handle_to_pointer;
84 : : #endif
85 : : };
86 : :
87 : 9 : void data_interface_test_summary_print(FILE *f,
88 : : struct data_interface_test_summary *s)
89 : : {
90 [ - + ]: 9 : if (!f)
91 : 0 : f = stderr;
92 : :
93 [ + - ]: 9 : FPRINTF(f, "%s : %s\n",
94 : : current_config->name, enum_to_string(s->success));
95 [ + - ]: 9 : FPRINTF(f, "Asynchronous :\n");
96 : : #ifdef STARPU_USE_CUDA
97 [ + - ]: 9 : FPRINTF(f, "\tCPU -> CUDA : %s\n",
98 : : enum_to_string(s->cpu_to_cuda_async));
99 [ + - ]: 9 : FPRINTF(f, "\tCUDA -> CUDA : %s\n",
100 : : enum_to_string(s->cuda_to_cuda_async));
101 [ + - ]: 9 : FPRINTF(f, "\tCUDA -> CPU : %s\n",
102 : : enum_to_string(s->cuda_to_cpu_async));
103 : : #endif /* !STARPU_USE_CUDA */
104 : : #ifdef STARPU_USE_OPENCL
105 [ + - ]: 9 : FPRINTF(f, "\tCPU -> OpenCl : %s\n",
106 : : enum_to_string(s->cpu_to_opencl_async));
107 [ + - ]: 9 : FPRINTF(f, "\tOpenCl -> CPU : %s\n",
108 : : enum_to_string(s->opencl_to_cpu_async));
109 : : #endif /* !STARPU_USE_OPENCL */
110 : :
111 [ + - ]: 9 : FPRINTF(f, "Synchronous :\n");
112 : : #ifdef STARPU_USE_CUDA
113 [ + - ]: 9 : FPRINTF(f, "\tCPU -> CUDA ; %s\n",
114 : : enum_to_string(s->cpu_to_cuda));
115 [ + - ]: 9 : FPRINTF(f, "\tCUDA -> CUDA : %s\n",
116 : : enum_to_string(s->cuda_to_cuda));
117 [ + - ]: 9 : FPRINTF(f, "\tCUDA -> CPU : %s\n",
118 : : enum_to_string(s->cuda_to_cpu));
119 : : #endif /* !STARPU_USE_CUDA */
120 : : #ifdef STARPU_USE_OPENCL
121 [ + - ]: 9 : FPRINTF(f, "\tCPU -> OpenCl : %s\n",
122 : : enum_to_string(s->cpu_to_opencl));
123 [ + - ]: 9 : FPRINTF(f, "\tOpenCl -> CPU : %s\n",
124 : : enum_to_string(s->opencl_to_cpu));
125 : : #endif /* !STARPU_USE_OPENCL */
126 : : #ifdef STARPU_USE_CPU
127 [ + - ]: 9 : FPRINTF(f, "CPU -> CPU : %s\n",
128 : : enum_to_string(s->cpu_to_cpu));
129 [ + - ]: 9 : FPRINTF(f, "handle_to_pointer() : %s\n",
130 : : enum_to_string(s->handle_to_pointer));
131 : : #endif /* !STARPU_USE_CPU */
132 [ + - ]: 9 : FPRINTF(f, "compare() : %s\n",
133 : : enum_to_string(s->compare));
134 : 9 : }
135 : :
136 : : int
137 : 9 : data_interface_test_summary_success(data_interface_test_summary *s)
138 : : {
139 : 9 : return s->success;
140 : : }
141 : :
142 : : enum operation
143 : : {
144 : : CPU_TO_CPU
145 : : #ifdef STARPU_USE_CUDA
146 : : ,
147 : : CPU_TO_CUDA,
148 : : CUDA_TO_CUDA,
149 : : CUDA_TO_CPU
150 : : #endif /* !STARPU_USE_CUDA */
151 : : #ifdef STARPU_USE_OPENCL
152 : : ,
153 : : CPU_TO_OPENCL,
154 : : OPENCL_TO_CPU
155 : : #endif /* !STARPU_USE_OPENCL */
156 : : };
157 : :
158 : : static int*
159 : 81 : get_field(struct data_interface_test_summary *s, int async, enum operation op)
160 : : {
161 [ + + - + : 81 : switch (op)
+ + - ]
162 : : {
163 : : #ifdef STARPU_USE_CPU
164 : : case CPU_TO_CPU:
165 : 9 : return &s->cpu_to_cpu;
166 : : #endif
167 : : #ifdef STARPU_USE_CUDA
168 : : case CPU_TO_CUDA:
169 [ + + ]: 18 : return async?&s->cpu_to_cuda_async:&s->cpu_to_cuda;
170 : : case CUDA_TO_CUDA:
171 [ # # ]: 0 : return async?&s->cuda_to_cuda_async:&s->cuda_to_cuda;
172 : : case CUDA_TO_CPU:
173 [ + + ]: 18 : return async?&s->cuda_to_cpu_async:&s->cuda_to_cpu;
174 : : #endif /* !STARPU_USE_CUDA */
175 : : #ifdef STARPU_USE_OPENCL
176 : : case CPU_TO_OPENCL:
177 [ + + ]: 18 : return async?&s->cpu_to_opencl_async:&s->cpu_to_opencl;
178 : : case OPENCL_TO_CPU:
179 [ + + ]: 18 : return async?&s->opencl_to_cpu_async:&s->opencl_to_cpu;
180 : : #endif /* !STARPU_USE_OPENCL */
181 : : default:
182 : 81 : STARPU_ABORT();
183 : : }
184 : : /* that instruction should never be reached */
185 : : return NULL;
186 : : }
187 : :
188 : : static void
189 : 81 : set_field(struct data_interface_test_summary *s, int async,
190 : : enum operation op, int ret)
191 : : {
192 : 81 : int *field = get_field(s, async, op);
193 [ + - - - : 81 : switch (ret)
- - ]
194 : : {
195 : : case SUCCESS:
196 : 81 : *field = SUCCESS;
197 : 81 : break;
198 : : case FAILURE:
199 : 0 : *field = FAILURE;
200 : 0 : s->success = FAILURE;
201 : 0 : break;
202 : : case UNTESTED:
203 : 0 : *field = UNTESTED;
204 : 0 : break;
205 : : case TASK_CREATION_FAILURE:
206 : 0 : *field = TASK_CREATION_FAILURE;
207 : 0 : break;
208 : : case TASK_SUBMISSION_FAILURE:
209 : 0 : *field = TASK_SUBMISSION_FAILURE;
210 : 0 : break;
211 : : default:
212 : 0 : STARPU_ABORT();
213 : : }
214 : 81 : }
215 : :
216 : : static struct data_interface_test_summary summary =
217 : : {
218 : : #ifdef STARPU_USE_CPU
219 : : .cpu_to_cpu = UNTESTED,
220 : : .compare = UNTESTED,
221 : : #endif
222 : : #ifdef STARPU_USE_CUDA
223 : : .cpu_to_cuda = UNTESTED,
224 : : .cuda_to_cuda = UNTESTED,
225 : : .cuda_to_cpu = UNTESTED,
226 : : .cpu_to_cuda_async = UNTESTED,
227 : : .cuda_to_cpu_async = UNTESTED,
228 : : .cuda_to_cuda_async = UNTESTED,
229 : : #endif
230 : : #ifdef STARPU_USE_OPENCL
231 : : .cpu_to_opencl = UNTESTED,
232 : : .opencl_to_cpu = UNTESTED,
233 : : .cpu_to_opencl_async = UNTESTED,
234 : : .opencl_to_cpu_async = UNTESTED,
235 : : #endif
236 : : #ifdef STARPU_USE_CPU
237 : : .handle_to_pointer = UNTESTED,
238 : : #endif
239 : : .success = SUCCESS
240 : : };
241 : :
242 : :
243 : : /*
244 : : * This variable has to be either -1 or 1.
245 : : * The kernels should check that the ith value stored in the data interface is
246 : : * equal to i, if factor == 1, or -i, if factor == -1.
247 : : */
248 : : static int factor = -1;
249 : :
250 : : /*
251 : : * Creates a complete task, only knowing on what device it should be executed.
252 : : * Note that the global variable <current_config> is heavily used here.
253 : : * Arguments :
254 : : * - taskp : a pointer to a valid task
255 : : * - type : STARPU_{CPU,CUDA,OPENCL}_WORKER.
256 : : * - id : -1 if you dont care about the device where the task will be
257 : : * executed, as long as it has the right type.
258 : : * >= 0 if you want to make sure the task will be executed on the
259 : : * idth device that has the specified type.
260 : : * Return values :
261 : : * -ENODEV
262 : : * 0 : success.
263 : : */
264 : : static int
265 : 81 : create_task(struct starpu_task **taskp, enum starpu_archtype type, int id)
266 : : {
267 : : static int cpu_workers[STARPU_MAXCPUS];
268 : : #ifdef STARPU_USE_CUDA
269 : : static int cuda_workers[STARPU_MAXCUDADEVS];
270 : : #endif
271 : : #ifdef STARPU_USE_OPENCL
272 : : static int opencl_workers[STARPU_MAXOPENCLDEVS];
273 : : #endif
274 : :
275 : : static int n_cpus = -1;
276 : : #ifdef STARPU_USE_CUDA
277 : : static int n_cudas = -1;
278 : : #endif
279 : : #ifdef STARPU_USE_OPENCL
280 : : static int n_opencls = -1;
281 : : #endif
282 : :
283 [ + + ]: 81 : if (n_cpus == -1) /* First time here */
284 : : {
285 : : /* We do not check the return values of the calls to
286 : : * starpu_worker_get_ids_by_type now, because it is simpler to
287 : : * detect a problem in the switch that comes right after this
288 : : * block of code. */
289 : 9 : n_cpus = starpu_worker_get_ids_by_type(STARPU_CPU_WORKER,
290 : : cpu_workers,
291 : : STARPU_MAXCPUS);
292 : : #ifdef STARPU_USE_CUDA
293 : 9 : n_cudas = starpu_worker_get_ids_by_type(STARPU_CUDA_WORKER,
294 : : cuda_workers,
295 : : STARPU_MAXCUDADEVS);
296 : : #endif
297 : : #ifdef STARPU_USE_OPENCL
298 : 9 : n_opencls = starpu_worker_get_ids_by_type(STARPU_OPENCL_WORKER,
299 : : opencl_workers,
300 : : STARPU_MAXOPENCLDEVS);
301 : : #endif
302 : : }
303 : :
304 : 81 : int workerid=0;
305 : : static struct starpu_codelet cl;
306 : 81 : cl.nbuffers = 1;
307 : 81 : cl.modes[0] = STARPU_RW;
308 : :
309 [ + + + - ]: 81 : switch (type)
310 : : {
311 : : case STARPU_CPU_WORKER:
312 [ - + ]: 45 : if (id != -1)
313 : : {
314 [ # # ]: 0 : if (id >= n_cpus)
315 : : {
316 [ # # ]: 0 : FPRINTF(stderr, "Not enough CPU workers\n");
317 : 0 : return -ENODEV;
318 : : }
319 : 0 : workerid = *(cpu_workers + id);
320 : : }
321 : 45 : cl.where = STARPU_CPU;
322 : 45 : cl.cpu_funcs[0] = current_config->cpu_func;
323 : 45 : break;
324 : : #ifdef STARPU_USE_CUDA
325 : : case STARPU_CUDA_WORKER:
326 [ + - ]: 18 : if (id != -1)
327 : : {
328 [ - + ]: 18 : if (id >= n_cudas)
329 : : {
330 [ # # ]: 0 : FPRINTF(stderr, "Not enough CUDA workers\n");
331 : 0 : return -ENODEV;
332 : : }
333 : 18 : workerid = cuda_workers[id];
334 : : }
335 : 18 : cl.where = STARPU_CUDA;
336 : 18 : cl.cuda_funcs[0] = current_config->cuda_func;
337 : 18 : break;
338 : : #endif /* !STARPU_USE_CUDA */
339 : : #ifdef STARPU_USE_OPENCL
340 : : case STARPU_OPENCL_WORKER:
341 [ + - ]: 18 : if (id != -1)
342 : : {
343 [ - + ]: 18 : if (id >= n_opencls)
344 : : {
345 [ # # ]: 0 : FPRINTF(stderr, "Not enough OpenCL workers\n");
346 : 0 : return -ENODEV;
347 : : }
348 : 18 : workerid = *(opencl_workers + id);
349 : : }
350 : 18 : cl.where = STARPU_OPENCL;
351 : 18 : cl.opencl_funcs[0] = current_config->opencl_func;
352 : 18 : break;
353 : : #endif /* ! STARPU_USE_OPENCL */
354 : : default:
355 : 0 : return -ENODEV;
356 : : }
357 : :
358 : :
359 : 81 : struct starpu_task *task = starpu_task_create();
360 : 81 : task->synchronous = 1;
361 : 81 : task->cl = &cl;
362 : 81 : task->handles[0] = *current_config->handle;
363 : 81 : task->destroy = 0;
364 [ + + ]: 81 : if (id != -1)
365 : : {
366 : 36 : task->execute_on_a_specific_worker = 1;
367 : 36 : task->workerid = workerid;
368 : : }
369 : 81 : factor = -factor;
370 : 81 : task->cl_arg = &factor;
371 : 81 : task->cl_arg_size = sizeof(&factor);
372 : :
373 : 81 : *taskp = task;
374 : 81 : return 0;
375 : : }
376 : :
377 : : /*
378 : : * <device1>_to_<device2> functions.
379 : : * They all create and submit a task that has to be executed on <device2>,
380 : : * forcing a copy between <device1> and <device2>.
381 : : * XXX : could we sometimes use starp_insert_task() ? It seems hars because we
382 : : * need to set the execute_on_a_specific_worker field...
383 : : */
384 : : #ifdef STARPU_USE_CUDA
385 : : static enum exit_code
386 : 18 : ram_to_cuda(void)
387 : : {
388 : : int err;
389 : : struct starpu_task *task;
390 : :
391 : 18 : err = create_task(&task, STARPU_CUDA_WORKER, 0);
392 [ - + ]: 18 : if (err != 0)
393 : 0 : return TASK_CREATION_FAILURE;
394 : :
395 : 18 : err = starpu_task_submit(task);
396 [ - + ]: 18 : if (err != 0)
397 : 0 : return TASK_SUBMISSION_FAILURE;
398 : :
399 [ + - ]: 18 : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
400 : 18 : return current_config->copy_failed;
401 : : }
402 : :
403 : : #ifdef HAVE_CUDA_MEMCPY_PEER
404 : : static enum exit_code
405 : : cuda_to_cuda(void)
406 : : {
407 : : int err;
408 : : struct starpu_task *task;
409 : :
410 : : err = create_task(&task, STARPU_CUDA_WORKER, 1);
411 : : if (err != 0)
412 : : return TASK_CREATION_FAILURE;
413 : :
414 : : err = starpu_task_submit(task);
415 : : if (err != 0)
416 : : return TASK_SUBMISSION_FAILURE;
417 : :
418 : : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
419 : : return current_config->copy_failed;
420 : : }
421 : : #endif
422 : :
423 : : static enum exit_code
424 : 18 : cuda_to_ram(void)
425 : : {
426 : : int err;
427 : : struct starpu_task *task;
428 : :
429 : 18 : err = create_task(&task, STARPU_CPU_WORKER, -1);
430 [ - + ]: 18 : if (err != 0)
431 : 0 : return TASK_CREATION_FAILURE;
432 : :
433 : 18 : err = starpu_task_submit(task);
434 [ - + ]: 18 : if (err != 0)
435 : 0 : return TASK_SUBMISSION_FAILURE;
436 : :
437 [ + - ]: 18 : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
438 : 18 : return current_config->copy_failed;
439 : : }
440 : : #endif /* !STARPU_USE_CUDA */
441 : :
442 : : #ifdef STARPU_USE_OPENCL
443 : : static enum exit_code
444 : 18 : ram_to_opencl(void)
445 : : {
446 : : int err;
447 : : struct starpu_task *task;
448 : :
449 : 18 : err = create_task(&task, STARPU_OPENCL_WORKER, 0);
450 [ - + ]: 18 : if (err != 0)
451 : 0 : return TASK_CREATION_FAILURE;
452 : :
453 : 18 : err = starpu_task_submit(task);
454 [ - + ]: 18 : if (err != 0)
455 : 0 : return TASK_SUBMISSION_FAILURE;
456 : :
457 [ + - ]: 18 : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
458 : 18 : return current_config->copy_failed;
459 : : }
460 : :
461 : : static enum exit_code
462 : 18 : opencl_to_ram(void)
463 : : {
464 : : int err;
465 : : struct starpu_task *task;
466 : :
467 : 18 : err = create_task(&task, STARPU_CPU_WORKER, -1);
468 [ - + ]: 18 : if (err != 0)
469 : 0 : return TASK_CREATION_FAILURE;
470 : :
471 : 18 : err = starpu_task_submit(task);
472 [ - + ]: 18 : if (err != 0)
473 : 0 : return TASK_SUBMISSION_FAILURE;
474 : :
475 [ + - ]: 18 : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
476 : 18 : return current_config->copy_failed;
477 : : }
478 : : #endif /* !STARPU_USE_OPENCL */
479 : : /* End of the <device1>_to_<device2> functions. */
480 : :
481 : : #ifdef STARPU_USE_CUDA
482 : : static void
483 : 18 : run_cuda(int async)
484 : : {
485 : : /* RAM -> CUDA (-> CUDA) -> RAM */
486 : : int err;
487 : 18 : err = ram_to_cuda();
488 : 18 : set_field(&summary, async, CPU_TO_CUDA, err);
489 : : /* If this failed, there is no point in continuing. */
490 [ - + ]: 18 : if (err != SUCCESS)
491 : 18 : return;
492 : :
493 : : #ifdef HAVE_CUDA_MEMCPY_PEER
494 : : if (starpu_cuda_worker_get_count() >= 2)
495 : : {
496 : : err = cuda_to_cuda();
497 : : set_field(&summary, async, CUDA_TO_CUDA, err);
498 : : /* Even if cuda_to_cuda() failed, a valid copy is left on the first
499 : : * cuda device, which means we can safely test cuda_to_ram() */
500 : : }
501 : : else
502 : : {
503 : : summary.cuda_to_cuda_async = UNTESTED;
504 : : }
505 : : #else
506 : 18 : summary.cuda_to_cuda_async = UNTESTED;
507 : : #endif /* !HAVE_CUDA_MEMCPY_PEER */
508 : :
509 : : #ifdef STARPU_USE_CPU
510 : 18 : err = cuda_to_ram();
511 : 18 : set_field(&summary, async, CUDA_TO_CPU, err);
512 : : #endif /* !STARPU_USE_CPU */
513 : :
514 : : }
515 : : #endif /* !STARPU_USE_CUDA */
516 : :
517 : : #ifdef STARPU_USE_OPENCL
518 : : static void
519 : 18 : run_opencl(int async)
520 : : {
521 : : /* RAM -> OpenCL -> RAM */
522 : : int err;
523 : :
524 : 18 : err = ram_to_opencl();
525 : 18 : set_field(&summary, async, CPU_TO_OPENCL, err);
526 [ - + ]: 18 : if (err != SUCCESS)
527 : 18 : return;
528 : :
529 : : #ifdef STARPU_USE_CPU
530 : 18 : err = opencl_to_ram();
531 : 18 : set_field(&summary, async, OPENCL_TO_CPU, err);
532 : : #endif /*!STARPU_USE_CPU */
533 : :
534 : : }
535 : : #endif /* !STARPU_USE_OPENCL */
536 : :
537 : : #ifdef STARPU_USE_CPU
538 : : /* Valid data should be in RAM before calling this function */
539 : : static void
540 : 9 : ram_to_ram(void)
541 : : {
542 : : int err;
543 : : struct starpu_task *task;
544 : : starpu_data_handle_t src, dst;
545 : : void *src_interface, *dst_interface;
546 : :
547 : 9 : src = *current_config->handle;
548 : 9 : dst = *current_config->dummy_handle;
549 : :
550 : : /* We do not care about the nodes */
551 : 9 : src_interface = starpu_data_get_interface_on_node(src, 0);
552 : 9 : dst_interface = starpu_data_get_interface_on_node(dst, 0);
553 [ + + ]: 9 : if (src->ops->copy_methods->ram_to_ram)
554 : 3 : src->ops->copy_methods->ram_to_ram(src_interface, 0, dst_interface, 0);
555 : : else
556 : 6 : src->ops->copy_methods->any_to_any(src_interface, 0, dst_interface, 0, NULL);
557 : :
558 : 9 : err = create_task(&task, STARPU_CPU_WORKER, -1);
559 [ - + ]: 9 : if (err != 0)
560 : 0 : goto out;
561 : :
562 : 9 : task->handles[0] = dst;
563 : 9 : err = starpu_task_submit(task);
564 : 9 : starpu_task_destroy(task);
565 : :
566 [ - + ]: 9 : if (err != 0)
567 : : {
568 : 0 : err = TASK_SUBMISSION_FAILURE;
569 : 0 : goto out;
570 : : }
571 : :
572 [ + - ]: 9 : FPRINTF(stderr, "[%s] : %d\n", __starpu_func__, current_config->copy_failed);
573 : 9 : err = current_config->copy_failed;
574 : :
575 : : out:
576 : 9 : set_field(&summary, 0, CPU_TO_CPU, err);
577 : 9 : }
578 : : #endif /* !STARPU_USE_CPU */
579 : :
580 : : static void
581 : 9 : run_async(void)
582 : : {
583 : 9 : int async = starpu_asynchronous_copy_disabled();
584 [ - + ]: 9 : if (async == 1)
585 : : {
586 [ # # ]: 0 : FPRINTF(stderr, "Asynchronous copies have been disabled\n");
587 : 9 : return;
588 : : }
589 : : #ifdef STARPU_USE_CUDA
590 : 9 : run_cuda(1);
591 : : #endif /* !STARPU_USE_CUDA */
592 : : #ifdef STARPU_USE_OPENCL
593 : 9 : run_opencl(1);
594 : : #endif /* !STARPU_USE_OPENCL */
595 : : }
596 : :
597 : : static void
598 : 9 : run_sync(void)
599 : : {
600 : 9 : starpu_data_handle_t handle = *current_config->handle;
601 : : struct starpu_data_copy_methods new_copy_methods;
602 : : struct starpu_data_copy_methods *old_copy_methods;
603 : :
604 : 9 : old_copy_methods = (struct starpu_data_copy_methods *) handle->ops->copy_methods;
605 : :
606 : 9 : memcpy(&new_copy_methods,
607 : : old_copy_methods,
608 : : sizeof(struct starpu_data_copy_methods));
609 : :
610 : : #ifdef STARPU_USE_CUDA
611 : 9 : new_copy_methods.ram_to_cuda_async = NULL;
612 : 9 : new_copy_methods.cuda_to_cuda_async = NULL;
613 : 9 : new_copy_methods.cuda_to_ram_async = NULL;
614 : : #endif /* !STARPU_USE_CUDA */
615 : : #ifdef STARPU_USE_OPENCL
616 : 9 : new_copy_methods.ram_to_opencl_async = NULL;
617 : 9 : new_copy_methods.opencl_to_ram_async = NULL;
618 : : #endif /* !STARPU_USE_OPENCL */
619 : :
620 : 9 : handle->ops->copy_methods = &new_copy_methods;
621 : :
622 : : #ifdef STARPU_USE_CUDA
623 : 9 : run_cuda(0);
624 : : #endif /* !STARPU_USE_CUDA */
625 : : #ifdef STARPU_USE_OPENCL
626 : 9 : run_opencl(0);
627 : : #endif /* !STARPU_USE_OPENCL */
628 : :
629 : 9 : handle->ops->copy_methods = old_copy_methods;
630 : 9 : }
631 : :
632 : : static void
633 : 9 : compare(void)
634 : : {
635 : : int err;
636 : : void *interface_a, *interface_b;
637 : : starpu_data_handle_t handle, dummy_handle;
638 : :
639 : 9 : handle = *current_config->handle;
640 : 9 : dummy_handle = *current_config->dummy_handle;
641 : 9 : interface_a = starpu_data_get_interface_on_node(handle, 0);
642 : 9 : interface_b = starpu_data_get_interface_on_node(dummy_handle, 0);
643 : :
644 : 9 : err = handle->ops->compare(interface_a, interface_b);
645 : :
646 [ - + ]: 9 : if (err == 0)
647 : : {
648 : 0 : summary.compare = FAILURE;
649 : 0 : summary.success = FAILURE;
650 : : }
651 : : else
652 : : {
653 : 9 : summary.compare = SUCCESS;
654 : : }
655 : 9 : }
656 : :
657 : : #ifdef STARPU_USE_CPU
658 : : static void
659 : 9 : handle_to_pointer(void)
660 : : {
661 : : void *ptr;
662 : : unsigned int node;
663 : 9 : unsigned int tests = 0;
664 : : starpu_data_handle_t handle;
665 : :
666 : 9 : handle = *current_config->handle;
667 [ + + ]: 9 : if (!handle->ops->handle_to_pointer)
668 : 4 : return;
669 : :
670 [ + + ]: 85 : for (node = 0; node < STARPU_MAXNODES; node++)
671 : : {
672 [ + + ]: 80 : if (starpu_node_get_kind(node) != STARPU_CPU_RAM)
673 : 75 : continue;
674 : :
675 : 5 : ptr = handle->ops->handle_to_pointer(handle, node);
676 [ - + ]: 5 : if (starpu_data_lookup(ptr) != handle)
677 : : {
678 : 0 : summary.handle_to_pointer = FAILURE;
679 : 0 : return;
680 : : }
681 : 5 : tests++;
682 : : }
683 : :
684 [ + - ]: 5 : if (tests > 0)
685 : 9 : summary.handle_to_pointer = SUCCESS;
686 : : }
687 : : #endif /* !STARPU_USE_CPU */
688 : :
689 : : static int
690 : 9 : load_conf(struct test_config *config)
691 : : {
692 [ + - ][ + - ]: 9 : if (!config ||
693 : : #ifdef STARPU_USE_CPU
694 [ + - ]: 9 : !config->cpu_func ||
695 [ + - ]: 9 : !config->dummy_handle ||
696 : : #endif
697 : : #ifdef STARPU_USE_CUDA
698 [ + - ]: 9 : !config->cuda_func ||
699 : : #endif
700 : : #ifdef STARPU_USE_OPENCL
701 [ - + ]: 9 : !config->opencl_func ||
702 : : #endif
703 : 9 : !config->handle)
704 : : {
705 : 0 : return 1;
706 : : }
707 : :
708 : 9 : current_config = config;
709 : 9 : return 0;
710 : : }
711 : :
712 : :
713 : : data_interface_test_summary*
714 : 9 : run_tests(struct test_config *conf)
715 : : {
716 [ - + ]: 9 : if (load_conf(conf) == 1)
717 : : {
718 [ # # ]: 0 : FPRINTF(stderr, "Failed to load conf.\n");
719 : 0 : return NULL;
720 : : }
721 : 9 : run_async();
722 : 9 : run_sync();
723 : :
724 : : #ifdef STARPU_USE_CPU
725 : 9 : ram_to_ram();
726 : 9 : compare();
727 : 9 : handle_to_pointer();
728 : : #endif
729 : :
730 : 9 : return &summary;
731 : : }
|