@@ -48,8 +48,8 @@ include "_slicing.pxi"
48
48
49
49
cdef class InternalUSMArrayError(Exception ):
50
50
"""
51
- A InternalError exception is raised when internal
52
- inconsistency has been detected.
51
+ A InternalUSMArrayError exception is raised when internal
52
+ inconsistency has been detected in :class:`.usm_ndarray` .
53
53
"""
54
54
pass
55
55
@@ -170,7 +170,7 @@ cdef class usm_ndarray:
170
170
"""
171
171
strides and offset must be given in units of array elements.
172
172
buffer can be strings ('device'|'shared'|'host' to allocate new memory)
173
- or dpctl.memory.MemoryUSM* buffers, or usm_ndrray instances.
173
+ or `` dpctl.memory.MemoryUSM*`` buffers, or `` usm_ndrray`` instances.
174
174
"""
175
175
cdef int nd = 0
176
176
cdef int typenum = 0
@@ -200,7 +200,7 @@ cdef class usm_ndarray:
200
200
except Exception as e:
201
201
raise TypeError (
202
202
" Argument shape must a non-negative integer, "
203
- " or a list/tuple of such integers."
203
+ " or a list/tuple of such integers."
204
204
) from e
205
205
nd = len (shape)
206
206
if dtype is None :
@@ -302,7 +302,10 @@ cdef class usm_ndarray:
302
302
303
303
@property
304
304
def _pointer (self ):
305
- " Returns USM pointer for data allocation encoded as integer"
305
+ """
306
+ Returns USM pointer to the start of array (element with zero
307
+ multi-index) encoded as integer.
308
+ """
306
309
return < size_t> self .get_data()
307
310
308
311
cdef Py_ssize_t get_offset(self ) except * :
@@ -324,7 +327,26 @@ cdef class usm_ndarray:
324
327
325
328
@property
326
329
def _byte_bounds (self ):
327
- """ Returns a 2-tuple with pointers to the end-points of the array"""
330
+ """ Returns a 2-tuple with pointers to the end-points of the array
331
+
332
+ :Example:
333
+
334
+ .. code-block:: python
335
+
336
+ from dpctl import tensor
337
+
338
+ x = tensor.ones((3, 10, 7))
339
+ y = tensor.flip(x[:, 1::2], axis=1)
340
+
341
+ beg_p, end_p = y._byte_bounds
342
+ # Bytes taken to store this array
343
+ bytes_extent = end_p - beg_p
344
+
345
+ # C-contiguous copy is more compact
346
+ yc = tensor.copy(y, order="C")
347
+ beg_pc, end_pc = yc._byte_bounds
348
+ assert bytes_extent < end_pc - beg_pc
349
+ """
328
350
cdef Py_ssize_t min_disp = 0
329
351
cdef Py_ssize_t max_disp = 0
330
352
cdef Py_ssize_t step_ = 0
@@ -480,7 +502,7 @@ cdef class usm_ndarray:
480
502
@property
481
503
def usm_data (self ):
482
504
"""
483
- Gives USM memory object underlying usm_array instance.
505
+ Gives USM memory object underlying :class:`.usm_ndarray` instance.
484
506
"""
485
507
return self .get_base()
486
508
@@ -489,6 +511,20 @@ cdef class usm_ndarray:
489
511
"""
490
512
Elements of the shape tuple give the lengths of the
491
513
respective array dimensions.
514
+
515
+ Setting shape is allowed only when reshaping to the requested
516
+ dimensions can be returned as view, otherwise :exc:`AttributeError`
517
+ is raised. Use :func:`dpctl.tensor.reshape` to reshape the array
518
+ in all cases.
519
+
520
+ :Example:
521
+
522
+ .. code-block:: python
523
+
524
+ from dpctl import tensor
525
+
526
+ x = tensor.arange(899)
527
+ x.shape = (29, 31)
492
528
"""
493
529
if self .nd_ > 0 :
494
530
return _make_int_tuple(self .nd_, self .shape_)
@@ -497,11 +533,6 @@ cdef class usm_ndarray:
497
533
498
534
@shape.setter
499
535
def shape (self , new_shape ):
500
- """
501
- Setting shape is only allowed when reshaping to the requested
502
- dimensions can be returned as view. Use :func:`dpctl.tensor.reshape`
503
- to reshape the array in all other cases.
504
- """
505
536
cdef int new_nd = - 1
506
537
cdef Py_ssize_t nelems = - 1
507
538
cdef int err = 0
@@ -567,9 +598,25 @@ cdef class usm_ndarray:
567
598
Returns memory displacement in array elements, upon unit
568
599
change of respective index.
569
600
570
- E.g. for strides (s1, s2, s3) and multi-index (i1, i2, i3)
601
+ For example, for strides ``(s1, s2, s3)`` and multi-index
602
+ ``(i1, i2, i3)`` position of the respective element relative
603
+ to zero multi-index element is ``s1*s1 + s2*i2 + s3*i3``.
571
604
572
- a[i1, i2, i3] == (&a[0,0,0])[ s1*s1 + s2*i2 + s3*i3]
605
+ :Example:
606
+
607
+ .. code-block:: python
608
+
609
+ from dpctl import tensor
610
+
611
+ x = tensor.zeros((20, 30))
612
+ xv = x[10:, :15]
613
+
614
+ multi_id = (3, 5)
615
+ byte_displacement = xv[multi_id]._pointer - xv[0, 0]._pointer
616
+ element_displacement = sum(
617
+ i * s for i, s in zip(multi_id, xv.strides)
618
+ )
619
+ assert byte_displacement == element_displacement * xv.itemsize
573
620
"""
574
621
if (self .strides_):
575
622
return _make_int_tuple(self .nd_, self .strides_)
@@ -595,8 +642,17 @@ cdef class usm_ndarray:
595
642
@property
596
643
def usm_type (self ):
597
644
"""
598
- USM type of underlying memory. Can be ``"device"``, ``"shared"``,
599
- or ``"host"``.
645
+ USM type of underlying memory. Possible values are:
646
+
647
+ * ``"device"``
648
+ USM-device allocation in device memory, only accessible
649
+ to kernels executed on the device
650
+ * ``"shared"``
651
+ USM-shared allocation in device memory, accessible both
652
+ from the device and from host
653
+ * ``"host"``
654
+ USM-host allocation in host memory, accessible both
655
+ from the device and from host
600
656
601
657
See: https://docs.oneapi.com/versions/latest/dpcpp/iface/usm.html
602
658
"""
@@ -650,7 +706,22 @@ cdef class usm_ndarray:
650
706
@property
651
707
def device (self ):
652
708
"""
653
- Returns data-API object representing residence of the array data.
709
+ Returns :class:`dpctl.tensor.Device` object representing
710
+ residence of the array data.
711
+
712
+ The ``Device`` object represents Array API notion of the
713
+ device, and contains :class:`dpctl.SyclQueue` associated
714
+ with this array. Hence, ``.device`` property provides
715
+ information distinct from ``.sycl_device`` property.
716
+
717
+ :Example:
718
+
719
+ .. code-block:: python
720
+
721
+ >>> from dpctl import tensor
722
+ >>> x = tensor.ones(10)
723
+ >>> x.device
724
+ Device(level_zero:gpu:0)
654
725
"""
655
726
return Device.create_device(self .sycl_queue)
656
727
@@ -664,7 +735,7 @@ cdef class usm_ndarray:
664
735
665
736
@property
666
737
def T (self ):
667
- """ Returns transposed array for 2D array, raises `ValueError`
738
+ """ Returns transposed array for 2D array, raises `` ValueError` `
668
739
otherwise.
669
740
"""
670
741
if self .nd_ == 2 :
@@ -678,7 +749,8 @@ cdef class usm_ndarray:
678
749
679
750
@property
680
751
def mT (self ):
681
- """ Returns array where the last two dimensions are transposed.
752
+ """ Returns array (a view) where the last two dimensions are
753
+ transposed.
682
754
"""
683
755
if self .nd_ < 2 :
684
756
raise ValueError (
@@ -688,8 +760,26 @@ cdef class usm_ndarray:
688
760
689
761
@property
690
762
def real (self ):
691
- """ Returns real component for arrays with complex data-types
692
- and returns itself for all other data-types.
763
+ """
764
+ Returns view into real component for arrays with
765
+ complex data-types and returns itself for all other
766
+ data-types.
767
+
768
+ :Example:
769
+
770
+ .. code-block:: python
771
+
772
+ from dpctl import tensor
773
+
774
+ # Create complex array from
775
+ # arrays of real and imaginary parts
776
+
777
+ re = tensor.linspace(-1, 1, num=100, dtype="f4")
778
+ im = tensor.full_like(re, fill_value=tensor.pi)
779
+
780
+ z = tensor.empty_like(re, dtype="c8")
781
+ z.real[:] = re
782
+ z.imag[:] = im
693
783
"""
694
784
# explicitly check for UAR_HALF, which is greater than UAR_CFLOAT
695
785
if (self .typenum_ < UAR_CFLOAT or self .typenum_ == UAR_HALF):
@@ -700,8 +790,20 @@ cdef class usm_ndarray:
700
790
701
791
@property
702
792
def imag (self ):
703
- """ Returns imaginary component for arrays with complex data-types
704
- and returns zero array for all other data-types.
793
+ """ Returns view into imaginary component for arrays with
794
+ complex data-types and returns new zero array for all other
795
+ data-types.
796
+
797
+ :Example:
798
+
799
+ .. code-block:: python
800
+
801
+ from dpctl import tensor
802
+
803
+ # Reset imaginary part of complex array
804
+
805
+ z = tensor.ones(100, dtype="c8")
806
+ z.imag[:] = dpt.pi/2
705
807
"""
706
808
# explicitly check for UAR_HALF, which is greater than UAR_CFLOAT
707
809
if (self .typenum_ < UAR_CFLOAT or self .typenum_ == UAR_HALF):
@@ -771,7 +873,7 @@ cdef class usm_ndarray:
771
873
res.flags_ = _copy_writable(res.flags_, self .flags_)
772
874
return res
773
875
774
- def to_device (self , target , stream = None ):
876
+ def to_device (self , target_device , stream = None ):
775
877
""" to_device(target_device)
776
878
777
879
Transfers this array to specified target device.
@@ -799,7 +901,10 @@ cdef class usm_ndarray:
799
901
an instance of :class:`dpctl.SyclDevice` corresponding to a
800
902
non-partitioned SYCL device, an instance of
801
903
:class:`dpctl.SyclQueue`, or a :class:`dpctl.tensor.Device`
802
- object returned by :attr:`dpctl.tensor.usm_array.device`.
904
+ object returned by :attr:`dpctl.tensor.usm_ndarray.device`.
905
+ stream (:class:`dpctl.SyclQueue`, optional):
906
+ Execution queue to synchronize with. If ``None``,
907
+ synchronization is not performed.
803
908
804
909
Returns:
805
910
usm_ndarray:
@@ -810,7 +915,7 @@ cdef class usm_ndarray:
810
915
"""
811
916
cdef c_dpctl.DPCTLSyclQueueRef QRef = NULL
812
917
cdef c_dpmem._Memory arr_buf
813
- d = Device.create_device(target )
918
+ d = Device.create_device(target_device )
814
919
815
920
if (stream is None or type (stream) is not dpctl.SyclQueue or
816
921
stream == self .sycl_queue):
@@ -861,7 +966,20 @@ cdef class usm_ndarray:
861
966
"""
862
967
Returns array namespace, member functions of which
863
968
implement data API.
969
+
970
+ Args:
971
+ api_version (str, optional)
972
+ Request namespace compliant with given version of
973
+ array API. If ``None``, namespace for the most
974
+ recent supported version is returned.
975
+ Default: ``None``.
864
976
"""
977
+ if api_version is not None :
978
+ from ._array_api import __array_api_version__
979
+ if not isinstance (api_version, str ):
980
+ raise TypeError (f" Expected type str, got {type(api_version)}" )
981
+ if api_version != __array_api_version__:
982
+ raise ValueError (f" Only {__array_api_version__} is supported" )
865
983
return self .array_namespace_ if self .array_namespace_ is not None else dpctl.tensor
866
984
867
985
def __bool__ (self ):
@@ -929,12 +1047,17 @@ cdef class usm_ndarray:
929
1047
"""
930
1048
Produces DLPack capsule.
931
1049
1050
+ Args:
1051
+ stream (:class:`dpctl.SyclQueue`, optional):
1052
+ Execution queue to synchronize with. If ``None``,
1053
+ synchronization is not performed.
1054
+
932
1055
Raises:
933
- MemoryError: when host memory can not be allocated.
934
- DLPackCreationError: when array is allocated on a partitioned
1056
+ MemoryError:
1057
+ when host memory can not be allocated.
1058
+ DLPackCreationError:
1059
+ when array is allocated on a partitioned
935
1060
SYCL device, or with a non-default context.
936
- NotImplementedError: when non-default value of `stream` keyword
937
- is used.
938
1061
"""
939
1062
_caps = c_dlpack.to_dlpack_capsule(self )
940
1063
if (stream is None or type (stream) is not dpctl.SyclQueue or
@@ -947,15 +1070,15 @@ cdef class usm_ndarray:
947
1070
948
1071
def __dlpack_device__ (self ):
949
1072
"""
950
- Gives a tuple (`device_type`, `device_id`) corresponding to ``DLDevice``
951
- entry in ``DLTensor`` in DLPack protocol.
1073
+ Gives a tuple (`` device_type`` , `` device_id`` ) corresponding to
1074
+ ``DLDevice`` entry in ``DLTensor`` in DLPack protocol.
952
1075
953
- The tuple describes the non-partitioned device where the array
954
- has been allocated .
1076
+ The tuple describes the non-partitioned device where the array has been allocated,
1077
+ or the non-partitioned parent device of the allocation device .
955
1078
956
1079
Raises:
957
- DLPackCreationError: when array is allocation on a partitioned
958
- SYCL device
1080
+ DLPackCreationError:
1081
+ when the ``device_id`` could not be determined.
959
1082
"""
960
1083
cdef int dev_id = c_dlpack.get_parent_device_ordinal_id(< c_dpctl.SyclDevice> self .sycl_device)
961
1084
if dev_id < 0 :
@@ -1541,5 +1664,5 @@ cdef api object UsmNDArray_MakeFromPtr(
1541
1664
1542
1665
1543
1666
def _is_object_with_buffer_protocol (o ):
1544
- " Returns True if object support Python buffer protocol"
1667
+ " Returns True if object supports Python buffer protocol"
1545
1668
return _is_buffer(o)
0 commit comments