Skip to content

Commit e142b5a

Browse files
Update test_statistic.py to run on Iris Xe (#1494)
* Update dpnp_median * Update dpnp_cov * Update test_statistics.py * Move get_ret_type_and_func to dpnp_algo_utils * Call get_default_floating_type without <>
1 parent 1fc100f commit e142b5a

File tree

9 files changed

+94
-66
lines changed

9 files changed

+94
-66
lines changed

dpnp/backend/kernels/dpnp_krnl_common.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,17 +1167,17 @@ void func_map_init_linalg(func_map_t &fmap)
11671167
eft_DBL, (void *)dpnp_eig_default_c<double, double>};
11681168

11691169
fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_INT][eft_INT] = {
1170-
get_default_floating_type<>(),
1170+
get_default_floating_type(),
11711171
(void *)dpnp_eig_ext_c<
1172-
int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1172+
int32_t, func_type_map_t::find_type<get_default_floating_type()>>,
11731173
get_default_floating_type<std::false_type>(),
11741174
(void *)dpnp_eig_ext_c<
11751175
int32_t, func_type_map_t::find_type<
11761176
get_default_floating_type<std::false_type>()>>};
11771177
fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_LNG][eft_LNG] = {
1178-
get_default_floating_type<>(),
1178+
get_default_floating_type(),
11791179
(void *)dpnp_eig_ext_c<
1180-
int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1180+
int64_t, func_type_map_t::find_type<get_default_floating_type()>>,
11811181
get_default_floating_type<std::false_type>(),
11821182
(void *)dpnp_eig_ext_c<
11831183
int64_t, func_type_map_t::find_type<
@@ -1197,17 +1197,17 @@ void func_map_init_linalg(func_map_t &fmap)
11971197
eft_DBL, (void *)dpnp_eigvals_default_c<double, double>};
11981198

11991199
fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_INT][eft_INT] = {
1200-
get_default_floating_type<>(),
1200+
get_default_floating_type(),
12011201
(void *)dpnp_eigvals_ext_c<
1202-
int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1202+
int32_t, func_type_map_t::find_type<get_default_floating_type()>>,
12031203
get_default_floating_type<std::false_type>(),
12041204
(void *)dpnp_eigvals_ext_c<
12051205
int32_t, func_type_map_t::find_type<
12061206
get_default_floating_type<std::false_type>()>>};
12071207
fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_LNG][eft_LNG] = {
1208-
get_default_floating_type<>(),
1208+
get_default_floating_type(),
12091209
(void *)dpnp_eigvals_ext_c<
1210-
int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1210+
int64_t, func_type_map_t::find_type<get_default_floating_type()>>,
12111211
get_default_floating_type<std::false_type>(),
12121212
(void *)dpnp_eigvals_ext_c<
12131213
int64_t, func_type_map_t::find_type<

dpnp/backend/kernels/dpnp_krnl_linalg.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -879,17 +879,17 @@ void func_map_init_linalg_func(func_map_t &fmap)
879879
eft_DBL, (void *)dpnp_inv_default_c<double, double>};
880880

881881
fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_INT][eft_INT] = {
882-
get_default_floating_type<>(),
882+
get_default_floating_type(),
883883
(void *)dpnp_inv_ext_c<
884-
int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
884+
int32_t, func_type_map_t::find_type<get_default_floating_type()>>,
885885
get_default_floating_type<std::false_type>(),
886886
(void *)dpnp_inv_ext_c<
887887
int32_t, func_type_map_t::find_type<
888888
get_default_floating_type<std::false_type>()>>};
889889
fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_LNG][eft_LNG] = {
890-
get_default_floating_type<>(),
890+
get_default_floating_type(),
891891
(void *)dpnp_inv_ext_c<
892-
int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
892+
int64_t, func_type_map_t::find_type<get_default_floating_type()>>,
893893
get_default_floating_type<std::false_type>(),
894894
(void *)dpnp_inv_ext_c<
895895
int64_t, func_type_map_t::find_type<
@@ -1051,17 +1051,17 @@ void func_map_init_linalg_func(func_map_t &fmap)
10511051
// eft_C128, (void*)dpnp_qr_c<std::complex<double>, std::complex<double>>};
10521052

10531053
fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_INT][eft_INT] = {
1054-
get_default_floating_type<>(),
1054+
get_default_floating_type(),
10551055
(void *)dpnp_qr_ext_c<
1056-
int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1056+
int32_t, func_type_map_t::find_type<get_default_floating_type()>>,
10571057
get_default_floating_type<std::false_type>(),
10581058
(void *)dpnp_qr_ext_c<
10591059
int32_t, func_type_map_t::find_type<
10601060
get_default_floating_type<std::false_type>()>>};
10611061
fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_LNG][eft_LNG] = {
1062-
get_default_floating_type<>(),
1062+
get_default_floating_type(),
10631063
(void *)dpnp_qr_ext_c<
1064-
int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
1064+
int64_t, func_type_map_t::find_type<get_default_floating_type()>>,
10651065
get_default_floating_type<std::false_type>(),
10661066
(void *)dpnp_qr_ext_c<
10671067
int64_t, func_type_map_t::find_type<
@@ -1086,10 +1086,10 @@ void func_map_init_linalg_func(func_map_t &fmap)
10861086
std::complex<double>, double>};
10871087

10881088
fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_INT][eft_INT] = {
1089-
get_default_floating_type<>(),
1089+
get_default_floating_type(),
10901090
(void *)dpnp_svd_ext_c<
1091-
int32_t, func_type_map_t::find_type<get_default_floating_type<>()>,
1092-
func_type_map_t::find_type<get_default_floating_type<>()>>,
1091+
int32_t, func_type_map_t::find_type<get_default_floating_type()>,
1092+
func_type_map_t::find_type<get_default_floating_type()>>,
10931093
get_default_floating_type<std::false_type>(),
10941094
(void *)
10951095
dpnp_svd_ext_c<int32_t,
@@ -1098,10 +1098,10 @@ void func_map_init_linalg_func(func_map_t &fmap)
10981098
func_type_map_t::find_type<
10991099
get_default_floating_type<std::false_type>()>>};
11001100
fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_LNG][eft_LNG] = {
1101-
get_default_floating_type<>(),
1101+
get_default_floating_type(),
11021102
(void *)dpnp_svd_ext_c<
1103-
int64_t, func_type_map_t::find_type<get_default_floating_type<>()>,
1104-
func_type_map_t::find_type<get_default_floating_type<>()>>,
1103+
int64_t, func_type_map_t::find_type<get_default_floating_type()>,
1104+
func_type_map_t::find_type<get_default_floating_type()>>,
11051105
get_default_floating_type<std::false_type>(),
11061106
(void *)
11071107
dpnp_svd_ext_c<int64_t,

dpnp/backend/kernels/dpnp_krnl_statistics.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,9 +1330,21 @@ void func_map_init_statistics(func_map_t &fmap)
13301330
eft_DBL, (void *)dpnp_median_default_c<double, double>};
13311331

13321332
fmap[DPNPFuncName::DPNP_FN_MEDIAN_EXT][eft_INT][eft_INT] = {
1333-
eft_DBL, (void *)dpnp_median_ext_c<int32_t, double>};
1333+
get_default_floating_type(),
1334+
(void *)dpnp_median_ext_c<
1335+
int32_t, func_type_map_t::find_type<get_default_floating_type()>>,
1336+
get_default_floating_type<std::false_type>(),
1337+
(void *)dpnp_median_ext_c<
1338+
int32_t, func_type_map_t::find_type<
1339+
get_default_floating_type<std::false_type>()>>};
13341340
fmap[DPNPFuncName::DPNP_FN_MEDIAN_EXT][eft_LNG][eft_LNG] = {
1335-
eft_DBL, (void *)dpnp_median_ext_c<int64_t, double>};
1341+
get_default_floating_type(),
1342+
(void *)dpnp_median_ext_c<
1343+
int64_t, func_type_map_t::find_type<get_default_floating_type()>>,
1344+
get_default_floating_type<std::false_type>(),
1345+
(void *)dpnp_median_ext_c<
1346+
int64_t, func_type_map_t::find_type<
1347+
get_default_floating_type<std::false_type>()>>};
13361348
fmap[DPNPFuncName::DPNP_FN_MEDIAN_EXT][eft_FLT][eft_FLT] = {
13371349
eft_FLT, (void *)dpnp_median_ext_c<float, float>};
13381350
fmap[DPNPFuncName::DPNP_FN_MEDIAN_EXT][eft_DBL][eft_DBL] = {

dpnp/dpnp_algo/dpnp_algo_statistics.pxi

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,12 @@ cpdef utils.dpnp_descriptor dpnp_median(utils.dpnp_descriptor array1):
265265

266266
array1_obj = array1.get_array()
267267

268+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(array1_obj, kernel_data)
269+
cdef DPNPFuncType return_type = ret_type_and_func[0]
270+
cdef custom_statistic_1in_1out_func_ptr_t func = < custom_statistic_1in_1out_func_ptr_t > ret_type_and_func[1]
271+
268272
cdef utils.dpnp_descriptor result = utils.create_output_descriptor((1,),
269-
kernel_data.return_type,
273+
return_type,
270274
None,
271275
device=array1_obj.sycl_device,
272276
usm_type=array1_obj.usm_type,
@@ -277,8 +281,6 @@ cpdef utils.dpnp_descriptor dpnp_median(utils.dpnp_descriptor array1):
277281
cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
278282
cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
279283

280-
cdef custom_statistic_1in_1out_func_ptr_t func = <custom_statistic_1in_1out_func_ptr_t > kernel_data.ptr
281-
282284
# stub for interface support
283285
cdef shape_type_c axis
284286
cdef Py_ssize_t axis_size = 0

dpnp/dpnp_utils/dpnp_algo_utils.pxd

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from libcpp cimport bool as cpp_bool
2929

3030
from dpnp.dpnp_algo cimport shape_type_c
31-
from dpnp.dpnp_algo.dpnp_algo cimport DPNPFuncName, DPNPFuncType
31+
from dpnp.dpnp_algo.dpnp_algo cimport DPNPFuncData, DPNPFuncName, DPNPFuncType
3232

3333

3434
cpdef checker_throw_runtime_error(function_name, message)
@@ -162,3 +162,9 @@ cdef tuple get_common_usm_allocation(dpnp_descriptor x1, dpnp_descriptor x2)
162162
"""
163163
Get common USM allocation in the form of (sycl_device, usm_type, sycl_queue)
164164
"""
165+
166+
cdef (DPNPFuncType, void *) get_ret_type_and_func(x1_obj, DPNPFuncData kernel_data)
167+
"""
168+
Get the corresponding return type and function pointer based on the
169+
capability of the allocated input array device for the integer types.
170+
"""

dpnp/dpnp_utils/dpnp_algo_utils.pyx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,16 @@ cdef tuple get_common_usm_allocation(dpnp_descriptor x1, dpnp_descriptor x2):
663663
return (common_sycl_queue.sycl_device, common_usm_type, common_sycl_queue)
664664

665665

666+
cdef (DPNPFuncType, void *) get_ret_type_and_func(x1_obj, DPNPFuncData kernel_data):
667+
if dpnp.issubdtype(x1_obj.dtype, dpnp.integer) and not x1_obj.sycl_device.has_aspect_fp64:
668+
return_type = kernel_data.return_type_no_fp64
669+
func = kernel_data.ptr_no_fp64
670+
else:
671+
return_type = kernel_data.return_type
672+
func = kernel_data.ptr
673+
return return_type, func
674+
675+
666676
cdef class dpnp_descriptor:
667677
def __init__(self, obj, dpnp_descriptor orig_desc=None):
668678
""" Initialze variables """

dpnp/dpnp_utils/dpnp_utils_statistics.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ def _get_2dmin_array(x, dtype):
5959
It casts to another dtype, if the input array differs from requested one.
6060
6161
"""
62-
6362
if x.ndim == 0:
6463
x = x.reshape((1, 1))
6564
elif x.ndim == 1:
@@ -81,6 +80,13 @@ def _get_2dmin_array(x, dtype):
8180
if y is not None:
8281
dtypes.append(y.dtype)
8382
dtype = dpt.result_type(*dtypes)
83+
# TODO: remove when dpctl.result_type() is fixed
84+
fp64 = queue.sycl_device.has_aspect_fp64
85+
if not fp64:
86+
if dtype == dpnp.float64:
87+
dtype = dpnp.float32
88+
elif dtype == dpnp.complex128:
89+
dtype = dpnp.complex64
8490

8591
X = _get_2dmin_array(m, dtype)
8692
if y is not None:

dpnp/linalg/dpnp_algo_linalg.pyx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,6 @@ ctypedef c_dpctl.DPCTLSyclEventRef(*custom_linalg_2in_1out_func_ptr_t)(c_dpctl.D
7979
const c_dpctl.DPCTLEventVectorRef)
8080

8181

82-
cdef (DPNPFuncType, void *) get_ret_type_and_func(x1_obj, DPNPFuncData kernel_data):
83-
if dpnp.issubdtype(x1_obj.dtype, dpnp.integer) and not x1_obj.sycl_device.has_aspect_fp64:
84-
return_type = kernel_data.return_type_no_fp64
85-
func = kernel_data.ptr_no_fp64
86-
else:
87-
return_type = kernel_data.return_type
88-
func = kernel_data.ptr
89-
return return_type, func
90-
91-
9282
cpdef utils.dpnp_descriptor dpnp_cholesky(utils.dpnp_descriptor input_):
9383
size_ = input_.shape[-1]
9484

@@ -206,7 +196,7 @@ cpdef tuple dpnp_eig(utils.dpnp_descriptor x1):
206196

207197
x1_obj = x1.get_array()
208198

209-
cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
199+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(x1_obj, kernel_data)
210200
cdef DPNPFuncType return_type = ret_type_and_func[0]
211201
cdef custom_linalg_2in_1out_func_ptr_t func = < custom_linalg_2in_1out_func_ptr_t > ret_type_and_func[1]
212202

@@ -252,7 +242,7 @@ cpdef utils.dpnp_descriptor dpnp_eigvals(utils.dpnp_descriptor input):
252242

253243
input_obj = input.get_array()
254244

255-
cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(input_obj, kernel_data)
245+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(input_obj, kernel_data)
256246
cdef DPNPFuncType return_type = ret_type_and_func[0]
257247
cdef custom_linalg_1in_1out_with_size_func_ptr_t_ func = < custom_linalg_1in_1out_with_size_func_ptr_t_ > ret_type_and_func[1]
258248

@@ -291,7 +281,7 @@ cpdef utils.dpnp_descriptor dpnp_inv(utils.dpnp_descriptor input):
291281

292282
input_obj = input.get_array()
293283

294-
cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(input_obj, kernel_data)
284+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(input_obj, kernel_data)
295285
cdef DPNPFuncType return_type = ret_type_and_func[0]
296286
cdef custom_linalg_1in_1out_func_ptr_t func = < custom_linalg_1in_1out_func_ptr_t > ret_type_and_func[1]
297287

@@ -472,7 +462,7 @@ cpdef tuple dpnp_qr(utils.dpnp_descriptor x1, str mode):
472462

473463
x1_obj = x1.get_array()
474464

475-
cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
465+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(x1_obj, kernel_data)
476466
cdef DPNPFuncType return_type = ret_type_and_func[0]
477467
cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > ret_type_and_func[1]
478468

@@ -525,7 +515,7 @@ cpdef tuple dpnp_svd(utils.dpnp_descriptor x1, cpp_bool full_matrices, cpp_bool
525515

526516
x1_obj = x1.get_array()
527517

528-
cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
518+
cdef (DPNPFuncType, void *) ret_type_and_func = utils.get_ret_type_and_func(x1_obj, kernel_data)
529519
cdef DPNPFuncType return_type = ret_type_and_func[0]
530520
cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > ret_type_and_func[1]
531521

tests/test_statistics.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
import numpy
22
import pytest
3+
from numpy.testing import assert_allclose
34

45
import dpnp
56

67
from .helper import get_all_dtypes
78

89

910
@pytest.mark.parametrize(
10-
"type",
11-
[numpy.float64, numpy.float32, numpy.int64, numpy.int32],
12-
ids=["float64", "float32", "int64", "int32"],
11+
"dtype", get_all_dtypes(no_none=True, no_bool=True, no_complex=True)
1312
)
1413
@pytest.mark.parametrize("size", [2, 4, 8, 16, 3, 9, 27, 81])
15-
def test_median(type, size):
16-
a = numpy.arange(size, dtype=type)
14+
def test_median(dtype, size):
15+
a = numpy.arange(size, dtype=dtype)
1716
ia = dpnp.array(a)
1817

1918
np_res = numpy.median(a)
2019
dpnp_res = dpnp.median(ia)
2120

22-
numpy.testing.assert_allclose(dpnp_res, np_res)
21+
assert_allclose(dpnp_res, np_res)
2322

2423

2524
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
2625
@pytest.mark.parametrize("axis", [0, 1, -1, 2, -2, (1, 2), (0, -2)])
27-
def test_max(axis):
28-
a = numpy.arange(768, dtype=numpy.float64).reshape((4, 4, 6, 8))
26+
@pytest.mark.parametrize(
27+
"dtype", get_all_dtypes(no_none=True, no_bool=True, no_complex=True)
28+
)
29+
def test_max(axis, dtype):
30+
a = numpy.arange(768, dtype=dtype).reshape((4, 4, 6, 8))
2931
ia = dpnp.array(a)
3032

3133
np_res = numpy.max(a, axis=axis)
3234
dpnp_res = dpnp.max(ia, axis=axis)
3335

34-
numpy.testing.assert_allclose(dpnp_res, np_res)
36+
assert_allclose(dpnp_res, np_res)
3537

3638

3739
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -70,17 +72,21 @@ def test_max(axis):
7072
"[[np.nan, np.nan], [np.inf, np.nan]]",
7173
],
7274
)
73-
def test_nanvar(array):
74-
a = numpy.array(array)
75+
@pytest.mark.parametrize(
76+
"dtype", get_all_dtypes(no_none=True, no_bool=True, no_complex=True)
77+
)
78+
def test_nanvar(array, dtype):
79+
dtype = dpnp.default_float_type()
80+
a = numpy.array(array, dtype=dtype)
7581
ia = dpnp.array(a)
7682
for ddof in range(a.ndim):
7783
expected = numpy.nanvar(a, ddof=ddof)
7884
result = dpnp.nanvar(ia, ddof=ddof)
79-
numpy.testing.assert_array_equal(expected, result)
85+
assert_allclose(expected, result, rtol=1e-06)
8086

8187
expected = numpy.nanvar(a, axis=None, ddof=0)
8288
result = dpnp.nanvar(ia, axis=None, ddof=0)
83-
numpy.testing.assert_array_equal(expected, result)
89+
assert_allclose(expected, result, rtol=1e-06)
8490

8591

8692
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -99,7 +105,7 @@ def test_bincount_minlength(self, array, minlength):
99105

100106
expected = numpy.bincount(np_a, minlength=minlength)
101107
result = dpnp.bincount(dpnp_a, minlength=minlength)
102-
numpy.testing.assert_array_equal(expected, result)
108+
assert_allclose(expected, result)
103109

104110
@pytest.mark.parametrize(
105111
"array", [[1, 2, 2, 1, 2, 4]], ids=["[1, 2, 2, 1, 2, 4]"]
@@ -115,7 +121,7 @@ def test_bincount_weights(self, array, weights):
115121

116122
expected = numpy.bincount(np_a, weights=weights)
117123
result = dpnp.bincount(dpnp_a, weights=weights)
118-
numpy.testing.assert_array_equal(expected, result)
124+
assert_allclose(expected, result)
119125

120126

121127
@pytest.mark.parametrize(
@@ -124,10 +130,8 @@ def test_bincount_weights(self, array, weights):
124130
def test_cov_rowvar(dtype):
125131
a = dpnp.array([[0, 2], [1, 1], [2, 0]], dtype=dtype)
126132
b = numpy.array([[0, 2], [1, 1], [2, 0]], dtype=dtype)
127-
numpy.testing.assert_array_equal(dpnp.cov(a.T), dpnp.cov(a, rowvar=False))
128-
numpy.testing.assert_array_equal(
129-
numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False)
130-
)
133+
assert_allclose(dpnp.cov(a.T), dpnp.cov(a, rowvar=False))
134+
assert_allclose(numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False))
131135

132136

133137
@pytest.mark.parametrize(
@@ -136,6 +140,4 @@ def test_cov_rowvar(dtype):
136140
def test_cov_1D_rowvar(dtype):
137141
a = dpnp.array([[0, 1, 2]], dtype=dtype)
138142
b = numpy.array([[0, 1, 2]], dtype=dtype)
139-
numpy.testing.assert_array_equal(
140-
numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False)
141-
)
143+
assert_allclose(numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False))

0 commit comments

Comments
 (0)