def make_title(qres, pack=False, remove_dsuuids=False, remove_chip=False, remove_feat=False, textwidth=80): cfgstr = qres.cfgstr def parse_remove(format_, string_): import parse # TODO: move to ut # Do padding so prefix or suffix could be empty pad_format_ = '{prefix}' + format_ + '{suffix}' pad_string_ = '_' + string_ + '_' parse_result = parse.parse(pad_format_, pad_string_) new_string = parse_result['prefix'][1:] + parse_result['suffix'][:-1] return new_string, parse_result if remove_dsuuids: cfgstr, _ = parse_remove('_DSUUIDS(({daid_shape}){daid_hash})', cfgstr) if remove_chip: cfgstr, _ = parse_remove('_CHIP({chip_cfgstr})', cfgstr) if remove_feat: cfgstr, _ = parse_remove('_FEAT({feat_cfgstr})', cfgstr) if pack: # Separate into newlines if requested (makes it easier to fit on screen) cfgstr = ut.packstr(cfgstr, textwidth=textwidth, break_words=False, breakchars='_', wordsep='_') component_list = [ 'qaid={qaid} '.format(qaid=qres.qaid), #'qauuid={qauuid}'.format(qauuid=qres.qauuid), 'cfgstr={cfgstr}'.format(cfgstr=cfgstr), ] title_str = ''.join(component_list) return title_str
def test_featcfg_combo(ibs, aid, alldictcomb, count, nKpts_list, cfgstr_list): for dict_ in ut.progiter(alldictcomb, lbl='FeatCFG Combo: '): # Set ibs parameters to the current config for key_, val_ in six.iteritems(dict_): ibs.cfg.feat_cfg[key_] = val_ cfgstr_ = ibs.cfg.feat_cfg.get_cfgstr() if count == 0: # On first run just record info kpts = ibs.get_annot_kpts(aid) nKpts_list.append(len(kpts)) cfgstr_list.append(cfgstr_) if count == 1: kpts = ibs.get_annot_kpts(aid) # If second run happens display info cfgpackstr = utool.packstr(cfgstr_, textwidth=80, breakchars=',', newline_prefix='', break_words=False, wordsep=',') title_suffix = (' len(kpts) = %r \n' % len(kpts)) + cfgpackstr viz.show_chip(ibs, aid, fnum=pt.next_fnum(), title_suffix=title_suffix, darken=.8, ell_linewidth=2, ell_alpha=.6)
def make_title(allres): return allres.dbname + '\n' + ut.packstr(allres.get_cfgstr(), textwidth=80, break_words=False, breakchars='_', wordsep='_')
def devfunc(ibs, qaid_list): """ Function for developing something """ print('[dev] devfunc') import ibeis # NOQA from ibeis.algo import Config # NOQA #from ibeis.algo.Config import * # NOQA feat_cfg = Config.FeatureConfig() #feat_cfg.printme3() print('\ncfgstr..') print(feat_cfg.get_cfgstr()) print(utool.dict_str(feat_cfg.get_hesaff_params())) from ibeis import viz aid = 1 ibs.cfg.feat_cfg.threshold = 16.0 / 3.0 kpts = ibs.get_annot_kpts(aid) print('len(kpts) = %r' % len(kpts)) from ibeis.expt import experiment_configs #varyparams_list = [ # #{ # # 'threshold': [16.0 / 3.0, 32.0 / 3.0], # 8.0 / 3.0 # # 'numberOfScales': [3, 2, 1], # # 'maxIterations': [16, 32], # # 'convergenceThreshold': [.05, .1], # # 'initialSigma': [1.6, 1.2], # #}, # { # #'threshold': [16.0 / 3.0, 32.0 / 3.0], # 8.0 / 3.0 # 'numberOfScales': [1], # #'maxIterations': [16, 32], # #'convergenceThreshold': [.05, .1], # #'initialSigma': [6.0, 3.0, 2.0, 1.6, 1.2, 1.1], # 'initialSigma': [3.2, 1.6, 0.8], # 'edgeEigenValueRatio': [10, 5, 3], # }, #] varyparams_list = [experiment_configs.featparams] # low threshold = more keypoints # low initialSigma = more keypoints nKpts_list = [] cfgstr_list = [] alldictcomb = utool.flatten([utool.util_dict.all_dict_combinations(varyparams) for varyparams in featparams_list]) NUM_PASSES = 1 if not utool.get_argflag('--show') else 2 for count in range(NUM_PASSES): for aid in qaid_list: #for dict_ in utool.progiter(alldictcomb, lbl='feature param comb: ', total=len(alldictcomb)): for dict_ in alldictcomb: for key_, val_ in six.iteritems(dict_): ibs.cfg.feat_cfg[key_] = val_ cfgstr_ = ibs.cfg.feat_cfg.get_cfgstr() cfgstr = utool.packstr(cfgstr_, textwidth=80, breakchars=',', newline_prefix='', break_words=False, wordsep=',') if count == 0: kpts = ibs.get_annot_kpts(aid) #print('___________') #print('len(kpts) = %r' % len(kpts)) #print(cfgstr) nKpts_list.append(len(kpts)) cfgstr_list.append(cfgstr_) if count == 1: title_suffix = (' len(kpts) = %r \n' % len(kpts)) + cfgstr viz.show_chip(ibs, aid, fnum=pt.next_fnum(), title_suffix=title_suffix, darken=.4, ell_linewidth=2, ell_alpha=.8) if count == 0: nKpts_list = np.array(nKpts_list) cfgstr_list = np.array(cfgstr_list) print(get_sortbystr(cfgstr_list, nKpts_list, 'cfg', 'nKpts')) pt.present() locals_ = locals() return locals_
def autogen_parts(binding_name=None): r""" CommandLine: python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=set_dataset python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=add_points python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=remove_point --py python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=used_memory --py python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=remove_points --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=veclen --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=size --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=clean_removed_points --py --c Ignore: # Logic goes here ~/code/flann/src/cpp/flann/algorithms/kdtree_index.h ~/code/flann/src/cpp/flann/util/serialization.h ~/code/flann/src/cpp/flann/util/dynamic_bitset.h # Bindings go here ~/code/flann/src/cpp/flann/flann.cpp ~/code/flann/src/cpp/flann/flann.h # Contains stuff for the flann namespace like flann::log_level # Also has Index with # Matrix<ElementType> features; SEEMS USEFUL ~/code/flann/src/cpp/flann/flann.hpp # Wrappers go here ~/code/flann/src/python/pyflann/flann_ctypes.py ~/code/flann/src/python/pyflann/index.py ~/local/build_scripts/flannscripts/autogen_bindings.py Example: >>> # ENABLE_DOCTEST >>> from autogen_bindings import * # NOQA >>> result = autogen_parts() >>> print(result) """ #ut.get_dynlib_exports(pyflann.flannlib._name) #flannlib if binding_name is None: binding_name = ut.get_argval('--bindingname', type_=str, default='add_points') # Variable names used in flann cpp source simple_c_to_ctypes = { 'void': None, 'char*': 'c_char_p', 'unsigned int': 'c_uint', 'int': 'c_int', 'float': 'c_float', 'float*': 'POINTER(c_float)', 'flann_index_t': 'FLANN_INDEX', 'FLANNParameters*': 'POINTER(FLANNParameters)', 'Distance::ResultType*': "ndpointer(%(restype)s, flags='aligned, c_contiguous, writeable')", 'Distance::ElementType*': "ndpointer(%(numpy)s, ndim=2, flags='aligned, c_contiguous')", 'typename Distance::ElementType*': "ndpointer(%(numpy)s, ndim=2, flags='aligned, c_contiguous')", 'typename Distance::ResultType*': "ndpointer(%(restype), ndim=2, flags='aligned, c_contiguous, writeable')", } templated_ctype_map = { 'filename': 'char*', 'level': 'int', 'rows': 'int', 'cols': 'int', 'point_id': 'unsigned int', 'num': 'int', 'max_nn': 'int', 'tcount': 'int', 'nn': 'int', 'radius': 'float', 'clusters': 'int', 'rebuild_threshold': 'float', 'index_ptr': 'flann_index_t', 'flann_params': 'FLANNParameters*', 'speedup': 'float*', 'id_list': 'int*', #'indices' : 'int*', 'dataset': 'typename Distance::ElementType*', 'points': 'typename Distance::ElementType*', 'query': 'typename Distance::ElementType*', 'query1d': 'typename Distance::ElementType*', 'testset': 'typename Distance::ElementType*', 'dists': 'typename Distance::ResultType*', 'dists1d': 'typename Distance::ResultType*', 'result_centers': 'typename Distance::ResultType*', 'result_ids': 'int*', } # Python ctype bindings python_ctype_map = { 'flann_params': 'POINTER(FLANNParameters)', 'id_list': "ndpointer(int32, ndim=1, flags='aligned, c_contiguous')", #'indices' : "ndpointer(int32, ndim=1, flags='aligned, c_contiguous, writeable')", 'query1d': "ndpointer(%(numpy)s, ndim=1, flags='aligned, c_contiguous')", 'dists1d': "ndpointer(%(restype), ndim=1, flags='aligned, c_contiguous, writeable')", 'result_ids': "ndpointer(int32, ndim=2, flags='aligned, c_contiguous, writeable')", #'query' : "ndpointer(float64, ndim=1, flags='aligned, c_contiguous')", } for key, val in templated_ctype_map.items(): if key not in python_ctype_map: python_ctype_map[key] = simple_c_to_ctypes[val] binding_def = define_flann_bindings(binding_name) docstr_cpp = binding_def['docstr_cpp'] docstr_py = binding_def['docstr_py'] cpp_binding_name = binding_def['cpp_binding_name'] return_type = binding_def['return_type'] binding_argnames = binding_def['binding_argnames'] c_source = binding_def['c_source'] py_source = binding_def['py_source'] optional_args = binding_def['optional_args'] py_alias = binding_def['py_alias'] py_args = binding_def['py_args'] binding_args = [ python_ctype_map[name] + ', # ' + name for name in binding_argnames ] binding_args_str = ' ' + '\n '.join(binding_args) callargs = ', '.join(binding_argnames) pycallargs = ', '.join( [name for name in ['self'] + binding_argnames if name != 'index_ptr']) if py_args is None: py_args = binding_argnames pyinputargs = pycallargs # FIXME else: pyinputargs = ', '.join(['self'] + py_args) pyrestype = simple_c_to_ctypes[return_type] if py_alias is None: py_binding_name = binding_name else: py_binding_name = py_alias binding_def['py_binding_name'] = py_binding_name #### flann_ctypes.py flann_ctypes_codeblock = ut.codeblock(''' flann.{binding_name} = {{}} define_functions(r""" flannlib.flann_{binding_name}_%(C)s.restype = {pyrestype} flannlib.flann_{binding_name}_%(C)s.argtypes = [ {binding_args_str} ] flann.{binding_name}[%(numpy)s] = flannlib.flann_{binding_name}_%(C)s """) ''').format(binding_name=binding_name, binding_args_str=binding_args_str, pyrestype=pyrestype) #### index.py default_py_source_parts = [] if 'pts' in py_args: default_py_source_parts.append( ut.codeblock(''' if pts.dtype.type not in allowed_types: raise FLANNException('Cannot handle type: %s' % pts.dtype) pts = ensure_2d_array(pts, default_flags) ''')) default_py_source_parts.append( ut.codeblock(''' rows = pts.shape[0] raise NotImplementedError('requires custom implementation') flann.{binding_name}[self.__curindex_type](self.__curindex, {pycallargs}) ''')) if py_source is None: py_source = '\n'.join(default_py_source_parts) flann_index_codeblock = ut.codeblock(r''' def {py_binding_name}({pyinputargs}): """''' + ut.indent('\n' + docstr_py, ' ') + ''' """''' + '\n' + ut.indent(py_source, ' ') + ''' ''').format(binding_name=binding_name, pycallargs=pycallargs, py_binding_name=py_binding_name, pyinputargs=pyinputargs, py_source=py_source) #### flann.cpp #// {binding_name} BEGIN CPP BINDING #template <typename Distance> #{return_type} __flann_{binding_name}({templated_args}) flann_cpp_code_fmtstr_ = ut.codeblock(r''' {{''' + '\n' + ut.indent(c_source, ' ' * (4 * 3)) + r''' }} ''') #implicit_type_bindings_fmtstr = ut.codeblock( # NOQA # ''' # DISTANCE_TYPE_BINDINGS({return_type}, {binding_name}, # SINGLE_ARG({T_typed_sigargs_cpp}), # SINGLE_ARG({callargs})) # ''' #) #type_bindings_fmtstr = implicit_type_bindings_fmtstr explicit_type_bindings_part3_fmtstr = ut.codeblock(r''' {{ if (flann_distance_type==FLANN_DIST_EUCLIDEAN) {{ return __flann_{binding_name}<L2<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_MANHATTAN) {{ return __flann_{binding_name}<L1<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_MINKOWSKI) {{ return __flann_{binding_name}<MinkowskiDistance<T> >({callargs}{minkowski_option}); }} else if (flann_distance_type==FLANN_DIST_HIST_INTERSECT) {{ return __flann_{binding_name}<HistIntersectionDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_HELLINGER) {{ return __flann_{binding_name}<HellingerDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_CHI_SQUARE) {{ return __flann_{binding_name}<ChiSquareDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_KULLBACK_LEIBLER) {{ return __flann_{binding_name}<KL_Divergence<T> >({callargs}); }} else {{ Logger::error( "Distance type unsupported in the C bindings, use the C++ bindings instead\n"); {errorhandle} }} }} ''') # c binding body c_bodyblock_fmtstr = ut.codeblock(''' {return_type} flann_{binding_name}{signame_type}({T_typed_sigargs2}) {{ {ifreturns}_flann_{binding_name}{iftemplate}({callargs}); }} ''') #### flann.h # c binding header #c_headersig_fmtstr = 'FLANN_EXPORT {return_type} flann_{binding_name}{signame_type}({T_typed_sigargs2});' c_headersig_part1_fmtstr = 'FLANN_EXPORT {return_type} flann_{binding_name}{signame_type}(' #### format cpp parts binding_argtypes = ut.dict_take(templated_ctype_map, binding_argnames) _fix_T = { 'typename Distance::ElementType*': 'T*', 'typename Distance::ResultType*': 'R*', } templated_ctype_map_cpp = { name: _fix_T.get(type_, type_) for name, type_ in templated_ctype_map.items() } binding_argtypes_cpp = ut.dict_take(templated_ctype_map_cpp, binding_argnames) binding_sigargs_cpp = [ type_ + ' ' + name for type_, name in zip(binding_argtypes_cpp, binding_argnames) ] templated_bindings = [ templated_ctype_map[name] + ' ' + name for name in binding_argnames ] if optional_args is not None: templated_bindings += optional_args minkowski_option = ', MinkowskiDistance<T>(flann_distance_order)' else: minkowski_option = '' templated_args = ', '.join(templated_bindings) if binding_name == 'remove_point': # HACK templated_args += '_uint' cpp_sig_part1 = '{return_type} __flann_{binding_name}('.format( return_type=return_type, binding_name=binding_name) maxlen = 100 cpp_sig_ = ut.packstr(cpp_sig_part1 + templated_args, textwidth=maxlen, breakchars=', ', wordsep=', ', break_words=False, newline_prefix=' ' * len(cpp_sig_part1)) cpp_sig = cpp_sig_[:-2] + ')' flann_cpp_code_fmtstr = 'template <typename Distance>\n' + cpp_sig + '\n' + flann_cpp_code_fmtstr_ #print(cpp_sig) T_typed_sigargs_cpp = ', '.join(binding_sigargs_cpp) used_template_list = [] used_template_list.append('typename T') if 'typename Distance::ResultType*' in binding_argtypes: used_template_list.append('typename R') used_templates = ', '.join(used_template_list) type_binding_part1 = 'template <{used_templates}>'.format( used_templates=used_templates) type_binding_part2_ = '{return_type} _flann_{binding_name}('.format( return_type=return_type, binding_name=binding_name) maxlen = 100 cpp_type_sig_ = ut.packstr(type_binding_part2_ + T_typed_sigargs_cpp, textwidth=maxlen, breakchars=', ', wordsep=', ', break_words=False, newline_prefix=' ' * len(type_binding_part2_)) cpp_type_sig = cpp_type_sig_[:-2] + ')' type_binding_part12 = type_binding_part1 + '\n' + cpp_type_sig explicit_type_bindings_fmtstr = type_binding_part12 + '\n' + explicit_type_bindings_part3_fmtstr flann_cpp_codeblock_fmtstr = flann_cpp_code_fmtstr + '\n\n\n' + explicit_type_bindings_fmtstr + '\n' if return_type == 'int': errorhandle = 'return -1;' elif return_type == 'flann_index_t': errorhandle = 'return NULL;' else: errorhandle = 'throw 0;' # print('------') # print('flann_cpp_codeblock_fmtstr.format = %s' % (flann_cpp_codeblock_fmtstr,)) try: flann_cpp_codeblock = flann_cpp_codeblock_fmtstr.format( cpp_binding_name=cpp_binding_name, minkowski_option=minkowski_option, binding_name=binding_name, #templated_args=templated_args, callargs=callargs, #T_typed_sigargs_cpp=T_typed_sigargs_cpp, errorhandle=errorhandle, used_templates=used_templates, return_type=return_type) except KeyError as ex: ut.printex(ex, keys=['binding_name']) raise dataset_types = [ '', 'float', 'double', 'byte', 'int', ] #### format c parts c_header_sigs = [] c_body_blocks = [] templated_ctype_map_c = templated_ctype_map.copy() #templated_ctype_map_c['dataset'] = 'float' _fix_explicit_ctype = { '': 'float', 'byte': 'unsigned char', } # For each explicit c type for dataset_type in dataset_types: T_type = _fix_explicit_ctype.get(dataset_type, dataset_type) if dataset_type != '': signame_type = '_' + dataset_type else: signame_type = dataset_type R_type = 'float' if T_type != 'double' else 'double' dstype = T_type + '*' rstype = R_type + '*' # Overwrite template types with explicit c types needstemplate = True for type_, name in zip(binding_argtypes, binding_argnames): if type_ == 'typename Distance::ElementType*': templated_ctype_map_c[name] = dstype needstemplate = False if type_ == 'typename Distance::ResultType*': templated_ctype_map_c[name] = rstype needstemplate = False if type_ == 'Distance::ResultType*': templated_ctype_map_c[name] = rstype needstemplate = False #if type_ == 'struct FLANNParameters*': # # hack # templated_ctype_map_c[name] = 'FLANNParameters*' # HACK if binding_name == 'load_index' or binding_name == 'add_points': needstemplate = True if binding_name == 'build_index': needstemplate = True binding_argtypes2 = ut.dict_take(templated_ctype_map_c, binding_argnames) binding_sigargs2 = [ type_ + ' ' + name for type_, name in zip(binding_argtypes2, binding_argnames) ] T_typed_sigargs2 = ', '.join(binding_sigargs2) T_typed_sigargs2_nl = ',\n'.join(binding_sigargs2) if needstemplate: iftemplate = '<{T_type}>'.format(T_type=T_type) else: iftemplate = '' if return_type != 'void': ifreturns = 'return ' else: ifreturns = '' bodyblock = c_bodyblock_fmtstr.format( signame_type=signame_type, T_typed_sigargs2=T_typed_sigargs2, binding_name=binding_name, callargs=callargs, iftemplate=iftemplate, ifreturns=ifreturns, return_type=return_type) header_line_part1 = c_headersig_part1_fmtstr.format( signame_type=signame_type, binding_name=binding_name, return_type=return_type) header_line = header_line_part1 + ut.indent( T_typed_sigargs2_nl, ' ' * len(header_line_part1)).lstrip(' ') + ');' # Hack for header header_line = header_line.replace( 'FLANNParameters* flann_params', 'struct FLANNParameters* flann_params') #header_line = c_headersig_fmtstr.format(signame_type=signame_type, # T_typed_sigargs2=T_typed_sigargs2, # binding_name=binding_name, # return_type=return_type) c_header_sigs.append(header_line) c_body_blocks.append(bodyblock) flann_cpp_codeblock += '\n' + '\n'.join(c_body_blocks) #flann_cpp_codeblock += '\n' + '// {binding_name} END'.format(binding_name=binding_name) #BEGIN {binding_name} flann_h_codeblock = ut.codeblock(r''' /** {docstr_cpp} */ ''').format(docstr_cpp=docstr_cpp, binding_name=binding_name) flann_h_codeblock += '\n\n' + '\n\n'.join(c_header_sigs) blocks_dict = {} import re flann_index_codeblock = ut.indent(flann_index_codeblock, ' ') blocks_dict['flann_ctypes.py'] = flann_ctypes_codeblock blocks_dict['index.py'] = flann_index_codeblock blocks_dict['flann.h'] = flann_h_codeblock blocks_dict['flann.cpp'] = flann_cpp_codeblock for key in blocks_dict.keys(): blocks_dict[key] = re.sub('\n\s+\n', '\n\n', blocks_dict[key]) # , flags=re.MULTILINE) blocks_dict[key] = re.sub('\s\s+\n', '\n', blocks_dict[key]) pass if ut.get_argflag('--py'): print('\n\n# ---------------\n\n') print('GOES IN flann_ctypes.py') print('\n\n# ---------------\n\n') print(flann_ctypes_codeblock) print('\n\n# ---------------\n\n') print('GOES IN index.py') print('\n\n# ---------------\n\n') print(flann_index_codeblock) if ut.get_argflag('--c'): print('\n\n# ---------------\n\n') print('GOES IN flann.h') print('\n\n# ---------------\n\n') print(flann_h_codeblock) print('\n\n# ---------------\n\n') print('GOES IN flann.cpp') print('\n\n# ---------------\n\n') print(flann_cpp_codeblock) return blocks_dict, binding_def
def devfunc(ibs, qaid_list): """ Function for developing something """ print('[dev] devfunc') import ibeis # NOQA from ibeis.algo import Config # NOQA #from ibeis.algo.Config import * # NOQA feat_cfg = Config.FeatureConfig() #feat_cfg.printme3() print('\ncfgstr..') print(feat_cfg.get_cfgstr()) print(utool.dict_str(feat_cfg.get_hesaff_params())) from ibeis import viz aid = 1 ibs.cfg.feat_cfg.threshold = 16.0 / 3.0 kpts = ibs.get_annot_kpts(aid) print('len(kpts) = %r' % len(kpts)) from ibeis.expt import experiment_configs #varyparams_list = [ # #{ # # 'threshold': [16.0 / 3.0, 32.0 / 3.0], # 8.0 / 3.0 # # 'numberOfScales': [3, 2, 1], # # 'maxIterations': [16, 32], # # 'convergenceThreshold': [.05, .1], # # 'initialSigma': [1.6, 1.2], # #}, # { # #'threshold': [16.0 / 3.0, 32.0 / 3.0], # 8.0 / 3.0 # 'numberOfScales': [1], # #'maxIterations': [16, 32], # #'convergenceThreshold': [.05, .1], # #'initialSigma': [6.0, 3.0, 2.0, 1.6, 1.2, 1.1], # 'initialSigma': [3.2, 1.6, 0.8], # 'edgeEigenValueRatio': [10, 5, 3], # }, #] varyparams_list = [experiment_configs.featparams] # low threshold = more keypoints # low initialSigma = more keypoints nKpts_list = [] cfgstr_list = [] alldictcomb = utool.flatten([ utool.util_dict.all_dict_combinations(varyparams) for varyparams in featparams_list ]) NUM_PASSES = 1 if not utool.get_argflag('--show') else 2 for count in range(NUM_PASSES): for aid in qaid_list: #for dict_ in utool.progiter(alldictcomb, lbl='feature param comb: ', total=len(alldictcomb)): for dict_ in alldictcomb: for key_, val_ in six.iteritems(dict_): ibs.cfg.feat_cfg[key_] = val_ cfgstr_ = ibs.cfg.feat_cfg.get_cfgstr() cfgstr = utool.packstr(cfgstr_, textwidth=80, breakchars=',', newline_prefix='', break_words=False, wordsep=',') if count == 0: kpts = ibs.get_annot_kpts(aid) #print('___________') #print('len(kpts) = %r' % len(kpts)) #print(cfgstr) nKpts_list.append(len(kpts)) cfgstr_list.append(cfgstr_) if count == 1: title_suffix = (' len(kpts) = %r \n' % len(kpts)) + cfgstr viz.show_chip(ibs, aid, fnum=pt.next_fnum(), title_suffix=title_suffix, darken=.4, ell_linewidth=2, ell_alpha=.8) if count == 0: nKpts_list = np.array(nKpts_list) cfgstr_list = np.array(cfgstr_list) print(get_sortbystr(cfgstr_list, nKpts_list, 'cfg', 'nKpts')) pt.present() locals_ = locals() return locals_
def autogen_parts(binding_name=None): r""" CommandLine: python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=set_dataset python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=add_points python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=remove_point --py python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=used_memory --py python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=remove_points --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=veclen --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=size --py --c python ~/local/build_scripts/flannscripts/autogen_bindings.py --exec-autogen_parts --bindingname=clean_removed_points --py --c Ignore: # Logic goes here ~/code/flann/src/cpp/flann/algorithms/kdtree_index.h ~/code/flann/src/cpp/flann/util/serialization.h ~/code/flann/src/cpp/flann/util/dynamic_bitset.h # Bindings go here ~/code/flann/src/cpp/flann/flann.cpp ~/code/flann/src/cpp/flann/flann.h # Contains stuff for the flann namespace like flann::log_level # Also has Index with # Matrix<ElementType> features; SEEMS USEFUL ~/code/flann/src/cpp/flann/flann.hpp # Wrappers go here ~/code/flann/src/python/pyflann/flann_ctypes.py ~/code/flann/src/python/pyflann/index.py ~/local/build_scripts/flannscripts/autogen_bindings.py Example: >>> # ENABLE_DOCTEST >>> from autogen_bindings import * # NOQA >>> result = autogen_parts() >>> print(result) """ #ut.get_dynlib_exports(pyflann.flannlib._name) #flannlib if binding_name is None: binding_name = ut.get_argval('--bindingname', type_=str, default='add_points') # Variable names used in flann cpp source simple_c_to_ctypes = { 'void' : None, 'char*' : 'c_char_p', 'unsigned int' : 'c_uint', 'int' : 'c_int', 'float' : 'c_float', 'float*' : 'POINTER(c_float)', 'flann_index_t' : 'FLANN_INDEX', 'FLANNParameters*' : 'POINTER(FLANNParameters)', 'Distance::ResultType*' : "ndpointer(%(restype)s, flags='aligned, c_contiguous, writeable')", 'Distance::ElementType*' : "ndpointer(%(numpy)s, ndim=2, flags='aligned, c_contiguous')", 'typename Distance::ElementType*' : "ndpointer(%(numpy)s, ndim=2, flags='aligned, c_contiguous')", 'typename Distance::ResultType*' : "ndpointer(%(restype), ndim=2, flags='aligned, c_contiguous, writeable')", } templated_ctype_map = { 'filename' : 'char*', 'level' : 'int', 'rows' : 'int', 'cols' : 'int', 'point_id' : 'unsigned int', 'num' : 'int', 'max_nn' : 'int', 'tcount' : 'int', 'nn' : 'int', 'radius' : 'float', 'clusters' : 'int', 'rebuild_threshold' : 'float', 'index_ptr' : 'flann_index_t', 'flann_params' : 'FLANNParameters*', 'speedup' : 'float*', 'id_list' : 'int*', #'indices' : 'int*', 'dataset' : 'typename Distance::ElementType*', 'points' : 'typename Distance::ElementType*', 'query' : 'typename Distance::ElementType*', 'query1d' : 'typename Distance::ElementType*', 'testset' : 'typename Distance::ElementType*', 'dists' : 'typename Distance::ResultType*', 'dists1d' : 'typename Distance::ResultType*', 'result_centers' : 'typename Distance::ResultType*', 'result_ids' : 'int*', } # Python ctype bindings python_ctype_map = { 'flann_params' : 'POINTER(FLANNParameters)', 'id_list' : "ndpointer(int32, ndim=1, flags='aligned, c_contiguous')", #'indices' : "ndpointer(int32, ndim=1, flags='aligned, c_contiguous, writeable')", 'query1d' : "ndpointer(%(numpy)s, ndim=1, flags='aligned, c_contiguous')", 'dists1d' : "ndpointer(%(restype), ndim=1, flags='aligned, c_contiguous, writeable')", 'result_ids' : "ndpointer(int32, ndim=2, flags='aligned, c_contiguous, writeable')", #'query' : "ndpointer(float64, ndim=1, flags='aligned, c_contiguous')", } for key, val in templated_ctype_map.items(): if key not in python_ctype_map: python_ctype_map[key] = simple_c_to_ctypes[val] binding_def = define_flann_bindings(binding_name) docstr_cpp = binding_def['docstr_cpp'] docstr_py = binding_def['docstr_py'] cpp_binding_name = binding_def['cpp_binding_name'] return_type = binding_def['return_type'] binding_argnames = binding_def['binding_argnames'] c_source = binding_def['c_source'] py_source = binding_def['py_source'] optional_args = binding_def['optional_args'] py_alias = binding_def['py_alias'] py_args = binding_def['py_args'] binding_args = [python_ctype_map[name] + ', # ' + name for name in binding_argnames] binding_args_str = ' ' + '\n '.join(binding_args) callargs = ', '.join(binding_argnames) pycallargs = ', '.join([name for name in ['self'] + binding_argnames if name != 'index_ptr']) if py_args is None: py_args = binding_argnames pyinputargs = pycallargs # FIXME else: pyinputargs = ', '.join(['self'] + py_args) pyrestype = simple_c_to_ctypes[return_type] if py_alias is None: py_binding_name = binding_name else: py_binding_name = py_alias binding_def['py_binding_name'] = py_binding_name #### flann_ctypes.py flann_ctypes_codeblock = ut.codeblock( ''' flann.{binding_name} = {{}} define_functions(r""" flannlib.flann_{binding_name}_%(C)s.restype = {pyrestype} flannlib.flann_{binding_name}_%(C)s.argtypes = [ {binding_args_str} ] flann.{binding_name}[%(numpy)s] = flannlib.flann_{binding_name}_%(C)s """) ''' ).format(binding_name=binding_name, binding_args_str=binding_args_str, pyrestype=pyrestype) #### index.py default_py_source_parts = [] if 'pts' in py_args: default_py_source_parts.append(ut.codeblock( ''' if pts.dtype.type not in allowed_types: raise FLANNException('Cannot handle type: %s' % pts.dtype) pts = ensure_2d_array(pts, default_flags) ''')) default_py_source_parts.append(ut.codeblock( ''' rows = pts.shape[0] raise NotImplementedError('requires custom implementation') flann.{binding_name}[self.__curindex_type](self.__curindex, {pycallargs}) ''' )) if py_source is None: py_source = '\n'.join(default_py_source_parts) flann_index_codeblock = ut.codeblock( r''' def {py_binding_name}({pyinputargs}): """''' + ut.indent('\n' + docstr_py, ' ') + ''' """''' + '\n' + ut.indent(py_source, ' ') + ''' ''' ).format(binding_name=binding_name, pycallargs=pycallargs, py_binding_name=py_binding_name, pyinputargs=pyinputargs, py_source=py_source) #### flann.cpp #// {binding_name} BEGIN CPP BINDING #template <typename Distance> #{return_type} __flann_{binding_name}({templated_args}) flann_cpp_code_fmtstr_ = ut.codeblock( r''' {{''' + '\n' + ut.indent(c_source, ' ' * (4 * 3)) + r''' }} ''' ) #implicit_type_bindings_fmtstr = ut.codeblock( # NOQA # ''' # DISTANCE_TYPE_BINDINGS({return_type}, {binding_name}, # SINGLE_ARG({T_typed_sigargs_cpp}), # SINGLE_ARG({callargs})) # ''' #) #type_bindings_fmtstr = implicit_type_bindings_fmtstr explicit_type_bindings_part3_fmtstr = ut.codeblock( r''' {{ if (flann_distance_type==FLANN_DIST_EUCLIDEAN) {{ return __flann_{binding_name}<L2<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_MANHATTAN) {{ return __flann_{binding_name}<L1<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_MINKOWSKI) {{ return __flann_{binding_name}<MinkowskiDistance<T> >({callargs}{minkowski_option}); }} else if (flann_distance_type==FLANN_DIST_HIST_INTERSECT) {{ return __flann_{binding_name}<HistIntersectionDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_HELLINGER) {{ return __flann_{binding_name}<HellingerDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_CHI_SQUARE) {{ return __flann_{binding_name}<ChiSquareDistance<T> >({callargs}); }} else if (flann_distance_type==FLANN_DIST_KULLBACK_LEIBLER) {{ return __flann_{binding_name}<KL_Divergence<T> >({callargs}); }} else {{ Logger::error( "Distance type unsupported in the C bindings, use the C++ bindings instead\n"); {errorhandle} }} }} ''' ) # c binding body c_bodyblock_fmtstr = ut.codeblock( ''' {return_type} flann_{binding_name}{signame_type}({T_typed_sigargs2}) {{ {ifreturns}_flann_{binding_name}{iftemplate}({callargs}); }} ''' ) #### flann.h # c binding header #c_headersig_fmtstr = 'FLANN_EXPORT {return_type} flann_{binding_name}{signame_type}({T_typed_sigargs2});' c_headersig_part1_fmtstr = 'FLANN_EXPORT {return_type} flann_{binding_name}{signame_type}(' #### format cpp parts binding_argtypes = ut.dict_take(templated_ctype_map, binding_argnames) _fix_T = { 'typename Distance::ElementType*': 'T*', 'typename Distance::ResultType*': 'R*', } templated_ctype_map_cpp = {name: _fix_T.get(type_, type_) for name, type_ in templated_ctype_map.items()} binding_argtypes_cpp = ut.dict_take(templated_ctype_map_cpp, binding_argnames) binding_sigargs_cpp = [type_ + ' ' + name for type_, name in zip(binding_argtypes_cpp, binding_argnames)] templated_bindings = [templated_ctype_map[name] + ' ' + name for name in binding_argnames] if optional_args is not None: templated_bindings += optional_args minkowski_option = ', MinkowskiDistance<T>(flann_distance_order)' else: minkowski_option = '' templated_args = ', '.join(templated_bindings) if binding_name == 'remove_point': # HACK templated_args += '_uint' cpp_sig_part1 = '{return_type} __flann_{binding_name}('.format(return_type=return_type, binding_name=binding_name) maxlen = 100 cpp_sig_ = ut.packstr(cpp_sig_part1 + templated_args, textwidth=maxlen, breakchars=', ', wordsep=', ', break_words=False, newline_prefix=' ' * len(cpp_sig_part1)) cpp_sig = cpp_sig_[:-2] + ')' flann_cpp_code_fmtstr = 'template <typename Distance>\n' + cpp_sig + '\n' + flann_cpp_code_fmtstr_ #print(cpp_sig) T_typed_sigargs_cpp = ', '.join(binding_sigargs_cpp) used_template_list = [] used_template_list.append('typename T') if 'typename Distance::ResultType*' in binding_argtypes: used_template_list.append('typename R') used_templates = ', '.join(used_template_list) type_binding_part1 = 'template <{used_templates}>'.format(used_templates=used_templates) type_binding_part2_ = '{return_type} _flann_{binding_name}('.format(return_type=return_type, binding_name=binding_name) maxlen = 100 cpp_type_sig_ = ut.packstr(type_binding_part2_ + T_typed_sigargs_cpp, textwidth=maxlen, breakchars=', ', wordsep=', ', break_words=False, newline_prefix=' ' * len(type_binding_part2_)) cpp_type_sig = cpp_type_sig_[:-2] + ')' type_binding_part12 = type_binding_part1 + '\n' + cpp_type_sig explicit_type_bindings_fmtstr = type_binding_part12 + '\n' + explicit_type_bindings_part3_fmtstr flann_cpp_codeblock_fmtstr = flann_cpp_code_fmtstr + '\n\n\n' + explicit_type_bindings_fmtstr + '\n' if return_type == 'int': errorhandle = 'return -1;' elif return_type == 'flann_index_t': errorhandle = 'return NULL;' else: errorhandle = 'throw 0;' # print('------') # print('flann_cpp_codeblock_fmtstr.format = %s' % (flann_cpp_codeblock_fmtstr,)) try: flann_cpp_codeblock = flann_cpp_codeblock_fmtstr.format( cpp_binding_name=cpp_binding_name, minkowski_option=minkowski_option, binding_name=binding_name, #templated_args=templated_args, callargs=callargs, #T_typed_sigargs_cpp=T_typed_sigargs_cpp, errorhandle=errorhandle, used_templates=used_templates, return_type=return_type) except KeyError as ex: ut.printex(ex, keys=['binding_name']) raise dataset_types = [ '', 'float', 'double', 'byte', 'int', ] #### format c parts c_header_sigs = [] c_body_blocks = [] templated_ctype_map_c = templated_ctype_map.copy() #templated_ctype_map_c['dataset'] = 'float' _fix_explicit_ctype = { '' : 'float', 'byte' : 'unsigned char', } # For each explicit c type for dataset_type in dataset_types: T_type = _fix_explicit_ctype.get(dataset_type, dataset_type) if dataset_type != '': signame_type = '_' + dataset_type else: signame_type = dataset_type R_type = 'float' if T_type != 'double' else 'double' dstype = T_type + '*' rstype = R_type + '*' # Overwrite template types with explicit c types needstemplate = True for type_, name in zip(binding_argtypes, binding_argnames): if type_ == 'typename Distance::ElementType*': templated_ctype_map_c[name] = dstype needstemplate = False if type_ == 'typename Distance::ResultType*': templated_ctype_map_c[name] = rstype needstemplate = False if type_ == 'Distance::ResultType*': templated_ctype_map_c[name] = rstype needstemplate = False #if type_ == 'struct FLANNParameters*': # # hack # templated_ctype_map_c[name] = 'FLANNParameters*' # HACK if binding_name == 'load_index' or binding_name == 'add_points': needstemplate = True if binding_name == 'build_index': needstemplate = True binding_argtypes2 = ut.dict_take(templated_ctype_map_c, binding_argnames) binding_sigargs2 = [type_ + ' ' + name for type_, name in zip(binding_argtypes2, binding_argnames)] T_typed_sigargs2 = ', '.join(binding_sigargs2) T_typed_sigargs2_nl = ',\n'.join(binding_sigargs2) if needstemplate: iftemplate = '<{T_type}>'.format(T_type=T_type) else: iftemplate = '' if return_type != 'void': ifreturns = 'return ' else: ifreturns = '' bodyblock = c_bodyblock_fmtstr.format(signame_type=signame_type, T_typed_sigargs2=T_typed_sigargs2, binding_name=binding_name, callargs=callargs, iftemplate=iftemplate, ifreturns=ifreturns, return_type=return_type) header_line_part1 = c_headersig_part1_fmtstr.format(signame_type=signame_type, binding_name=binding_name, return_type=return_type) header_line = header_line_part1 + ut.indent(T_typed_sigargs2_nl, ' ' * len(header_line_part1)).lstrip(' ') + ');' # Hack for header header_line = header_line.replace('FLANNParameters* flann_params', 'struct FLANNParameters* flann_params') #header_line = c_headersig_fmtstr.format(signame_type=signame_type, # T_typed_sigargs2=T_typed_sigargs2, # binding_name=binding_name, # return_type=return_type) c_header_sigs.append(header_line) c_body_blocks.append(bodyblock) flann_cpp_codeblock += '\n' + '\n'.join(c_body_blocks) #flann_cpp_codeblock += '\n' + '// {binding_name} END'.format(binding_name=binding_name) #BEGIN {binding_name} flann_h_codeblock = ut.codeblock( r''' /** {docstr_cpp} */ ''' ).format(docstr_cpp=docstr_cpp, binding_name=binding_name) flann_h_codeblock += '\n\n' + '\n\n'.join(c_header_sigs) blocks_dict = {} import re flann_index_codeblock = ut.indent(flann_index_codeblock, ' ') blocks_dict['flann_ctypes.py'] = flann_ctypes_codeblock blocks_dict['index.py'] = flann_index_codeblock blocks_dict['flann.h'] = flann_h_codeblock blocks_dict['flann.cpp'] = flann_cpp_codeblock for key in blocks_dict.keys(): blocks_dict[key] = re.sub('\n\s+\n', '\n\n', blocks_dict[key]) # , flags=re.MULTILINE) blocks_dict[key] = re.sub('\s\s+\n', '\n', blocks_dict[key]) pass if ut.get_argflag('--py'): print('\n\n# ---------------\n\n') print('GOES IN flann_ctypes.py') print('\n\n# ---------------\n\n') print(flann_ctypes_codeblock) print('\n\n# ---------------\n\n') print('GOES IN index.py') print('\n\n# ---------------\n\n') print(flann_index_codeblock) if ut.get_argflag('--c'): print('\n\n# ---------------\n\n') print('GOES IN flann.h') print('\n\n# ---------------\n\n') print(flann_h_codeblock) print('\n\n# ---------------\n\n') print('GOES IN flann.cpp') print('\n\n# ---------------\n\n') print(flann_cpp_codeblock) return blocks_dict, binding_def