class Banner : """create nt2 banner you can set a banner_template_begin and a banner_template_end as string lists but defaults are provided you can also define or add to the default list banner_cprth (copyrights) """ Std_begin = [ "//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", ] Std_end = [ "//@", "//@ Distributed under the Boost Software License, Version 1.0", "//@ See accompanying file LICENSE.txt or copy at", "//@ http://www.boost.org/LICENSE_1_0.txt", "//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", ] Std_cpght = [ "//@ Copyright 2003 and onward LASMEA UMR 6602 CNRS/U.B.P Clermont-Ferrand", "//@ Copyright 2009 and onward LRI UMR 8623 CNRS/Univ Paris Sud XI", ] def __init__(self, year = None, banner_cpght = None, banner_template_begin = None, banner_template_end = None, comment = '//') : self.logger = Mylogging("nt2.banner.Banner") self.__banner_begin = Banner.Std_begin if (banner_template_begin is None) else banner_template_begin self.__banner_end = Banner.Std_end if (banner_template_end is None) else banner_template_end self.__banner_cpght = Banner.Std_cpght if (banner_cpght is None) else banner_cpght self.__year = year self.__comment=comment self.set_year() self.cpght = sub_list('^//',self.__comment,self.__banner_cpght) self.__banner_begin = sub_list('^//',self.__comment,self.__banner_begin) self.__banner_end = sub_list('^//',self.__comment,self.__banner_end) self.__banner_cpght = sub_list('<year>',self.__year,self.__banner_cpght) self.__banner_cpght = sub_list('^//',self.__comment,self.__banner_cpght) self.__banner_begin = sub_list('@',self.__comment[0],self.__banner_begin) self.__banner_end = sub_list('@',self.__comment[0],self.__banner_end) self.__banner_cpght = sub_list('@',self.__comment[0],self.__banner_cpght) def add_cpght(self, cpght) : if type(cpght) is str : self.__banner_cpght.append(cpght) elif type(cpght) is list : self.__banner_cpght.extend(cpght) self.__banner_cpght = sub_list('<year>',self.__year,self.__banner_cpght) self.__banner_cpght = sub_list('^//',self.__comment,self.__banner_cpght) self.__banner_cpght = sub_list('@',self.__comment[0],self.__banner_cpght) def __str__(self) : return "\n".join(self.__call__()) def set_year(self) : if self.__year is None : self.__year = time.localtime().tm_year if type(self.__year) is not str : self.__year = str(self.__year) if len(self.__year)==1 : self.__year = '0'+self.__year if len(self.__year)==2 : self.__year = "20"+self.__year try : self.__year = str(int(self.__year)) except : saved_year =self.__year self.logger.warning( "\nin setyear\n"+ ("year has been given the incorrect value: %s" % self.__year) ) self.__year = str(time.localtime().tm_year) self.logger.warning( "\nin Banner.setyear\n "+ "year has been given the incorrect value: %s" % saved_year + "\nyear is turned to %s " % self.__year ) self.__banner_cpght = sub_list('<year>',self.__year,self.__banner_cpght) def get_banner(self) : """ return the complete banner """ return self.__banner_begin + self.__banner_cpght + self.__banner_end def __call__(self) : """ return the complete banner """ return self.__banner_begin + self.__banner_cpght + self.__banner_end def get_banner_begin(self) : """ return the high part of the banner """ return self.__banner_begin def get_banner_end(self) : """ return the low part of the banner """ return self.__banner_end def get_banner_cprght(self) : """ return the copyright part of the banner """ return self.__banner_cpght def get_year(self) : """ return the current end year of the copyright""" return self.__year
class Functor(Toolbox) : """adding/removing functors to a toolbox""" Fct_actions = { "" : { 'add' : { "file" : "../../include/functions/$fct_name$.hpp", "tmpl" : "gbl_include.tpl", "cmmt" : "//", "head" : 'full', }, 'mdy' : { "file" : "$root_name$.hpp", "l2ad" : "#include <$self.tb_pathfnt2$/include/$fct_name$.hpp>", "tokn" : "//<\include>", }, }, "bench/scalar" : { 'add' : { "file" : "$fct_name$.cpp", "tmpl" : "mk_cppbench.tpl", "cmmt" : "//", "head" : 'banner+inner', "parm" : "nt2::uint32_t", }, 'mdy' : { "file" : "CMakeLists.txt", "l2ad" : " $fct_name$.cpp", "tokn" : "SET\( SOURCES", }, }, "bench/simd" : { 'add' : { "file" : "$fct_name$.cpp", "tmpl" : "mk_cppbench.tpl", "cmmt" : "//", "head" : 'banner+inner', "parm" : "nt2::simd::native<float,nt2::tag::sse_>", }, 'mdy' : { "file" : "CMakeLists.txt", "l2ad" : " $fct_name$.cpp", "tokn" : "SET\( SOURCES", }, }, "doc/source" : { "add" : { "file" : "$fct_name$.rst", "tmpl" : "mk_doc.tpl", "cmmt" : " ", "head" : 'inner' }, }, "include" : { "add" : { "file" : "$fct_name$.hpp", "tmpl" : "mk_include.tpl", "cmmt" : "//", "head" : "full" } }, "function" : { "add" : { "file" : "$fct_name$.hpp", "tmpl" : "mk_define.tpl", "cmmt" : "//", "head" : "full" } }, "function/scalar" : { "add" : { "file" : "$fct_name$.hpp", "tmpl" : "mk_scalar.tpl", "cmmt" : "//", "head" : "full" } }, "function/simd/common" : { "add" : { "file" : "$fct_name$.hpp", "tmpl" : "mk_common.tpl", "cmmt" : "//", "head" : "full" } }, "function/simd/vmx" : { "hie" : { "file" : "$fct_name$.hpp", "hier" : Vmx(), "cmmt" : "//", "head" : "full" } }, "function/simd/sse" : { "hie" : { "file" : "$fct_name$.hpp", "hier" : Sse(), "cmmt" : "//", "head" : "full" } }, "unit/scalar" : { 'add' : { "file" : "$fct_name$.cpp", "tmpl" : "mk_cppunit.tpl", "cmmt" : "//", "head" : 'banner+inner' }, 'mdy' : { "file" : "CMakeLists.txt", "l2ad" : " $fct_name$.cpp", "tokn" : "SET\( SOURCES", }, }, "unit/simd" : { 'add' : { "file" : "$fct_name$.cpp", "tmpl" : "mk_cppunit_simd.tpl", "cmmt" : "//", "head" : 'banner+inner' }, 'mdy' : { "file" : "CMakeLists.txt", "l2ad" : " $fct_name$.cpp", "tokn" : "SET\( SOURCES", }, }, } def __init__(self, tool_box_name, mode = 'modify', style='usr', actions = None) : self.logger = Mylogging("nt2.fctor.Functor") Toolbox.__init__(self, tool_box_name, mode=mode, style=style) if not self.get_tb_status() and mode !='check' : self.logger.error( "\ntoolbox %s has invalid status\n" % self.get_tb_name() + "aborting" ) raise SystemExit self.__fct_actions = Functor.Fct_actions if actions is None else actions self.ext='.hpp' def get_fct_actions(self) : return self.__fct_actions def add_functor(self,fct_name,fct_arity=1) : "adding a new functor" self.read_style() def strlist(tpl,n=1,sep = ", ") : s = tpl % (n*(0,)) tpl =sep+tpl for i in range(1,fct_arity) : s += tpl % (n*(i,)) return s if self.get_tb_style()[0] != 's' : tb_taggedname = self.get_tb_name()+'::'+fct_name else : tb_taggedname = fct_name subs_dict = { "\$self.tb_name\$" : self.get_tb_name(), "\$self.tb_nameupper\$" : self.get_tb_name().upper(), "\$self.name\$" : fct_name, "\$self.arity\$" : str(fct_arity), "\$self.class_list\$" : strlist("class A%d"), "\$self.const_type_list\$" : strlist("A0",0), "\$self.const_class_list\$" : strlist("class A0",0), "\$self.type_list\$" : strlist("A%d"), "\$self.parm_list\$" : strlist("a%d"), "\$self.parm_list_j\$" : strlist("a%d[j]"), "\$self.const_type_T_list\$" : strlist("T",0), "\$self.const_type_n_t_list\$" : strlist("n_t",0), "\$self.gl_list\$" : strlist("// n_t a%d = load<n_t>(&data[0],%d);",2,"\n"), "\$self.call_list\$" : strlist("const A%d& a%d",2), "\$self.const_type_call_list\$" : strlist("const A0& a%d",1), "\$self.tb_namespace\$" : self.get_tb_namespace(), "\$self.tb_taggedname\$" : tb_taggedname, "\$parms_type_and_ranges\$" : strlist("(($parm$, -10, 10))",0,"\n//"+(17+len(fct_name))*' '), } for acts, datas in self.get_fct_actions().items() : action_names = self.get_fct_actions()[acts] for action_name, action_data in action_names.items() : action = getattr(Functor,action_name,None) action(self,fct_name,acts,subs_dict,action_data,check=True) def rmv_functor(self,fct_name) : "removing an existing functor" for acts, datas in self.get_fct_actions().items() : action_names = self.get_fct_actions()[acts] for action_name, action_data in action_names.items() : action_name = action_name[::-1] action = getattr(Functor,action_name,None) action(self,fct_name,acts,{},action_data,check=True) def add(self,fct_name,acts,subs_dict,action_data,check=True) : """add a file""" do_it = True fname = action_data["file"].replace('$fct_name$',fct_name) fct_name_path = os.path.abspath(os.path.join(self.get_tb_abs_path(),acts,fname)) if acts != "" : rel_path = os.path.join(self.get_tb_pathfnt2(),acts) else : rel_path = 'nt2/include/functions' do_it = self.get_tb_style()[0]=='s' if do_it : tplname = '../tpl/'+action_data["tmpl"] # print "action_data[tmpl] %s" % action_data["tmpl"] tpl_name_path = os.path.join(nt2_py_dir(),tplname) if "parm" in action_data.keys() : s = subs_dict["\$parms_type_and_ranges\$"] subs_dict["\$parms_type_and_ranges\$"] = re.sub('\$parm\$', action_data["parm"], s) subs_dict["\$acts\$"] = acts inner_text = self.__treat(read(tpl_name_path),subs_dict) if "parm" in action_data.keys() : subs_dict["\$parms_type_and_ranges\$"] = s comment = action_data["cmmt"] flag = action_data["head"] h = Headers(rel_path,fct_name,inner=inner_text,comment=comment) # print "fct_name_path %s" % fct_name_path h.write_header2(fct_name_path,flag=flag,check=check) def dda(self,fct_name,acts,subs_dict,action_data,check=True) : """remove a file: reverse of add""" fname = action_data["file"].replace('$fct_name$',fct_name) fct_name_path = os.path.abspath(os.path.join(self.get_tb_abs_path(),acts,fname)) os.remove(fct_name_path) def mdy(self,fct_name,acts,subs_dict,action_data,check=True) : """modify a file, inserting a line""" fname = action_data["file"].replace('$root_name$',self.get_tb_name()) file2modify = os.path.join(self.get_tb_abs_path(),acts,fname) text = read(file2modify) subs_dict["\$self.tb_pathfnt2\$"]=self.get_tb_pathfnt2() subs_dict["\$fct_name\$"]=fct_name line2add = self.__treat(action_data["l2ad"], subs_dict) token = action_data["tokn"] test, text = self.__add_line(text, line2add, token) if test : self.logger.info( "\nmodifying \n%s\nfor definition of functor %s\n" % (file2modify,fct_name) ) write(file2modify,text,False) else : self.logger.warning( "\nFile %s was already included\n" % fct_name + "in file\n%s\n" % file2modify ) def ydm(self,fct_name,acts,subs_dict,action_data,check=True) : """modify a file (reverse of mdy): deleting a line""" fname = action_data["file"].replace('$root_name$',self.get_tb_name()) file2modify = os.path.join(self.get_tb_abs_path(),acts,fname) text = read(file2modify) subs_dict["\$self.tb_pathfnt2\$"]=self.get_tb_pathfnt2() subs_dict["\$fct_name\$"]=fct_name line2rmv = self.__treat(action_data["l2ad"], subs_dict) test, text = self.__rmv_line(text, line2rmv) if test : self.logger.info( "\nmodifying \n%s\nfor definition of functor %s\n" % (file2modify,fct_name) ) write(file2modify,text,False) else : self.logger.warning( "\nFile %s was not present in file\n%s\n" % (fct_name,file2modify) ) def hie(self,fct_name,acts,subs_dict,action_data,check=True) : """create an include hierarchy for simd""" fname = action_data["file"].replace('$fct_name$',fct_name) path = os.path.join(self.get_tb_abs_path(),acts) hierarchy = action_data["hier"] cmmt = action_data["cmmt"] head = action_data["head"] relpath = os.path.join(self.get_tb_pathfnt2(),acts) relpathm1 = '/'.join(relpath.split('/')[:-1]) for base, prev in hierarchy.Variants.items() : file = os.path.join(path,base,fct_name+'.hpp') inner_text = ["#include <" + os.path.join(relpathm1, prev,fct_name + '.hpp>')] rpath = os.path.join(relpath,base) h = Headers(rpath,fct_name, inner=inner_text) h.write_header2(file,flag='full',check=check) def eih(self,fct_name,acts,subs_dict,action_data,check=True) : """delete an include hierarchy for simd(reverse of hie)""" path = os.path.join(self.get_tb_abs_path(),acts) hierarchy = action_data["hier"] for base, prev in hierarchy.Variants.items() : file = os.path.join(path,base,fct_name+'.hpp') os.remove(file) def __treat(self,s, subs_dict) : """__treat substitutes all $self.<id>$ chains in the string s with the value of the variable self.<id> if it exist else leaves it as is""" if type(s) is str : for k,v in subs_dict.items() : s = re.sub(k,str(v),s) return s elif type(s) is list : self.tb_name = self.get_tb_name() l= [] for ss in s : l.append(self.__treat(ss, subs_dict)) del self.tb_name return l def __add_line(self,text, line2add, token) : pattern = re.compile(line2add) def find_index(p) : for i,l in enumerate(text) : if p.match(l) : return i+1 return 0 if find_index(pattern) : return (False,text) else : #### match for token pattern = re.compile(token) i = find_index(pattern) if i != 0 : text.insert(i,line2add) return (True,text) def __rmv_line(self,text, line2rmv) : if line2rmv in text : text.remove(line2rmv) return (True,text) else : return (False,text) def read_functor(self,fct_name,type) : fct_name_path = os.path.join(self.get_tb_abs_path(),'function',type,fct_name+'.hpp') r = read(fct_name_path) return r def write_functor(self,fct_name,type,s,check) : fct_name_path = os.path.join(self.get_tb_abs_path(),'function',type,fct_name+'.hpp') r = write(fct_name_path,s,check)
class Toolbox(Nt2,Tb_files) : Tb_tree = [ "", "include", "src", "doc", "doc/source", "unit", "unit/scalar", "unit/simd", "bench", "bench/scalar", "bench/simd", "function", "function/scalar", "function/simd", "function/simd/common", "function/simd/vmx", "function/simd/vmx/common", "function/simd/vmx/altivec", "function/simd/vmx/spu", "function/simd/sse", "function/simd/sse/common", "function/simd/sse/sse2", "function/simd/sse/sse3", "function/simd/sse/ssse3", "function/simd/sse/sse4_1", "function/simd/sse/sse4_2", "function/simd/sse/avx", "function/simd/sse/sse4a", "function/simd/sse/xop", "function/simd/sse/fma4", ] Tb_files = { "" : { "py_data" : "py_data.py", "base" : "$root_name$", "root" : "$root_name$", "root_include" : "include.hpp", }, "bench" : { "inner" : "CMakeLists.txt" }, "bench/scalar" : { "scalar" : "CMakeLists.txt" }, "bench/simd" : { "simd" : "CMakeLists.txt", }, "unit" : { "inner" : "CMakeLists.txt" }, "unit/scalar" : { "scalar" : "CMakeLists.txt" }, "unit/simd" : { "simd" : "CMakeLists.txt", }, } def __init__(self, tool_box_name, mode = 'create', p2nt2 = None, style = 'usr') : """creation or recovery of a toolbox <tool_box_name> is the name of the toolbox <mode> is the opening mode. Proper modes are create(default) or modify create : creates a new toolbox tree under .../nt2/toolbox/ with the given <tool_box_name> provided that a directory of this name not existed previously (default) update : add all missing directories or files to an existing toolbox without modifying any existing files or directories modify : creates a new toolbox tree or allow access to an existing one to add or suppress functors extensions <p2nt2> is the path to nt2. The path defaults to the computation furnished by the Nt2 class <style> determines if the functors defined in the toolbox functors will reside in the namespace nt2 ('sys') or in the namespace <tool_box_name> ('usr'). It is only needed when mode is 'create' and is 'usr' by default. The other modes recover the creation parameter from existing data: in the present implementation, once created the toolbox mode cannot be modified. """ Mode = [ 'create', 'update', 'check', 'modify'] Style = ['usr','sys'] Nt2.__init__(self,'toolbox') self.__status = True self.logger = Mylogging("nt2.toolbox.Toolbox") if p2nt2 is None : p2nt2 = self.get_path2nt2() self.__tb_name = tool_box_name self.__tb_pathfnt2 = os.path.join(self.get_pathfnt2(),self.__tb_name) self.__tb = os.path.join(self.get_path2nt2(),self.__tb_pathfnt2) self.__tb_path2mode= os.path.join(self.get_path2nt2(),self.get_pathfnt2()) self.__tb_style = style if style == "sys" else "usr" if os.path.exists(self.get_tb_abs_path()) : self.read_style() self.__test_status = True self.__mode = mode self.__tb_tree = Toolbox.Tb_tree self.__tb_files= Toolbox.Tb_files Tb_files.__init__(self,self.__tb_name,self.__tb_path2mode, self.__tb_tree, self.__tb_files, style) if mode in Mode : self.logger.info( ("\nopening toolbox %s with mode: "% self.__tb_name) + mode+"\nin directory\n" + self.__tb ) action = getattr(self,mode+'_tbox') action() else: self.logger.error( "\nopening with unknown mode: "+mode+"\n"+ " raising SystemExit\n" ) raise SystemExit def get_tb_name(self) : return self.__tb_name def get_tb_pathfnt2(self) : return self.__tb_pathfnt2 def get_tb_abs_path(self) : return self.__tb def get_tb_path2mode(self) : return self.__tb_path2mode # def get_status(self) : return self.__status def get_tb_style (self) : return self.__tb_style def get_tb_namespace(self) : return "functors" if (self.__tb_style == "sys") else self.__tb_name def get_tb_mode(self) : return self.__mode def get_tb_status(self) : return self.__status def get_tb_tree(self) : return self.__tb_tree def get_tb_files(self) : return self.__tb_files def exist_tb(self) : return os.path.exists(self.get_tb_abs_path()) def create_tbox(self): """ create a toolbox tree and global files only if it does not exist""" if os.path.exists(self.get_tb_abs_path()) : self.__status = False self.logger.error( "\ntoolbox %s already exists\n" % self.get_tb_name() + "in path: %s\n" % self.get_tb_abs_path() + "please use another toolbox name\n" + "or delete the old one using remove_tbox " "before creating the new one\n" ) raise SystemExit else: self.create_tb_tree() self.create_tb_files() return self.__status def update_tbox(self): """ add missing directory and files to a toolbox without modifying any existing ones """ self.read_style() self.update_tb_tree() self.update_tb_files() return self.__status def check_tbox(self): """ check the toolbox integrity """ self.__status = self.check_tb_tree() and self.check_tb_files() if self.__status : self.read_style() return self.__status def rm_tbox(self): """ remove a toolbox tree and global files""" if os.path.exists(self.get_tb_abs_path()) : path = self.get_tb_abs_path() os.remove( path+'.hpp') shutil.rmtree(path,True) def modify_tbox(self): if not os.path.exists(self.get_tb_abs_path()) : self.logger.warning( "\ntoolbox %s does not exists\n" % self.get_tb_name() + "in path: %s\n" % self.get_tb_abs_path() + "\nIt will be created using 'usr' style" ) self.__tb_style = 'usr' self.create_tbox() self.read_style() return self.__status def read_style(self) : dirname = self.get_tb_abs_path() filename = os.path.join(dirname,'py_data.py') if exist(filename) : sys.path.insert(0,dirname) from py_data import datas s = datas['style'] sys.path.pop(0) self.__tb_style = s return s dirname = self.get_tb_path2mode() filename = os.path.join(dirname,self.get_tb_name()+'.hpp') if exist(filename) : s = read(filename) pattern = re.compile("^// This toolbox is of (.*) type") for l in s : d1 = re.match(pattern,l) if d1 : self.__tb_style = d1.groups() return d1 self.logger.warning( "\nno file allowing to determine the style of " % self.get_tb_name() + "longer exists.\nAssuming an usr toolbox.\n" ) self.__tb_style = 'usr' return 'usr'
class Tb_tree : """ creation and deletion of (empty) toolbox trees. <root_name> is the name of the root directory <root_abs_path> is the path to the root directory not including it <rel_tree> is the list of path from the root (not including it to be created or deleted) """ def __init__(self, root_name, root_abs_path, rel_tree) : self.logger = Mylogging("nt2.tb_tree.Tb_tree") self.__root_name = root_name self.__mk_rel_tree(rel_tree) self.__root_abs_path = root_abs_path def __mk_rel_tree (self,tree) : self.__rel_tree = [] for l in tree : self.__rel_tree.append(os.path.join( self.__root_name,l)) self.__rel_tree.sort() def get_root_name (self) : return self.__root_name def get_rel_tree (self) : return self.__rel_tree def get_root_abs_path(self) : return self.__root_abs_path def show_tb_tree(self) : for l in self.get_abs_tree() : print l def get_abs_tree(self) : r = [] for l in self.get_rel_tree() : r.append(os.path.join(self.get_root_abs_path(),l)) return r def create_tb_tree(self) : for l in self.get_abs_tree() : if not exist(l) : self.logger.info("\ncreating : \n%s" % l) mkdir(l) else : self.logger.warning("\ndirectory : \n%s\nalready exists" % l) def update_tb_tree(self) : for l in self.get_abs_tree() : if not exist(l) : self.logger.info("\ncreating : \n%s" % l) mkdir(l) def list_tb_tree(self) : return self.get_abs_tree() def check_tb_tree(self) : for l in self.get_abs_tree() : r = exist(l) if not r : self.logger.info("\ndirectory %s\ndoes not exist\n" % l) return False return True def remove_tb_tree(self) : r = self.get_abs_tree() r.reverse() for l in r : try : os.rmdir(l) self.logger.info("\ndirectory : \n%s\nhas been removed" % l) except (OsError) : self.logger.warning("\ndirectory : \n%s\nis not empty, so not removed" % l) def get_tb_tree_lack(self) : """return the list of non existing directories required for defined tree. Returns an empty list if the tree is full. """ r = [] for l in self.get_abs_tree() : if not exist(l) : r.append(l) return r