def Cfunction(includes=None, prefunc="", desc="", c_type="void", name=None, params=None, preloop="", body=None, loopopts="", postloop="", enableCparameters=True, rel_path_to_Cparams=os.path.join("./")): if name is None or params is None or body is None: # use "is None" instead of "==None", as the former is more correct. print("Cfunction() error: strings must be provided for function name, parameters, and body") sys.exit(1) func_prototype = c_type+" "+name+"("+params+")" include_Cparams_str = "" if enableCparameters: if "enable_SIMD" in loopopts or "SIMD_width" in body: # If using manual SIMD looping, SIMD_width will appear in body. include_Cparams_str = "#include \"" + os.path.join(rel_path_to_Cparams, "set_Cparameters-SIMD.h") + "\"\n" else: include_Cparams_str = "#include \"" + os.path.join(rel_path_to_Cparams, "set_Cparameters.h") + "\"\n" complete_func = "" if includes is not None: if not isinstance(includes, list): print("Error in Cfunction(name="+name+"): includes must be set to a list of strings") print("e.g., includes=[\"stdio.h\",\"stdlib.h\"] ; or None (default)") print("Found includes = " + str(includes)) sys.exit(1) for inc in includes: if "<" in inc: # for C++ style code e.g., #include <cstdio> complete_func += "#include " + inc + "\n" else: if "NRPy_basic_defines.h" in inc or "NRPy_function_prototypes.h" in inc or \ "SIMD_intrinsics.h" in inc: inc = os.path.join(rel_path_to_Cparams, inc) complete_func += "#include \"" + inc + "\"\n" # complete_func += "\n" if prefunc != "": complete_func += prefunc + "\n" def indent_Ccode(indent, Ccode): Ccodesplit = Ccode.splitlines() outstring = "" for i in range(len(Ccodesplit)): outstring += indent + Ccodesplit[i] + '\n' return outstring if desc != "": complete_func += "/*\n" + indent_Ccode(" * ", desc) + " */\n" complete_func += func_prototype + " {\n"+include_Cparams_str+preloop+"\n"+lp.simple_loop(loopopts, body)+postloop+"}\n" return func_prototype+";", complete_func
def Cfunction(includes=None, prefunc="", desc="", type="void", name=None, params=None, preloop="", body=None, loopopts="", postloop="", opts="", rel_path_to_Cparams=os.path.join("./")): if name is None or params is None or body is None: # use "is None" instead of "==None", as the former is more correct. print("Cfunction() error: strings must be provided for function name, parameters, and body") sys.exit(1) func_prototype = type+" "+name+"("+params+")" include_Cparams_str = "" if "DisableCparameters" not in opts: if "EnableSIMD" in loopopts: include_Cparams_str = "#include \"" + os.path.join(rel_path_to_Cparams, "set_Cparameters-SIMD.h") + "\"\n" else: include_Cparams_str = "#include \"" + os.path.join(rel_path_to_Cparams, "set_Cparameters.h") + "\"\n" complete_func = "" if includes is not None: if not isinstance(includes, list): print("Error in outCfunction(): includes must be set to a list of strings") print("e.g., includes=[\"stdio.h\",\"stdlib.h\"] ; or None (default)") sys.exit(1) for inc in includes: complete_func += "#include \"" + inc + "\"\n" complete_func += "\n" if prefunc != "": complete_func += prefunc + "\n" def indent_Ccode(indent, Ccode): Ccodesplit = Ccode.splitlines() outstring = "" for i in range(len(Ccodesplit)): outstring += indent + Ccodesplit[i] + '\n' return outstring if desc != "": complete_func += "/*\n" + indent_Ccode(" * ", desc) + " */\n" complete_func += func_prototype + " {\n"+include_Cparams_str+preloop+"\n"+lp.simple_loop(loopopts,body)+postloop+"}\n" return func_prototype+";", complete_func
def Cfunction(desc="", type="void", name=None, params=None, preloop="", body=None, loopopts="", postloop="", opts=""): if name == None or params == None or body == None: print( "Cfunction() error: strings must be provided for function name, parameters, and body" ) sys.exit(1) func_prototype = type + " " + name + "(" + params + ")" include_Cparams_str = "" if not "DisableCparameters" in opts: if "EnableSIMD" in loopopts: include_Cparams_str = "#include \"set_Cparameters-SIMD.h\"\n" else: include_Cparams_str = "#include \"set_Cparameters.h\"\n" complete_func = "" if desc != "": complete_func = "/*\n" + desc + "\n */\n" complete_func += func_prototype + " {\n" + include_Cparams_str + preloop + "\n" + lp.simple_loop( loopopts, body) + postloop + "}\n" return func_prototype + ";", complete_func
def add_Ricci_eval_to_Cfunction_dict( includes=None, rel_path_to_Cparams=os.path.join("."), enable_rfm_precompute=True, enable_golden_kernels=False, enable_SIMD=True, enable_split_for_optimizations_doesnt_help=False, OMP_pragma_on="i2", func_name_suffix=""): if includes is None: includes = [] if enable_SIMD: includes += [os.path.join("SIMD", "SIMD_intrinsics.h")] enable_FD_functions = bool( par.parval_from_str("finite_difference::enable_FD_functions")) if enable_FD_functions: includes += ["finite_difference_functions.h"] # Set up the C function for the 3-Ricci tensor desc = "Evaluate the 3-Ricci tensor" name = "Ricci_eval" + func_name_suffix params = "const paramstruct *restrict params, " if enable_rfm_precompute: params += "const rfm_struct *restrict rfmstruct, " else: params += "REAL *xx[3], " params += "const REAL *restrict in_gfs, REAL *restrict auxevol_gfs" # Construct body: Ricci_SymbExpressions = Ricci__generate_symbolic_expressions() FD_outCparams = "outCverbose=False,enable_SIMD=" + str(enable_SIMD) FD_outCparams += ",GoldenKernelsEnable=" + str(enable_golden_kernels) loopopts = get_loopopts("InteriorPoints", enable_SIMD, enable_rfm_precompute, OMP_pragma_on) FDorder = par.parval_from_str("finite_difference::FD_CENTDERIVS_ORDER") starttime = print_msg_with_timing("3-Ricci tensor (FD order=" + str(FDorder) + ")", msg="Ccodegen", startstop="start") # Construct body: preloop = "" enableCparameters = True # Set up preloop in case we're outputting code for the Einstein Toolkit (ETK) if par.parval_from_str("grid::GridFuncMemAccess") == "ETK": params, preloop = set_ETK_func_params_preloop(func_name_suffix) enableCparameters = False if enable_split_for_optimizations_doesnt_help and FDorder >= 8: loopopts += ",DisableOpenMP" Ricci_SymbExpressions_pt1 = [] Ricci_SymbExpressions_pt2 = [] for lhsrhs in Ricci_SymbExpressions: if "RBARDD00" in lhsrhs.lhs or "RBARDD11" in lhsrhs.lhs or "RBARDD22" in lhsrhs.lhs: Ricci_SymbExpressions_pt1.append( lhrh(lhs=lhsrhs.lhs, rhs=lhsrhs.rhs)) else: Ricci_SymbExpressions_pt2.append( lhrh(lhs=lhsrhs.lhs, rhs=lhsrhs.rhs)) preloop = """#pragma omp parallel { #pragma omp for """ preloopbody = fin.FD_outputC("returnstring", Ricci_SymbExpressions_pt1, params=FD_outCparams) preloop += lp.simple_loop(loopopts, preloopbody) preloop += "#pragma omp for\n" body = fin.FD_outputC("returnstring", Ricci_SymbExpressions_pt2, params=FD_outCparams) postloop = "\n } // END #pragma omp parallel\n" else: body = fin.FD_outputC("returnstring", Ricci_SymbExpressions, params=FD_outCparams) postloop = "" print_msg_with_timing("3-Ricci tensor (FD order=" + str(FDorder) + ")", msg="Ccodegen", startstop="stop", starttime=starttime) add_to_Cfunction_dict(includes=includes, desc=desc, name=name, params=params, preloop=preloop, body=body, loopopts=loopopts, postloop=postloop, rel_path_to_Cparams=rel_path_to_Cparams, enableCparameters=enableCparameters) return pickle_NRPy_env()
def add_rhs_eval_to_Cfunction_dict( includes=None, rel_path_to_Cparams=os.path.join("."), enable_rfm_precompute=True, enable_golden_kernels=False, enable_SIMD=True, enable_split_for_optimizations_doesnt_help=False, LapseCondition="OnePlusLog", ShiftCondition="GammaDriving2ndOrder_Covariant", enable_KreissOliger_dissipation=False, enable_stress_energy_source_terms=False, leave_Ricci_symbolic=True, OMP_pragma_on="i2", func_name_suffix=""): if includes is None: includes = [] if enable_SIMD: includes += [os.path.join("SIMD", "SIMD_intrinsics.h")] enable_FD_functions = bool( par.parval_from_str("finite_difference::enable_FD_functions")) if enable_FD_functions: includes += ["finite_difference_functions.h"] # Set up the C function for the BSSN RHSs desc = "Evaluate the BSSN RHSs" name = "rhs_eval" + func_name_suffix params = "const paramstruct *restrict params, " if enable_rfm_precompute: params += "const rfm_struct *restrict rfmstruct, " else: params += "REAL *xx[3], " params += """ const REAL *restrict auxevol_gfs,const REAL *restrict in_gfs,REAL *restrict rhs_gfs""" betaU, BSSN_RHSs_SymbExpressions = \ BSSN_RHSs__generate_symbolic_expressions(LapseCondition=LapseCondition, ShiftCondition=ShiftCondition, enable_KreissOliger_dissipation=enable_KreissOliger_dissipation, enable_stress_energy_source_terms=enable_stress_energy_source_terms, leave_Ricci_symbolic=leave_Ricci_symbolic) # Construct body: preloop = "" enableCparameters = True # Set up preloop in case we're outputting code for the Einstein Toolkit (ETK) if par.parval_from_str("grid::GridFuncMemAccess") == "ETK": params, preloop = set_ETK_func_params_preloop(func_name_suffix) enableCparameters = False FD_outCparams = "outCverbose=False,enable_SIMD=" + str(enable_SIMD) FD_outCparams += ",GoldenKernelsEnable=" + str(enable_golden_kernels) loopopts = get_loopopts("InteriorPoints", enable_SIMD, enable_rfm_precompute, OMP_pragma_on) FDorder = par.parval_from_str("finite_difference::FD_CENTDERIVS_ORDER") starttime = print_msg_with_timing("BSSN_RHSs (FD order=" + str(FDorder) + ")", msg="Ccodegen", startstop="start") if enable_split_for_optimizations_doesnt_help and FDorder == 6: loopopts += ",DisableOpenMP" BSSN_RHSs_SymbExpressions_pt1 = [] BSSN_RHSs_SymbExpressions_pt2 = [] for lhsrhs in BSSN_RHSs_SymbExpressions: if "BETU" in lhsrhs.lhs or "LAMBDAU" in lhsrhs.lhs: BSSN_RHSs_SymbExpressions_pt1.append( lhrh(lhs=lhsrhs.lhs, rhs=lhsrhs.rhs)) else: BSSN_RHSs_SymbExpressions_pt2.append( lhrh(lhs=lhsrhs.lhs, rhs=lhsrhs.rhs)) preloop += """#pragma omp parallel { """ preloopbody = fin.FD_outputC("returnstring", BSSN_RHSs_SymbExpressions_pt1, params=FD_outCparams, upwindcontrolvec=betaU) preloop += "\n#pragma omp for\n" + lp.simple_loop( loopopts, preloopbody) preloop += "\n#pragma omp for\n" body = fin.FD_outputC("returnstring", BSSN_RHSs_SymbExpressions_pt2, params=FD_outCparams, upwindcontrolvec=betaU) postloop = "\n } // END #pragma omp parallel\n" else: preloop += "" body = fin.FD_outputC("returnstring", BSSN_RHSs_SymbExpressions, params=FD_outCparams, upwindcontrolvec=betaU) postloop = "" print_msg_with_timing("BSSN_RHSs (FD order=" + str(FDorder) + ")", msg="Ccodegen", startstop="stop", starttime=starttime) add_to_Cfunction_dict(includes=includes, desc=desc, name=name, params=params, preloop=preloop, body=body, loopopts=loopopts, postloop=postloop, rel_path_to_Cparams=rel_path_to_Cparams, enableCparameters=enableCparameters) return pickle_NRPy_env()
def Cfunction(desc="", type="void", name=None, params=None, preloop="", body=None, loopopts="", postloop="", opts="", rel_path_for_Cparams=os.path.join("./")): if name is None or params is None or body is None: # use "is None" instead of "==None", as the former is more correct. print( "Cfunction() error: strings must be provided for function name, parameters, and body" ) sys.exit(1) func_prototype = type + " " + name + "(" + params + ")" include_Cparams_str = "" if "DisableCparameters" not in opts: if "EnableSIMD" in loopopts: include_Cparams_str = "#include \"" + os.path.join( rel_path_for_Cparams, "set_Cparameters-SIMD.h") + "\"\n" else: include_Cparams_str = "#include \"" + os.path.join( rel_path_for_Cparams, "set_Cparameters.h") + "\"\n" complete_func = "" if desc != "": complete_func = "/*\n" + desc + "\n */\n" complete_func += func_prototype + " {\n" + include_Cparams_str + preloop + "\n" + lp.simple_loop( loopopts, body) + postloop + "}\n" return func_prototype + ";", complete_func