@@ -116,6 +116,49 @@ def _to_memory(unsigned char[::1] b, str usm_kind):
116
116
return res
117
117
118
118
119
+ def get_usm_pointer_type (ptr , syclobj ):
120
+ """
121
+ get_usm_pointer_type(ptr, syclobj)
122
+
123
+ Gives the SYCL(TM) USM pointer type, using ``sycl::get_pointer_type``,
124
+ returning one of 4 possible strings: 'shared', 'host', 'device',
125
+ or 'unknown'.
126
+
127
+ Args:
128
+ ptr: int
129
+ A pointer stored as size_t Python integer.
130
+ syclobj: :class:`dpctl.SyclContext` or :class:`dpctl.SyclQueue`
131
+ Python object providing :class:`dpctl.SyclContext` against which
132
+ to query for the pointer type.
133
+ Returns:
134
+ 'unknown' if the pointer does not represent USM allocation made using
135
+ the given context. Otherwise, returns 'shared', 'device', or 'host'
136
+ type of the allocation.
137
+ """
138
+ cdef const char * kind
139
+ cdef SyclContext ctx
140
+ cdef SyclQueue q
141
+ cdef DPCTLSyclUSMRef USMRef = NULL
142
+ try :
143
+ USMRef = < DPCTLSyclUSMRef> (< size_t> ptr)
144
+ except Exception as e:
145
+ raise TypeError (
146
+ " First argument {} could not be converted to Python integer of "
147
+ " size_t" .format(ptr)
148
+ ) from e
149
+ if isinstance (syclobj, SyclContext):
150
+ ctx = < SyclContext> (syclobj)
151
+ return _Memory.get_pointer_type(USMRef, ctx).decode(" UTF-8" )
152
+ elif isinstance (syclobj, SyclQueue):
153
+ q = < SyclQueue> (syclobj)
154
+ ctx = q.get_sycl_context()
155
+ return _Memory.get_pointer_type(USMRef, ctx).decode(" UTF-8" )
156
+ raise TypeError (
157
+ " Second argument {} is expected to be an instance of "
158
+ " SyclContext or SyclQueue" .format(syclobj)
159
+ )
160
+
161
+
119
162
cdef class _Memory:
120
163
""" Internal class implementing methods common to
121
164
MemoryUSMShared, MemoryUSMDevice, MemoryUSMHost
@@ -282,7 +325,7 @@ cdef class _Memory:
282
325
283
326
def __repr__ (self ):
284
327
return (
285
- " <SYCL(TM) USM-{} allocated memory block of {} bytes at {}>"
328
+ " <SYCL(TM) USM-{} allocation of {} bytes at {}>"
286
329
.format(
287
330
self .get_usm_type(),
288
331
self .nbytes,
@@ -316,31 +359,37 @@ cdef class _Memory:
316
359
return iface
317
360
318
361
def get_usm_type (self , syclobj = None ):
362
+ """
363
+ get_usm_type(syclobj=None)
364
+
365
+ Returns the type of USM allocation using Sycl context carried by
366
+ `syclobj` keyword argument. Value of None is understood to query
367
+ against `self.sycl_context` - the context used to create the
368
+ allocation.
369
+ """
319
370
cdef const char * kind
320
371
cdef SyclContext ctx
321
372
cdef SyclQueue q
322
373
if syclobj is None :
323
374
ctx = self ._context
324
- kind = DPCTLUSM_GetPointerType (
325
- self .memory_ptr, ctx.get_context_ref()
326
- )
375
+ return _Memory.get_pointer_type (
376
+ self .memory_ptr, ctx
377
+ ).decode( " UTF-8 " )
327
378
elif isinstance (syclobj, SyclContext):
328
379
ctx = < SyclContext> (syclobj)
329
- kind = DPCTLUSM_GetPointerType (
330
- self .memory_ptr, ctx.get_context_ref()
331
- )
380
+ return _Memory.get_pointer_type (
381
+ self .memory_ptr, ctx
382
+ ).decode( " UTF-8 " )
332
383
elif isinstance (syclobj, SyclQueue):
333
384
q = < SyclQueue> (syclobj)
334
385
ctx = q.get_sycl_context()
335
- kind = DPCTLUSM_GetPointerType(
336
- self .memory_ptr, ctx.get_context_ref()
337
- )
338
- else :
339
- raise ValueError (
340
- " syclobj keyword can be either None, or an instance of "
341
- " SyclContext or SyclQueue"
342
- )
343
- return kind.decode(' UTF-8' )
386
+ return _Memory.get_pointer_type(
387
+ self .memory_ptr, ctx
388
+ ).decode(" UTF-8" )
389
+ raise TypeError (
390
+ " syclobj keyword can be either None, or an instance of "
391
+ " SyclContext or SyclQueue"
392
+ )
344
393
345
394
cpdef copy_to_host(self , obj = None ):
346
395
"""
@@ -457,7 +506,24 @@ cdef class _Memory:
457
506
458
507
@staticmethod
459
508
cdef bytes get_pointer_type(DPCTLSyclUSMRef p, SyclContext ctx):
460
- """ Returns USM-type of given pointer `p` in given sycl context `ctx`"""
509
+ """
510
+ get_pointer_type(p, ctx)
511
+
512
+ Gives the SYCL(TM) USM pointer type, using ``sycl::get_pointer_type``,
513
+ returning one of 4 possible strings: 'shared', 'host', 'device', or
514
+ 'unknown'.
515
+
516
+ Args:
517
+ p: DPCTLSyclUSMRef
518
+ A pointer to test the type of.
519
+ ctx: :class:`dpctl.SyclContext`
520
+ Python object providing :class:`dpctl.SyclContext` against
521
+ which to query for the pointer type.
522
+ Returns:
523
+ b'unknown' if the pointer does not represent USM allocation made
524
+ using the given context. Otherwise, returns b'shared', b'device',
525
+ or b'host' type of the allocation.
526
+ """
461
527
cdef const char * usm_type = DPCTLUSM_GetPointerType(
462
528
p, ctx.get_context_ref()
463
529
)
@@ -530,12 +596,14 @@ cdef class MemoryUSMShared(_Memory):
530
596
allocates nbytes of USM shared memory.
531
597
532
598
Non-positive alignments are not used (malloc_shared is used instead).
533
- For the queue=None cast the `dpctl.SyclQueue()` is used to allocate memory.
534
-
535
- MemoryUSMShared(usm_obj) constructor create instance from `usm_obj`
536
- expected to implement `__sycl_usm_array_interface__` protocol and exposing
537
- a contiguous block of USM memory of USM shared type. Using copy=True to
538
- perform a copy if USM type is other than 'shared'.
599
+ For the queue=None case the ``dpctl.SyclQueue()`` is used to allocate
600
+ memory.
601
+
602
+ MemoryUSMShared(usm_obj) constructor creates instance from `usm_obj`
603
+ expected to implement `__sycl_usm_array_interface__` protocol and to expose
604
+ a contiguous block of USM shared allocation. Use `copy=True` to
605
+ perform a copy if USM type of the allocation represented by the argument
606
+ is other than 'shared'.
539
607
"""
540
608
def __cinit__ (self , other , *, Py_ssize_t alignment = 0 ,
541
609
SyclQueue queue = None , int copy = False ):
@@ -569,12 +637,14 @@ cdef class MemoryUSMHost(_Memory):
569
637
allocates nbytes of USM host memory.
570
638
571
639
Non-positive alignments are not used (malloc_host is used instead).
572
- For the queue=None case `dpctl.SyclQueue()` is used to allocate memory.
640
+ For the queue=None case the ``dpctl.SyclQueue()`` is used to allocate
641
+ memory.
573
642
574
643
MemoryUSMDevice(usm_obj) constructor create instance from `usm_obj`
575
- expected to implement `__sycl_usm_array_interface__` protocol and exposing
576
- a contiguous block of USM memory of USM host type. Using copy=True to
577
- perform a copy if USM type is other than 'host'.
644
+ expected to implement `__sycl_usm_array_interface__` protocol and to expose
645
+ a contiguous block of USM host allocation. Use `copy=True` to
646
+ perform a copy if USM type of the allocation represented by the argument
647
+ is other than 'host'.
578
648
"""
579
649
def __cinit__ (self , other , *, Py_ssize_t alignment = 0 ,
580
650
SyclQueue queue = None , int copy = False ):
@@ -609,12 +679,14 @@ cdef class MemoryUSMDevice(_Memory):
609
679
allocates nbytes of USM device memory.
610
680
611
681
Non-positive alignments are not used (malloc_device is used instead).
612
- For the queue=None cast the `dpctl.SyclQueue()` is used to allocate memory.
682
+ For the queue=None case the ``dpctl.SyclQueue()`` is used to allocate
683
+ memory.
613
684
614
685
MemoryUSMDevice(usm_obj) constructor create instance from `usm_obj`
615
686
expected to implement `__sycl_usm_array_interface__` protocol and exposing
616
- a contiguous block of USM memory of USM device type. Using copy=True to
617
- perform a copy if USM type is other than 'device'.
687
+ a contiguous block of USM device allocation. Use `copy=True` to
688
+ perform a copy if USM type of the allocation represented by the argument
689
+ is other than 'device'.
618
690
"""
619
691
def __cinit__ (self , other , *, Py_ssize_t alignment = 0 ,
620
692
SyclQueue queue = None , int copy = False ):
@@ -638,3 +710,41 @@ cdef class MemoryUSMDevice(_Memory):
638
710
other, self .get_usm_type()
639
711
)
640
712
)
713
+
714
+
715
+ def as_usm_memory (obj ):
716
+ """
717
+ as_usm_memory(obj)
718
+
719
+ Converts Python object with `__sycl_usm_array_interface__` property
720
+ to one of :class:`.MemoryUSMShared`, :class:`.MemoryUSMDevice`, or
721
+ :class:`.MemoryUSMHost` instances depending on the type of USM allocation
722
+ they represent.
723
+
724
+ Raises:
725
+ ValueError
726
+ When object does not expose the `__sycl_usm_array_interface__`,
727
+ or it is malformed
728
+ TypeError
729
+ When unexpected types of entries in the interface are encountered
730
+ SyclQueueCreationError
731
+ When a :class:`dpctl.SyclQueue` could not be created from the
732
+ information given by the interface
733
+ """
734
+ cdef _Memory res = _Memory.__new__ (_Memory)
735
+ cdef str kind
736
+ res._cinit_empty()
737
+ res._cinit_other(obj)
738
+ kind = res.get_usm_type()
739
+ if kind == " shared" :
740
+ return MemoryUSMShared(res)
741
+ elif kind == " device" :
742
+ return MemoryUSMDevice(res)
743
+ elif kind == " host" :
744
+ return MemoryUSMHost(res)
745
+ else :
746
+ raise ValueError (
747
+ " Could not determine the type "
748
+ " USM allocation represented by argument {}" .
749
+ format(obj)
750
+ )
0 commit comments