@@ -699,21 +699,22 @@ def _lower_parfor_gufunc(lowerer, parfor):
699
699
numba .parfors .parfor .sequential_parfor_lowering = True
700
700
loop_ranges = [(l .start , l .stop , l .step ) for l in parfor .loop_nests ]
701
701
702
- func , func_args , func_sig , func_arg_types , modified_arrays = (
703
- _create_gufunc_for_parfor_body (
704
- lowerer ,
705
- parfor ,
706
- typemap ,
707
- typingctx ,
708
- targetctx ,
709
- flags ,
710
- loop_ranges ,
711
- {},
712
- bool (alias_map ),
713
- index_var_typ ,
714
- parfor .races ))
715
-
716
- numba .parfors .parfor .sequential_parfor_lowering = False
702
+ try :
703
+ func , func_args , func_sig , func_arg_types , modified_arrays = (
704
+ _create_gufunc_for_parfor_body (
705
+ lowerer ,
706
+ parfor ,
707
+ typemap ,
708
+ typingctx ,
709
+ targetctx ,
710
+ flags ,
711
+ loop_ranges ,
712
+ {},
713
+ bool (alias_map ),
714
+ index_var_typ ,
715
+ parfor .races ))
716
+ finally :
717
+ numba .parfors .parfor .sequential_parfor_lowering = False
717
718
718
719
# get the shape signature
719
720
get_shape_classes = parfor .get_shape_classes
@@ -956,10 +957,14 @@ def load_range(v):
956
957
from numba .core .lowering import Lower
957
958
958
959
960
+ class CopyIRException (RuntimeError ):
961
+ def __init__ (self , * args , ** kwargs ):
962
+ super ().__init__ (* args , ** kwargs )
963
+
964
+
959
965
class DPPLLower (Lower ):
960
966
def __init__ (self , context , library , fndesc , func_ir , metadata = None ):
961
967
Lower .__init__ (self , context , library , fndesc , func_ir , metadata )
962
-
963
968
fndesc_cpu = copy .copy (fndesc )
964
969
fndesc_cpu .calltypes = fndesc .calltypes .copy ()
965
970
fndesc_cpu .typemap = fndesc .typemap .copy ()
@@ -984,17 +989,23 @@ def lower(self):
984
989
# WARNING: this approach only works in case no device specific modifications were added to
985
990
# parent function (function with parfor). In case parent function was patched with device specific
986
991
# different solution should be used.
992
+
987
993
try :
988
994
#lowering.lower_extensions[parfor.Parfor] = lower_parfor_rollback
989
995
lowering .lower_extensions [parfor .Parfor ].append (lower_parfor_rollback )
990
996
self .gpu_lower .lower ()
991
997
self .base_lower = self .gpu_lower
992
998
#lowering.lower_extensions[parfor.Parfor] = numba.parfors.parfor_lowering._lower_parfor_parallel
993
999
lowering .lower_extensions [parfor .Parfor ].pop ()
994
- except :
995
- lowering .lower_extensions [parfor .Parfor ].append (numba .parfors .parfor_lowering ._lower_parfor_parallel )
996
- self .cpu_lower .lower ()
997
- self .base_lower = self .cpu_lower
1000
+ except Exception as e :
1001
+ if numba .dppl .compiler .DEBUG :
1002
+ print ("Failed to lower parfor on DPPL-device. Due to:\n " , e )
1003
+ lowering .lower_extensions [parfor .Parfor ].pop ()
1004
+ if (lowering .lower_extensions [parfor .Parfor ][- 1 ] == numba .parfors .parfor_lowering ._lower_parfor_parallel ):
1005
+ self .cpu_lower .lower ()
1006
+ self .base_lower = self .cpu_lower
1007
+ else :
1008
+ raise e
998
1009
999
1010
self .env = self .base_lower .env
1000
1011
self .call_helper = self .base_lower .call_helper
@@ -1003,20 +1014,88 @@ def create_cpython_wrapper(self, release_gil=False):
1003
1014
return self .base_lower .create_cpython_wrapper (release_gil )
1004
1015
1005
1016
1017
+ def copy_block (block ):
1018
+ def relatively_deep_copy (obj , memo ):
1019
+ obj_id = id (obj )
1020
+ if obj_id in memo :
1021
+ return memo [obj_id ]
1022
+
1023
+ from numba .core .dispatcher import Dispatcher
1024
+ from numba .core .types .functions import Function
1025
+ from types import ModuleType
1026
+
1027
+ if isinstance (obj , (Dispatcher , Function , ModuleType )):
1028
+ return obj
1029
+
1030
+ if isinstance (obj , list ):
1031
+ cpy = copy .copy (obj )
1032
+ cpy .clear ()
1033
+ for item in obj :
1034
+ cpy .append (relatively_deep_copy (item , memo ))
1035
+ memo [obj_id ] = cpy
1036
+ return cpy
1037
+ elif isinstance (obj , dict ):
1038
+ cpy = copy .copy (obj )
1039
+ cpy .clear ()
1040
+ # do we need to copy keys?
1041
+ for key , item in obj .items ():
1042
+ cpy [relatively_deep_copy (key , memo )] = relatively_deep_copy (item , memo )
1043
+ memo [obj_id ] = cpy
1044
+ return cpy
1045
+ elif isinstance (obj , tuple ):
1046
+ cpy = type (obj )([relatively_deep_copy (item , memo ) for item in obj ])
1047
+ memo [obj_id ] = cpy
1048
+ return cpy
1049
+ elif isinstance (obj , set ):
1050
+ cpy = copy .copy (obj )
1051
+ cpy .clear ()
1052
+ for item in obj :
1053
+ cpy .add (relatively_deep_copy (item , memo ))
1054
+ memo [obj_id ] = cpy
1055
+ return cpy
1056
+
1057
+ cpy = copy .copy (obj )
1058
+
1059
+ memo [obj_id ] = cpy
1060
+ keys = []
1061
+ try :
1062
+ keys = obj .__dict__ .keys ()
1063
+ except :
1064
+ try :
1065
+ keys = obj .__slots__
1066
+ except :
1067
+ return cpy
1068
+
1069
+ for key in keys :
1070
+ attr = getattr (obj , key )
1071
+ attr_cpy = relatively_deep_copy (attr , memo )
1072
+ setattr (cpy , key , attr_cpy )
1073
+
1074
+ return cpy
1075
+
1076
+ memo = {}
1077
+ new_block = ir .Block (block .scope , block .loc )
1078
+ new_block .body = [relatively_deep_copy (stmt , memo ) for stmt in block .body ]
1079
+ return new_block
1080
+
1081
+
1006
1082
def lower_parfor_rollback (lowerer , parfor ):
1007
- cache_parfor_races = copy .copy (parfor .races )
1008
- cache_parfor_params = copy .copy (parfor .params )
1009
- cache_parfor_loop_body = copy .deepcopy (parfor .loop_body )
1010
- cache_parfor_init_block = parfor .init_block .copy ()
1011
- cache_parfor_loop_nests = parfor .loop_nests .copy ()
1083
+ try :
1084
+ cache_parfor_races = copy .copy (parfor .races )
1085
+ cache_parfor_params = copy .copy (parfor .params )
1086
+ cache_parfor_loop_body = {key : copy_block (block ) for key , block in parfor .loop_body .items ()}
1087
+ cache_parfor_init_block = parfor .init_block .copy ()
1088
+ cache_parfor_loop_nests = parfor .loop_nests .copy ()
1089
+ except Exception as e :
1090
+ raise CopyIRException ("Failed to copy IR" ) from e
1012
1091
1013
1092
try :
1014
1093
_lower_parfor_gufunc (lowerer , parfor )
1015
1094
if numba .dppl .compiler .DEBUG :
1016
1095
msg = "Parfor lowered on DPPL-device"
1017
1096
print (msg , parfor .loc )
1018
1097
except Exception as e :
1019
- msg = "Failed to lower parfor on DPPL-device"
1098
+ msg = "Failed to lower parfor on DPPL-device. \n To see details set environment variable NUMBA_DEBUG=1 "
1020
1099
warnings .warn (NumbaPerformanceWarning (msg , parfor .loc ))
1021
1100
raise e
1022
1101
finally :
0 commit comments