@@ -904,7 +904,7 @@ def zeros(
904904 data type of the array. Can be typestring,
905905 a :class:`numpy.dtype` object, :mod:`numpy` char string,
906906 or a NumPy scalar type. Default: ``None``
907- order ("C", or F"):
907+ order ("C", or " F"):
908908 memory layout for the array. Default: ``"C"``
909909 device (optional): array API concept of device where the output array
910910 is created. ``device`` can be ``None``, a oneAPI filter selector
@@ -975,7 +975,7 @@ def ones(
975975 data type of the array. Can be typestring,
976976 a :class:`numpy.dtype` object, :mod:`numpy` char string,
977977 or a NumPy scalar type. Default: ``None``
978- order ("C", or F"): memory layout for the array. Default: ``"C"``
978+ order ("C", or " F"): memory layout for the array. Default: ``"C"``
979979 device (optional): array API concept of device where the output array
980980 is created. ``device`` can be ``None``, a oneAPI filter selector
981981 string, an instance of :class:`dpctl.SyclDevice` corresponding to
@@ -1021,6 +1021,22 @@ def ones(
10211021 return res
10221022
10231023
1024+ def _cast_fill_val (fill_val , dt ):
1025+ """
1026+ Casts the Python scalar `fill_val` to another Python type coercible to the
1027+ requested data type `dt`, if necessary.
1028+ """
1029+ val_type = type (fill_val )
1030+ if val_type in [float , complex ] and np .issubdtype (dt , np .integer ):
1031+ return int (fill_val .real )
1032+ elif val_type is complex and np .issubdtype (dt , np .floating ):
1033+ return fill_val .real
1034+ elif val_type is int and np .issubdtype (dt , np .integer ):
1035+ return _to_scalar (fill_val , dt )
1036+ else :
1037+ return fill_val
1038+
1039+
10241040def full (
10251041 shape ,
10261042 fill_value ,
@@ -1043,7 +1059,7 @@ def full(
10431059 dtype (optional): data type of the array. Can be typestring,
10441060 a :class:`numpy.dtype` object, :mod:`numpy` char string,
10451061 or a NumPy scalar type. Default: ``None``
1046- order ("C", or F"):
1062+ order ("C", or " F"):
10471063 memory layout for the array. Default: ``"C"``
10481064 device (optional): array API concept of device where the output array
10491065 is created. ``device`` can be ``None``, a oneAPI filter selector
@@ -1097,21 +1113,15 @@ def full(
10971113
10981114 sycl_queue = normalize_queue_device (sycl_queue = sycl_queue , device = device )
10991115 usm_type = usm_type if usm_type is not None else "device"
1100- fill_value_type = type (fill_value )
1101- dtype = _get_dtype (dtype , sycl_queue , ref_type = fill_value_type )
1116+ dtype = _get_dtype (dtype , sycl_queue , ref_type = type (fill_value ))
11021117 res = dpt .usm_ndarray (
11031118 shape ,
11041119 dtype = dtype ,
11051120 buffer = usm_type ,
11061121 order = order ,
11071122 buffer_ctor_kwargs = {"queue" : sycl_queue },
11081123 )
1109- if fill_value_type in [float , complex ] and np .issubdtype (dtype , np .integer ):
1110- fill_value = int (fill_value .real )
1111- elif fill_value_type is complex and np .issubdtype (dtype , np .floating ):
1112- fill_value = fill_value .real
1113- elif fill_value_type is int and np .issubdtype (dtype , np .integer ):
1114- fill_value = _to_scalar (fill_value , dtype )
1124+ fill_value = _cast_fill_val (fill_value , dtype )
11151125
11161126 _manager = dpctl .utils .SequentialOrderManager [sycl_queue ]
11171127 # populating new allocation, no dependent events
@@ -1120,8 +1130,23 @@ def full(
11201130 return res
11211131
11221132
1133+ def _normalize_order (order , arr ):
1134+ """
1135+ Utility function for processing the `order` keyword of array-like
1136+ constructors, which support `"K"` and `"A"` orders.
1137+ """
1138+ arr_flags = arr .flags
1139+ f_contig = arr_flags ["F" ]
1140+ c_contig = arr_flags ["C" ]
1141+ if order == "A" :
1142+ order = "F" if f_contig and not c_contig else "C"
1143+ if order == "K" and (f_contig or c_contig ):
1144+ order = "C" if c_contig else "F"
1145+ return order
1146+
1147+
11231148def empty_like (
1124- x , / , * , dtype = None , order = "C " , device = None , usm_type = None , sycl_queue = None
1149+ x , / , * , dtype = None , order = "K " , device = None , usm_type = None , sycl_queue = None
11251150):
11261151 """
11271152 Returns an uninitialized :class:`dpctl.tensor.usm_ndarray` with the
@@ -1134,8 +1159,8 @@ def empty_like(
11341159 data type of the array. Can be a typestring,
11351160 a :class:`numpy.dtype` object, NumPy char string,
11361161 or a NumPy scalar type. Default: ``None``
1137- order ("C", or F "):
1138- memory layout for the array. Default: ``"C "``
1162+ order ("C", "F", "A", or "K "):
1163+ memory layout for the array. Default: ``"K "``
11391164 device (optional): array API concept of device where the output array
11401165 is created. ``device`` can be ``None``, a oneAPI filter selector
11411166 string, an instance of :class:`dpctl.SyclDevice` corresponding to
@@ -1161,9 +1186,13 @@ def empty_like(
11611186 """
11621187 if not isinstance (x , dpt .usm_ndarray ):
11631188 raise TypeError (f"Expected instance of dpt.usm_ndarray, got { type (x )} ." )
1164- if not isinstance (order , str ) or len (order ) == 0 or order [0 ] not in "CcFf" :
1189+ if (
1190+ not isinstance (order , str )
1191+ or len (order ) == 0
1192+ or order [0 ] not in "CcFfAaKk"
1193+ ):
11651194 raise ValueError (
1166- "Unrecognized order keyword value, expecting 'F' or 'C '."
1195+ "Unrecognized order keyword value, expecting 'C', 'F', 'A', or 'K '."
11671196 )
11681197 order = order [0 ].upper ()
11691198 if dtype is None :
@@ -1174,21 +1203,26 @@ def empty_like(
11741203 if device is None and sycl_queue is None :
11751204 device = x .device
11761205 sycl_queue = normalize_queue_device (sycl_queue = sycl_queue , device = device )
1177- shape = x .shape
11781206 dtype = dpt .dtype (dtype )
1179- _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1180- res = dpt .usm_ndarray (
1181- shape ,
1182- dtype = dtype ,
1183- buffer = usm_type ,
1184- order = order ,
1185- buffer_ctor_kwargs = {"queue" : sycl_queue },
1186- )
1187- return res
1207+ order = _normalize_order (order , x )
1208+ if order == "K" :
1209+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1210+ return _empty_like_orderK (x , dtype , usm_type , sycl_queue )
1211+ else :
1212+ shape = x .shape
1213+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1214+ res = dpt .usm_ndarray (
1215+ shape ,
1216+ dtype = dtype ,
1217+ buffer = usm_type ,
1218+ order = order ,
1219+ buffer_ctor_kwargs = {"queue" : sycl_queue },
1220+ )
1221+ return res
11881222
11891223
11901224def zeros_like (
1191- x , / , * , dtype = None , order = "C " , device = None , usm_type = None , sycl_queue = None
1225+ x , / , * , dtype = None , order = "K " , device = None , usm_type = None , sycl_queue = None
11921226):
11931227 """
11941228 Creates :class:`dpctl.tensor.usm_ndarray` from USM allocation
@@ -1203,7 +1237,7 @@ def zeros_like(
12031237 a :class:`numpy.dtype` object, :mod:`numpy` char string, or a
12041238 NumPy scalar type. If `None`, output array has the same data
12051239 type as the input array. Default: ``None``
1206- order ("C", or F"):
1240+ order ("C", or " F"):
12071241 memory layout for the array. Default: ``"C"``
12081242 device (optional):
12091243 array API concept of device where the output array
@@ -1231,9 +1265,13 @@ def zeros_like(
12311265 """
12321266 if not isinstance (x , dpt .usm_ndarray ):
12331267 raise TypeError (f"Expected instance of dpt.usm_ndarray, got { type (x )} ." )
1234- if not isinstance (order , str ) or len (order ) == 0 or order [0 ] not in "CcFf" :
1268+ if (
1269+ not isinstance (order , str )
1270+ or len (order ) == 0
1271+ or order [0 ] not in "CcFfAaKk"
1272+ ):
12351273 raise ValueError (
1236- "Unrecognized order keyword value, expecting 'F' or 'C '."
1274+ "Unrecognized order keyword value, expecting 'C', 'F', 'A', or 'K '."
12371275 )
12381276 order = order [0 ].upper ()
12391277 if dtype is None :
@@ -1244,20 +1282,31 @@ def zeros_like(
12441282 if device is None and sycl_queue is None :
12451283 device = x .device
12461284 sycl_queue = normalize_queue_device (sycl_queue = sycl_queue , device = device )
1247- sh = x .shape
12481285 dtype = dpt .dtype (dtype )
1249- return zeros (
1250- sh ,
1251- dtype = dtype ,
1252- order = order ,
1253- device = device ,
1254- usm_type = usm_type ,
1255- sycl_queue = sycl_queue ,
1256- )
1286+ order = _normalize_order (order , x )
1287+ if order == "K" :
1288+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1289+ res = _empty_like_orderK (x , dtype , usm_type , sycl_queue )
1290+ _manager = dpctl .utils .SequentialOrderManager [sycl_queue ]
1291+ # populating new allocation, no dependent events
1292+ hev , full_ev = ti ._full_usm_ndarray (0 , res , sycl_queue )
1293+ _manager .add_event_pair (hev , full_ev )
1294+ return res
1295+ else :
1296+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1297+ sh = x .shape
1298+ return zeros (
1299+ sh ,
1300+ dtype = dtype ,
1301+ order = order ,
1302+ device = device ,
1303+ usm_type = usm_type ,
1304+ sycl_queue = sycl_queue ,
1305+ )
12571306
12581307
12591308def ones_like (
1260- x , / , * , dtype = None , order = "C " , device = None , usm_type = None , sycl_queue = None
1309+ x , / , * , dtype = None , order = "K " , device = None , usm_type = None , sycl_queue = None
12611310):
12621311 """
12631312 Returns a new :class:`dpctl.tensor.usm_ndarray` filled with ones and
@@ -1270,7 +1319,7 @@ def ones_like(
12701319 data type of the array. Can be typestring,
12711320 a :class:`numpy.dtype` object, :mod:`numpy` char string,
12721321 or a NumPy scalar type. Default: `None`
1273- order ("C", or F "):
1322+ order ("C", "F", "A", or "K "):
12741323 memory layout for the array. Default: ``"C"``
12751324 device (optional):
12761325 array API concept of device where the output array
@@ -1298,9 +1347,13 @@ def ones_like(
12981347 """
12991348 if not isinstance (x , dpt .usm_ndarray ):
13001349 raise TypeError (f"Expected instance of dpt.usm_ndarray, got { type (x )} ." )
1301- if not isinstance (order , str ) or len (order ) == 0 or order [0 ] not in "CcFf" :
1350+ if (
1351+ not isinstance (order , str )
1352+ or len (order ) == 0
1353+ or order [0 ] not in "CcFfAaKk"
1354+ ):
13021355 raise ValueError (
1303- "Unrecognized order keyword value, expecting 'F' or 'C '."
1356+ "Unrecognized order keyword value, expecting 'C', 'F', 'A', or 'K '."
13041357 )
13051358 order = order [0 ].upper ()
13061359 if dtype is None :
@@ -1311,16 +1364,26 @@ def ones_like(
13111364 if device is None and sycl_queue is None :
13121365 device = x .device
13131366 sycl_queue = normalize_queue_device (sycl_queue = sycl_queue , device = device )
1314- sh = x .shape
13151367 dtype = dpt .dtype (dtype )
1316- return ones (
1317- sh ,
1318- dtype = dtype ,
1319- order = order ,
1320- device = device ,
1321- usm_type = usm_type ,
1322- sycl_queue = sycl_queue ,
1323- )
1368+ order = _normalize_order (order , x )
1369+ if order == "K" :
1370+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1371+ res = _empty_like_orderK (x , dtype , usm_type , sycl_queue )
1372+ _manager = dpctl .utils .SequentialOrderManager [sycl_queue ]
1373+ # populating new allocation, no dependent events
1374+ hev , full_ev = ti ._full_usm_ndarray (1 , res , sycl_queue )
1375+ _manager .add_event_pair (hev , full_ev )
1376+ return res
1377+ else :
1378+ sh = x .shape
1379+ return ones (
1380+ sh ,
1381+ dtype = dtype ,
1382+ order = order ,
1383+ device = device ,
1384+ usm_type = usm_type ,
1385+ sycl_queue = sycl_queue ,
1386+ )
13241387
13251388
13261389def full_like (
@@ -1329,12 +1392,12 @@ def full_like(
13291392 fill_value ,
13301393 * ,
13311394 dtype = None ,
1332- order = "C " ,
1395+ order = "K " ,
13331396 device = None ,
13341397 usm_type = None ,
13351398 sycl_queue = None ,
13361399):
1337- """ full_like(x, fill_value, dtype=None, order="C ", \
1400+ """ full_like(x, fill_value, dtype=None, order="K ", \
13381401 device=None, usm_type=None, sycl_queue=None)
13391402
13401403 Returns a new :class:`dpctl.tensor.usm_ndarray` filled with `fill_value`
@@ -1349,8 +1412,8 @@ def full_like(
13491412 a :class:`numpy.dtype` object, :mod:`numpy` char string, or a
13501413 NumPy scalar type. If ``dtype`` is ``None``, the output array data
13511414 type is inferred from ``x``. Default: ``None``
1352- order ("C", or F "):
1353- memory layout for the array. Default: ``"C "``
1415+ order ("C", "F", "A", or "K "):
1416+ memory layout for the array. Default: ``"K "``
13541417 device (optional):
13551418 array API concept of device where the output array
13561419 is created. ``device`` can be ``None``, a oneAPI filter selector
@@ -1377,9 +1440,13 @@ def full_like(
13771440 """
13781441 if not isinstance (x , dpt .usm_ndarray ):
13791442 raise TypeError (f"Expected instance of dpt.usm_ndarray, got { type (x )} ." )
1380- if not isinstance (order , str ) or len (order ) == 0 or order [0 ] not in "CcFf" :
1443+ if (
1444+ not isinstance (order , str )
1445+ or len (order ) == 0
1446+ or order [0 ] not in "CcFfAaKk"
1447+ ):
13811448 raise ValueError (
1382- "Unrecognized order keyword value, expecting 'F' or 'C '."
1449+ "Unrecognized order keyword value, expecting 'C', 'F', 'A', or 'K '."
13831450 )
13841451 order = order [0 ].upper ()
13851452 if dtype is None :
@@ -1392,15 +1459,46 @@ def full_like(
13921459 sycl_queue = normalize_queue_device (sycl_queue = sycl_queue , device = device )
13931460 sh = x .shape
13941461 dtype = dpt .dtype (dtype )
1395- return full (
1396- sh ,
1397- fill_value ,
1398- dtype = dtype ,
1399- order = order ,
1400- device = device ,
1401- usm_type = usm_type ,
1402- sycl_queue = sycl_queue ,
1403- )
1462+ order = _normalize_order (order , x )
1463+ if order == "K" :
1464+ _ensure_native_dtype_device_support (dtype , sycl_queue .sycl_device )
1465+ if isinstance (fill_value , (dpt .usm_ndarray , np .ndarray , tuple , list )):
1466+ X = dpt .asarray (
1467+ fill_value ,
1468+ dtype = dtype ,
1469+ order = order ,
1470+ usm_type = usm_type ,
1471+ sycl_queue = sycl_queue ,
1472+ )
1473+ X = dpt .broadcast_to (X , sh )
1474+ res = _empty_like_orderK (x , dtype , usm_type , sycl_queue )
1475+ _manager = dpctl .utils .SequentialOrderManager [sycl_queue ]
1476+ # order copy after tasks populating X
1477+ dep_evs = _manager .submitted_events
1478+ hev , copy_ev = ti ._copy_usm_ndarray_into_usm_ndarray (
1479+ src = X , dst = res , sycl_queue = sycl_queue , depends = dep_evs
1480+ )
1481+ _manager .add_event_pair (hev , copy_ev )
1482+ return res
1483+
1484+ dtype = _get_dtype (dtype , sycl_queue , ref_type = type (fill_value ))
1485+ res = _empty_like_orderK (x , dtype , usm_type , sycl_queue )
1486+ fill_value = _cast_fill_val (fill_value , dtype )
1487+ _manager = dpctl .utils .SequentialOrderManager [sycl_queue ]
1488+ # populating new allocation, no dependent events
1489+ hev , full_ev = ti ._full_usm_ndarray (fill_value , res , sycl_queue )
1490+ _manager .add_event_pair (hev , full_ev )
1491+ return res
1492+ else :
1493+ return full (
1494+ sh ,
1495+ fill_value ,
1496+ dtype = dtype ,
1497+ order = order ,
1498+ device = device ,
1499+ usm_type = usm_type ,
1500+ sycl_queue = sycl_queue ,
1501+ )
14041502
14051503
14061504def linspace (
@@ -1536,7 +1634,7 @@ def eye(
15361634 data type of the array. Can be typestring,
15371635 a :class:`numpy.dtype` object, :mod:`numpy` char string, or
15381636 a NumPy scalar type. Default: ``None``
1539- order ("C" or F"):
1637+ order ("C" or " F"):
15401638 memory layout for the array. Default: ``"C"``
15411639 device (optional):
15421640 array API concept of device where the output array
0 commit comments