1313
1414import numba
1515from numba .core import types , utils
16- from numba .core .errors import TypingError , InternalError
16+ from numba .core .errors import (
17+ TypingError ,
18+ InternalError ,
19+ InternalTargetMismatchError ,
20+ )
1721from numba .core .cpu_options import InlineOptions
1822
1923# info store for inliner callback functions e.g. cost model
@@ -887,23 +891,13 @@ def generic(self, args, kws):
887891 """
888892 Type the intrinsic by the arguments.
889893 """
890- from numba .core .target_extension import (get_local_target ,
891- resolve_target_str ,
894+ from numba .core .target_extension import (_get_local_target_checked ,
892895 dispatcher_registry )
893896 from numba .core .imputils import builtin_registry
894897
895898 cache_key = self .context , args , tuple (kws .items ())
896899 hwstr = self .metadata .get ('target' , 'generic' )
897- # Get the class for the target declared by the function
898- hw_clazz = resolve_target_str (hwstr )
899- # get the local target
900- target_hw = get_local_target (self .context )
901- # make sure the target_hw is in the MRO for hw_clazz else bail
902- if not target_hw .inherits_from (hw_clazz ):
903- msg = (f"Intrinsic being resolved on a target from which it does "
904- f"not inherit. Local target is { target_hw } , declared "
905- f"target class is { hw_clazz } ." )
906- raise InternalError (msg )
900+ target_hw = _get_local_target_checked (self .context , hwstr , "intrinsic" )
907901 disp = dispatcher_registry [target_hw ]
908902 tgtctx = disp .targetdescr .target_context
909903 # This is all workarounds...
@@ -990,28 +984,12 @@ def make_intrinsic_template(handle, defn, name, kwargs):
990984
991985
992986class AttributeTemplate (object ):
993- _initialized = False
994-
995987 def __init__ (self , context ):
996- self ._lazy_class_init ()
997988 self .context = context
998989
999990 def resolve (self , value , attr ):
1000991 return self ._resolve (value , attr )
1001992
1002- @classmethod
1003- def _lazy_class_init (cls ):
1004- if not cls ._initialized :
1005- cls .do_class_init ()
1006- cls ._initialized = True
1007-
1008- @classmethod
1009- def do_class_init (cls ):
1010- """
1011- Class-wide initialization. Can be overridden by subclasses to
1012- register permanent typing or target hooks.
1013- """
1014-
1015993 def _resolve (self , value , attr ):
1016994 fn = getattr (self , "resolve_%s" % attr , None )
1017995 if fn is None :
@@ -1038,15 +1016,33 @@ class _OverloadAttributeTemplate(AttributeTemplate):
10381016 def __init__ (self , context ):
10391017 super (_OverloadAttributeTemplate , self ).__init__ (context )
10401018 self .context = context
1019+ self ._init_once ()
10411020
1042- @classmethod
1043- def do_class_init (cls ):
1044- """
1045- Register attribute implementation.
1021+ def _get_target_registry (self ):
1022+ """Returns the registry for the current target
10461023 """
1047- from numba .core .imputils import lower_getattr
1024+ from numba .core .target_extension import (_get_local_target_checked ,
1025+ dispatcher_registry )
1026+ hwstr = self .metadata .get ('target' , 'generic' )
1027+ target_hw = _get_local_target_checked (self .context , hwstr , "attribute" )
1028+ # Get resgistry for the current hardware
1029+ disp = dispatcher_registry [target_hw ]
1030+ tgtctx = disp .targetdescr .target_context
1031+ tgtctx .refresh ()
1032+ if builtin_registry in tgtctx ._registries :
1033+ reg = builtin_registry
1034+ else :
1035+ # Pick a registry in which to install intrinsics
1036+ registries = iter (tgtctx ._registries )
1037+ reg = next (registries )
1038+ return reg
1039+
1040+ def _init_once (self ):
1041+ cls = type (self )
10481042 attr = cls ._attr
10491043
1044+ lower_getattr = self ._get_target_registry ().lower_getattr
1045+
10501046 @lower_getattr (cls .key , attr )
10511047 def getattr_impl (context , builder , typ , value ):
10521048 typingctx = context .typing_context
@@ -1082,24 +1078,30 @@ class _OverloadMethodTemplate(_OverloadAttributeTemplate):
10821078 """
10831079 is_method = True
10841080
1085- @classmethod
1086- def do_class_init (cls ):
1081+ def _init_once (self ):
10871082 """
1088- Register generic method implementation.
1083+ Overriding parent definition
10891084 """
1090- from numba .core .imputils import lower_builtin
1091- attr = cls ._attr
1085+ attr = self ._attr
10921086
1093- @lower_builtin ((cls .key , attr ), cls .key , types .VarArg (types .Any ))
1094- def method_impl (context , builder , sig , args ):
1095- typ = sig .args [0 ]
1096- typing_context = context .typing_context
1097- fnty = cls ._get_function_type (typing_context , typ )
1098- sig = cls ._get_signature (typing_context , fnty , sig .args , {})
1099- call = context .get_function (fnty , sig )
1100- # Link dependent library
1101- context .add_linking_libs (getattr (call , 'libs' , ()))
1102- return call (builder , args )
1087+ try :
1088+ registry = self ._get_target_registry ()
1089+ except InternalTargetMismatchError :
1090+ # Target mismatch. Do not register attribute lookup here.
1091+ pass
1092+ else :
1093+ lower_builtin = registry .lower
1094+
1095+ @lower_builtin ((self .key , attr ), self .key , types .VarArg (types .Any ))
1096+ def method_impl (context , builder , sig , args ):
1097+ typ = sig .args [0 ]
1098+ typing_context = context .typing_context
1099+ fnty = self ._get_function_type (typing_context , typ )
1100+ sig = self ._get_signature (typing_context , fnty , sig .args , {})
1101+ call = context .get_function (fnty , sig )
1102+ # Link dependent library
1103+ context .add_linking_libs (getattr (call , 'libs' , ()))
1104+ return call (builder , args )
11031105
11041106 def _resolve (self , typ , attr ):
11051107 if self ._attr != attr :
@@ -1132,7 +1134,8 @@ def generic(_, args, kws):
11321134
11331135def make_overload_attribute_template (typ , attr , overload_func , inline ,
11341136 prefer_literal = False ,
1135- base = _OverloadAttributeTemplate ):
1137+ base = _OverloadAttributeTemplate ,
1138+ ** kwargs ):
11361139 """
11371140 Make a template class for attribute *attr* of *typ* overloaded by
11381141 *overload_func*.
@@ -1145,20 +1148,22 @@ def make_overload_attribute_template(typ, attr, overload_func, inline,
11451148 _inline_overloads = {},
11461149 _overload_func = staticmethod (overload_func ),
11471150 prefer_literal = prefer_literal ,
1151+ metadata = kwargs ,
11481152 )
11491153 obj = type (base )(name , (base ,), dct )
11501154 return obj
11511155
11521156
11531157def make_overload_method_template (typ , attr , overload_func , inline ,
1154- prefer_literal = False ):
1158+ prefer_literal = False , ** kwargs ):
11551159 """
11561160 Make a template class for method *attr* of *typ* overloaded by
11571161 *overload_func*.
11581162 """
11591163 return make_overload_attribute_template (
11601164 typ , attr , overload_func , inline = inline ,
11611165 base = _OverloadMethodTemplate , prefer_literal = prefer_literal ,
1166+ ** kwargs ,
11621167 )
11631168
11641169
0 commit comments