agd.Eikonal.HFM_CUDA.kernel_traits
1# Copyright 2020 Jean-Marie Mirebeau, University Paris-Sud, CNRS, University Paris-Saclay 2# Distributed WITHOUT ANY WARRANTY. Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 3 4import numpy as np 5 6def default_traits(self): 7 """ 8 Default traits of the GPU implementation of an HFM model. 9 (self is an instance of the class Interface from file interface.py) 10 Side effect : sets the default FIM front width. (None : AGSI is fine.) 11 """ 12 traits = { 13 'Scalar': np.float32, 14 'Int': np.int32, 15 'OffsetT':np.int32, 16# 'multiprecision_macro':False, 17 'pruning_macro':False, 18 'geom_first_macro':True, 19 } 20 21 ndim = self.ndim 22 model = self.model 23 24 if model == 'ReedsShepp2': 25 traits.update({'shape_i':(4,4,4),'niter_i':6}) 26 fim_front_width = None 27 elif model == 'ReedsSheppForward2': 28 traits.update({'shape_i':(4,4,4),'niter_i':6}) 29 fim_front_width = 5 30 elif model == 'Elastica2': 31 # Small shape, single iteration, since stencils are too wide anyway 32 traits.update({'shape_i':(4,4,2),'niter_i':1, 33 'merge_sort_macro':True,'nFejer_macro':5}) 34 fim_front_width = 4 35 elif model == 'Dubins2': 36 traits.update({'shape_i':(4,4,2),'niter_i':1}) 37 #traits.update({'shape_i':(4,4,4),'niter_i':2}) # Similar, often slightly better 38 fim_front_width = None 39 40 elif model == 'AsymmetricQuadratic2': 41 traits.update({'shape_i':(8,8),'niter_i':10}) 42 fim_front_width = 6 43 elif model == 'AsymmetricQuadratic3': 44 traits.update({'shape_i':(4,4,4),'niter_i':4}) 45 fim_front_width = 5 46 47 elif model == 'TTI2': 48 traits.update({'shape_i':(8,8),'niter_i':10,'nmix_macro':7}) 49 fim_front_width = 6 50 elif model == 'TTI3': 51 traits.update({'shape_i':(4,4,4),'niter_i':3,'nmix_macro':7}) 52 fim_front_width = 6 53 54 elif model == 'Rander2': 55 traits.update({'shape_i':(8,8),'niter_i':12}) 56 fim_front_width = 8 57 elif model == 'Rander3': 58 traits.update({'shape_i':(4,4,4),'niter_i':8}) 59 fim_front_width = 8 60 61 elif model == 'Riemann2': 62 traits.update({'shape_i':(8,8),'niter_i':8}) 63 fim_front_width = 4 64 elif model == 'Riemann3': 65 traits.update({'shape_i':(4,4,4),'niter_i':4}) 66 fim_front_width = 6 67 elif model in ('Riemann4','Rander4'): 68 traits.update({'shape_i':(4,4,4,2),'niter_i':3}) 69 fim_front_width = None 70 elif model in ('Riemann5','Rander5'): 71 traits.update({'shape_i':(2,2,2,2,2),'niter_i':3}) # Untested 72 fim_front_width = None 73 elif model == ('Riemann6','Rander6'): 74 traits.update({'shape_i':(2,2,2,2,2,2),'niter_i':2}) # Untested 75 fim_front_width = None 76 77 elif model in ('Isotropic2','Diagonal2'): 78 #Alternative : Large shape, many iterations, to take advantage of block based causality 79# traits.update({'shape_i':(16,16),'niter_i':32,}) 80# traits.update({'shape_i':(24,24),'niter_i':48,}) # Slightly faster, but may fail with forwardAD : CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES 81# fim_front_width = None 82 # Alternative, more standard and reasonable shape 83 #traits.update({'shape_i':(8,8),'niter_i':16,}) 84 traits.update({'shape_i':(16,16),'niter_i':16,}) 85 fim_front_width = 4 86 elif model in ('Isotropic3','Diagonal3'): 87 traits.update({'shape_i':(4,4,4),'niter_i':8,}) 88 fim_front_width = 4 89 elif model in ('Isotropic4','Diagonal4'): 90 traits.update({'shape_i':(4,4,4,4),'niter_i':8,}) # Untested 91 fim_front_width = None 92 elif model in ('Isotropic5','Diagonal5'): 93 traits.update({'shape_i':(2,2,2,2,2),'niter_i':4,}) # Untested 94 fim_front_width = None 95 elif model in ('Isotropic6','Diagonal6'): 96 traits.update({'shape_i':(2,2,2,2,2,2),'niter_i':4,}) # Untested 97 fim_front_width = None 98 99 # traits below have not been optimized 100 elif model == 'DubinsState2': 101 traits.update({'shape_i':(32,2),'niter_i':32}) 102 fim_front_width = 4 103 elif model == 'DubinsState3': 104 traits.update({'shape_i':(8,8,2),'niter_i':8}) 105 fim_front_width = 4 106 elif model == 'DubinsState4': 107 traits.update({'shape_i':(4,4,2,1),'niter_i':1}) 108 fim_front_width = 4 109 110 elif model in ('Forward1','Custom1'): 111 traits.update({'shape_i':(32,),'niter_i':32}) 112 fim_front_width = 4 113 elif model in ('Forward2','Custom2'): 114 traits.update({'shape_i':(8,8),'niter_i':8}) 115 fim_front_width = 4 116 elif model in ('Forward3','Custom3'): 117 traits.update({'shape_i':(4,4,2),'niter_i':2}) 118 fim_front_width = 4 119 elif model in ('Forward4','Custom4'): 120 traits.update({'shape_i':(4,2,2,2),'niter_i':2}) 121 fim_front_width = 4 122 elif model in ('Forward5','Custom5'): 123 traits.update({'shape_i':(2,2,2,2,2),'niter_i':2}) 124 fim_front_width = 4 125 126 else: 127 raise ValueError("Unsupported model") 128 129 if model in ('ReedsSheppForward2','Elastica2','Dubins2'): 130 traits['convex_curvature_macro']=self.convex 131 if self.model_ == 'DubinsState': traits['nstates_macro']=self.hfmIn.shape[-1] 132 if self.model_ in ('DubinsState','Custom'): 133 traits['ncontrols_macro']=len(self.hfmIn['controls']) 134 traits['controls_max_macro']=True 135 136 self.fim_front_width_default = fim_front_width 137 return traits 138 139def voronoi_decompdim(ndim): 140 """ 141 Number of offsets in Voronoi's decomposition of a symmetric positive definite matrix. 142 """ 143 return 12 if ndim==4 else (ndim*(ndim+1))//2 144 145def nscheme(self): 146 """ 147 Provides the structure of the finite difference scheme used. 148 (number of symmmetric offsets, foward offsets, max or min of a number of schemes) 149 """ 150 ndim = self.ndim 151 model = self.model_ 152 traits = self.kernel_data['eikonal'].traits 153 decompdim = voronoi_decompdim(ndim) 154 155 nsym=0 # Number of symmetric offsets 156 nfwd=0 # Number of forward offsets 157 nmix=1 # maximum or minimum of nmix schemes 158 if model in ('Isotropic','Diagonal'): nsym = ndim 159 elif model in ('Riemann','Rander'): nsym = decompdim 160 161 elif model=='ReedsShepp': nsym = decompdim 162 elif model=='ReedsSheppForward': 163 if traits['convex_curvature_macro']:nfwd = 1+decompdim; 164 else: nsym = 1; nfwd = decompdim 165 elif model=='Dubins': nfwd = decompdim; nmix = 2 166 elif model=='Elastica': nfwd = traits['nFejer_macro']*decompdim 167 elif self.model=='ReedsSheppGPU3': 168 if traits['forward_macro']: nsym=2; nfwd=6 169 else: nsym=2+6 170 171 elif model=='AsymmetricQuadratic': nsym = decompdim; nmix = 3 172 elif model=='TTI': nsym = decompdim; nmix = traits['nmix_macro'] 173 174 elif model=='DubinsState': 175 if traits['controls_max_macro']: 176 nfwd = voronoi_decompdim(ndim-1) # One dimension is for the state 177 nmix = traits['ncontrols_macro']+int(traits['nstates_macro']>1) 178 else: 179 nfwd = (voronoi_decompdim(ndim-1) * traits['ncontrols_macro'] 180 + traits['nstates_macro']-1) 181 elif model=='Custom': 182 if traits['controls_max_macro']: nfwd = decompdim; nmix = traits['ncontrols_macro'] 183 else: nfwd = decompdim * traits['ncontrols_macro'] 184 elif model=="Forward": 185 nfwd = voronoi_decompdim(ndim) 186 187 else: raise ValueError('Unsupported model') 188 189 nact = nsym+nfwd # max number of active offsets 190 ntot = 2*nsym+nfwd 191 nactx = nact*nmix 192 ntotx = ntot*nmix 193 194 195 196 return {'nsym':nsym,'nfwd':nfwd,'nmix':nmix, 197 'nact':nact,'ntot':ntot,'nactx':nactx,'ntotx':ntotx}
def
default_traits(self):
7def default_traits(self): 8 """ 9 Default traits of the GPU implementation of an HFM model. 10 (self is an instance of the class Interface from file interface.py) 11 Side effect : sets the default FIM front width. (None : AGSI is fine.) 12 """ 13 traits = { 14 'Scalar': np.float32, 15 'Int': np.int32, 16 'OffsetT':np.int32, 17# 'multiprecision_macro':False, 18 'pruning_macro':False, 19 'geom_first_macro':True, 20 } 21 22 ndim = self.ndim 23 model = self.model 24 25 if model == 'ReedsShepp2': 26 traits.update({'shape_i':(4,4,4),'niter_i':6}) 27 fim_front_width = None 28 elif model == 'ReedsSheppForward2': 29 traits.update({'shape_i':(4,4,4),'niter_i':6}) 30 fim_front_width = 5 31 elif model == 'Elastica2': 32 # Small shape, single iteration, since stencils are too wide anyway 33 traits.update({'shape_i':(4,4,2),'niter_i':1, 34 'merge_sort_macro':True,'nFejer_macro':5}) 35 fim_front_width = 4 36 elif model == 'Dubins2': 37 traits.update({'shape_i':(4,4,2),'niter_i':1}) 38 #traits.update({'shape_i':(4,4,4),'niter_i':2}) # Similar, often slightly better 39 fim_front_width = None 40 41 elif model == 'AsymmetricQuadratic2': 42 traits.update({'shape_i':(8,8),'niter_i':10}) 43 fim_front_width = 6 44 elif model == 'AsymmetricQuadratic3': 45 traits.update({'shape_i':(4,4,4),'niter_i':4}) 46 fim_front_width = 5 47 48 elif model == 'TTI2': 49 traits.update({'shape_i':(8,8),'niter_i':10,'nmix_macro':7}) 50 fim_front_width = 6 51 elif model == 'TTI3': 52 traits.update({'shape_i':(4,4,4),'niter_i':3,'nmix_macro':7}) 53 fim_front_width = 6 54 55 elif model == 'Rander2': 56 traits.update({'shape_i':(8,8),'niter_i':12}) 57 fim_front_width = 8 58 elif model == 'Rander3': 59 traits.update({'shape_i':(4,4,4),'niter_i':8}) 60 fim_front_width = 8 61 62 elif model == 'Riemann2': 63 traits.update({'shape_i':(8,8),'niter_i':8}) 64 fim_front_width = 4 65 elif model == 'Riemann3': 66 traits.update({'shape_i':(4,4,4),'niter_i':4}) 67 fim_front_width = 6 68 elif model in ('Riemann4','Rander4'): 69 traits.update({'shape_i':(4,4,4,2),'niter_i':3}) 70 fim_front_width = None 71 elif model in ('Riemann5','Rander5'): 72 traits.update({'shape_i':(2,2,2,2,2),'niter_i':3}) # Untested 73 fim_front_width = None 74 elif model == ('Riemann6','Rander6'): 75 traits.update({'shape_i':(2,2,2,2,2,2),'niter_i':2}) # Untested 76 fim_front_width = None 77 78 elif model in ('Isotropic2','Diagonal2'): 79 #Alternative : Large shape, many iterations, to take advantage of block based causality 80# traits.update({'shape_i':(16,16),'niter_i':32,}) 81# traits.update({'shape_i':(24,24),'niter_i':48,}) # Slightly faster, but may fail with forwardAD : CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES 82# fim_front_width = None 83 # Alternative, more standard and reasonable shape 84 #traits.update({'shape_i':(8,8),'niter_i':16,}) 85 traits.update({'shape_i':(16,16),'niter_i':16,}) 86 fim_front_width = 4 87 elif model in ('Isotropic3','Diagonal3'): 88 traits.update({'shape_i':(4,4,4),'niter_i':8,}) 89 fim_front_width = 4 90 elif model in ('Isotropic4','Diagonal4'): 91 traits.update({'shape_i':(4,4,4,4),'niter_i':8,}) # Untested 92 fim_front_width = None 93 elif model in ('Isotropic5','Diagonal5'): 94 traits.update({'shape_i':(2,2,2,2,2),'niter_i':4,}) # Untested 95 fim_front_width = None 96 elif model in ('Isotropic6','Diagonal6'): 97 traits.update({'shape_i':(2,2,2,2,2,2),'niter_i':4,}) # Untested 98 fim_front_width = None 99 100 # traits below have not been optimized 101 elif model == 'DubinsState2': 102 traits.update({'shape_i':(32,2),'niter_i':32}) 103 fim_front_width = 4 104 elif model == 'DubinsState3': 105 traits.update({'shape_i':(8,8,2),'niter_i':8}) 106 fim_front_width = 4 107 elif model == 'DubinsState4': 108 traits.update({'shape_i':(4,4,2,1),'niter_i':1}) 109 fim_front_width = 4 110 111 elif model in ('Forward1','Custom1'): 112 traits.update({'shape_i':(32,),'niter_i':32}) 113 fim_front_width = 4 114 elif model in ('Forward2','Custom2'): 115 traits.update({'shape_i':(8,8),'niter_i':8}) 116 fim_front_width = 4 117 elif model in ('Forward3','Custom3'): 118 traits.update({'shape_i':(4,4,2),'niter_i':2}) 119 fim_front_width = 4 120 elif model in ('Forward4','Custom4'): 121 traits.update({'shape_i':(4,2,2,2),'niter_i':2}) 122 fim_front_width = 4 123 elif model in ('Forward5','Custom5'): 124 traits.update({'shape_i':(2,2,2,2,2),'niter_i':2}) 125 fim_front_width = 4 126 127 else: 128 raise ValueError("Unsupported model") 129 130 if model in ('ReedsSheppForward2','Elastica2','Dubins2'): 131 traits['convex_curvature_macro']=self.convex 132 if self.model_ == 'DubinsState': traits['nstates_macro']=self.hfmIn.shape[-1] 133 if self.model_ in ('DubinsState','Custom'): 134 traits['ncontrols_macro']=len(self.hfmIn['controls']) 135 traits['controls_max_macro']=True 136 137 self.fim_front_width_default = fim_front_width 138 return traits
Default traits of the GPU implementation of an HFM model. (self is an instance of the class Interface from file interface.py) Side effect : sets the default FIM front width. (None : AGSI is fine.)
def
voronoi_decompdim(ndim):
140def voronoi_decompdim(ndim): 141 """ 142 Number of offsets in Voronoi's decomposition of a symmetric positive definite matrix. 143 """ 144 return 12 if ndim==4 else (ndim*(ndim+1))//2
Number of offsets in Voronoi's decomposition of a symmetric positive definite matrix.
def
nscheme(self):
146def nscheme(self): 147 """ 148 Provides the structure of the finite difference scheme used. 149 (number of symmmetric offsets, foward offsets, max or min of a number of schemes) 150 """ 151 ndim = self.ndim 152 model = self.model_ 153 traits = self.kernel_data['eikonal'].traits 154 decompdim = voronoi_decompdim(ndim) 155 156 nsym=0 # Number of symmetric offsets 157 nfwd=0 # Number of forward offsets 158 nmix=1 # maximum or minimum of nmix schemes 159 if model in ('Isotropic','Diagonal'): nsym = ndim 160 elif model in ('Riemann','Rander'): nsym = decompdim 161 162 elif model=='ReedsShepp': nsym = decompdim 163 elif model=='ReedsSheppForward': 164 if traits['convex_curvature_macro']:nfwd = 1+decompdim; 165 else: nsym = 1; nfwd = decompdim 166 elif model=='Dubins': nfwd = decompdim; nmix = 2 167 elif model=='Elastica': nfwd = traits['nFejer_macro']*decompdim 168 elif self.model=='ReedsSheppGPU3': 169 if traits['forward_macro']: nsym=2; nfwd=6 170 else: nsym=2+6 171 172 elif model=='AsymmetricQuadratic': nsym = decompdim; nmix = 3 173 elif model=='TTI': nsym = decompdim; nmix = traits['nmix_macro'] 174 175 elif model=='DubinsState': 176 if traits['controls_max_macro']: 177 nfwd = voronoi_decompdim(ndim-1) # One dimension is for the state 178 nmix = traits['ncontrols_macro']+int(traits['nstates_macro']>1) 179 else: 180 nfwd = (voronoi_decompdim(ndim-1) * traits['ncontrols_macro'] 181 + traits['nstates_macro']-1) 182 elif model=='Custom': 183 if traits['controls_max_macro']: nfwd = decompdim; nmix = traits['ncontrols_macro'] 184 else: nfwd = decompdim * traits['ncontrols_macro'] 185 elif model=="Forward": 186 nfwd = voronoi_decompdim(ndim) 187 188 else: raise ValueError('Unsupported model') 189 190 nact = nsym+nfwd # max number of active offsets 191 ntot = 2*nsym+nfwd 192 nactx = nact*nmix 193 ntotx = ntot*nmix 194 195 196 197 return {'nsym':nsym,'nfwd':nfwd,'nmix':nmix, 198 'nact':nact,'ntot':ntot,'nactx':nactx,'ntotx':ntotx}
Provides the structure of the finite difference scheme used. (number of symmmetric offsets, foward offsets, max or min of a number of schemes)