Open MightyBOBcnc opened 1 year ago
I haven't done any speed tests yet but I have gotten the code base working with the main OpenSimplex module. One thing I haven't successfully done is gotten the numba integration working on the sample_octaves() func.
The reason the OpenSimplex module doesn't play nice with a jit decorated sample_octaves()
func in lathe.py
is that the OpenSimplex class isn't jit decorated, and neither are the other api functions in api.py
: https://github.com/lmas/opensimplex/blob/master/opensimplex/api.py
Jit compiled code in numba can't call undecorated code, so if sample_octaves
is jit decorated and it calls sample_noise
and then sample_noise
calls osi.noise3
and then the noise3
uses the class, and the class calls the functions in internals.py
they all need to be jit decorated. (The funcs in internals.py
are jit decorated, but the undecorated "gap" in api.py
breaks the "chain" of decoration.)
It's possible to jit decorate a class: https://numba.readthedocs.io/en/stable/user/jitclass.html
Here's a simple class that numba can successfully compile:
from numba.experimental import jitclass
from numba import int32, float32
@jitclass
class WaterDroplet(object):
prev_loc: int32 # Drop's previous index
cur_loc: int32 # Drop's current index
next_loc: int32 # Drop's destination index
def __init__(self, prev_loc, cur_loc, next_loc):
self.prev_loc = prev_loc
self.cur_loc = cur_loc
self.next_loc= next_loc
def debug(self):
print("prev_loc:", self.prev_loc)
print("cur_loc:", self.cur_loc)
print("next_loc:", self.next_loc)
I'm not sure what the type spec for the OpenSimplex class would be, however, because x, y, z (and w) for some of the internal functions are floats, but for others they are ndarrays, but they share the same variable names in the class. Maybe for the array versions the var names could be changed to something such as xa, ya, za, wa like:
def noise4array(self, xa: np.ndarray, ya: np.ndarray, za: np.ndarray, wa: np.ndarray) -> np.ndarray:
return _noise4a(xa, ya, za, wa, self._perm)
Of course this means we'd be back to using a custom OpenSimplex fork again, unless we can get a pull request upstream to lmas (Alex) for decorating everything in api.py
and he accepts it.
Or maybe calling directly to the functions within internals.py
similar to the way Nixis currently does with perm, pgi = osi.init(world_seed)
might work to keep the full chain jit decorated without needing a custom fork or upstream commit. Not the best solution, I admit.
https://github.com/MightyBOBcnc/nixis/blob/main/nixis.py#L308
https://github.com/MightyBOBcnc/nixis/blob/main/nixis.py#L330
Nixis is using a stripped down OpenSimplex modified to support numba for its noise generation. However, newer updates to OpenSimplex have built-in numba support. Investigate whether the updated OpenSimplex will work with Nixis and whether its performance is on par with the custom fork that Nixis is currently using. If so we could replace the custom fork.