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)