Welcome    Usage    Browse    Find CID    Search     Log in

cM API Documentation

module.py

Go to the documentation of this file.
00001 #
00002 # Collective Mind
00003 #
00004 # See cM LICENSE.txt for licensing details.
00005 # See cM Copyright.txt for copyright details.
00006 #
00007 # Developer(s): (C) Grigori Fursin, started on 2011.09
00008 #
00009 
00010 # Should always be here
00011 ini={}
00012 cm_kernel=None
00013 
00014 # Local settings
00015 import os
00016 import json
00017 
00018 # ============================================================================
00019 def init(i):
00020     return {'cm_return':0}
00021 
00022 # ============================================================================
00023 def convert_flags_from_ccc(i):
00024 
00025     """
00026     Convert flags from CCC framework
00027 
00028     Input:  {
00029               cm_filename            - CCC compiler configuration file
00030               (add_base_opt_upfront) - if 'yes', add base opts upfront (such as -O3, -O2, etc).
00031                                        One should edit final config!
00032 
00033               (create_cm_entry)      - if 'yes' add to cM
00034               (repo_uoa)             - repository to create entry
00035               (data_uoa)             - data uoa to create entry
00036             }
00037     """
00038 
00039     if 'cm_filename' not in i: return {'cm_return':1, 'cm_error':'"cm_filename" is not defined'}
00040     fn=i['cm_filename']
00041 
00042     if not os.path.isfile(fn):
00043        return {'cm_return':1, 'cm_error':'input CCC file not found'}
00044 
00045     f1=open(fn, 'r')
00046 
00047     l="x"
00048 
00049     final={}
00050     array=[]
00051 
00052     while (l != "" ):
00053        l = f1.readline().rstrip()
00054        cm_kernel.print_for_con(l)
00055 
00056        r=cm_kernel.gen_uid({})
00057        if r['cm_return']>0: return r
00058        uid=r['cm_uid']
00059 
00060        cm_kernel.print_for_con(uid)
00061 
00062        a={'cm_choice':'true',
00063           'cm_uoa':uid}
00064 
00065        x=l.split(',')
00066        if x[0]=='1':
00067           a['cm_type']='range'
00068           a['cm_prefix']=x[3].strip()
00069           a['cm_range_start']=x[1].strip()
00070           a['cm_range_stop']=x[2].strip()
00071           a['cm_range_step']='1'
00072 
00073        elif x[0]=='2':
00074           y=[x[1].strip(), '']
00075           a['cm_type']='one_of'
00076           a['cm_prefix']=''
00077           a['cm_list']=[y, '']
00078 
00079        elif x[0]=='3':
00080           y=[]
00081           for q in range(0, int(x[1])):
00082               y.append(x[q+2].strip())
00083           a['cm_type']='one_of'
00084           a['cm_prefix']=''
00085           a['cm_list']=y
00086 
00087        array.append(a)
00088 
00089     f1.close()
00090 
00091     final['compiler_flags']={}
00092 
00093     array1=array
00094     if i.get('add_base_opt_upfront','')=='yes':
00095        r=cm_kernel.gen_uid({})
00096        if r['cm_return']>0: return r
00097        uid1=r['cm_uid']
00098        r=cm_kernel.gen_uid({})
00099        if r['cm_return']>0: return r
00100        uid2=r['cm_uid']
00101        r=cm_kernel.gen_uid({})
00102        if r['cm_return']>0: return r
00103        uid3=r['cm_uid']
00104 
00105        array1={"cm_list":[{"cm_list": [
00106                                  "-O1", 
00107                                  "-O2", 
00108                                  "-O3", 
00109                                  "-Os", 
00110                                  "-Ofast"
00111                                ], 
00112                                "cm_type": "one_of", 
00113                                "cm_uoa": uid1, 
00114                                "cm_prefix": "", 
00115                                "cm_choice": "true"
00116                            }, 
00117                            {"cm_list":[
00118                               array
00119                              ],
00120                             "cm_type": "combine_without_order", 
00121                             "cm_prefix": "", 
00122                             "cm_uoa": uid2, 
00123                             "cm_choice": "true"
00124                            }
00125                           ],
00126                "cm_type": "select_all", 
00127                "cm_prefix": "", 
00128                "cm_uoa": uid3, 
00129                "cm_choice": "true"
00130               }
00131 
00132 
00133     r=cm_kernel.gen_uid({})
00134     if r['cm_return']>0: return r
00135     uid1=r['cm_uid']
00136     r=cm_kernel.gen_uid({})
00137     if r['cm_return']>0: return r
00138     uid2=r['cm_uid']
00139     array2={"cm_list": [
00140                          {
00141                            "cm_list": [
00142                              "-O0", 
00143                              "-O1", 
00144                              "-O2", 
00145                              "-O3", 
00146                              "-Os"
00147                            ], 
00148                            "cm_type": "one_of", 
00149                            "cm_uoa": uid1, 
00150                            "cm_prefix": "", 
00151                            "cm_choice": "true"
00152                          }, 
00153                        ], 
00154                        "cm_type": "combine_with_order", 
00155                        "cm_prefix": "", 
00156                        "cm_uoa": uid2, 
00157                        "cm_choice": "true"
00158                      }
00159 
00160     final['compiler_flags']['all_optimizations']=array1
00161     final['compiler_flags']['base_optimizations']=array2
00162 
00163     # Check where to write
00164     if i.get('create_cm_entry','')=='yes':
00165        ii={'cm_run_module_uoa':ini['cm_module_uoa'],
00166            'cm_action':'update',
00167            'cm_array':final}
00168        if 'repo_uoa' in i: ii['cm_repo_uoa']=i['repo_uoa']
00169        if 'data_uoa' in i: ii['cm_data_uoa']=i['data_uoa']
00170        r=cm_kernel.access(ii)
00171        if r['cm_return']>0: return r
00172 
00173        cm_kernel.print_for_con('Entry was created successfully: '+r['cm_uoa'])
00174        cm_kernel.print_for_con('')
00175        cm_kernel.print_for_con('Path: '+r['cm_path'])
00176 
00177     else:
00178        f2=open(fn+'.json', 'w')
00179        s = json.dumps(final, indent=2)
00180        f2.write(s+'\n')
00181        f2.close()
00182 
00183     return {'cm_return':0}
00184 
00185 # ============================================================================
00186 def prepare_flags(i):
00187 
00188     """
00189     Prepare flags from array
00190 
00191     Input:  {
00192               cm_data_uoa       - data with compiler description
00193               all_flags         - {} all flags
00194               (all_flags_order) - [] order of flags
00195             }
00196 
00197     Output: {
00198               cm_return       - if =0, success
00199               prepared_flags  - string with prepared flags
00200               all_flags_order - [] order of flags (if original was empty, 
00201                                 prepare order according to sort_index in description)
00202             }
00203     """
00204 
00205     cdu=i.get('cm_data_uoa','')
00206     if cdu=='': return {'cm_return':1, 'cm_error':'"cm_data_uoa" is not defined in ctuning.compiler/prepare_flags'}
00207 
00208     # Load compiler description
00209     jj={'cm_run_module_uoa':ini['cm_module_uoa'],
00210         'cm_action':'load',
00211         'cm_data_uoa':cdu}
00212     r=cm_kernel.access(jj)
00213     if r['cm_return']>0: return r
00214     cfg=r['cm_data_obj']['cfg']
00215 
00216     d=cfg.get('all_compiler_flags_desc',{})
00217     
00218     all_flags=i.get('all_flags',{})
00219     all_flags_order=i.get('all_flags_order',[])
00220 
00221     afo1=[]
00222 
00223     pf=all_flags.get('base_flag','')
00224 
00225     # all other flags
00226 #    all_flags_sorted=sorted(all_flags.keys(), key=lambda k: (int(d.get(k,{}).get('sort_index','999999')), d.get(k,{}).get('desc_text','').lower()))
00227 
00228     keys=all_flags.keys()
00229     if len(all_flags_order)>0: keys=all_flags_order
00230 
00231     for q in keys:
00232         if q in all_flags:
00233            afo1.append(q)
00234 
00235            if q!='base_flag':
00236               v=all_flags[q]
00237               if v!='':
00238                  if '##'+q not in d:
00239                     v=''
00240                  elif 'explore_prefix' in d['##'+q]:
00241                     v=d['##'+q]['explore_prefix']+v
00242               if v!='':
00243                  pf+=' '+v
00244 
00245     return {'cm_return':0, 'prepared_flags':pf, 'all_flags_order':afo1}
00246 
00247 # ============================================================================
00248 def compile_program(i):
00249 
00250     """
00251     Compile program
00252 
00253     Input:  {
00254               cm_unparsed
00255               (mode)
00256               (no_default_compiler_in_cmd)
00257               (default_compiler_name)
00258             }
00259 
00260     Output: {
00261               cm_return       - if =0, success
00262             }
00263     """
00264 
00265     # Check if there is a cTuning local setup 
00266     if ini['cfg']['env_ctuning_local_setup_uoa'] in os.environ.keys():
00267        x=os.environ[ini['cfg']['env_ctuning_local_setup_uoa']]
00268        if x!='':
00269           # Try to load setup
00270           ii={'cm_run_module_uoa':ini['cfg']['cm_modules']['ctuning.setup.local'],
00271               'cm_action':'load',
00272               'cm_data_uoa':x}
00273           r=cm_kernel.access(ii)
00274           if r['cm_return']>0: return r 
00275         
00276           d=r['cm_data_obj']['cfg']
00277 
00278           cm_kernel.merge_arrays({'cm_array':i, 'cm_array1':d})
00279 
00280     # Check if environment has additional parameter
00281     if ini['cfg']['env_cmd'] in os.environ.keys():
00282        x=os.environ[ini['cfg']['env_cmd']]
00283        if x!='':
00284           r=cm_kernel.str2cm('dummy_module dummy_action '+x) # we add dummy to be able to reuse cM kernel cmd parsing function
00285           if r['cm_return']>0: return r
00286 
00287           y=r['cm_array']
00288           if 'cm_run_module_uoa' in y: del(y['cm_run_module_uoa'])
00289           if 'cm_action' in y: del(y['cm_action'])
00290 
00291           cm_kernel.merge_arrays({'cm_array':i, 'cm_array1':y})
00292 
00293     # Get unparsed parameters (after --)
00294     ap=i.get('cm_unparsed',[])
00295 
00296     # Get mode (if any)
00297     mode=i.get('ct_mode','')
00298     if '--ct-mode' in ap:
00299       x=ap.index('--ct-mode')
00300       del(ap[x])
00301       if len(ap)>x:
00302          mode=ap[x]
00303          del(ap[x])
00304 
00305     # Get repo (if any)
00306     repo=i.get('ct_repo','')
00307     if '--ct-repo' in ap:
00308       x=ap.index('--ct-repo')
00309       del(ap[x])
00310       if len(ap)>x:
00311          repo=ap[x]
00312          del(ap[x])
00313 
00314     # Get verbosity
00315     vrb=i.get('ct_verbose','')
00316     if '--ct-verbose' in ap:
00317       x=ap.index('--ct-verbose')
00318       del(ap[x])
00319       if len(ap)>x:
00320          vrb=ap[x]
00321          del(ap[x])
00322 
00323     # Get verbosity
00324     out_file=i.get('ct_output_file','')
00325     if '--ct-output-file' in ap:
00326       x=ap.index('--ct-output-file')
00327       del(ap[x])
00328       if len(ap)>x:
00329          out_file=ap[x]
00330          del(ap[x])
00331 
00332     # Get verbosity
00333     clean_output_file=i.get('ct_clean_output_file','')
00334     if '--ct-clean-output-file' in ap:
00335       x=ap.index('--ct-clean-output-file')
00336       del(ap[x])
00337       clean_output_file='yes'
00338 
00339     # Get verbosity
00340     record_compilation_flow=i.get('ct_record_compilation_flow','')
00341     if '--ct-record-compilation-flow' in ap:
00342       x=ap.index('--ct-record-compilation-flow')
00343       del(ap[x])
00344       record_compilation_flow='yes'
00345 
00346     # If no repo, get default
00347     if repo=='':
00348        repo=ini['cfg']['ct_default_repo']
00349 
00350     # Check some host environment parameters
00351     xenv1='$';xenv2='';xenv3='.';xenv4='.sh';xenv5=';'
00352     if cm_kernel.is_windows():
00353        xenv1='%';xenv2='%';xenv3='call';xenv4='.bat';xenv5='&&'
00354 
00355     # Default compiler
00356     compiler_code_uoa=i.get('compiler_code_uoa','')
00357 
00358     # Check if help, otherwise continue processing ***********************************************
00359     if mode=='help' or '-h' in ap or '-help' in ap or '--help' in ap or '-?' in ap:
00360       cm_kernel.print_for_con("")
00361       cm_kernel.print_for_con("cM machine-learning based compiler wrapper")
00362       cm_kernel.print_for_con("")
00363       cm_kernel.print_for_con("  cm ctuning-compiler (cTuning parameters) ... @config.json -- <UNCHANGED COMMAND LINE for a user compiler>")
00364       cm_kernel.print_for_con("")
00365       cm_kernel.print_for_con("   cTuning parameters:")
00366       cm_kernel.print_for_con("     ct_mode=help                    - print this help")
00367       cm_kernel.print_for_con("             test-repo               - test current repository with characterized computer systems")
00368       cm_kernel.print_for_con("                                          and their profitable optimization cases")
00369       cm_kernel.print_for_con("             clean-output-file       - clean output file")
00370       cm_kernel.print_for_con("             record-compilation-flow - record compilation flow")
00371       cm_kernel.print_for_con("             <empty>                 - transparently call user compiler with user parameters")
00372       cm_kernel.print_for_con("     ct_verbose=yes/no               - print various Debug info")
00373       cm_kernel.print_for_con("     ct_repo=<REPO UOA>              - select current repo UOA (by default, cmind)")
00374       cm_kernel.print_for_con("     ct_out_file=<output file>       - output file (if needed)")
00375       cm_kernel.print_for_con("     ct_clean_out_file=yes/no        - cleaning output file")
00376       cm_kernel.print_for_con("")
00377       cm_kernel.print_for_con("")
00378       cm_kernel.print_for_con(" Alternative call:")
00379       cm_kernel.print_for_con("")
00380       cm_kernel.print_for_con("  ctuning-cc / ctuning-cpp / ctuning-fortran (cTuning flags) <UNCHANGED COMMAND LINE for a user compiler>")
00381       cm_kernel.print_for_con("   cTuning flags:")
00382       cm_kernel.print_for_con("     -h / -help / --help / -?       - print this help")
00383       cm_kernel.print_for_con("     --ct-mode help                 - print this help")
00384       cm_kernel.print_for_con("     --ct-verbose yes               - print various Debug info")
00385       cm_kernel.print_for_con("     --ct-out-file <filename>       - output file")
00386       cm_kernel.print_for_con("     --ct-clean-output-file         - clean output file")
00387       cm_kernel.print_for_con("     --ct-record-compilation-flow   - record compilation flow")
00388 
00389       exit(0)
00390 
00391     # Test repo ***********************************************
00392     elif mode=='test-repo' or '-tr' in ap or '--test-repo' in ap:
00393       cm_kernel.print_for_con('Testing repository with characterized computer systems and their profitable cases')
00394 
00395       r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['cm-repo'],
00396                           'cm_action':'test',
00397                           'test_repo_uoa':repo})
00398       cm_kernel.print_for_con('')
00399       if r['cm_return']>0: return r
00400 
00401       cm_kernel.print_for_con('Test passed successfully!')
00402 
00403       exit(0)
00404 
00405     # Select collective optimization from repository ***************************************
00406     if mode=='clean_output_file' or clean_output_file=='yes':
00407       if vrb=='yes':
00408          cm_kernel.print_for_con('')
00409          cm_kernel.print_for_con('Removing output file '+out_file+' ...')
00410       if out_file!='':
00411          if os.path.isfile(out_file):
00412             os.remove(out_file)  
00413             if vrb=='yes':
00414                cm_kernel.print_for_con('')
00415                cm_kernel.print_for_con('Output file cleaned!')
00416 
00417     # ***************** Compile program, if needed *****************
00418 
00419     # Check various additional cTuning params 
00420     # and remove them from the unparsed cmd if needed
00421 
00422     # Check if default compiler name is specified
00423     dcn=i.get('default_compiler_name','')
00424 
00425     # Check if first parameter is compiler name
00426     # I.e. we can allow both to use a default compiler name and just prefix with cm
00427     # or fully substitute it from the start - it depends on user needs and configuration
00428     ndc=i.get('no_default_compiler_in_cmd','')
00429 
00430     # Compiler type
00431     compiler_type=i.get('compiler_type','')
00432 
00433     if ndc=='yes':
00434        if dcn=='': 
00435           if compiler_type!='':
00436              dcn=xenv1+'CM_'+compiler_type+xenv2
00437           else:
00438              return {'cm_return':1, 'cm_error':'default compiler is not defined (no "compiler_type" in CMD)'}
00439     else:
00440        if len(ap)>0:
00441           dcn=ap[0]
00442           del(ap[0])
00443        else:
00444           return {'cm_return':1, 'cm_error':'no default compiler in cmd'}
00445 
00446     # Now we have default cmd without compiler (need to add ndc)
00447     # FGG separated it since default compiler can have additional options so
00448     # we will not be able to change it when substituting with various ICI/OpenME
00449     # feature extractors ...
00450     cmd=''
00451     for x in ap: #i.get('cm_unparsed',[]):
00452         if ' ' in x: x='"'+x+'"' #      We need to add " to values with spaces otherwise will break into sub-values
00453         cmd+=x+' '
00454 
00455     xcmd=''
00456     ycmd=''
00457 
00458     # Check if need to remove flags
00459     if mode=='extract_milepost_properties' or mode=='predict_opt' or mode=='select_collective_opt':
00460        tccdu=i.get('target_ctuning_compiler_desc_uoa','')
00461 
00462        # Remove opts from original CMD
00463        r=cm_kernel.access({'cm_run_module_uoa':ini['cm_module_uid'],
00464                            'cm_action':'load',
00465                            'cm_data_uoa':tccdu})
00466        if r['cm_return']>0: return r
00467        da=r['cm_data_obj']['cfg'].get('all_compiler_flags_desc',{})
00468 
00469        if vrb=='yes':
00470           cm_kernel.print_for_con('')
00471           cm_kernel.print_for_con('Removing old optimization flags from CMD:')
00472        ap1=[]
00473        for q in ap:
00474            add=True
00475            for k in da:
00476                v=da[k]
00477                ep=v.get('explore_prefix','')
00478 
00479                if ep!='':
00480                   if q.startswith(ep):
00481                      add=False
00482                else:
00483                   ch=v.get('choice',[])
00484                   for l in ch:
00485                       if q==l:
00486                          add=False
00487                          break
00488 
00489                if not add:
00490                   xcmd+=' '+q
00491                   break
00492 
00493            if add: ap1.append(q)
00494 
00495        xcmd=xcmd.strip()
00496 
00497        for x in ap1: #i.get('cm_unparsed',[]):
00498            if ' ' in x: x='"'+x+'"' #      We need to add " to values with spaces otherwise will break into sub-values
00499            ycmd+=x+' '
00500 
00501     # Read output file if needed
00502     of={}
00503     changed=False
00504     if out_file!='' and os.path.isfile(out_file):
00505        r=cm_kernel.load_json_file({'cm_filename':out_file})
00506        if r['cm_return']>0: return r
00507        of=r['cm_array']
00508 
00509     # If cTuning mode is not selected, simply call default cmd
00510     run_default_cmd=True
00511 
00512     # Record compilation flow *****************************************************************************************
00513     if mode=='record_compilation_flow' or record_compilation_flow=='yes':
00514        if vrb=='yes':
00515           cm_kernel.print_for_con('')
00516           cm_kernel.print_for_con('cTuning mode: recording compilation flow ...')
00517 
00518        if 'compilation_flow' not in of: of['compilation_flow']=[]
00519        of['compilation_flow'].append(dcn+' '+cmd)
00520        changed=True
00521 
00522     # Select collective optimization from repository ******************************************************************
00523     elif mode=='extract_milepost_properties' or mode=='predict_opt':
00524        if vrb=='yes':
00525           cm_kernel.print_for_con('')
00526           if mode=='extract_milepost_properties':
00527              cm_kernel.print_for_con('cTuning mode: extracting semantic program properties (features) ...')
00528           elif mode=='predict_opt':
00529              cm_kernel.print_for_con('cTuning mode: predict optimization using semantic program properties (features) ...')
00530 
00531           cm_kernel.print_for_con('')
00532           cm_kernel.print_for_con('Preparing cTuning CC / MILEPOST GCC ...')
00533 
00534        ii={}
00535 
00536        if vrb!='yes': ii['cm_verbose']='no'
00537 
00538        ii['build_target_os_uoa']=i['target_os_uoa']
00539        ii['run_host_os_uoa']=i['host_os_uoa']
00540 
00541        milepost_compiler_extract_after_pass=i.get('milepost_compiler_extract_after_pass','')
00542        milepost_compiler_flags=i.get('milepost_compiler_flags','')
00543 
00544        ctuning_compiler_plugins_code_uoa=i.get('ctuning_compiler_plugins_code_uoa','')
00545        milepost_compiler_code_uoa=i.get('milepost_compiler_code_uoa','')
00546        functions=i.get('ct_functions',[])
00547 
00548        xcompiler_type=i['compiler_type']
00549        if xcompiler_type=='CPP': xcompiler_type='CXX'
00550 
00551        if len(ii.get('run_set_env2',{}))==0: ii['run_set_env2']={}
00552        ii['run_set_env2']['CT_CMD']=' '+milepost_compiler_flags+' '+ycmd
00553        ii['run_set_env2']['CT_COMPILER_TYPE']=compiler_type
00554        ii['run_set_env2']['CT_COMPILER_TYPEX']=xcompiler_type
00555        ii['run_set_env2']['CT_MILEPOST_COMPILER_BIN_DIR']='CM_'+milepost_compiler_code_uoa+'_BIN'
00556 
00557        if milepost_compiler_code_uoa=='' or ctuning_compiler_plugins_code_uoa=='':
00558           return {'cm_return':1,'cm_error':'milepost_compiler_code_uoa or ctuning_compiler_plugins_code_uoa is not defined'}
00559 
00560        if len(ii.get('code_deps',[]))==0: ii['code_deps']=[]
00561        ii['code_deps'].append({"CM_CODE_DEP_MILEPOST_GCC":milepost_compiler_code_uoa})              # first MILEPOST GCC
00562        ii['code_deps'].append({"CM_CODE_DEP_CTUNING_CC_PLUGIN":ctuning_compiler_plugins_code_uoa})  # then cTuning CC plugins
00563        if compiler_code_uoa!='':
00564           ii['code_deps'].append({"CM_CODE_DEP_MAIN_COMPILER":compiler_code_uoa})                   # then real compiler if not default
00565 
00566        if len(ii.get('run_set_env2',{}))==0: ii['run_set_env2']={}
00567        if milepost_compiler_extract_after_pass!='': ii['run_set_env2']['ICI_PROG_FEAT_PASS']=milepost_compiler_extract_after_pass
00568 
00569        ici_structure='ici_passes_function.'
00570        ici_properties='ici_features_function.'
00571 
00572        # Clean old files
00573        if i.get('keep_all_files','')!='yes':
00574           dirList=os.listdir('.')
00575           for fn in dirList:
00576               if os.path.isfile(fn) and (fn.startswith(ici_structure) or fn.startswith(ici_properties)):
00577                  os.remove(fn)
00578 
00579        # Check if functions are selected
00580        if len(functions)>0:
00581           rx=cm_kernel.gen_uid({})
00582           if rx['cm_return']>0: return rx
00583           file_with_funcs=os.path.join(os.getcwd(), 'tmp-funcs-'+rx['cm_uid']+'.txt')
00584           f=open(file_with_funcs,'wt')
00585           for q in functions:
00586               f.write(q+'\n')
00587           f.close()
00588 
00589           ii['run_set_env2']['ICI_FILE_SELECT_FUNCTIONS']=file_with_funcs
00590 
00591        # Check which flags to use!
00592        #ii['run_set_env2']['CM_COMPILER_FLAGS_CC_OPTS']=''
00593 
00594        if i.get('keep_all_files','')!='':
00595           ii['keep_all_files']=i['keep_all_files']
00596 
00597        ii['ignore_script_error']='no'
00598        ii['skip_target_file_check']='yes'
00599 
00600        ii['run_script_uoa']=ini['cfg']['run_script_uoa']
00601        ii['run_script']=ini['cfg']['run_script']
00602 
00603        ii['run_cmd_out1']='tmp-build-output1.tmp'
00604        ii['run_cmd_out2']='tmp-build-output2.tmp'
00605 
00606        ii['cm_run_module_uoa']=ini['cfg']['cm_modules']['code.source']
00607        ii['cm_action']='build'
00608 
00609        # Building program to get program structure and extract features
00610        if vrb=='yes':
00611           cm_kernel.print_for_con('')
00612           cm_kernel.print_for_con('Building program ...')
00613 
00614        r=cm_kernel.access(ii)
00615        if r['cm_return']>0: return r
00616 
00617        ici_structure='ici_passes_function.'
00618        ici_properties='ici_features_function.'
00619 
00620        structure={}
00621 
00622        # Read program structure
00623        dirList=os.listdir('.')
00624        for fn in dirList:
00625            if os.path.isfile(fn):
00626               if fn.startswith(ici_structure):
00627                  i1=fn.find('.')
00628                  if i1>0:
00629                     i2=fn.find('.',i1+1)
00630                     if i2>0:
00631                        func=fn[i1+1:i2]
00632                        if func not in structure:
00633                           structure[func]={}
00634                        structure[func]['compiler_passes']=[]
00635                        f=open(fn,'rt')
00636                        l='x'
00637                        while (l != "" ):
00638                           l = f.readline().strip()
00639                           structure[func]['compiler_passes'].append(l)
00640                        f.close()
00641                        if i.get('keep_all_files','')!='yes':
00642                           os.remove(fn)
00643               elif fn.startswith(ici_properties):
00644                  i1=fn.find('.')
00645                  if i1>0:
00646                     i2=fn.find('.',i1+1)
00647                     if i2>0:
00648                        func=fn[i1+1:i2]
00649                        i3=fn.find('.',i2+1)
00650                        if i3>0:
00651                           ps=fn[i2+1:i3]
00652                           if func not in structure:
00653                              structure[func]={}
00654                           if 'program_static_properties' not in structure[func]:
00655                              structure[func]['program_static_properties']={}
00656                           if ps not in structure[func]['program_static_properties']:
00657                              structure[func]['program_static_properties'][ps]={}
00658                           f=open(fn,'rt')
00659                           l = f.readline().strip()
00660                           y=-1
00661                           while True:
00662                             y=l.find('ft', y+1)
00663                             if y>=0:
00664                                i1=l.find('=',y+1)
00665                                if i1>0:
00666                                   n=l[y+2:i1]
00667                                   i2=l.find(',',i1+1)
00668                                   if i2==-1: i2=len(l)
00669                                   v=l[i1+1:i2]
00670                                   structure[func]['program_static_properties'][ps][n]=v
00671                                else: break
00672                             else: break
00673                           f.close()
00674                           if i.get('keep_all_files','')!='yes':
00675                              os.remove(fn)
00676 
00677        if 'program_milepost_properties' not in of: of['program_milepost_properties']={}
00678        of['program_milepost_properties'].update(structure)
00679        changed=True
00680 
00681        if len(functions)>0:
00682           if os.path.isfile(file_with_funcs): os.remove(file_with_funcs)
00683 
00684        # Clean the file mess
00685        for q in ini['cfg']['clean_files']:
00686            if os.path.isfile(q): os.remove(q)
00687 
00688     # Select collective optimization from repository ******************************************************************
00689     elif mode=='select_collective_opt':
00690        if vrb=='yes':
00691           cm_kernel.print_for_con('')
00692           cm_kernel.print_for_con('cTuning mode: selecting collective optimization from a repository ...')
00693 
00694        opt_uid=i.get('ct_opt_uid','')
00695 
00696        if opt_uid!='':
00697           return {'cm_return':1, 'cm_error':'"opt_uid" is not defined'}
00698 
00699        if vrb=='yes':
00700           cm_kernel.print_for_con('')
00701           cm_kernel.print_for_con('Obtaining compiler flags from the repository ('+repo+') ...')
00702 
00703        ocdu=i.get('opt_class_data_uoa','')
00704        ocu=i.get('opt_class_uid','')
00705        to=i.get('tuning_objective','')
00706        
00707        if ocdu!='' and ocu!='' and to!='' and tccdu!='':
00708           r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['ctuning.compiler.optimizations'],
00709                               'cm_action':'load',
00710                               'cm_data_uoa':ocdu,
00711                               'cm_repo_uoa':repo})
00712           if r['cm_return']>0: return r
00713 
00714           d=r['cm_data_obj']['cfg']
00715 
00716           dx=d.get('opt_classes',{}).get(to,{})
00717 
00718           found=False
00719           for q in dx:
00720               if q.get('cm_uid','')==ocu:
00721                  found=True
00722                  break
00723 
00724           opt=q.get('prepared_compiler_flags','')
00725 
00726           cm_kernel.print_for_con('')
00727           if xcmd=='':
00728              cm_kernel.print_for_con('No optimization flags were detected for a target compiler ...')
00729           else:
00730              cm_kernel.print_for_con('Original flags:')
00731              cm_kernel.print_for_con(xcmd)
00732 
00733           if opt!='' and vrb=='yes':
00734              cm_kernel.print_for_con('')
00735              cm_kernel.print_for_con('Adding new flags ...')
00736 
00737           cmd=opt+' '+ycmd
00738 
00739     # Predict optimization based on similarities between programs *****************************************************
00740     if mode=='predict_opt':
00741        # Find first encountered features (for now for the first function - later add per function)
00742        ft={}
00743 
00744        q1=of.get('program_milepost_properties',{})
00745        qq={}
00746        for qf in q1:
00747            qx=q1[qf].get('program_static_properties',{})
00748            if len(qx)>0:
00749               kx=qx.keys()[0]
00750               ft=qx[kx]
00751               qq=qx
00752  
00753        if len(ft)>0:
00754           if vrb=='yes':
00755              cm_kernel.print_for_con('')
00756              cm_kernel.print_for_con('Extracted following features:')
00757              cm_kernel.print_for_con(json.dumps(ft))
00758 
00759              cm_kernel.print_for_con('')
00760              cm_kernel.print_for_con('Searching most close programs with speedups ...')
00761 
00762           pmp={'program_milepost_properties':{qf:qq}}
00763           r=cm_kernel.access({'cm_run_module_uoa':ini['cfg']['cm_modules']['ctuning.pipeline.build_and_run_program'],
00764                               'cm_action':'predict_opts',
00765                               'program_milepost_properties':ft,
00766                               'cm_submit_prune':'yes',
00767                               'opt_predictor':'nearest_neighbour', # FGG TBD: move outside
00768                               'pruning_similar_programs':i.get('pruning_similar_programs',{}),
00769                               'number_of_returned_items':i.get('number_of_returned_items',''),
00770                               'cm_repo_uoa':repo})
00771           if r['cm_return']>0: return r
00772 
00773 #          print json.dumps(r, indent=2)
00774 
00775           sp=r.get('similar_programs',[])
00776           if len(sp)==0:
00777              if vrb=='yes':
00778                 cm_kernel.print_for_con('')
00779                 cm_kernel.print_for_con('Close programs not found in the repository!')
00780  
00781           else:
00782              if vrb=='yes':
00783                 cm_kernel.print_for_con('')
00784                 cm_kernel.print_for_con('Found similar program(s) in the repository!')
00785 
00786              most_close_program=sp[0]
00787              if vrb=='yes':
00788                 cm_kernel.print_for_con('')
00789                 cm_kernel.print_for_con('Most close program: '+most_close_program['program_name']+' (distance='+most_close_program['milepost_distance']+')')
00790              
00791                 # Get only first speed up point
00792                 # FGG TBD: get/print more points with different speedups
00793                 spp=r['similar_programs_points']
00794                 sppi=r['similar_programs_points_improvements']
00795 
00796                 if len(spp)<1 or len(sppi)<1:
00797                    cm_kernel.print_for_con('')
00798                    cm_kernel.print_for_con('Solutions are not found for the most close program!')
00799                 else:
00800                    xspp=spp[1]
00801                    xsppi=sppi[1]
00802 
00803                    cm_kernel.print_for_con('Execution time speedup for the most close program: '+xsppi.get('#75581c4a4e4072c8#output#global_execution_time_div_by_repeat',''))
00804 
00805                    opt=xspp.get('#1048eba38df5b240#output#prepared_compiler_flags','')
00806 
00807                    cm_kernel.print_for_con('')
00808                    if xcmd=='':
00809                       cm_kernel.print_for_con('No optimization flags were detected for a target compiler ...')
00810                    else:
00811                       cm_kernel.print_for_con('Original flags:')
00812                       cm_kernel.print_for_con(xcmd)
00813 
00814                    if opt!='' and vrb=='yes':
00815                       cm_kernel.print_for_con('')
00816                       cm_kernel.print_for_con('Reusing new flags from most similar program from the repository ...')
00817 
00818                    cmd=opt+' '+ycmd
00819 
00820     # Write output file if needed
00821     if changed:
00822        if out_file!='':
00823           r=cm_kernel.save_array_to_file_as_json({'cm_filename':out_file, 'cm_array':of})
00824           if r['cm_return']>0: return r
00825 
00826     # Call default 
00827     if run_default_cmd:
00828        # Default cmd
00829        dcmd=dcn+' '+cmd
00830 
00831        if vrb=='yes':
00832           cm_kernel.print_for_con('')
00833           cm_kernel.print_for_con('Executing the following command:')
00834           cm_kernel.print_for_con('')
00835           cm_kernel.print_for_con(dcmd)
00836           cm_kernel.print_for_con('')
00837 
00838        if compiler_code_uoa!='':
00839           dcmd=xenv3+' cm_code_env_'+compiler_code_uoa+xenv4+' '+xenv5+' '+dcmd 
00840 
00841        r=os.system(dcmd)
00842 
00843        # Process return code
00844        if r>0:
00845           if r>255: r=r >> 8 # use only first 8 bits; the rest is usually the signal that killed process on Linux
00846           return{'cm_return':r, 'cm_error':'compiler returned non-zero code ('+str(r)+')'}
00847 
00848     return {'cm_return':0}
00849 
00850 # ============================================================================
00851 def prepare_environment(i):
00852 
00853     """
00854     Prepare environment
00855 
00856     Input:  {
00857             }
00858 
00859     Output: {
00860               cm_return       - if =0, success
00861             }
00862     """
00863 
00864 
00865     return {'cm_return':0}

Generated on Wed May 28 02:49:01 2014 for Collective Mind Framework by DoxyGen 1.6.1
Concept, design and coordination: Grigori Fursin (C) 1993-2013