5656from .dpnp_utils import get_usm_allocations
5757from .dpnp_utils .dpnp_utils_pad import dpnp_pad
5858from .exceptions import AxisError
59+ from .tensor ._manipulation_functions import _broadcast_shapes
5960from .tensor ._numpy_helper import (
6061 normalize_axis_index ,
6162 normalize_axis_tuple ,
@@ -1047,6 +1048,193 @@ def atleast_3d(*arys):
10471048 return tuple (res )
10481049
10491050
1051+ class broadcast : # pylint: disable=invalid-name
1052+ """
1053+ Produce an object that mimics broadcasting.
1054+
1055+ For full documentation refer to :obj:`numpy.broadcast`.
1056+
1057+ Parameters
1058+ ----------
1059+ *args : {dpnp.ndarray, usm_ndarray}
1060+ Input arrays to broadcast against one another.
1061+
1062+ Returns
1063+ -------
1064+ broadcast : broadcast object
1065+ Broadcast the input parameters against one another, and
1066+ return an object that encapsulates the result.
1067+ Amongst others, it has ``shape`` and ``ndim`` properties.
1068+
1069+ Limitations
1070+ -----------
1071+ Input arrays are not coerced, so array-like objects and scalars are not
1072+ supported and ``TypeError`` exception will be raised.
1073+
1074+ See Also
1075+ --------
1076+ :obj:`dpnp.broadcast_arrays` : Broadcast any number of arrays against
1077+ each other.
1078+ :obj:`dpnp.broadcast_shapes` : Broadcast the input shapes into a single
1079+ shape.
1080+ :obj:`dpnp.broadcast_to` : Broadcast an array to a new shape.
1081+
1082+ Notes
1083+ -----
1084+ Iterator functionality is not supported.
1085+
1086+ The legacy ``nd`` attribute of :obj:`numpy.broadcast` is not provided,
1087+ ``ndim`` has to be used instead.
1088+
1089+ Examples
1090+ --------
1091+ >>> import dpnp as np
1092+ >>> x = np.array([[1], [2], [3]])
1093+ >>> y = np.array([4, 5, 6])
1094+ >>> b = np.broadcast(x, y)
1095+ >>> b.shape
1096+ (3, 3)
1097+ >>> b.ndim
1098+ 2
1099+ >>> b.size
1100+ 9
1101+
1102+ """
1103+
1104+ def __init__ (self , * args ):
1105+ dpnp .check_supported_arrays_type (* args )
1106+
1107+ self ._arrays = args
1108+ self ._values = None
1109+
1110+ # _broadcast_shapes() does not accept an empty sequence of arrays
1111+ self ._shape = _broadcast_shapes (* args ) if args else ()
1112+ self ._size = math .prod (self ._shape )
1113+ self ._ndim = len (self ._shape )
1114+
1115+ @property
1116+ def shape (self ):
1117+ """
1118+ Shape of the broadcasted result.
1119+
1120+ Returns
1121+ -------
1122+ out : tuple
1123+ A tuple containing the shape of the broadcasted result.
1124+
1125+ Examples
1126+ --------
1127+ >>> import dpnp as np
1128+ >>> x = np.array([[1], [2], [3]])
1129+ >>> y = np.array([4, 5, 6])
1130+ >>> np.broadcast(x, y).shape
1131+ (3, 3)
1132+
1133+ """
1134+ return self ._shape
1135+
1136+ @property
1137+ def size (self ):
1138+ """
1139+ Total size of the broadcasted result.
1140+
1141+ Returns
1142+ -------
1143+ out : int
1144+ The total size (number of elements) of the broadcasted result.
1145+
1146+ Examples
1147+ --------
1148+ >>> import dpnp as np
1149+ >>> x = np.array([[1], [2], [3]])
1150+ >>> y = np.array([4, 5, 6])
1151+ >>> np.broadcast(x, y).size
1152+ 9
1153+
1154+ """
1155+ return self ._size
1156+
1157+ @property
1158+ def ndim (self ):
1159+ """
1160+ Number of dimensions of the broadcasted result.
1161+
1162+ Returns
1163+ -------
1164+ out : int
1165+ The number of dimensions of the broadcasted result.
1166+
1167+ Examples
1168+ --------
1169+ >>> import dpnp as np
1170+ >>> x = np.array([[1], [2], [3]])
1171+ >>> y = np.array([4, 5, 6])
1172+ >>> np.broadcast(x, y).ndim
1173+ 2
1174+
1175+ """
1176+ return self ._ndim
1177+
1178+ @property
1179+ def numiter (self ):
1180+ """
1181+ Number of iterators possessed by the broadcast object.
1182+
1183+ Returns
1184+ -------
1185+ out : int
1186+ The number of iterators.
1187+
1188+ Examples
1189+ --------
1190+ >>> import dpnp as np
1191+ >>> x = np.array([[1], [2], [3]])
1192+ >>> y = np.array([4, 5, 6])
1193+ >>> np.broadcast(x, y).numiter
1194+ 2
1195+
1196+ """
1197+ return len (self ._arrays )
1198+
1199+ @property
1200+ def values (self ):
1201+ """
1202+ The input arrays broadcast against one another.
1203+
1204+ Returns
1205+ -------
1206+ out : tuple of dpnp.ndarray
1207+ A tuple of arrays which are views on the original input arrays.
1208+
1209+ Examples
1210+ --------
1211+ >>> import dpnp as np
1212+ >>> x = np.array([[1], [2], [3]])
1213+ >>> y = np.array([4, 5, 6])
1214+ >>> b = np.broadcast(x, y)
1215+ >>> b.values[0]
1216+ array([[1, 1, 1],
1217+ [2, 2, 2],
1218+ [3, 3, 3]])
1219+ >>> b.values[1]
1220+ array([[4, 5, 6],
1221+ [4, 5, 6],
1222+ [4, 5, 6]])
1223+
1224+ """
1225+ if self ._values is None :
1226+ self ._values = tuple (
1227+ broadcast_to (a , self ._shape ) for a in self ._arrays
1228+ )
1229+ return self ._values
1230+
1231+ def __repr__ (self ):
1232+ return (
1233+ f"<broadcast shape={ self .shape } , "
1234+ f"ndim={ self .ndim } , size={ self .size } >"
1235+ )
1236+
1237+
10501238def broadcast_arrays (* args , subok = False ):
10511239 """
10521240 Broadcast any number of arrays against each other.
@@ -1055,7 +1243,7 @@ def broadcast_arrays(*args, subok=False):
10551243
10561244 Parameters
10571245 ----------
1058- args : {dpnp.ndarray, usm_ndarray}
1246+ * args : {dpnp.ndarray, usm_ndarray}
10591247 A list of arrays to broadcast.
10601248
10611249 Returns
@@ -1070,6 +1258,9 @@ def broadcast_arrays(*args, subok=False):
10701258
10711259 See Also
10721260 --------
1261+ :obj:`dpnp.broadcast` : Produce an object that mimics broadcasting.
1262+ :obj:`dpnp.broadcast_shapes` : Broadcast the input shapes into a single
1263+ shape.
10731264 :obj:`dpnp.broadcast_to` : Broadcast an array to a new shape.
10741265
10751266 Examples
@@ -1112,6 +1303,7 @@ def broadcast_shapes(*args):
11121303
11131304 See Also
11141305 --------
1306+ :obj:`dpnp.broadcast` : Produce an object that mimics broadcasting.
11151307 :obj:`dpnp.broadcast_arrays` : Broadcast any number of arrays against
11161308 each other.
11171309 :obj:`dpnp.broadcast_to` : Broadcast an array to a new shape.
@@ -1175,8 +1367,11 @@ def broadcast_to(array, /, shape, subok=False):
11751367
11761368 See Also
11771369 --------
1370+ :obj:`dpnp.broadcast` : Produce an object that mimics broadcasting.
11781371 :obj:`dpnp.broadcast_arrays` : Broadcast any number of arrays against
11791372 each other.
1373+ :obj:`dpnp.broadcast_shapes` : Broadcast the input shapes into a single
1374+ shape.
11801375
11811376 Examples
11821377 --------
0 commit comments