Skip to content

Subject: Numba Type Assertion Error in generate_worley_noise & Proposed Fix #455

Description

@centrl7

Description
Hello,

First off, thank you so much for this fantastic project!

I’ve run into a Numba-related issue while using it and was hoping to discuss it with you. When I use the BadPhotoCopy function to augment an image, if the randomly selected noise_type is 4, it attempts to add Worley noise. However, during Numba’s JIT compilation of the generate_worley_noise method, an assertion error related to element type precision occurs.

I was able to resolve this with some modifications and have the code running smoothly now. I’ve pasted my solution below. If you have a better approach or a more concise way to implement this fix, I hope you might consider integrating it into the project.

Thanks again for your work and for considering my suggestion. : >

Version
augraphy==8.2.6
numba==0.61.2

** Traceback**

  File "/usr/local/lib/python3.12/dist-packages/augraphy/utilities/noisegenerator.py", line 432, in generate_mask_main
    img_mask = self.generate_worley_noise(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 443, in _compile_for_args
    raise e
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 376, in _compile_for_args
    return_val = self.compile(tuple(argtypes))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 904, in compile
    cres = self._compiler.compile(args, return_type)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 80, in compile
    status, retval = self._compile_cached(args, return_type)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 94, in _compile_cached
    retval = self._compile_core(args, return_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/dispatcher.py", line 107, in _compile_core
    cres = compiler.compile_extra(self.targetdescr.typing_context,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 739, in compile_extra
    return pipeline.compile_extra(func)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 439, in compile_extra
    return self._compile_bytecode()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 505, in _compile_bytecode
    return self._compile_core()
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 481, in _compile_core
    raise e
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 473, in _compile_core
    pm.run(self.state)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 363, in run
    raise e
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 356, in run
    self._runPass(idx, pass_inst, state)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_lock.py", line 35, in _acquire_compile_lock
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 311, in _runPass
    mutated |= check(pss.run_pass, internal_state)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 272, in check
    mangled = func(compiler_state)
              ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typed_passes.py", line 468, in run_pass
    lower.lower()
  File "/usr/local/lib/python3.12/dist-packages/numba/core/lowering.py", line 193, in lower
    self.lower_normal_function(self.fndesc)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/lowering.py", line 232, in lower_normal_function
    entry_block_tail = self.lower_function_body()
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/lowering.py", line 262, in lower_function_body
    self.lower_block(block)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/lowering.py", line 276, in lower_block
    self.lower_inst(inst)
  File "/usr/local/lib/python3.12/dist-packages/numba/parfors/parfor_lowering.py", line 52, in lower_inst
    _lower_parfor_parallel(self, inst)
  File "/usr/local/lib/python3.12/dist-packages/numba/parfors/parfor_lowering.py", line 68, in _lower_parfor_parallel
    return _lower_parfor_parallel_std(lowerer, parfor)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/parfors/parfor_lowering.py", line 350, in _lower_parfor_parallel_std
    exp_name_to_tuple_var) = _create_gufunc_for_parfor_body(
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/parfors/parfor_lowering.py", line 1609, in _create_gufunc_for_parfor_body
    kernel_func = compiler.compile_ir(
                  ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 802, in compile_ir
    return pipeline.compile_ir(func_ir=func_ir, lifted=lifted,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 449, in compile_ir
    return self._compile_ir()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 512, in _compile_ir
    return self._compile_core()
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 481, in _compile_core
    raise e
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler.py", line 473, in _compile_core
    pm.run(self.state)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 363, in run
    raise e
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 356, in run
    self._runPass(idx, pass_inst, state)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_lock.py", line 35, in _acquire_compile_lock
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 311, in _runPass
    mutated |= check(pss.run_pass, internal_state)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/compiler_machinery.py", line 272, in check
    mangled = func(compiler_state)
              ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typed_passes.py", line 112, in run_pass
    typemap, return_type, calltypes, errs = type_inference_stage(
                                            ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typed_passes.py", line 93, in type_inference_stage
    errs = infer.propagate(raise_errors=raise_errors)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 1066, in propagate
    errors = self.constraints.propagate(self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 160, in propagate
    constraint(typeinfer)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 714, in __call__
    typeinfer.add_type(self.target, attrty, loc=self.loc)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 1088, in add_type
    self.propagate_refined_type(var, unified)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 1104, in propagate_refined_type
    source_constraint.refine(self, updated_type)
  File "/usr/local/lib/python3.12/dist-packages/numba/core/typeinfer.py", line 720, in refine
    assert recvr.is_precise()
           ^^^^^^^^^^^^^^^^^^
AssertionError

Solution
Make sure the elements in the distances array are explicitly typed as a numeric value.

    @staticmethod
    @jit(nopython=True, cache=True, parallel=True)
    def generate_worley_noise(width, height, npoints, option, noise_background):
        """Generates Worley noise, also known as cellular noise or Voronoi noise.
            Worley noise creates a pattern of irregularly shaped cells,
            where each cell is centered around a randomly placed point.

        :param width: Width of the generated 2d worley noise array.
        :type width: int
        :param height: Height of the generated 2d worley noise array.
        :type height: int
        :param npoints: Number of randomly placed points that will define the Voronoi cells.
        :param npoints: int
        :param option: An option to choose which distance value to calculate within each cell.
            0 is the closest point, 1 is the second closest point and so on.
        :param option: int
        :param noise_background: Background value of mask.
        :type noise_background: int
        """

        points = [(random.randint(0, width), random.randint(0, height)) for _ in range(npoints)]
        image_worley = np.full((height, width), fill_value=noise_background, dtype=np.float64)
        distances = np.empty(len(points), dtype=np.float64)

        for y in nb.prange(height):
            for x in nb.prange(width):
                for i in nb.prange(npoints):
                    p = points[i]
                    distances[i] = np.sqrt((p[0] - x) ** 2 + (p[1] - y) ** 2) 
                image_worley[y, x] = sorted(distances)[option]
        return image_worley

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions