… | |
… | |
270 | /* they can be upgraded at runtime to the array form */ |
270 | /* they can be upgraded at runtime to the array form */ |
271 | static void * |
271 | static void * |
272 | SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg) |
272 | SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg) |
273 | { |
273 | { |
274 | if (SvROK (sv) && sv_derived_from (sv, pkg)) |
274 | if (SvROK (sv) && sv_derived_from (sv, pkg)) |
275 | { |
|
|
276 | SV *rv = SvRV (sv); |
|
|
277 | |
|
|
278 | if (SvTYPE (rv) == SVt_PVAV) |
|
|
279 | rv = AvARRAY (rv)[0]; |
|
|
280 | |
|
|
281 | return (void *)SvIV (SvRV (sv)); |
275 | return (void *)SvIV (SvRV (sv)); |
282 | } |
|
|
283 | |
276 | |
284 | croak ("%s: %s is not of type %s", func, svname, pkg); |
277 | croak ("%s: %s is not of type %s", func, svname, pkg); |
285 | } |
|
|
286 | |
|
|
287 | static void |
|
|
288 | CLOBJ_push (SV *self, SV *data) |
|
|
289 | { |
|
|
290 | SV *rv = SvRV (self); |
|
|
291 | |
|
|
292 | if (SvTYPE (rv) != SVt_PVAV) |
|
|
293 | { |
|
|
294 | AV *av = newAV (); |
|
|
295 | av_push (av, rv); |
|
|
296 | rv = (SV *)av; |
|
|
297 | SvRV_set (self, rv); |
|
|
298 | } |
|
|
299 | |
|
|
300 | av_push ((AV *)rv, data); |
|
|
301 | } |
|
|
302 | |
|
|
303 | static SV * |
|
|
304 | sv_struct (STRLEN size) |
|
|
305 | { |
|
|
306 | SV *sv = newSV (size); |
|
|
307 | SvPOK_only (sv); |
|
|
308 | return sv; |
|
|
309 | } |
|
|
310 | |
|
|
311 | static void * |
|
|
312 | CLOBJ_push_struct (SV *self, STRLEN size) |
|
|
313 | { |
|
|
314 | SV *sv = sv_struct (size); |
|
|
315 | CLOBJ_push (self, sv); |
|
|
316 | return SvPVX (sv); |
|
|
317 | } |
278 | } |
318 | |
279 | |
319 | /*****************************************************************************/ |
280 | /*****************************************************************************/ |
320 | /* callback stuff */ |
281 | /* callback stuff */ |
321 | |
282 | |
… | |
… | |
347 | |
308 | |
348 | static void |
309 | static void |
349 | eq_enq (eq_vtbl *vtbl, SV *cb, void *data1, void *data2, void *data3) |
310 | eq_enq (eq_vtbl *vtbl, SV *cb, void *data1, void *data2, void *data3) |
350 | { |
311 | { |
351 | eq_item *item = malloc (sizeof (eq_item)); |
312 | eq_item *item = malloc (sizeof (eq_item)); |
352 | |
|
|
353 | printf ("enq(%p,%p,%p,%p,%p)\n", vtbl, cb, data1, data2, data3);//D |
|
|
354 | |
313 | |
355 | item->next = 0; |
314 | item->next = 0; |
356 | item->vtbl = vtbl; |
315 | item->vtbl = vtbl; |
357 | item->cb = cb; |
316 | item->cb = cb; |
358 | item->data1 = data1; |
317 | item->data1 = data1; |
… | |
… | |
383 | X_UNLOCK (eq_lock); |
342 | X_UNLOCK (eq_lock); |
384 | |
343 | |
385 | return res; |
344 | return res; |
386 | } |
345 | } |
387 | |
346 | |
388 | #if 0 |
|
|
389 | static void |
|
|
390 | mem_free (pTHX_ void *p) |
|
|
391 | { |
|
|
392 | free (p); |
|
|
393 | } |
|
|
394 | //SAVEDESTRUCTOR_X (mem_free, item); |
|
|
395 | #endif |
|
|
396 | |
|
|
397 | static void |
347 | static void |
398 | eq_poll (void) |
348 | eq_poll (void) |
399 | { |
349 | { |
400 | eq_item *item; |
350 | eq_item *item; |
401 | |
351 | |
… | |
… | |
428 | eq_poll_interrupt (pTHX_ void *c_arg, int value) |
378 | eq_poll_interrupt (pTHX_ void *c_arg, int value) |
429 | { |
379 | { |
430 | eq_poll (); |
380 | eq_poll (); |
431 | } |
381 | } |
432 | |
382 | |
|
|
383 | /*****************************************************************************/ |
433 | /* context notify */ |
384 | /* context notify */ |
434 | |
385 | |
435 | static void |
386 | static void |
436 | eq_context_push (void *data1, void *data2, void *data3) |
387 | eq_context_push (void *data1, void *data2, void *data3) |
437 | { |
388 | { |
438 | dSP; |
389 | dSP; |
439 | PUSHs (sv_2mortal (newSVpv (data1, 0))); |
390 | PUSHs (sv_2mortal (newSVpv (data1, 0))); |
440 | PUSHs (sv_2mortal (newSVpvn (data2, (STRLEN)data3))); |
391 | PUSHs (sv_2mortal (newSVpvn (data2, (STRLEN)data3))); |
441 | PUTBACK; |
392 | PUTBACK; |
|
|
393 | |
|
|
394 | free (data1); |
|
|
395 | free (data2); |
442 | } |
396 | } |
443 | |
397 | |
444 | static eq_vtbl eq_context_vtbl = { 0, eq_context_push }; |
398 | static eq_vtbl eq_context_vtbl = { 0, eq_context_push }; |
445 | |
399 | |
|
|
400 | static void CL_CALLBACK |
|
|
401 | eq_context_notify (const char *msg, const void *pvt, size_t cb, void *user_data) |
|
|
402 | { |
|
|
403 | void *pvt_copy = malloc (cb); |
|
|
404 | memcpy (pvt_copy, pvt, cb); |
|
|
405 | eq_enq (&eq_context_vtbl, user_data, strdup (msg), pvt_copy, (void *)cb); |
|
|
406 | } |
|
|
407 | |
|
|
408 | #define CONTEXT_NOTIFY_CALLBACK \ |
|
|
409 | void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *) = context_default_notify; \ |
|
|
410 | void *user_data = 0; \ |
|
|
411 | \ |
|
|
412 | if (SvOK (notify)) \ |
|
|
413 | { \ |
|
|
414 | pfn_notify = eq_context_notify; \ |
|
|
415 | user_data = s_get_cv (notify); \ |
|
|
416 | } |
|
|
417 | |
|
|
418 | static SV * |
|
|
419 | new_clobj_context (cl_context ctx, void *user_data) |
|
|
420 | { |
|
|
421 | SV *sv = NEW_CLOBJ ("OpenCL::Context", ctx); |
|
|
422 | |
|
|
423 | if (user_data) |
|
|
424 | sv_magicext (SvRV (sv), user_data, PERL_MAGIC_ext, 0, 0, 0); |
|
|
425 | |
|
|
426 | return sv; |
|
|
427 | } |
|
|
428 | |
|
|
429 | #define XPUSH_CLOBJ_CONTEXT XPUSHs (new_clobj_context (ctx, user_data)); |
|
|
430 | |
|
|
431 | /*****************************************************************************/ |
446 | /* build/compile/link notify */ |
432 | /* build/compile/link notify */ |
447 | |
433 | |
448 | static void |
434 | static void |
449 | eq_program_push (void *data1, void *data2, void *data3) |
435 | eq_program_push (void *data1, void *data2, void *data3) |
450 | { |
436 | { |
… | |
… | |
497 | |
483 | |
498 | xthread_t id; |
484 | xthread_t id; |
499 | thread_create (&id, build_program_thread, arg); |
485 | thread_create (&id, build_program_thread, arg); |
500 | } |
486 | } |
501 | |
487 | |
|
|
488 | /*****************************************************************************/ |
502 | /* event objects */ |
489 | /* event objects */ |
503 | |
490 | |
504 | static void |
491 | static void |
505 | eq_event_push (void *data1, void *data2, void *data3) |
492 | eq_event_push (void *data1, void *data2, void *data3) |
506 | { |
493 | { |
… | |
… | |
514 | |
501 | |
515 | static void CL_CALLBACK |
502 | static void CL_CALLBACK |
516 | eq_event_notify (cl_event event, cl_int event_command_exec_status, void *user_data) |
503 | eq_event_notify (cl_event event, cl_int event_command_exec_status, void *user_data) |
517 | { |
504 | { |
518 | clRetainEvent (event); |
505 | clRetainEvent (event); |
519 | eq_enq (&eq_event_vtbl, user_data, (void *)event, (void *)event_command_exec_status, 0); |
506 | eq_enq (&eq_event_vtbl, user_data, (void *)event, (void *)(IV)event_command_exec_status, 0); |
520 | } |
507 | } |
521 | |
508 | |
522 | /*****************************************************************************/ |
509 | /*****************************************************************************/ |
523 | |
510 | |
524 | static size_t |
511 | static size_t |
… | |
… | |
635 | EXTEND (SP, count); |
622 | EXTEND (SP, count); |
636 | for (i = 0; i < count; ++i) |
623 | for (i = 0; i < count; ++i) |
637 | PUSH_CLOBJ ("OpenCL::Platform", list [i]); |
624 | PUSH_CLOBJ ("OpenCL::Platform", list [i]); |
638 | |
625 | |
639 | void |
626 | void |
640 | context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, FUTURE notify = 0) |
627 | context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef) |
641 | PPCODE: |
628 | PPCODE: |
|
|
629 | CONTEXT_NOTIFY_CALLBACK; |
642 | NEED_SUCCESS_ARG (cl_context ctx, CreateContextFromType, (properties, type, 0, 0, &res)); |
630 | NEED_SUCCESS_ARG (cl_context ctx, CreateContextFromType, (properties, type, 0, 0, &res)); |
643 | XPUSH_CLOBJ ("OpenCL::Context", ctx); |
631 | XPUSH_CLOBJ_CONTEXT; |
644 | |
632 | |
645 | #if 0 |
|
|
646 | |
|
|
647 | void |
633 | void |
648 | context (cl_context_properties *properties = 0, FUTURE devices, FUTURE notify = 0) |
634 | context (FUTURE properties, FUTURE devices, FUTURE notify) |
649 | PPCODE: |
635 | PPCODE: |
650 | /* der Gipfel der Kunst */ |
636 | /* der Gipfel der Kunst */ |
651 | |
|
|
652 | #endif |
|
|
653 | |
637 | |
654 | void |
638 | void |
655 | wait_for_events (...) |
639 | wait_for_events (...) |
656 | CODE: |
640 | CODE: |
657 | EVENT_LIST (0, items); |
641 | EVENT_LIST (0, items); |
… | |
… | |
708 | EXTEND (SP, count); |
692 | EXTEND (SP, count); |
709 | for (i = 0; i < count; ++i) |
693 | for (i = 0; i < count; ++i) |
710 | PUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Device", list [i])); |
694 | PUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Device", list [i])); |
711 | |
695 | |
712 | void |
696 | void |
713 | context (OpenCL::Platform self, cl_context_properties *properties, SV *devices, SV *notify = 0) |
697 | context (OpenCL::Platform self, cl_context_properties *properties, SV *devices, SV *notify = &PL_sv_undef) |
714 | PPCODE: |
698 | PPCODE: |
715 | if (!SvROK (devices) || SvTYPE (SvRV (devices)) != SVt_PVAV) |
699 | if (!SvROK (devices) || SvTYPE (SvRV (devices)) != SVt_PVAV) |
716 | croak ("OpenCL::Platform::context argument 'device' must be an arrayref with device objects, in call"); |
700 | croak ("OpenCL::Platform::context argument 'device' must be an arrayref with device objects, in call"); |
717 | |
701 | |
718 | AV *av = (AV *)SvRV (devices); |
702 | AV *av = (AV *)SvRV (devices); |
… | |
… | |
721 | |
705 | |
722 | int i; |
706 | int i; |
723 | for (i = num_devices; i--; ) |
707 | for (i = num_devices; i--; ) |
724 | device_list [i] = SvCLOBJ ("clCreateContext", "devices", *av_fetch (av, i, 0), "OpenCL::Device"); |
708 | device_list [i] = SvCLOBJ ("clCreateContext", "devices", *av_fetch (av, i, 0), "OpenCL::Device"); |
725 | |
709 | |
726 | void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *) = context_default_notify; |
710 | CONTEXT_NOTIFY_CALLBACK; |
727 | void *user_data = 0; |
|
|
728 | |
|
|
729 | NEED_SUCCESS_ARG (cl_context ctx, CreateContext, (properties, num_devices, device_list, pfn_notify, user_data, &res)); |
711 | NEED_SUCCESS_ARG (cl_context ctx, CreateContext, (properties, num_devices, device_list, pfn_notify, user_data, &res)); |
730 | XPUSH_CLOBJ ("OpenCL::Context", ctx); |
712 | XPUSH_CLOBJ_CONTEXT; |
731 | |
713 | |
732 | void |
714 | void |
733 | context_from_type (OpenCL::Platform self, SV *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, FUTURE notify = 0) |
715 | context_from_type (OpenCL::Platform self, SV *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef) |
734 | PPCODE: |
716 | PPCODE: |
735 | cl_context_properties extra[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)self }; |
717 | cl_context_properties extra[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)self }; |
736 | cl_context_properties *props = SvCONTEXTPROPERTIES ("OpenCL::Platform::context_from_type", "properties", properties, extra, 2); |
718 | cl_context_properties *props = SvCONTEXTPROPERTIES ("OpenCL::Platform::context_from_type", "properties", properties, extra, 2); |
|
|
719 | |
|
|
720 | CONTEXT_NOTIFY_CALLBACK; |
737 | NEED_SUCCESS_ARG (cl_context ctx, CreateContextFromType, (props, type, 0, 0, &res)); |
721 | NEED_SUCCESS_ARG (cl_context ctx, CreateContextFromType, (props, type, 0, 0, &res)); |
738 | XPUSH_CLOBJ ("OpenCL::Context", ctx); |
722 | XPUSH_CLOBJ_CONTEXT; |
739 | |
723 | |
740 | MODULE = OpenCL PACKAGE = OpenCL::Device |
724 | MODULE = OpenCL PACKAGE = OpenCL::Device |
741 | |
725 | |
742 | void |
726 | void |
743 | info (OpenCL::Device self, cl_device_info name) |
727 | info (OpenCL::Device self, cl_device_info name) |