aboutsummaryrefslogtreecommitdiff
path: root/Tools/CodeGen/Differencing.m
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CodeGen/Differencing.m')
-rw-r--r--Tools/CodeGen/Differencing.m253
1 files changed, 160 insertions, 93 deletions
diff --git a/Tools/CodeGen/Differencing.m b/Tools/CodeGen/Differencing.m
index ff6db9c..ab3d478 100644
--- a/Tools/CodeGen/Differencing.m
+++ b/Tools/CodeGen/Differencing.m
@@ -142,6 +142,7 @@ DZero::usage = "";
shift::usage = "";
spacing::usage = "";
ComponentDerivativeOperatorStencilWidth::usage = "";
+CheckStencil::usage = "";
Begin["`Private`"];
@@ -155,7 +156,7 @@ DZero[n_] := (DPlus[n] + DMinus[n])/2;
(* User API *)
(*************************************************************)
-CreateDifferencingHeader[derivOps_, zeroDims_] :=
+CreateDifferencingHeader[derivOps_, zeroDims_, vectorise_] :=
Module[{componentDerivOps, dupsRemoved, expressions, componentDerivOps2, zeroDimRules, derivOps2, pDefs},
Map[DerivativeOperatorVerify, derivOps];
@@ -167,14 +168,12 @@ CreateDifferencingHeader[derivOps_, zeroDims_] :=
dupsRemoved = RemoveDuplicateRules[componentDerivOps2];
- mDefPairs = Map[ComponentDerivativeOperatorMacroDefinition, dupsRemoved];
+ mDefPairs = Map[ComponentDerivativeOperatorMacroDefinition[#, vectorise] &, dupsRemoved];
pDefs = Union[Flatten[Map[First, mDefPairs]]];
expressions = Flatten[Map[#[[2]]&, mDefPairs]];
-(* expressions = Flatten[Map[ComponentDerivativeOperatorInlineDefinition, dupsRemoved]];*)
-
- {pDefs,Map[{#, "\n"} &, expressions]}];
+ {pDefs, Map[{#, "\n"} &, expressions]}];
ordergfds[_[v1_,___], _[v2_,___]] :=
Order[v1,v2] != -1;
@@ -205,6 +204,16 @@ ReplaceDerivatives[derivOps_, expr_, precompute_] :=
rules = Map[# :> evaluateDerivative[#] &, gfds]];
expr /. rules];
+(* Generate code to ensure that there are sufficient ghost and
+ boundary points for the passed derivative operators used in eqs *)
+CheckStencil[derivOps_, eqs_, name_] :=
+ Module[{gfds, rgzList, rgz},
+ gfds = Map[GridFunctionDerivativesInExpression[{#}, eqs] &, derivOps];
+ rgzList = MapThread[If[Length[#2] > 0, DerivativeOperatorStencilWidth[#1], {0,0,0}] &, {derivOps, gfds}];
+ If[Length[rgzList] === 0, Return[{}]];
+ rgz = Map[Max, Transpose[rgzList]];
+ If[Max[rgz] == 0, {},
+ {"GenericFD_EnsureStencilFits(cctkGH, ", Quote@name, ", ", Riffle[rgz,", "], ");\n"}]];
(*************************************************************)
(* Misc *)
@@ -212,15 +221,18 @@ ReplaceDerivatives[derivOps_, expr_, precompute_] :=
PrecomputeDerivative[d:pd_[gf_, inds___]] :=
Module[{},
- DeclareAssignVariable["CCTK_REAL", GridFunctionDerivativeName[d], evaluateDerivative[d]]];
+ DeclareAssignVariable[DataType[], GridFunctionDerivativeName[d], evaluateDerivative[d]]];
evaluateDerivative[d:pd_[gf_, inds___]] :=
Module[{macroname},
macroName = ComponentDerivativeOperatorMacroName[pd[inds] -> expr];
- Return[ToString[macroName] <> "(" <> ToString[gf] <> ", i, j, k)"]];
+ (* Return[ToString[macroName] <> "(" <> ToString[gf] <> ", i, j, k)"] *)
+ (* Return[ToString[macroName] <> "(" <> ToString[gf] <> ")"] *)
+ Return[ToString[macroName] <> "(&" <> ToString[gf] <> "[index])"]
+ ];
DeclareDerivative[d:pd_[gf_, inds___]] :=
- DeclareVariable[GridFunctionDerivativeName[d], "// CCTK_REAL"];
+ DeclareVariable[GridFunctionDerivativeName[d], "// CCTK_REAL_VEC"];
(*************************************************************)
@@ -251,8 +263,8 @@ sbpMacroDefinition[macroName_, d_] :=
FlattenBlock[{"#define ", macroName, "(u,i,j,k) (sbp_deriv_" <> ds
<> "(i,j,k,sbp_" <> l <> "min,sbp_" <> l <> "max,d" <> ds <> ",u,q" <> ds <> ",cctkGH))"}] ];
-ComponentDerivativeOperatorMacroDefinition[componentDerivOp:(name_[inds___] -> expr_)] :=
- Module[{macroName, rhs, rhs2, i = "i", j = "j", k = "k", spacings, spacings2, pat, ss, num, den, newnum, signModifier, quotient, liName, rhs3, rhs4},
+ComponentDerivativeOperatorMacroDefinition[componentDerivOp:(name_[inds___] -> expr_), vectorise_] :=
+ Module[{macroName, rhs, i = "i", j = "j", k = "k", spacings, spacings2, pat, ss, num, den, newnum, signModifier, quotient, liName, finalDef},
macroName = ComponentDerivativeOperatorMacroName[componentDerivOp];
@@ -265,23 +277,24 @@ ComponentDerivativeOperatorMacroDefinition[componentDerivOp:(name_[inds___] -> e
If[expr === SBPDerivative[3],
Return[sbpMacroDefinition[macroName, 3]]];
- rhs = DifferenceGF[expr, i, j, k];
+ rhs = DifferenceGF[expr, i, j, k, vectorise];
+(* Print["rhs1 == ", FullForm[rhs]];*)
spacings = {spacing[1] -> 1/"dxi", spacing[2] -> 1/"dyi", spacing[3] -> 1/"dzi"};
spacings2 = {spacing[1] -> "dx", spacing[2] -> "dy", spacing[3] -> "dz"};
- rhs2 = FullSimplify[rhs];
+ rhs = FullSimplify[rhs];
-(* Print["rhs2 == ", FullForm[rhs2]];*)
+(* Print["rhs2 == ", FullForm[rhs]];*)
pat = (Times[spInExpr:(Power[spacing[_],_]...), (Rational[x_,y_])..., rest__]) | (rest__);
(* Print["pat == ", pat//FullForm]; *)
- If[MatchQ[rhs2, pat],
+ If[MatchQ[rhs, pat],
(* Print["matches!"];*)
- ss = Times[rhs2 /. pat -> spInExpr];
+ ss = Times[rhs /. pat -> spInExpr];
(* Print["ss == ", ss];*)
- num = rhs2 /. pat -> x;
- den = rhs2 /. pat -> y;
+ num = rhs /. pat -> x;
+ den = rhs /. pat -> y;
(* Print["num == ", num];
Print["den == ", den];*)
If[{num, 1, 2} === {1, 2},(* Print["SEQ!"]; *) newnum = 1; den=1; signModifier = "",
@@ -307,84 +320,117 @@ ComponentDerivativeOperatorMacroDefinition[componentDerivOp:(name_[inds___] -> e
liName = "p" <> signModifier <> quotient <> ToString[Apply[SequenceForm,Simplify[1/(ss /. spacings2)],{0,Infinity}]];
(* Print["liName == ", liName];*)
- rhs3 = rhs2 /. pat -> Times[liName, rest],
- ThrowError["Partial derivative operator definition ", rhs2,
- " does not match pattern ", pat];
- rhs3 = rhs2];
-
-(* Print["rhs3 == ", rhs3];*)
+ rhs = rhs /. pat -> Times[liName, rest],
+(*
+ rhs = (rhs /. pat -> Times[liName, rest]) / If[vectorise, liName, 1], (* horrible *)
+*)
+(* Print["!!!!!!!!DOES NOT MATCH!!!!!!!!!"];*)
+ rhs = rhs];
- pDefs = {{liName -> CFormHideStrings[ReplacePowers[num / den ss /. spacings2]]}};
+(* Print["rhs3 == ", FullForm[rhs]];*)
-(* rhs4 = Factor[rhs3];*)
+ pDefs = {{liName -> CFormHideStrings[ReplacePowers[num / den ss /. spacings2, vectorise]]}};
- rhs4 = rhs3 //. (x_ a_ + x_ b_) -> x(a+b);
- rhs5 = rhs4 //. (x_ a_ - x_ b_) -> x(a-b);
+(* rhs = Factor[rhs];*)
+ rhs = rhs //. (x_ a_ + x_ b_) -> x (a+b);
+ rhs = rhs //. (x_ a_ - x_ b_) -> x (a-b);
(* Print[componentDerivOp, ": "];
- Print[FullForm[rhs5]];
+ Print[FullForm[rhs]];
Print[""];*)
- rhs6 = CFormHideStrings[ReplacePowers[rhs5 /. spacings]];
- {pDefs, FlattenBlock[{"#define ", macroName, "(u,i,j,k) ", "(", rhs6, ")"}]}];
-
-ComponentDerivativeOperatorInlineDefinition[componentDerivOp:(name_[inds___] -> expr_)] :=
- Module[{inlineName, rhs, rhs2, i = "i", j = "j", k = "k", spacings},
-
- inlineName = ComponentDerivativeOperatorMacroName[componentDerivOp];
-
- rhs = DifferenceGF[expr, i, j, k];
-(* rhs = DifferenceGFInline[expr, i, j, k];*)
- spacings = {spacing[1] -> 1/"dxi", spacing[2] -> 1/"dyi", spacing[3] -> 1/"dzi"};
- rhs2 = CFormHideStrings[FullSimplify[ReplacePowers[rhs /. spacings]]];
-
- DefineFunction[inlineName, "static inline CCTK_REAL",
- "CCTK_REAL *u, int i, int j, int k",
- {"return ", rhs2, ";\n"}]];
+ rhs = CFormHideStrings[ReplacePowers[rhs /. spacings, vectorise]];
+ (* Print["rhs=",FullForm[rhs]]; *)
+ (* {pDefs, FlattenBlock[{"#define ", macroName, "(u,i,j,k) ", "(", rhs, ")"}]} *)
+ finalDef =
+ If[vectorise,
+ {pDefs, FlattenBlock[{
+ "#ifndef KRANC_DIFF_FUNCTIONS\n",
+ (* default, differencing operators are macros *)
+(*
+ "# define ", macroName, "(u) ", "(kmul(", liName, ",", rhs, "))\n",
+*)
+ "# define ", macroName, "(u) ", "(", rhs, ")\n",
+ "#else\n",
+ (* new, differencing operators are static functions *)
+(*
+ "# define ", macroName, "(u) ", "(kmul(", liName, ",", macroName, "_impl((u),dj,dk)))\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, ptrdiff_t const dj, ptrdiff_t const dk) CCTK_ATTRIBUTE_NOINLINE CCTK_ATTRIBUTE_UNUSED;\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, ptrdiff_t const dj, ptrdiff_t const dk)\n",
+ If[StringMatchQ[rhs, RegularExpression[".*\\bdir\\d\\b.*"]],
+ { "{ return ToReal(1e30); /* ERROR */ }\n" },
+ { "{ return ", rhs, "; }\n" }],
+*)
+(*
+ "# define ", macroName, "(u) ", "(kmul(", liName, ",", macroName, "_impl(u,cdj,cdk)))\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, ptrdiff_t const cdj, ptrdiff_t const cdk) CCTK_ATTRIBUTE_NOINLINE CCTK_ATTRIBUTE_UNUSED;\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, ptrdiff_t const cdj, ptrdiff_t const cdk)\n",
+ (* We cannot handle dirN,
+ so we punt on all expressions that contain dirN *)
+ If[StringMatchQ[rhs, RegularExpression[".*\\bdir\\d\\b.*"]],
+ { "{ return ToReal(1e30); /* ERROR */ }\n" },
+ { "{\n",
+ " ptrdiff_t const cdi=sizeof(CCTK_REAL);\n",
+ " return ", rhs, ";\n",
+ "}\n" }],
+*)
+ "# define ", macroName, "(u) ", "(", macroName, "_impl(u,", liName, ",cdj,cdk))\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, CCTK_REAL_VEC const ", liName, ", ptrdiff_t const cdj, ptrdiff_t const cdk) CCTK_ATTRIBUTE_NOINLINE CCTK_ATTRIBUTE_UNUSED;\n",
+ "static CCTK_REAL_VEC ", macroName, "_impl(CCTK_REAL const* restrict const u, CCTK_REAL_VEC const ", liName, ", ptrdiff_t const cdj, ptrdiff_t const cdk)\n",
+ (* We cannot handle dirN,
+ so we punt on all expressions that contain dirN *)
+ If[StringMatchQ[rhs, RegularExpression[".*\\bdir\\d\\b.*"]],
+ { "{ return ToReal(1e30); /* ERROR */ }\n" },
+ { "{\n",
+ " ptrdiff_t const cdi=sizeof(CCTK_REAL);\n",
+ " return ", rhs, ";\n",
+ "}\n" }],
+ "#endif\n"
+ }]},
+
+ {pDefs, FlattenBlock[{"#define ", macroName, "(u) ", "(", rhs, ")"}]}];
+ finalDef
+];
ComponentDerivativeOperatorMacroName[componentDerivOp:(name_[inds___] -> expr_)] :=
Module[{stringName},
stringName = StringJoin[Map[ToString, Join[{name}, {inds}]]];
stringName];
-
-
+DerivativeOperatorStencilWidth[derivOp_] :=
+ Map[Max, Transpose[Map[ComponentDerivativeOperatorStencilWidth, DerivativeOperatorToComponents[derivOp]]]];
ComponentDerivativeOperatorStencilWidth[componentDerivOp:(name_[inds___] -> expr_)] :=
- Module[{cases, nx, ny, nz},
- cases = Union[Flatten[Cases[{expr}, shift[_] | Power[shift[_],_], Infinity]]];
- Print[cases];
-
- nx = Exponent[op, shift[1]];
- ny = Exponent[op, shift[2]];
- nz = Exponent[op, shift[3]];
-
- ];
-
-
-
+ Module[{cases, nx, ny, nz, result},
+ result = Table[
+ cases = Union[Flatten[Cases[{expr}, shift[d] | Power[shift[d],_], Infinity]]];
+ ns = Map[Exponent[#, shift[d]] &, cases];
+ If[Length[ns] == 0, 0, Max[Abs[ns]]], {d, 1, 3}];
+
+ (* We do not know the run-time value of any shorthands used in
+ operator definitions. In all the current known cases, this
+ will be a "direction" which is +/- 1. In future, the
+ differencing mechanism will support shorthand arguments to
+ operators and this hack can be removed. *)
+ result = Replace[result, _Symbol -> 1, {-1}];
+
+ If[!And@@Map[NumericQ, result],
+ Throw["Stencil width is not numeric in "<>ToString[componentDerivOp]]];
+ result];
(* Farm out each term of a difference operator *)
-DifferenceGF[op_, i_, j_, k_] :=
- Module[{expanded},
- expanded = Expand[op];
-
- If[Head[expanded] === Plus,
- Apply[Plus, Map[DifferenceGFTerm[#, i, j, k] &, expanded]],
- DifferenceGFTerm[expanded, i, j, k]]];
-
-DifferenceGFInline[op_, i_, j_, k_] :=
+DifferenceGF[op_, i_, j_, k_, vectorise_] :=
Module[{expanded},
expanded = Expand[op];
If[Head[expanded] === Plus,
- Apply[Plus, Map[DifferenceGFTermInline[#, i, j, k] &, expanded]],
+ Apply[Plus, Map[DifferenceGFTerm[#, i, j, k, vectorise] &, expanded]],
DifferenceGFTerm[expanded, i, j, k]]];
(* Return the fragment of a macro definition for defining a derivative
operator *)
-DifferenceGFTerm[op_, i_, j_, k_] :=
+DifferenceGFTerm[op_, i_, j_, k_, vectorise_] :=
Module[{nx, ny, nz, remaining},
If[op === 0,
@@ -409,10 +455,52 @@ DifferenceGFTerm[op_, i_, j_, k_] :=
"(int)(" <> ToString[CFormHideStrings[j+ny]] <> ")," <>
"(int)(" <> ToString[CFormHideStrings[k+nz]] <> "))]",
*)
- remaining "(u)[index" <>
- "+di*(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+(*
+ remaining "vec_loadu_maybe" <>
+ "(" <> ToString[CFormHideStrings[nx]] <> "," <>
+ "(u)[index" <>
+ "+di*(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+ "+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
+ "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")])",
+*)
+(*
+ remaining "vec_loadu_maybe(" <> ToString[CFormHideStrings[nx]] <> "," <>
+ "(u)[(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+ "+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
+ "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")])",
+*)
+
+ If[vectorise,
+(*
+ remaining "vec_loadu_maybe3" <>
+ "(" <> ToString[CFormHideStrings[nx /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ ToString[CFormHideStrings[ny /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ ToString[CFormHideStrings[nz /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ "(u)[(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+ "+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
+ "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")])",
+*)
+ remaining "vec_loadu_maybe3" <>
+ "(" <> ToString[CFormHideStrings[nx /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ ToString[CFormHideStrings[ny /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ ToString[CFormHideStrings[nz /. {dir1->1, dir2->1, dir3->1}]] <> "," <>
+ "*(CCTK_REAL const*)&((char const*)(u))" <>
+ "[cdi*(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+ "+cdj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
+ "+cdk*(" <> ToString[CFormHideStrings[nz]] <> ")])",
+
+ remaining "(u)[" <>
+ "di*(" <> ToString[CFormHideStrings[nx]] <> ")" <>
"+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
- "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")]",
+ "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")]"],
+
+
+(*
+ remaining "vec_loadu" <>
+ "(u[(" <> ToString[CFormHideStrings[nx]] <> ")" <>
+ "+dj*(" <> ToString[CFormHideStrings[ny]] <> ")" <>
+ "+dk*(" <> ToString[CFormHideStrings[nz]] <> ")])",
+*)
(*
remaining "(u)[CCTK_GFINDEX3D(cctkGH,floor((" <>
ToString[CFormHideStrings[i+nx]] <> ")+0.5),floor((" <>
@@ -422,27 +510,6 @@ DifferenceGFTerm[op_, i_, j_, k_] :=
remaining "u(" <> ToString[FortranForm[i+nx]] <> "," <>
ToString[FortranForm[j+ny]] <> "," <> ToString[FortranForm[k+nz]] <> ")"] ];
-(* Return the fragment of a function definition for defining a derivative
- operator *)
-DifferenceGFTermInline[op_, i_, j_, k_] :=
- Module[{nx, ny, nz, remaining},
-
- If[op === 0,
- Return[0]];
-
- nx = Exponent[op, shift[1]];
- ny = Exponent[op, shift[2]];
- nz = Exponent[op, shift[3]];
-
- remaining = op / (shift[1]^nx) / (shift[2]^ny) / (shift[3]^nz);
-
- If[Cases[{remaining}, shift[_], Infinity] != {},
- ThrowError["Could not parse difference operator:", op]];
-
- remaining "(u)[CCTK_GFINDEX3D(cctkGH," <> ToString[CFormHideStrings[i+nx]] <> "," <>
- ToString[CFormHideStrings[j+ny]] <> "," <> ToString[CFormHideStrings[k+nz]] <> ")]"
- ];
-
DerivativeOperatorGFDs[gf_];