meinardmueller / synctoolbox

Sync Toolbox - Python package with reference implementations for efficient, robust, and accurate music synchronization based on dynamic time warping (DTW)
https://meinardmueller.github.io/synctoolbox
Other
112 stars 12 forks source link

numba error `key already in dictionary: 'index.5'` in tutorial notebook #19

Closed johentsch closed 2 years ago

johentsch commented 2 years ago

Hi there,

Thanks for making this code available!

Just cloned the repo and tried to run the notebook sync_audio_score_full.ipynb. For cell 7 (in the section "Finding optimal shift of chroma vectors"), I'm getting an error message. Posting the complete stacktrace here. Please let me know if you require more information to address this.

AssertionError                            Traceback (most recent call last)
/tmp/ipykernel_25695/2527601981.py in <cell line: 3>()
      1 f_cens_1hz_audio = quantized_chroma_to_CENS(f_chroma_quantized_audio, 201, 50, feature_rate)[0]
      2 f_cens_1hz_annotation = quantized_chroma_to_CENS(f_chroma_quantized_annotation, 201, 50, feature_rate)[0]
----> 3 opt_chroma_shift = compute_optimal_chroma_shift(f_cens_1hz_audio, f_cens_1hz_annotation)
      4 print('Pitch shift between the audio recording and score, determined by DTW:', opt_chroma_shift, 'bins')
      5 

~/synctoolbox/synctoolbox/dtw/utils.py in compute_optimal_chroma_shift(f_chroma1, f_chroma2, chroma_transpositions, step_sizes, step_weights)
     42     for chroma_shift in chroma_transpositions:
     43         cost_matrix_tmp = cosine_distance(f_chroma1, shift_chroma_vectors(f_chroma2, chroma_shift))
---> 44         D, _, _ = compute_warping_path(cost_matrix_tmp, step_sizes=step_sizes, step_weights=step_weights)
     45         if D[-1, -1] < dtw_cost:
     46             dtw_cost = D[-1, -1]

~/synctoolbox/synctoolbox/dtw/core.py in compute_warping_path(C, step_sizes, step_weights, implementation)
    194                          sub_sequence=False)
    195 
--> 196         wp = __E_to_warping_path(E=E,
    197                                  dn=dn,
    198                                  dm=dm,

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
    485                     e.patch_message('\n'.join((str(e).rstrip(), help_msg)))
    486             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 487             raise e
    488         finally:
    489             self._types_active_call = []

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
    418         return_val = None
    419         try:
--> 420             return_val = self.compile(tuple(argtypes))
    421         except errors.ForceLiteralArg as e:
    422             # Received request for compiler re-entry with the list of arguments

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in compile(self, sig)
    963                 with ev.trigger_event("numba:compile", data=ev_details):
    964                     try:
--> 965                         cres = self._compiler.compile(args, return_type)
    966                     except errors.ForceLiteralArg as e:
    967                         def folded(args, kws):

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in compile(self, args, return_type)
    123 
    124     def compile(self, args, return_type):
--> 125         status, retval = self._compile_cached(args, return_type)
    126         if status:
    127             return retval

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_cached(self, args, return_type)
    137 
    138         try:
--> 139             retval = self._compile_core(args, return_type)
    140         except errors.TypingError as e:
    141             self._failed_cache[key] = e

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_core(self, args, return_type)
    150 
    151         impl = self._get_implementation(args, {})
--> 152         cres = compiler.compile_extra(self.targetdescr.typing_context,
    153                                       self.targetdescr.target_context,
    154                                       impl,

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
    691     pipeline = pipeline_class(typingctx, targetctx, library,
    692                               args, return_type, flags, locals)
--> 693     return pipeline.compile_extra(func)
    694 
    695 

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in compile_extra(self, func)
    427         self.state.lifted = ()
    428         self.state.lifted_from = None
--> 429         return self._compile_bytecode()
    430 
    431     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_bytecode(self)
    495         """
    496         assert self.state.func_ir is None
--> 497         return self._compile_core()
    498 
    499     def _compile_ir(self):

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_core(self)
    474                     self.state.status.fail_reason = e
    475                     if is_final_pipeline:
--> 476                         raise e
    477             else:
    478                 raise CompilerError("All available pipelines exhausted")

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_core(self)
    461                 res = None
    462                 try:
--> 463                     pm.run(self.state)
    464                     if self.state.cr is not None:
    465                         break

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in run(self, state)
    351                     (self.pipeline_name, pass_desc)
    352                 patched_exception = self._patch_error(msg, e)
--> 353                 raise patched_exception
    354 
    355     def dependency_analysis(self):

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in run(self, state)
    339                 pass_inst = _pass_registry.get(pss).pass_inst
    340                 if isinstance(pass_inst, CompilerPass):
--> 341                     self._runPass(idx, pass_inst, state)
    342                 else:
    343                     raise BaseException("Legacy pass in use")

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
     33         def _acquire_compile_lock(*args, **kwargs):
     34             with self:
---> 35                 return func(*args, **kwargs)
     36         return _acquire_compile_lock
     37 

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in _runPass(self, index, pss, internal_state)
    294             mutated |= check(pss.run_initialization, internal_state)
    295         with SimpleTimer() as pass_time:
--> 296             mutated |= check(pss.run_pass, internal_state)
    297         with SimpleTimer() as finalize_time:
    298             mutated |= check(pss.run_finalizer, internal_state)

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in check(func, compiler_state)
    267 
    268         def check(func, compiler_state):
--> 269             mangled = func(compiler_state)
    270             if mangled not in (True, False):
    271                 msg = ("CompilerPass implementations should return True/False. "

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/typed_passes.py in run_pass(self, state)
    238         pp.run(True)
    239         with fallback_context(state, msg):
--> 240             rewrites.rewrite_registry.apply('after-inference', state)
    241         pp.remove_dels()
    242         return True

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/rewrites/registry.py in apply(self, kind, state)
     65             while work_list:
     66                 key, block = work_list.pop()
---> 67                 matches = rewrite.match(state.func_ir, block, state.typemap,
     68                                         state.calltypes)
     69                 if matches:

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in match(self, func_ir, block, typemap, calltypes)
   1339             return False
   1340         self.crnt_block = block
-> 1341         self.new_body = guard(_inline_const_arraycall, block, func_ir,
   1342                               self.typingctx, typemap, calltypes)
   1343         return self.new_body is not None

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/ir_utils.py in guard(func, *args, **kwargs)
   1530     """
   1531     try:
-> 1532         return func(*args, **kwargs)
   1533     except GuardException:
   1534         return None

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in _inline_const_arraycall(block, func_ir, context, typemap, calltypes)
   1509                 elif expr.op == 'call' and expr in calltypes:
   1510                     arr_var = inst.target
-> 1511                     if guard(inline_array, inst.target, expr,
   1512                              state.stmts, state.list_vars, state.dels):
   1513                         state.modified = True

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/ir_utils.py in guard(func, *args, **kwargs)
   1530     """
   1531     try:
-> 1532         return func(*args, **kwargs)
   1533     except GuardException:
   1534         return None

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in inline_array(array_var, expr, stmts, list_vars, dels)
   1440             index_var = ir.Var(scope, mk_unique_var("index"), loc)
   1441             index_typ = types.intp
-> 1442             typemap[index_var.name] = index_typ
   1443             stmts.append(_new_definition(func_ir, index_var,
   1444                     ir.Const(i, loc), loc))

~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/utils.py in __setitem__(self, key, value)
    373     def __setitem__(self, key, value):
    374         if key in self:
--> 375             raise AssertionError("key already in dictionary: %r" % (key,))
    376         super(UniqueDict, self).__setitem__(key, value)
    377 

AssertionError: Failed in nopython mode pipeline (step: nopython rewrites)
key already in dictionary: 'index.5'
clelf commented 2 years ago

I've got the same error. When ignoring this error in numba, compute_optimal_chroma_shift works but the tutorial gets stuck at the next step, i.e. when computing the warping path with sync_via_mrmsdtw. Here's what it outputs at this point:


AssertionError                            Traceback (most recent call last)
<ipython-input-9-ed7c0e4ec178> in <module>
      6                       step_weights=step_weights,
      7                       threshold_rec=threshold_rec,
----> 8                       verbose=True)

c:\Users\cleme\OneDrive\Documents\EPFL\SV MA4\DMCL\synctoolbox\synctoolbox\synctoolbox\dtw\mrmsdtw.py in sync_via_mrmsdtw(f_chroma1, f_chroma2, f_onset1, f_onset2, input_feature_rate, step_sizes, step_weights, threshold_rec, win_len_smooth, downsamp_smooth, verbose, dtw_implementation, normalize_chroma, chroma_norm_ord, chroma_norm_threshold, visualization_title)
    172         # Concatenate warping paths
    173         wp = build_path_from_warping_paths(warping_paths=wp_list,
--> 174                                            anchors=anchors)
    175 
    176         anchors_step1 = None

c:\Users\cleme\OneDrive\Documents\EPFL\SV MA4\DMCL\synctoolbox\synctoolbox\synctoolbox\dtw\utils.py in build_path_from_warping_paths(warping_paths, anchors)
    190         # consistency checks
    191         assert np.array_equal(wp[:, 0], anchor1), 'First entry of warping path does not coincide with anchor point'
--> 192         assert np.array_equal(wp[:, -1], anchor2), 'Last entry of warping path does not coincide with anchor point'
    193 
    194         if path is None:

AssertionError: Last entry of warping path does not coincide with anchor point```
ahnonay commented 2 years ago

Dear @johentsch @clelf

thanks for letting us know about this problem. This seems to be due to a recent numba update. As a hotfix, you may use

pip install numba==0.54.1

to install a compatible numba version. The example notebooks should then run without problems. Please let us know if you still have problems after applying this!

I'll also create a new release of synctoolbox today with an updated setup.py. We will later look into making synctoolbox compatible with newer numba versions.

johentsch commented 2 years ago

Thank you for looking into this! numba 0.54.1 is not available via pip but I managed to install it using pip install https://github.com/numba/numba/archive/refs/tags/0.54.1.zip and the notebook ran through smoothly, thanks!

P.S.: However, it requires Python<3.10 and librosa>0.9.0 P.P.S.: Got to love the sonification examples at the end of the notebook! :ok_hand:

ahnonay commented 2 years ago

Good to hear that things are working for you now!

I do believe that numba 0.54.1 should be available on pypi (https://pypi.org/project/numba/0.54.1/#files). Are you using a special kind of processor architecture or operating system?

johentsch commented 2 years ago

It was because I was on Python 3.10

ahnonay commented 2 years ago

Ah, I see, thank you! We'll make sure that synctoolbox works with newer versions of python and numba in a future release.

I will close this for now, please do not hesitate to reopen in case of further problems.

cjy2103 commented 2 years ago

Hello

Your issue has been very helpful to me.

I also used Python 3.10 version and there was the same problem.

After reading the above issue, I downgraded the Python version to 3.9 and confirmed that it works well.

Thank you for your help