Skip to content

Commit bb795a6

Browse files
Removing JITParticle Class
1 parent 43813b3 commit bb795a6

File tree

4 files changed

+23
-101
lines changed

4 files changed

+23
-101
lines changed

parcels/compilation/codegenerator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from parcels.field import Field, NestedField, VectorField
1111
from parcels.grid import Grid
12-
from parcels.particle import JITParticle
12+
from parcels.particle import ScipyParticle
1313
from parcels.tools.statuscodes import StatusCode
1414
from parcels.tools.warnings import KernelWarning
1515

@@ -214,7 +214,7 @@ class IntrinsicTransformer(ast.NodeTransformer):
214214
and propagates attribute access.
215215
"""
216216

217-
def __init__(self, fieldset=None, ptype=JITParticle):
217+
def __init__(self, fieldset=None, ptype=ScipyParticle):
218218
self.fieldset = fieldset
219219
self.ptype = ptype
220220

@@ -421,7 +421,7 @@ class KernelGenerator(ast.NodeVisitor):
421421
kernel_vars = ["particle", "fieldset", "time", "output_time", "tol"]
422422
array_vars: list[str] = []
423423

424-
def __init__(self, fieldset=None, ptype=JITParticle):
424+
def __init__(self, fieldset=None, ptype=ScipyParticle):
425425
self.fieldset = fieldset
426426
self.ptype = ptype
427427
self.field_args = collections.OrderedDict()

parcels/kernel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ def evaluate_particle(self, p, endtime):
680680
Parameters
681681
----------
682682
p :
683-
object of (sub-)type (ScipyParticle, JITParticle)
683+
object of (sub-)type ScipyParticle
684684
endtime :
685685
endtime of this overall kernel evaluation step
686686
dt :

parcels/particle.py

Lines changed: 7 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
from ctypes import c_void_p
21
from operator import attrgetter
32
from typing import Literal
43

54
import numpy as np
65

76
from parcels.tools.statuscodes import StatusCode
87

9-
__all__ = ["JITParticle", "ScipyInteractionParticle", "ScipyParticle", "Variable"]
10-
11-
indicators_64bit = [np.float64, np.uint64, np.int64, c_void_p]
8+
__all__ = ["ScipyInteractionParticle", "ScipyParticle", "Variable"]
129

1310

1411
class Variable:
@@ -41,24 +38,14 @@ def name(self):
4138
def __get__(self, instance, cls):
4239
if instance is None:
4340
return self
44-
if issubclass(cls, JITParticle):
45-
return instance._cptr.__getitem__(self.name)
46-
else:
47-
return getattr(instance, f"_{self.name}", self.initial)
41+
return getattr(instance, f"_{self.name}", self.initial)
4842

4943
def __set__(self, instance, value):
50-
if isinstance(instance, JITParticle):
51-
instance._cptr.__setitem__(self.name, value)
52-
else:
53-
setattr(instance, f"_{self.name}", value)
44+
setattr(instance, f"_{self.name}", value)
5445

5546
def __repr__(self):
5647
return f"Variable(name={self._name}, dtype={self.dtype}, initial={self.initial}, to_write={self.to_write})"
5748

58-
def is64bit(self):
59-
"""Check whether variable is 64-bit."""
60-
return True if self.dtype in indicators_64bit else False
61-
6249

6350
class ParticleType:
6451
"""Class encapsulating the type information for custom particles.
@@ -75,7 +62,7 @@ def __init__(self, pclass):
7562
if not issubclass(pclass, ScipyParticle):
7663
raise TypeError("Class object does not inherit from parcels.ScipyParticle")
7764
self.name = pclass.__name__
78-
self.uses_jit = issubclass(pclass, JITParticle)
65+
self.uses_jit = False # TODO v4: remove this attribute
7966
# Pick Variable objects out of __dict__.
8067
self.variables = [v for v in pclass.__dict__.values() if isinstance(v, Variable)]
8168
for cls in pclass.__bases__:
@@ -92,8 +79,6 @@ def __init__(self, pclass):
9279
"Custom Variable name 'z' is not allowed, as it is used for depth in ParticleFile"
9380
)
9481
self.variables = ptype.variables + self.variables
95-
# Sort variables with all the 64-bit first so that they are aligned for the JIT cptr
96-
self.variables = [v for v in self.variables if v.is64bit()] + [v for v in self.variables if not v.is64bit()]
9782

9883
def __repr__(self):
9984
return f"{type(self).__name__}(pclass={self.name})"
@@ -103,35 +88,6 @@ def __getitem__(self, item):
10388
if v.name == item:
10489
return v
10590

106-
@property
107-
def _cache_key(self):
108-
return "-".join([f"{v.name}:{v.dtype}" for v in self.variables])
109-
110-
@property
111-
def dtype(self):
112-
"""Numpy.dtype object that defines the C struct."""
113-
type_list = [(v.name, v.dtype) for v in self.variables]
114-
for v in self.variables:
115-
if v.dtype not in self.supported_dtypes:
116-
raise RuntimeError(str(v.dtype) + " variables are not implemented in JIT mode")
117-
if self.size % 8 > 0:
118-
# Add padding to be 64-bit aligned
119-
type_list += [("pad", np.float32)]
120-
return np.dtype(type_list)
121-
122-
@property
123-
def size(self):
124-
"""Size of the underlying particle struct in bytes."""
125-
return sum([8 if v.is64bit() else 4 for v in self.variables])
126-
127-
@property
128-
def supported_dtypes(self):
129-
"""List of all supported numpy dtypes. All others are not supported."""
130-
# Developer note: other dtypes (mostly 2-byte ones) are not supported now
131-
# because implementing and aligning them in cgen.GenerableStruct is a
132-
# major headache. Perhaps in a later stage
133-
return [np.int32, np.uint32, np.int64, np.uint64, np.float32, np.double, np.float64, c_void_p]
134-
13591

13692
class ScipyParticle:
13793
"""Class encapsulating the basic attributes of a particle, to be executed in SciPy mode.
@@ -192,9 +148,7 @@ def __init__(self, lon, lat, pid, fieldset=None, ngrids=None, depth=0.0, time=0.
192148
initial = v.initial(self)
193149
else:
194150
initial = v.initial
195-
# Enforce type of initial value
196-
if v.dtype != c_void_p:
197-
setattr(self, v.name, v.dtype(initial))
151+
setattr(self, v.name, v.dtype(initial))
198152

199153
def __del__(self):
200154
pass # superclass is 'object', and object itself has no destructor, hence 'pass'
@@ -267,7 +221,7 @@ def set_lonlatdepth_dtype(cls, dtype):
267221
cls.depth_nextloop.dtype = dtype
268222

269223
@classmethod
270-
def setLastID(cls, offset):
224+
def setLastID(cls, offset): # TODO v4: check if we can implement this in another way
271225
ScipyParticle.lastID = offset
272226

273227

@@ -277,36 +231,5 @@ def setLastID(cls, offset):
277231

278232

279233
class JITParticle(ScipyParticle):
280-
"""Particle class for JIT-based (Just-In-Time) Particle objects.
281-
282-
Parameters
283-
----------
284-
lon : float
285-
Initial longitude of particle
286-
lat : float
287-
Initial latitude of particle
288-
fieldset : parcels.fieldset.FieldSet
289-
mod:`parcels.fieldset.FieldSet` object to track this particle on
290-
dt :
291-
Execution timestep for this particle
292-
time :
293-
Current time of the particle
294-
295-
296-
Notes
297-
-----
298-
Additional Variables can be added via the :Class Variable: objects
299-
300-
Users should use JITParticles for faster advection computation.
301-
"""
302-
303234
def __init__(self, *args, **kwargs):
304-
self._cptr = kwargs.pop("cptr", None)
305-
if self._cptr is None:
306-
# Allocate data for a single particle
307-
ptype = self.getPType()
308-
self._cptr = np.empty(1, dtype=ptype.dtype)[0]
309-
super().__init__(*args, **kwargs)
310-
311-
def __del__(self):
312-
super().__del__()
235+
raise NotImplementedError("JITParticle has been deprecated in Parcels v4. Use ScipyParticle instead.")

parcels/particleset.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
KDTreeFlatNeighborSearch,
2525
)
2626
from parcels.kernel import Kernel
27-
from parcels.particle import JITParticle, Variable
27+
from parcels.particle import ScipyParticle, Variable
2828
from parcels.particledata import ParticleData, ParticleDataIterator
2929
from parcels.particlefile import ParticleFile
3030
from parcels.tools._helpers import particleset_repr, timedelta_to_float
@@ -56,9 +56,8 @@ class ParticleSet:
5656
----------
5757
fieldset :
5858
mod:`parcels.fieldset.FieldSet` object from which to sample velocity.
59-
pclass : parcels.particle.JITParticle or parcels.particle.ScipyParticle
60-
Optional :mod:`parcels.particle.JITParticle` or
61-
:mod:`parcels.particle.ScipyParticle` object that defines custom particle
59+
pclass : parcels.particle.ScipyParticle
60+
Optional object that inherits from :mod:`parcels.particle.ScipyParticle` object that defines custom particle
6261
lon :
6362
List of initial longitude values for particles
6463
lat :
@@ -87,7 +86,7 @@ class ParticleSet:
8786
def __init__(
8887
self,
8988
fieldset,
90-
pclass=JITParticle,
89+
pclass=ScipyParticle,
9190
lon=None,
9291
lat=None,
9392
depth=None,
@@ -481,8 +480,8 @@ def from_list(
481480
----------
482481
fieldset :
483482
mod:`parcels.fieldset.FieldSet` object from which to sample velocity
484-
pclass : parcels.particle.JITParticle or parcels.particle.ScipyParticle
485-
Particle class. May be a particle class as defined in parcels, or a subclass defining a custom particle.
483+
pclass :
484+
Particle class. May be a parcels.particle.ScipyParticle class as defined in parcels, or a subclass defining a custom particle.
486485
lon :
487486
List of initial longitude values for particles
488487
lat :
@@ -537,8 +536,8 @@ def from_line(
537536
----------
538537
fieldset :
539538
mod:`parcels.fieldset.FieldSet` object from which to sample velocity
540-
pclass : parcels.particle.JITParticle or parcels.particle.ScipyParticle
541-
Particle class. May be a particle class as defined in parcels, or a subclass defining a custom particle.
539+
pclass :
540+
Particle class. May be a parcels.particle.ScipyParticle as defined in parcels, or a subclass defining a custom particle.
542541
start :
543542
Start point (longitude, latitude) for initialisation of particles on a straight line.
544543
finish :
@@ -653,8 +652,8 @@ def from_field(
653652
----------
654653
fieldset : parcels.fieldset.FieldSet
655654
mod:`parcels.fieldset.FieldSet` object from which to sample velocity
656-
pclass : parcels.particle.JITParticle or parcels.particle.ScipyParticle
657-
Particle class. May be a particle class as defined in parcels, or a subclass defining a custom particle.
655+
pclass :
656+
Particle class. May be a parcels.particle.ScipyParticle class as defined in parcels, or a subclass defining a custom particle.
658657
start_field : parcels.field.Field
659658
Field for initialising particles stochastically (horizontally) according to the presented density field.
660659
size :
@@ -697,8 +696,8 @@ def from_particlefile(
697696
----------
698697
fieldset : parcels.fieldset.FieldSet
699698
mod:`parcels.fieldset.FieldSet` object from which to sample velocity
700-
pclass : parcels.particle.JITParticle or parcels.particle.ScipyParticle
701-
Particle class. May be a particle class as defined in parcels, or a subclass defining a custom particle.
699+
pclass :
700+
Particle class. May be a parcels.particle.ScipyParticle class as defined in parcels, or a subclass defining a custom particle.
702701
filename : str
703702
Name of the particlefile from which to read initial conditions
704703
restart : bool

0 commit comments

Comments
 (0)