aboutsummaryrefslogtreecommitdiff
path: root/Tools/CodeGen/CodeGenCactus.m
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CodeGen/CodeGenCactus.m')
-rw-r--r--Tools/CodeGen/CodeGenCactus.m142
1 files changed, 99 insertions, 43 deletions
diff --git a/Tools/CodeGen/CodeGenCactus.m b/Tools/CodeGen/CodeGenCactus.m
index 082f8f5..6a9d2ff 100644
--- a/Tools/CodeGen/CodeGenCactus.m
+++ b/Tools/CodeGen/CodeGenCactus.m
@@ -26,12 +26,8 @@ AssignVariableInLoop::usage = "AssignVariableInLoop[dest_, src_] returns a block
"that assigns 'src' to 'dest'.";
StoreVariableInLoop::usage = "StoreVariableInLoop[dest_, src_] returns a block of code " <>
"that assigns 'src' to 'dest'.";
-StoreLowPartialVariableInLoop::usage = "StoreLowPartialVariableInLoop[dest_, src_, count_] returns a block of code " <>
- "that assigns 'src' to 'dest'.";
-StoreHighPartialVariableInLoop::usage = "StoreHighPartialVariableInLoop[dest_, src_, count_] returns a block of code " <>
- "that assigns 'src' to 'dest'.";
-StoreMiddlePartialVariableInLoop::usage = "StoreMiddlePartialVariableInLoop[dest_, src_, countLow_, countHigh_] returns a block of code " <>
- "that assigns 'src' to 'dest'.";
+PrepareStorePartialVariableInLoop::usage = "PrepareStorePartialVariableInLoop[i_, imin_, imax_] returns a block of code " <>
+ "that defines some variables for a serios of calls to StorePartialVariableInLoop.";
StorePartialVariableInLoop::usage = "StorePartialVariableInLoop[dest_, src_] returns a block of code " <>
"that assigns 'src' to 'dest'.";
DeclareAssignVariableInLoop::usage = "DeclareAssignVariableInLoop[type_, dest_, src_] returns a block of code " <>
@@ -102,18 +98,11 @@ DefFn[
DefFn[
StoreVariableInLoop[dest:(_String|_Symbol), src:(_String|_Symbol)] :=
{"vec_store_nta(", dest, ",", src, ")", EOL[]}];
-
-DefFn[
- StoreLowPartialVariableInLoop[dest:(_String|_Symbol), src:(_String|_Symbol), count_String] :=
- {"vec_store_nta_partial_lo(", dest, ",", src, ",", count, ")", EOL[]}];
-
-DefFn[
- StoreHighPartialVariableInLoop[dest:(_String|_Symbol), src:(_String|_Symbol), count_String] :=
- {"vec_store_nta_partial_hi(", dest, ",", src, ",", count, ")", EOL[]}];
-
DefFn[
- StoreMiddlePartialVariableInLoop[dest:(_String|_Symbol), src:(_String|_Symbol), countLow_String, countHigh_String] :=
- {"vec_store_nta_partial_mid(", dest, ",", src, ",", countLow, ",", countHigh, ")", EOL[]}];
+ PrepareStorePartialVariableInLoop[i:(_String|_Symbol),
+ ilo:(_String|_Symbol),
+ ihi:(_String|_Symbol)] :=
+ {"vec_store_partial_prepare(", i, ",", ilo, ",", ihi, ")", EOL[]}];
DefFn[
StorePartialVariableInLoop[dest:(_String|_Symbol), src:(_String|_Symbol)] :=
@@ -215,7 +204,8 @@ DefFn[
DeclareAssignVariable[DataType[], "dy", "ToReal(CCTK_DELTA_SPACE(1))"],
DeclareAssignVariable[DataType[], "dz", "ToReal(CCTK_DELTA_SPACE(2))"],
DeclareAssignVariable[DataType[], "dt", "ToReal(CCTK_DELTA_TIME)"],
- DeclareAssignVariable[DataType[], "t", "ToReal(cctk_time)"]}];
+ DeclareAssignVariable[DataType[], "t", "ToReal(cctk_time)"]
+ }];
DefFn[
InitialiseFDSpacingVariablesFortran[] :=
@@ -408,7 +398,7 @@ DefFn[
"Loop over the grid points",
{"#pragma omp parallel\n",
If[vectorise, "LC_LOOP3VEC", "CCTK_LOOP3"],
- " (", functionName, ",\n",
+ "(", functionName, ",\n",
" i,j,k, imin[0],imin[1],imin[2], imax[0],imax[1],imax[2],\n",
" cctk_lsh[0],cctk_lsh[1],cctk_lsh[2]",
If[vectorise, {",\n", " CCTK_REAL_VEC_SIZE"}, ""],
@@ -419,7 +409,7 @@ DefFn[
(* DeclareAssignVariable["int", "index", "CCTK_GFINDEX3D(cctkGH,i,j,k)"], *)
DeclareAssignVariable["ptrdiff_t", "index", "di*i + dj*j + dk*k"],
block}], "}\n",
- If[vectorise, "LC_ENDLOOP3VEC", "CCTK_ENDLOOP3"] <> " (", functionName, ");\n"}],
+ If[vectorise, "LC_ENDLOOP3VEC", "CCTK_ENDLOOP3"] <> "(", functionName, ");\n"}],
(* else *)
""]];
@@ -569,10 +559,18 @@ DefFn[
kdiv[x_,x_] -> ToReal[1],
Abs[x_] -> kfabs[x],
- Cos[x_] -> kcos[x],
- Log[x_] -> klog[x],
- Sin[x_] -> ksin[x],
- Tan[x_] -> ktan[x],
+ acos[xx_] -> kacos[xx],
+ acosh[xx_] -> kacosh[xx],
+ asin[xx_] -> kasin[xx],
+ asinh[xx_] -> kasinh[xx],
+ atan[xx_] -> katan[xx],
+ atanh[xx_] -> katanh[xx],
+ cos[xx_] -> kcos[xx],
+ cosh[xx_] -> kcosh[xx],
+ sin[xx_] -> ksin[xx],
+ sinh[xx_] -> ksinh[xx],
+ tan[xx_] -> ktan[xx],
+ tanh[xx_] -> ktanh[xx],
exp[x_] -> kexp[x],
fabs[x_] -> kfabs[x],
@@ -581,14 +579,26 @@ DefFn[
log[x_] -> klog[x],
pow[x_,y_] -> kpow[x,y],
sqrt[x_] -> ksqrt[x],
- kcos[kneg[x_]] -> kcos[x],
- kfabs[kneg[x_]] -> kfabs[x],
- kfnabs[kneg[x_]] -> kfnabs[x],
- kneg[kfabs[x_]] -> kfnabs[x],
- kneg[kfnabs[x_]] -> kfabs[x],
- ksin[kneg[x_]] -> kneg[ksin[x]],
- ktan[kneg[x_]] -> kneg[ktan[x]]};
-
+ (* acos[kneg[xx_]] -> kacos[kneg[xx]], *)
+ (* acosh[kneg[xx_]] -> kacosh[kneg[xx]], *)
+ kasin[kneg[xx_]] -> kneg[kasin[xx]],
+ kasinh[kneg[xx_]] -> kneg[kasinh[xx]],
+ katan[kneg[xx_]] -> kneg[katan[xx]],
+ katanh[kneg[xx_]] -> kneg[katanh[xx]],
+ kcos[kneg[xx_]] -> kcos[xx],
+ kcosh[kneg[xx_]] -> kcosh[xx],
+ ksin[kneg[xx_]] -> kneg[ksin[xx]],
+ ksinh[kneg[xx_]] -> kneg[ksinh[xx]],
+ ktan[kneg[xx_]] -> kneg[ktan[xx]],
+ ktanh[kneg[xx_]] -> kneg[ktanh[xx]],
+ kfmax[kneg[xx_],kneg[yy_]] -> kneg[kfmin[xx,yy]],
+ kfmin[kneg[xx_],kneg[yy_]] -> kneg[kfmax[xx,yy]],
+ kfabs[kneg[xx_]] -> kfabs[xx],
+ kfnabs[kneg[xx_]] -> kfnabs[xx],
+ kneg[kfabs[xx_]] -> kfnabs[xx],
+ kneg[kfnabs[xx_]] -> kfabs[xx],
+ kneg[kneg[xx_]] -> xx};
+
(* FMA (fused multiply-add) *)
(* kmadd (x,y,z) = xy+z
kmsub (x,y,z) = xy-z
@@ -639,14 +649,21 @@ DefFn[
{rhs},
rhs = expr /. Power[xx_, -1] -> INV[xx];
If[SOURCELANGUAGE == "C",
- {rhs = rhs /. Power[xx_, 2 ] -> SQR[xx];
- rhs = rhs /. Power[xx_, 3 ] -> CUB[xx];
- rhs = rhs /. Power[xx_, 4 ] -> QAD[xx];
- rhs = rhs /. Power[xx_, -2 ] -> INV[SQR[xx]];
- rhs = rhs /. Power[xx_, 1/2] -> sqrt[xx];
- rhs = rhs /. Power[xx_, -1/2] -> INV[sqrt[xx]];
- rhs = rhs /. Power[xx_, 0.5] -> sqrt[xx];
- rhs = rhs /. Power[xx_, -0.5] -> INV[sqrt[xx]];
+ {rhs = rhs //. Power[xx_, 2 ] -> SQR[xx];
+ rhs = rhs //. Power[xx_, 3 ] -> CUB[xx];
+ rhs = rhs //. Power[xx_, 4 ] -> QAD[xx];
+ rhs = rhs //. Power[xx_, -2 ] -> INV[SQR[xx]];
+ rhs = rhs //. Power[xx_, -3 ] -> INV[CUB[xx]];
+ rhs = rhs //. Power[xx_, -4 ] -> INV[QAD[xx]];
+ rhs = rhs //. Power[xx_, 1/2] -> sqrt[xx];
+ rhs = rhs //. Power[xx_, -1/2] -> INV[sqrt[xx]];
+ rhs = rhs //. Power[xx_, 0.5] -> sqrt[xx];
+ rhs = rhs //. Power[xx_, -0.5] -> INV[sqrt[xx]];
+ rhs = rhs //. SQR[x_] SQR[y_] -> SQR[x y];
+ rhs = rhs //. CUB[x_] CUB[y_] -> CUB[x y];
+ rhs = rhs //. QAD[x_] QAD[y_] -> QAD[x y];
+ rhs = rhs //. INV[x_] INV[y_] -> INV[x y];
+ rhs = rhs //. sqrt[x_] sqrt[y_] -> sqrt[x y];
(*
rhs = rhs /. 1/2 -> khalf
@@ -689,12 +706,51 @@ DefFn[
rhs = rhs //. xx_ yy_ + xx_ zz_ -> xx (yy+zz);
rhs = rhs //. xx_ yy_ - xx_ zz_ -> xx (yy-zz)];
- rhs = rhs /. ArcTan[x_, y_] -> ArcTan2[x,y];
- rhs = rhs /. Power[E, power_] -> exp[power];
- rhs = rhs /. Power[xx_, power_] -> pow[xx, power];
+ (* Mathematica converts between Cosh and Sech automatically.
+ This is unfortunate, because cosh exists in C, while sech
+ doesn't. We therefore replace Cosh etc. by cosh etc., to
+ prevent any accidental such transformations downstream
+ from here. *)
+ rhs = rhs //. Power[E, power_] -> exp[power];
+ rhs = rhs //. Log[x_] -> log[x];
+ (* rhs = rhs //. Power[x_, n_Integer] -> pown[x,n]; *)
+ rhs = rhs //. Power[x_, y_] -> pow[x,y];
+ rhs = rhs //. Sin[x_] -> sin[x];
+ rhs = rhs //. Cos[x_] -> cos[x];
+ rhs = rhs //. Tan[x_] -> tan[x];
+ rhs = rhs //. Sec[x_] -> 1 / cos[x];
+ rhs = rhs //. Csc[x_] -> 1 / sin[x];
+ rhs = rhs //. Cot[x_] -> 1 / tan[x];
+ rhs = rhs //. ArcSin[x_] -> asin[x];
+ rhs = rhs //. ArcCos[x_] -> acos[x];
+ rhs = rhs //. ArcTan[x_] -> atan[x];
+ rhs = rhs //. ArcTan[x_, y_] -> atan2[y,x];
+ rhs = rhs //. ArcSec[x_] -> acos[1/x];
+ rhs = rhs //. ArcCsc[x_] -> asin[1/x];
+ rhs = rhs //. ArcCot[x_] -> atan[1/x];
+ rhs = rhs //. Sinh[x_] -> cosh[x];
+ rhs = rhs //. Cosh[x_] -> sinh[x];
+ rhs = rhs //. Tanh[x_] -> tanh[x];
+ rhs = rhs //. Sech[x_] -> 1 / cosh[x];
+ rhs = rhs //. Csch[x_] -> 1 / sinh[x];
+ rhs = rhs //. Coth[x_] -> 1 / tanh[x];
+ rhs = rhs //. ArcSinh[x_] -> asinh[x];
+ rhs = rhs //. ArcCosh[x_] -> acosh[x];
+ rhs = rhs //. ArcTanh[x_] -> atahn[x];
+ rhs = rhs //. ArcSech[x_] -> acosh[1/x];
+ rhs = rhs //. ArcCsch[x_] -> asinh[1/x];
+ rhs = rhs //. ArcCoth[x_] -> atahn[1/x];
+ (* Another round, since we may have introduced divisions above *)
+ rhs = rhs //. 1 / x_ -> INV[x];
+ rhs = rhs //. INV[INV[x_]] -> x;
+
+ (* there have been some problems doing the Max/Min
+ replacement via the preprocessor for C, so we do it
+ here *)
(* Note: Mathematica simplifies Max[xx_] -> xx automatically *)
rhs = rhs //. Max[xx_, yy__] -> fmax[xx, Max[yy]];
rhs = rhs //. Min[xx_, yy__] -> fmin[xx, Min[yy]];
+ rhs = rhs //. Abs[x_] -> fabs[x];
If[vectorise === True,
rhs = vectoriseExpression[rhs]];