diff options
-rw-r--r-- | Auxiliary/Cactus/KrancNumericalTools/GenericFD/interface.ccl | 1 | ||||
-rw-r--r-- | Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/GenericFD.h | 48 | ||||
-rw-r--r-- | Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/Vectors.hh | 236 | ||||
-rw-r--r-- | Tools/CodeGen/CalculationFunction.m | 8 | ||||
-rw-r--r-- | Tools/CodeGen/CodeGen.m | 34 | ||||
-rw-r--r-- | Tools/CodeGen/Differencing.m | 8 | ||||
-rw-r--r-- | Tools/CodeGen/KrancThorn.m | 2 | ||||
-rw-r--r-- | Tools/CodeGen/Thorn.m | 2 |
8 files changed, 282 insertions, 57 deletions
diff --git a/Auxiliary/Cactus/KrancNumericalTools/GenericFD/interface.ccl b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/interface.ccl index ccc3785..efbdaa6 100644 --- a/Auxiliary/Cactus/KrancNumericalTools/GenericFD/interface.ccl +++ b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/interface.ccl @@ -7,6 +7,7 @@ implements: GenericFD INCLUDE HEADER: GenericFD.h in GenericFD.h +INCLUDE HEADER: Vectors.hh in Vectors.hh INCLUDE HEADER: sbp_calc_coeffs.h in sbp_calc_coeffs.h USES INCLUDE: Boundary.h diff --git a/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/GenericFD.h b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/GenericFD.h index db74360..c9c9586 100644 --- a/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/GenericFD.h +++ b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/GenericFD.h @@ -27,7 +27,11 @@ along with Kranc; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + +#ifdef __cplusplus +extern "C" { +#endif + #ifndef NOPRECOMPUTE #define PRECOMPUTE #endif @@ -673,6 +677,14 @@ int sgn(CCTK_REAL x); #define Dupwind3(gf,dir,i,j,k) ((dir * gf[CCTK_GFINDEX3D(cctkGH,i,j,k+dir)] \ - dir * gf[CCTK_GFINDEX3D(cctkGH,i,j,k)]) * dxi) +#ifdef __cplusplus +// Define the restrict qualifier +# ifdef CCTK_CXX_RESTRICT +# undef restrict +# define restrict CCTK_CXX_RESTRICT +# endif +#endif + void GenericFD_GetBoundaryInfo(cGH const * restrict cctkGH, int const * restrict cctk_lsh, int const * restrict cctk_lssh, @@ -788,38 +800,8 @@ void GenericFD_LoopOverInterior(cGH const * restrict cctkGH, Kranc_Calculation c -/* Vectorisation of memory accesses */ - -#include <stdlib.h> -#include <cctk.h> - -#if defined(__SSE2__) && defined(CCTK_REAL_PRECISION_8) - -#include <emmintrin.h> - -/* A vector type corresponding to CCTK_REAL */ -typedef __m128d CCTK_REAL_VEC; - -/* Really only SSE is required, but there doesn't seem to be a - preprocessing flag to check for this */ -#elif defined(__SSE2__) && defined(CCTK_REAL_PRECISION_4) - -#include <emmintrin.h> - -/* A vector type corresponding to CCTK_REAL */ -typedef __m128 CCTK_REAL_VEC; - -#else - -/* There is no vector type corresponding to CCTK_REAL */ -typedef CCTK_REAL CCTK_REAL_VEC; - +#ifdef __cplusplus +} /* extern "C" */ #endif -/* The number of vector elements in a CCTK_REAL_VEC */ -static -size_t const CCTK_REAL_VEC_SIZE = sizeof(CCTK_REAL_VEC) / sizeof(CCTK_REAL); - - - #endif diff --git a/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/Vectors.hh b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/Vectors.hh new file mode 100644 index 0000000..3fb77e1 --- /dev/null +++ b/Auxiliary/Cactus/KrancNumericalTools/GenericFD/src/Vectors.hh @@ -0,0 +1,236 @@ +#ifndef VECTORS_HH +#define VECTORS_HH + + + +// Vectorisation + +#include <math.h> +#include <stdlib.h> +#include <cctk.h> + + + +// I: i,j: integer +// R: a,b: real +// V: x,y: vector (of real) +// P: p,q: pointer (i.e. const reference) to something +// L: l,m: L-value (i.e. non-const reference) to something + +#define DEFINE_FUNCTION_PR_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL const& p) \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_PRV(name,expr) \ +inline \ +void name (CCTK_REAL& p, CCTK_REAL_VEC const& x) \ +{ \ + expr; \ +} + +#define DEFINE_FUNCTION_PVR(name,expr) \ +inline \ +void name (CCTK_REAL_VEC& p, CCTK_REAL const& a) \ +{ \ + expr; \ +} + +#define DEFINE_FUNCTION_V_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL_VEC const& x) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return CCTK_REAL_VEC(expr); \ +} + +#define DEFINE_FUNCTION_V_R(name,expr) \ +inline \ +CCTK_REAL name (CCTK_REAL_VEC const& x) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_R_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL const& a) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_VV_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL_VEC const& x, CCTK_REAL_VEC const& y) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_VR_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL_VEC const& x, CCTK_REAL const& a) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_RV_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL const& a, CCTK_REAL_VEC const& x) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + +#define DEFINE_FUNCTION_RR_V(name,expr) \ +inline \ +CCTK_REAL_VEC name (CCTK_REAL const& a, CCTK_REAL const& b) \ + CCTK_ATTRIBUTE_PURE \ +{ \ + return expr; \ +} + + + +// Intel, double +#if defined(KRANC_VECTORS) && defined(__SSE2__) && defined(CCTK_REAL_PRECISION_8) + +#include <emmintrin.h> + +// Vector type corresponding to CCTK_REAL +struct CCTK_REAL_VEC { + // The underlying scalar and vector types + typedef double S; + typedef __m128d V; + static int const n = sizeof(V)/sizeof(S); + V v; + + // Set a vector from scalars + CCTK_REAL_VEC(S const& a, S const& b): v(_mm_set_pd(a,b)) { }; + + // Get a scalar from the vector + S elt0() const { return _mm_cvtsd_f64(v); /* this is a no-op */ } + S elt1() const { return _mm_cvtsd_f64(_mm_shuffle_pd(v,v,_MM_SHUFFLE2(1,1))); } + + // Set a vector from a scalar, replicating the scalar + CCTK_REAL_VEC(S const& a): v(_mm_set1_pd(a)) { }; + + // Convert from and to the underlying vector type + CCTK_REAL_VEC(V const& v_): v(v_) { }; + operator V const() const { return v; } + + CCTK_REAL_VEC() { }; + + // Copy constructor + CCTK_REAL_VEC(CCTK_REAL_VEC const& x): v(x) { }; +}; + +// Load a vector from memory (aligned and unaligned); this loads from +// a reference to a scalar +DEFINE_FUNCTION_PR_V(vec_load,_mm_load_pd(&p)); +DEFINE_FUNCTION_PR_V(vec_loadu,_mm_loadu_pd(&p)); + +// Store a vector to memory (aligned and non-temporal); this stores to +// a reference to a scalar +DEFINE_FUNCTION_PRV(vec_store,_mm_store_pd(&p,x)) +DEFINE_FUNCTION_PRV(vec_store_nta,_mm_stream_pd(&p,x)) + +// Double-argument operators, both vectors +DEFINE_FUNCTION_VV_V(operator+,_mm_add_pd(x,y)) +DEFINE_FUNCTION_VV_V(operator-,_mm_sub_pd(x,y)) +DEFINE_FUNCTION_VV_V(operator*,_mm_mul_pd(x,y)) +DEFINE_FUNCTION_VV_V(operator/,_mm_div_pd(x,y)) + +// Double-argument operators, vector and scalar +DEFINE_FUNCTION_VR_V(operator+,x+CCTK_REAL_VEC(a)) +DEFINE_FUNCTION_VR_V(operator-,x-CCTK_REAL_VEC(a)) +DEFINE_FUNCTION_VR_V(operator*,x*CCTK_REAL_VEC(a)) +DEFINE_FUNCTION_VR_V(operator/,x/CCTK_REAL_VEC(a)) + +// Double-argument operators, scalar and vector +DEFINE_FUNCTION_RV_V(operator+,CCTK_REAL_VEC(a)+x) +DEFINE_FUNCTION_RV_V(operator-,CCTK_REAL_VEC(a)-x) +DEFINE_FUNCTION_RV_V(operator*,CCTK_REAL_VEC(a)*x) +DEFINE_FUNCTION_RV_V(operator/,CCTK_REAL_VEC(a)/x) + +// Single-argument operators +DEFINE_FUNCTION_V_V(operator+,x) +DEFINE_FUNCTION_V_V(operator-,0.0-x) + +// Cheap functions +static union { + unsigned long long const bits[2]; + CCTK_REAL_VEC::V v; +} const fabs_mask = + { { 0x7fffffffffffffffULL, 0x7fffffffffffffffULL } }; +DEFINE_FUNCTION_V_V(fabs,_mm_and_pd(x,fabs_mask.v)) +DEFINE_FUNCTION_VV_V(fmax,_mm_max_pd(x,y)) +DEFINE_FUNCTION_VV_V(fmin,_mm_min_pd(x,y)) +DEFINE_FUNCTION_V_V(sqrt,_mm_sqrt_pd(x)) + +// Expensive functions +DEFINE_FUNCTION_V_V(exp,CCTK_REAL_VEC(exp(x.elt0()),exp(x.elt1()))) +DEFINE_FUNCTION_V_V(log,CCTK_REAL_VEC(log(x.elt0()),log(x.elt1()))) +DEFINE_FUNCTION_VR_V(pow,CCTK_REAL_VEC(pow(x.elt0(),a),pow(x.elt1(),a))) + +// Un-implemented functions +DEFINE_FUNCTION_V_R(signbit,0) + + + +#if 0 +// Intel, float +#elif defined(KRANC_VECTORS) && defined(__SSE__) && defined(CCTK_REAL_PRECISION_4) + +#include <xmmintrin.h> + +// A vector type corresponding to CCTK_REAL +typedef __m128 CCTK_REAL_VEC; +#endif + + + +// Fallback: no vectorisation +#else + +// There is no vector type corresponding to CCTK_REAL +typedef CCTK_REAL CCTK_REAL_VEC; + + + +DEFINE_FUNCTION_PR_V(vec_load,p) +DEFINE_FUNCTION_PR_V(vec_loadu,p) + +DEFINE_FUNCTION_PRV(vec_store,p=x) +DEFINE_FUNCTION_PRV(vec_store_nta,p=x) + +DEFINE_FUNCTION_V_R(signbit,x<0) + + + +#endif + + + +#undef DEFINE_FUNCTION_PR_V +#undef DEFINE_FUNCTION_PRV +#undef DEFINE_FUNCTION_V_V +#undef DEFINE_FUNCTION_R_V +#undef DEFINE_FUNCTION_VV_V +#undef DEFINE_FUNCTION_VR_V +#undef DEFINE_FUNCTION_RV_V +#undef DEFINE_FUNCTION_RR_V + + + +// Number of vector elements in a CCTK_REAL_VEC +static +size_t const CCTK_REAL_VEC_SIZE = sizeof(CCTK_REAL_VEC) / sizeof(CCTK_REAL); + + + +#endif // #ifndef VECTORS_HH diff --git a/Tools/CodeGen/CalculationFunction.m b/Tools/CodeGen/CalculationFunction.m index 295fd5e..9f10c55 100644 --- a/Tools/CodeGen/CalculationFunction.m +++ b/Tools/CodeGen/CalculationFunction.m @@ -239,7 +239,7 @@ simpCollect[collectList_, eqrhs_, localvar_, debug_] := assignVariableFromExpression[dest_, expr_, declare_] := Module[{tSym, type, cleanExpr, code}, tSym = Unique[]; - type = If[StringMatchQ[ToString[dest], "dir*"], "int", "CCTK_REAL"]; + type = If[StringMatchQ[ToString[dest], "dir*"], "int", "CCTK_REAL_VEC"]; cleanExpr = ReplacePowers[expr] /. sym`t -> tSym; If[SOURCELANGUAGE == "C", @@ -402,7 +402,7 @@ CreateCalculationFunction[calc_, debug_, useCSE_, opts:OptionsPattern[]] := "Calculation is:", cleancalc]]; { - DefineFunction[bodyFunctionName, "void", "cGH const * restrict const cctkGH, int const dir, int const face, CCTK_REAL const normal[3], CCTK_REAL const tangentA[3], CCTK_REAL const tangentB[3], int const min[3], int const max[3], int const n_subblock_gfs, CCTK_REAL * restrict const subblock_gfs[]", + DefineFunction[bodyFunctionName, "static void", "cGH const * restrict const cctkGH, int const dir, int const face, CCTK_REAL const normal[3], CCTK_REAL const tangentA[3], CCTK_REAL const tangentB[3], int const min[3], int const max[3], int const n_subblock_gfs, CCTK_REAL * restrict const subblock_gfs[]", { "DECLARE_CCTK_ARGUMENTS;\n", "DECLARE_CCTK_PARAMETERS;\n\n", @@ -541,7 +541,7 @@ equationLoop[eqs_, cleancalc_, gfs_, shorts_, incs_, groups_, pddefs_, CommentedBlock["Assign local copies of grid functions", Map[DeclareMaybeAssignVariableInLoop[ - "CCTK_REAL", localName[#], GridName[#], + "CCTK_REAL_VEC", localName[#], GridName[#], StringMatchQ[ToString[GridName[#]], "eT" ~~ _ ~~ _ ~~ "[" ~~ __ ~~ "]"], "*stress_energy_state"] &, gfsInRHS]], @@ -559,7 +559,7 @@ equationLoop[eqs_, cleancalc_, gfs_, shorts_, incs_, groups_, pddefs_, ""], CommentedBlock["Copy local copies back to grid functions", - Map[AssignVariableInLoop[GridName[#], localName[#]] &, + Map[StoreVariableInLoop[GridName[#], localName[#]] &, gfsInLHS]], If[debugInLoop, Map[InfoVariable[GridName[#]] &, gfsInLHS], ""]}, opts]]; diff --git a/Tools/CodeGen/CodeGen.m b/Tools/CodeGen/CodeGen.m index e1776ad..d45fea9 100644 --- a/Tools/CodeGen/CodeGen.m +++ b/Tools/CodeGen/CodeGen.m @@ -64,14 +64,16 @@ DeclareAssignVariable::usage = "DeclareAssignVariable[type_, dest_, src_] return "that declares and sets a constant variable of given name and type."; AssignVariableInLoop::usage = "AssignVariableInLoop[dest_, src_] returns a block of code " <> "that assigns 'src' to 'dest'."; +StoreVariableInLoop::usage = "StoreVariableInLoop[dest_, src_] returns a block of code " <> + "that assigns 'src' to 'dest'."; DeclareAssignVariableInLoop::usage = "DeclareAssignVariableInLoop[type_, dest_, src_] returns a block of code " <> "that assigns 'src' to 'dest'."; MaybeAssignVariableInLoop::usage = "MaybeAssignVariableInLoop[dest_, src_, cond_] returns a block of code " <> "that assigns 'src' to 'dest'."; DeclareMaybeAssignVariableInLoop::usage = "DeclareMaybeAssignVariableInLoop[type_, dest_, src_, cond_] returns a block of code " <> "that assigns 'src' to 'dest'."; -DeclareVariablesInLoopVectorised::usage = ""; -AssignVariablesInLoopVectorised::usage = ""; +UNUSEDDeclareVariablesInLoopVectorised::usage = ""; +UNUSEDAssignVariablesInLoopVectorised::usage = ""; TestForNaN::usage = "TestForNaN[expr_] returns a block of code " <> "that tests 'expr' for nan."; CommentedBlock::usage = "CommentedBlock[comment, block] returns a block consisting " <> @@ -132,11 +134,11 @@ PartitionVarList::usage = ""; Begin["`Private`"]; SOURCELANGUAGE = "C"; -SOURCESUFFIX = ".c"; +SOURCESUFFIX = ".cc"; setSourceSuffix[lang_] := If[ (lang == "C"), - SOURCESUFFIX = ".c"; + SOURCESUFFIX = ".cc"; , SOURCESUFFIX = ".F90"; ]; @@ -149,7 +151,7 @@ If[ (lang == "C" || lang == "Fortran"), InfoMessage[Terse, "User set source language to " <> lang], SOURCELANGUAGE = "C"; - setSourceSuffix[".c"]; + setSourceSuffix[".cc"]; InfoMessage[Terse, "Setting Source Language to C"]; ]; @@ -283,21 +285,24 @@ AssignVariableInLoop[dest_, src_] := TestForNaN[dest]}; *) +StoreVariableInLoop[dest_, src_] := + {"vec_store_nta(", dest, ",", src, ")", EOL[]}; + DeclareAssignVariableInLoop[type_, dest_, src_] := - {type, " const ", dest, " = ", src, EOL[]}; + {type, " const ", dest, " = vec_load(", src, ")", EOL[]}; MaybeAssignVariableInLoop[dest_, src_, cond_] := If [cond, - {dest, " = useMatter ? ", src, " : 0.0", EOL[]}, - {dest, " = ", src, EOL[]}]; + {dest, " = useMatter ? vec_load(", src, ") : 0.0", EOL[]}, + {dest, " = vec_load(", src, ")", EOL[]}]; DeclareMaybeAssignVariableInLoop[type_, dest_, src_, mmaCond_, codeCond_] := If [mmaCond, - {type, " ", dest, " = (", codeCond, ") ? (", src, ") : 0.0", EOL[]}, - {type, " ", dest, " = ", src, EOL[]}]; + {type, " ", dest, " = (", codeCond, ") ? vec_load(", src, ") : 0.0", EOL[]}, + {type, " ", dest, " = vec_load(", src, ")", EOL[]}]; (* TODO: move these into OpenMP loop *) -DeclareVariablesInLoopVectorised[dests_, temps_, srcs_] := +UNUSEDDeclareVariablesInLoopVectorised[dests_, temps_, srcs_] := { {"#undef LC_PRELOOP_STATEMENTS", "\n"}, {"#define LC_PRELOOP_STATEMENTS", " \\\n"}, @@ -310,7 +315,7 @@ DeclareVariablesInLoopVectorised[dests_, temps_, srcs_] := {"\n"} }; -AssignVariablesInLoopVectorised[dests_, temps_, srcs_] := +UNUSEDAssignVariablesInLoopVectorised[dests_, temps_, srcs_] := { {"{\n"}, {" if (i < GFD_imin || i >= GFD_imax) {\n"}, @@ -337,7 +342,7 @@ AssignVariablesInLoopVectorised[dests_, temps_, srcs_] := {"}\n"} }; -AssignVariableInLoopsVectorised[dest_, temp_, src_] := +UNUSEDAssignVariableInLoopsVectorised[dest_, temp_, src_] := {"GFD_save_and_store(", dest, ",", "index", ",", "&", temp, ",", src, ")", EOL[]}; TestForNaN[expr_] := @@ -409,7 +414,7 @@ defineSubroutine[name_, args_, contents_] := defineSubroutineC[name_, args_, contents_] := SeparatedBlock[ - {"void ", name, "(", args, ")", "\n", + {"extern \"C\" void ", name, "(", args, ")", "\n", CBlock[contents]}]; defineSubroutineF[name_, args_, contents_] := @@ -666,6 +671,7 @@ GenericGridLoopUsingLoopControl[functionName_, block_] := block } ], + "i += CCTK_REAL_VEC_SIZE-1;\n", "}\n", "LC_ENDLOOP3 (", functionName, ");\n" } diff --git a/Tools/CodeGen/Differencing.m b/Tools/CodeGen/Differencing.m index 7c7df2d..92da771 100644 --- a/Tools/CodeGen/Differencing.m +++ b/Tools/CodeGen/Differencing.m @@ -214,7 +214,7 @@ ReplaceDerivatives[derivOps_, expr_, precompute_] := PrecomputeDerivative[d:pd_[gf_, inds___]] := Module[{}, - DeclareAssignVariable["CCTK_REAL", GridFunctionDerivativeName[d], evaluateDerivative[d]]]; + DeclareAssignVariable["CCTK_REAL_VEC", GridFunctionDerivativeName[d], evaluateDerivative[d]]]; evaluateDerivative[d:pd_[gf_, inds___]] := Module[{macroname}, @@ -222,7 +222,7 @@ evaluateDerivative[d:pd_[gf_, inds___]] := Return[ToString[macroName] <> "(" <> ToString[gf] <> ", i, j, k)"]]; DeclareDerivative[d:pd_[gf_, inds___]] := - DeclareVariable[GridFunctionDerivativeName[d], "// CCTK_REAL"]; + DeclareVariable[GridFunctionDerivativeName[d], "// CCTK_REAL_VEC"]; (*************************************************************) @@ -410,10 +410,10 @@ DifferenceGFTerm[op_, i_, j_, k_] := "(int)(" <> ToString[CFormHideStrings[j+ny]] <> ")," <> "(int)(" <> ToString[CFormHideStrings[k+nz]] <> "))]", *) - remaining "(u)[index" <> + remaining "vec_loadu((u)[index" <> "+di*(" <> ToString[CFormHideStrings[nx]] <> ")" <> "+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <> - "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")]", + "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")])", (* remaining "(u)[CCTK_GFINDEX3D(cctkGH,floor((" <> ToString[CFormHideStrings[i+nx]] <> ")+0.5),floor((" <> diff --git a/Tools/CodeGen/KrancThorn.m b/Tools/CodeGen/KrancThorn.m index cf28179..67c4a3c 100644 --- a/Tools/CodeGen/KrancThorn.m +++ b/Tools/CodeGen/KrancThorn.m @@ -151,7 +151,7 @@ CreateKrancThorn[groupsOrig_, parentDirectory_, thornName_, opts:OptionsPattern[ coordGroup = {"grid::coordinates", {sym`x,sym`y,sym`z,sym`r}}; groups = Join[groupsOrig, {coordGroup}]; - includeFiles = Join[includeFiles, {"GenericFD.h", "Symmetry.h", "sbp_calc_coeffs.h"}]; + includeFiles = Join[includeFiles, {"GenericFD.h", "Symmetry.h", "Vectors.hh", "sbp_calc_coeffs.h"}]; inheritedImplementations = Join[inheritedImplementations, {"Grid", "GenericFD"}, CactusBoundary`GetInheritedImplementations[]]; diff --git a/Tools/CodeGen/Thorn.m b/Tools/CodeGen/Thorn.m index a412040..d9ebe6b 100644 --- a/Tools/CodeGen/Thorn.m +++ b/Tools/CodeGen/Thorn.m @@ -517,7 +517,7 @@ CreateSetterSource[calcs_, debug_, useCSE_, include_, ], Map[IncludeFile, Join[{"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", - (*"precomputations.h",*) "GenericFD.h", "Differencing.h"}, include]], + (*"precomputations.h",*) "GenericFD.h", "Differencing.h", "Vectors.hh"}, include]], calculationMacros[], (* For each function structure passed, create the function and |