@@ -557,9 +557,21 @@ def hamming(x):
557557
558558
559559def heaviside (x1 , x2 ):
560- raise NotImplementedError (
561- "`heaviside` is not supported with openvino backend"
562- )
560+ x1 = get_ov_output (x1 )
561+ x_type = x1 .get_element_type ()
562+ x2 = get_ov_output (x2 , x_type )
563+
564+ zero_scalar = ov_opset .constant (0 , x_type ).output (0 )
565+ one_scalar = ov_opset .constant (1 , x_type ).output (0 )
566+
567+ neg = ov_opset .less (x1 , zero_scalar ).output (0 )
568+ pos = ov_opset .greater (x1 , zero_scalar ).output (0 )
569+ eq = ov_opset .equal (x1 , zero_scalar ).output (0 )
570+
571+ x = ov_opset .select (neg , zero_scalar , x1 ).output (0 )
572+ x = ov_opset .select (pos , one_scalar , x ).output (0 )
573+ x = ov_opset .select (eq , x2 , x ).output (0 )
574+ return OpenVINOKerasTensor (x )
563575
564576
565577def kaiser (x , beta ):
@@ -699,15 +711,9 @@ def count_nonzero(x, axis=None):
699711 zero_constant = ov_opset .convert_like (zero_constant , x )
700712 x = ov_opset .not_equal (x , zero_constant ).output (0 )
701713 x = ov_opset .convert (x , Type .i32 ).output (0 )
702- if axis is None :
703- flatten_shape = ov_opset .constant ([- 1 ], Type .i32 ).output (0 )
704- x = ov_opset .reshape (x , flatten_shape , False ).output (0 )
705- axis = 0
706- if isinstance (axis , tuple ):
707- axis = list (axis )
708- if axis == []:
714+ x , axis = _resolve_axis (x , axis )
715+ if not axis :
709716 return OpenVINOKerasTensor (x )
710- axis = ov_opset .constant (axis , Type .i32 ).output (0 )
711717 return OpenVINOKerasTensor (ov_opset .reduce_sum (x , axis , False ).output (0 ))
712718
713719
@@ -726,11 +732,7 @@ def cumsum(x, axis=None, dtype=None):
726732 if dtype is not None :
727733 ov_type = OPENVINO_DTYPES [standardize_dtype (dtype )]
728734 x = ov_opset .convert (x , ov_type ).output (0 )
729- if axis is None :
730- flatten_shape = ov_opset .constant ([- 1 ], Type .i32 ).output (0 )
731- x = ov_opset .reshape (x , flatten_shape , False ).output (0 )
732- axis = 0
733- axis = ov_opset .constant (axis , Type .i32 ).output (0 )
735+ x , axis = _resolve_axis (x , axis )
734736 if x .get_element_type () == Type .boolean :
735737 x = ov_opset .convert (x , Type .i32 ).output (0 )
736738 return OpenVINOKerasTensor (ov_opset .cumsum (x , axis ).output (0 ))
@@ -841,9 +843,30 @@ def diff(a, n=1, axis=-1):
841843
842844
843845def digitize (x , bins ):
844- raise NotImplementedError (
845- "`digitize` is not supported with openvino backend"
846- )
846+ x_node = get_ov_output (x )
847+
848+ if isinstance (bins , OpenVINOKerasTensor ):
849+ bins_node = get_ov_output (bins )
850+ else :
851+ bins_np = np .asarray (bins )
852+ if bins_np .ndim != 1 :
853+ raise ValueError ("`bins` must be 1-D array-like" )
854+ bins_node = ov_opset .constant (bins_np ).output (0 )
855+
856+ x_node , bins_node = _align_operand_types (x_node , bins_node , "digitize()" )
857+
858+ if x_node .get_element_type () == Type .boolean :
859+ x_node = ov_opset .convert (x_node , Type .f32 ).output (0 )
860+ bins_node = ov_opset .convert (bins_node , Type .f32 ).output (0 )
861+
862+ result = ov_opset .bucketize (
863+ x_node ,
864+ bins_node ,
865+ output_type = Type .i32 ,
866+ with_right_bound = False ,
867+ ).output (0 )
868+
869+ return OpenVINOKerasTensor (result )
847870
848871
849872def dot (x1 , x2 ):
@@ -1765,7 +1788,9 @@ def pad(x, pad_width, mode="constant", constant_values=None):
17651788 "`pad` operation supports only scalar pad value "
17661789 "in constant mode by openvino backend"
17671790 )
1768- pad_value = constant_values
1791+ pad_value = ov_opset .constant (
1792+ constant_values , x .get_element_type ()
1793+ ).output (0 )
17691794
17701795 # split pad_width into two tensors pads_begin and pads_end
17711796 pads_begin = []
@@ -2061,22 +2086,9 @@ def stack(x, axis=0):
20612086
20622087
20632088def std (x , axis = None , keepdims = False ):
2064- x = get_ov_output (x )
2065- if axis is None :
2066- flatten_shape = ov_opset .constant ([- 1 ], Type .i32 ).output (0 )
2067- x = ov_opset .reshape (x , flatten_shape , False ).output (0 )
2068- axis = 0
2069- axis = ov_opset .constant (axis , Type .i32 ).output (0 )
2070- # The variance is computed using $Var = E[|x|^2] - |E[x]|^2$, It is faster
2071- # but less numerically stable.
2072- mean = ov_opset .reduce_mean (x , axis , keepdims ).output (0 )
2073- const_two = ov_opset .constant (2 , x .get_element_type ()).output (0 )
2074- squared_x = ov_opset .power (x , const_two ).output (0 )
2075- squared_mean = ov_opset .power (mean , const_two ).output (0 )
2076- squared_x_mean = ov_opset .reduce_mean (squared_x , axis , keepdims )
2077- variance = ov_opset .subtract (squared_x_mean , squared_mean ).output (0 )
2078- std_var = OpenVINOKerasTensor (ov_opset .sqrt (variance ).output (0 ))
2079- return std_var
2089+ var_x = var (x , axis , keepdims )
2090+ std_dev = ov_opset .sqrt (var_x ).output (0 )
2091+ return OpenVINOKerasTensor (std_dev )
20802092
20812093
20822094def swapaxes (x , axis1 , axis2 ):
@@ -2441,18 +2453,26 @@ def trapezoid(y, x=None, dx=1.0, axis=-1):
24412453
24422454def var (x , axis = None , keepdims = False ):
24432455 x = get_ov_output (x )
2456+ x_type = x .get_element_type ()
2457+ x , axis = _resolve_axis (x , axis )
2458+
2459+ work_dtype = Type .f64 if x_type .is_integral () else x .get_element_type ()
2460+ if x_type .is_integral ():
2461+ x = ov_opset .convert (x , work_dtype ).output (0 )
24442462 if axis is None :
2445- flatten_shape = ov_opset .constant ([ - 1 ], Type . i32 ).output (0 )
2446- x = ov_opset . reshape ( x , flatten_shape , False ). output ( 0 )
2447- axis = 0
2448- axis = ov_opset . constant ( axis , Type . i32 ). output ( 0 )
2463+ const_zero = ov_opset .constant (0 , dtype = work_dtype ).output (0 )
2464+ return OpenVINOKerasTensor (
2465+ ov_opset . broadcast ( const_zero , ov_opset . shape_of ( x )). output ( 0 )
2466+ )
24492467 # The variance is computed using $Var = E[|x|^2] - |E[x]|^2$, It is faster
24502468 # but less numerically stable.
24512469 mean = ov_opset .reduce_mean (x , axis , keepdims ).output (0 )
2452- const_two = ov_opset .constant (2 , x .get_element_type ()).output (0 )
2470+ const_two = ov_opset .constant (2 , work_dtype ).output (0 )
2471+
24532472 squared_x = ov_opset .power (x , const_two ).output (0 )
24542473 squared_mean = ov_opset .power (mean , const_two ).output (0 )
2455- squared_x_mean = ov_opset .reduce_mean (squared_x , axis , keepdims )
2474+
2475+ squared_x_mean = ov_opset .reduce_mean (squared_x , axis , keepdims ).output (0 )
24562476 variance = OpenVINOKerasTensor (
24572477 ov_opset .subtract (squared_x_mean , squared_mean ).output (0 )
24582478 )
0 commit comments