diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java index 5b1928a954265a3a102a64432cc8678f717d0e9a..ad560f471c1f8e794e525b770770c2932c34fbe6 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java @@ -16,10 +16,10 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; @@ -34,8 +34,7 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.nodes.ReadAccessor; -import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; import com.oracle.truffle.r.runtime.nmath.RMath; /* @@ -73,20 +72,20 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { /** * Compute Cov(xx[], yy[]) or Cor(.,.) with n = length(xx) */ - private static void COV_PAIRWISE_BODY(double[] ans, int n, int ncx, int i, int j, ReadAccessor.Double x, ReadAccessor.Double y, int xx, int yy, boolean[] sd_0, boolean cor, boolean kendall) { + private static void COV_PAIRWISE_BODY(double[] ans, int n, int ncx, int i, int j, double[] x, double[] y, int xx, int yy, boolean[] sd_0, boolean cor, boolean kendall) { double xmean = 0, ymean = 0; int nobs = 0; if (!kendall) { for (int k = 0; k < n; k++) { - if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { + if (!(ISNAN(x[xx + k]) || ISNAN(y[yy + k]))) { nobs++; - xmean += x.getDataAt(xx + k); - ymean += y.getDataAt(yy + k); + xmean += x[xx + k]; + ymean += y[yy + k]; } } } else /* kendall */ for (int k = 0; k < n; k++) { - if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { + if (!(ISNAN(x[xx + k]) || ISNAN(y[yy + k]))) { nobs++; } } @@ -100,10 +99,10 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { n1 = nobs - 1; } for (int k = 0; k < n; k++) { - if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { + if (!(ISNAN(x[xx + k]) || ISNAN(y[yy + k]))) { if (!kendall) { - double xm = x.getDataAt(xx + k) - xmean; - double ym = y.getDataAt(yy + k) - ymean; + double xm = x[xx + k] - xmean; + double ym = y[yy + k] - ymean; sum += xm * ym; if (cor) { @@ -114,9 +113,9 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { else { /* Kendall's tau */ for (n1 = 0; n1 < k; n1++) { - if (!(ISNAN(x.getDataAt(xx + n1)) || ISNAN(y.getDataAt(yy + n1)))) { - double xm = RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)); - double ym = RMath.sign(y.getDataAt(yy + k) - y.getDataAt(yy + n1)); + if (!(ISNAN(x[xx + n1]) || ISNAN(y[yy + n1]))) { + double xm = RMath.sign(x[xx + k] - x[xx + n1]); + double ym = RMath.sign(y[yy + k] - y[yy + n1]); sum += xm * ym; if (cor) { @@ -151,7 +150,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_pairwise1(int n, int ncx, ReadAccessor.Double x, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + @TruffleBoundary + private static void cov_pairwise1(int n, int ncx, double[] x, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { for (int i = 0; i < ncx; i++) { int xx = i * n; for (int j = 0; j <= i; j++) { @@ -164,7 +164,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_pairwise2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + @TruffleBoundary + private static void cov_pairwise2(int n, int ncx, int ncy, double[] x, double[] y, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { for (int i = 0; i < ncx; i++) { int xx = i * n; for (int j = 0; j < ncy; j++) { @@ -180,14 +181,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { */ /* This uses two passes for better accuracy */ - private static void MEAN(int n, int ncx, ReadAccessor.Double x, double[] xm, boolean[] ind, int nobs) { + private static void MEAN(int n, int ncx, double[] x, double[] xm, boolean[] ind, int nobs) { /* variable means */ for (int i = 0; i < ncx; i++) { int xx = i * n; double sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += x.getDataAt(xx + k); + sum += x[xx + k]; } } double tmp = sum / nobs; @@ -195,7 +196,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (x.getDataAt(xx + k) - tmp); + sum += (x[xx + k] - tmp); } } tmp = tmp + sum / nobs; @@ -205,7 +206,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } /* This uses two passes for better accuracy */ - private static void MEAN_(int n, int ncx, ReadAccessor.Double x, double[] xm, boolean[] has_na) { + private static void MEAN_(int n, int ncx, double[] x, double[] xm, boolean[] has_na) { /* variable means (has_na) */ for (int i = 0; i < ncx; i++) { double tmp; @@ -215,13 +216,13 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { int xx = i * n; double sum = 0; for (int k = 0; k < n; k++) { - sum += x.getDataAt(xx + k); + sum += x[xx + k]; } tmp = sum / n; if (Double.isFinite(tmp)) { sum = 0; for (int k = 0; k < n; k++) { - sum += (x.getDataAt(xx + k) - tmp); + sum += (x[xx + k] - tmp); } tmp = tmp + sum / n; } @@ -230,7 +231,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_complete1(int n, int ncx, ReadAccessor.Double x, double[] xm, boolean[] ind, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + private static void cov_complete1(int n, int ncx, double[] x, double[] xm, boolean[] ind, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { int n1 = -1; /* total number of complete observations */ @@ -264,7 +265,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (x.getDataAt(xx + k) - xxm) * (x.getDataAt(yy + k) - yym); + sum += (x[xx + k] - xxm) * (x[yy + k] - yym); } } double result = sum / n1; @@ -279,7 +280,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { if (ind[k]) { for (n1 = 0; n1 < n; n1++) { if (ind[n1]) { - sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(x.getDataAt(yy + k) - x.getDataAt(yy + n1)); + sum += RMath.sign(x[xx + k] - x[xx + n1]) * RMath.sign(x[yy + k] - x[yy + n1]); } } } @@ -316,7 +317,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_na_1(int n, int ncx, ReadAccessor.Double x, double[] xm, boolean[] has_na, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + private static void cov_na_1(int n, int ncx, double[] x, double[] xm, boolean[] has_na, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { int n1 = -1; if (n <= 1) { /* too many missing */ for (int i = 0; i < ncx; i++) { @@ -351,7 +352,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double yym = xm[j]; double sum = 0; for (int k = 0; k < n; k++) { - sum += (x.getDataAt(xx + k) - xxm) * (x.getDataAt(yy + k) - yym); + sum += (x[xx + k] - xxm) * (x[yy + k] - yym); } double result = sum / n1; ANS(ans, ncx, j, i, result); @@ -368,7 +369,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double sum = 0; for (int k = 0; k < n; k++) { for (n1 = 0; n1 < n; n1++) { - sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(x.getDataAt(yy + k) - x.getDataAt(yy + n1)); + sum += RMath.sign(x[xx + k] - x[xx + n1]) * RMath.sign(x[yy + k] - x[yy + n1]); } } ANS(ans, ncx, j, i, sum); @@ -409,7 +410,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void COV_SDEV1(int n, int n1, int nc, ReadAccessor.Double array, double[] m, boolean[] ind, boolean kendall) { + private static void COV_SDEV1(int n, int n1, int nc, double[] array, double[] m, boolean[] ind, boolean kendall) { for (int i = 0; i < nc; i++) { /* Var(X[i]) */ int xx = i * n; double sum = 0; @@ -417,7 +418,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double xxm = m[i]; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (array.getDataAt(xx + k) - xxm) * (array.getDataAt(xx + k) - xxm); + sum += (array[xx + k] - xxm) * (array[xx + k] - xxm); } } sum /= n1; @@ -425,7 +426,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { for (int k = 0; k < n; k++) { if (ind[k]) { for (int n1_ = 0; n1_ < n; n1_++) { - if (ind[n1_] && array.getDataAt(xx + k) != array.getDataAt(xx + n1_)) { + if (ind[n1_] && array[xx + k] != array[xx + n1_]) { sum++; /* = sign(. - .)^2 */ } } @@ -436,8 +437,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_complete2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, double[] xm, double[] ym, boolean[] ind, double[] ans, boolean[] sd_0, boolean cor, - boolean kendall) { + private static void cov_complete2(int n, int ncx, int ncy, double[] x, double[] y, double[] xm, double[] ym, boolean[] ind, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { int n1 = -1; /* total number of complete observations */ @@ -471,7 +471,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (x.getDataAt(xx + k) - xxm) * (y.getDataAt(yy + k) - yym); + sum += (x[xx + k] - xxm) * (y[yy + k] - yym); } } ANS(ans, ncx, i, j, sum / n1); @@ -484,7 +484,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { if (ind[k]) { for (n1 = 0; n1 < n; n1++) { if (ind[n1]) { - sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(y.getDataAt(yy + k) - y.getDataAt(yy + n1)); + sum += RMath.sign(x[xx + k] - x[xx + n1]) * RMath.sign(y[yy + k] - y[yy + n1]); } } } @@ -519,7 +519,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void COV_SDEV2(int n, int n1, int nc, ReadAccessor.Double array, double[] m, boolean[] has_na, boolean kendall) { + private static void COV_SDEV2(int n, int n1, int nc, double[] array, double[] m, boolean[] has_na, boolean kendall) { for (int i = 0; i < nc; i++) { if (!has_na[i]) { /* Var(X[j]) */ int xx = i * n; @@ -527,13 +527,13 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { if (!kendall) { double xxm = m[i]; for (int k = 0; k < n; k++) { - sum += (array.getDataAt(xx + k) - xxm) * (array.getDataAt(xx + k) - xxm); + sum += (array[xx + k] - xxm) * (array[xx + k] - xxm); } sum /= n1; } else { /* Kendall's tau */ for (int k = 0; k < n; k++) { for (int n1_ = 0; n1_ < n; n1_++) { - if (array.getDataAt(xx + k) != array.getDataAt(xx + n1_)) { + if (array[xx + k] != array[xx + n1_]) { sum++; /* = sign(. - .)^2 */ } } @@ -544,8 +544,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_na_2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, double[] xm, double[] ym, boolean[] has_na_x, boolean[] has_na_y, double[] ans, boolean[] sd_0, - boolean cor, + private static void cov_na_2(int n, int ncx, int ncy, double[] x, double[] y, double[] xm, double[] ym, boolean[] has_na_x, boolean[] has_na_y, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { int n1 = -1; if (n <= 1) {/* too many missing */ @@ -579,7 +578,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double yym = ym[j]; double sum = 0; for (int k = 0; k < n; k++) { - sum += (x.getDataAt(xx + k) - xxm) * (y.getDataAt(yy + k) - yym); + sum += (x[xx + k] - xxm) * (y[yy + k] - yym); } ANS(ans, ncx, i, j, sum / n1); } @@ -593,7 +592,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double sum = 0; for (int k = 0; k < n; k++) { for (n1 = 0; n1 < n; n1++) { - sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(y.getDataAt(yy + k) - y.getDataAt(yy + n1)); + sum += RMath.sign(x[xx + k] - x[xx + n1]) * RMath.sign(y[yy + k] - y[yy + n1]); } } ANS(ans, ncx, i, j, sum); @@ -641,9 +640,9 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { * This might look slightly inefficient, but it is designed to optimise paging in virtual memory * systems ... (or at least that's my story, and I'm sticking to it.) */ - private static void NA_LOOP(int n, int z, ReadAccessor.Double x, boolean[] ind, boolean na_fail) { + private static void NA_LOOP(int n, int z, double[] x, boolean[] ind, boolean na_fail) { for (int i = 0; i < n; i++) { - if (ISNAN(x.getDataAt(z + i))) { + if (ISNAN(x[z + i])) { if (na_fail) { error("missing observations in cov/cor"); } else { @@ -653,7 +652,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void complete1(int n, int ncx, ReadAccessor.Double x, boolean[] ind, boolean na_fail) { + private static void complete1(int n, int ncx, double[] x, boolean[] ind, boolean na_fail) { for (int i = 0; i < n; i++) { ind[i] = true; } @@ -663,7 +662,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void complete2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, boolean[] ind, boolean na_fail) { + static void complete2(int n, int ncx, int ncy, double[] x, double[] y, boolean[] ind, boolean na_fail) { complete1(n, ncx, x, ind, na_fail); for (int j = 0; j < ncy; j++) { @@ -672,12 +671,12 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void find_na_1(int n, int ncx, ReadAccessor.Double x, boolean[] has_na) { + static void find_na_1(int n, int ncx, double[] x, boolean[] has_na) { for (int j = 0; j < ncx; j++) { int z = j * n; has_na[j] = false; for (int i = 0; i < n; i++) { - if (ISNAN(x.getDataAt(z + i))) { + if (ISNAN(x[z + i])) { has_na[j] = true; break; } @@ -685,7 +684,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void find_na_2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, boolean[] has_na_x, boolean[] has_na_y) { + static void find_na_2(int n, int ncx, int ncy, double[] x, double[] y, boolean[] has_na_x, boolean[] has_na_y) { find_na_1(n, ncx, x, has_na_x); find_na_1(n, ncy, y, has_na_y); } @@ -694,36 +693,36 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { * co[vr](x, y, use = { 1, 2, 3, 4, 5 } "all.obs", "complete.obs", "pairwise.complete", * "everything", "na.or.complete" kendall = TRUE/FALSE) */ - public RDoubleVector corcov(ReadAccessor.Double x, ReadAccessor.Double y, int method, boolean kendall) throws RError { + public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, int method, boolean kendall) throws RError { int n, ncx, ncy; /* Arg.1: x */ - if (isFactorX.executeIsFactor(x.getVector())) { + if (isFactorX.executeIsFactor(x)) { error("'x' is a factor"); // maybe only warning: "Calling var(x) on a factor x is deprecated and will become an // error.\n Use something like 'all(duplicated(x)[-1L])' to test for a constant vector." } /* length check of x -- only if(empty_err) --> below */ - int[] xDims = getDimsXNode.getDimensions(x.getVector()); + int[] xDims = getDimsXNode.getDimensions(x); boolean ansmat = matrixProfile.profile(GetDimAttributeNode.isMatrix(xDims)); if ((ansmat)) { n = xDims[0]; ncx = xDims[1]; } else { - n = x.getVector().getLength(); + n = x.getLength(); ncx = 1; } /* Arg.2: y */ if (y == null) {/* y = x : var() */ ncy = ncx; } else { - if (isFactorY.executeIsFactor(y.getVector())) { + if (isFactorY.executeIsFactor(y)) { error("'y' is a factor"); // maybe only warning: "Calling var(x) on a factor x is deprecated and will become // an error.\n Use something like 'all(duplicated(x)[-1L])' to test for a constant // vector." } - int[] yDims = getDimsYNode.getDimensions(y.getVector()); + int[] yDims = getDimsYNode.getDimensions(y); if (GetDimAttributeNode.isMatrix(yDims)) { if (yDims[0] != n) { error("incompatible dimensions"); @@ -731,7 +730,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { ncy = yDims[1]; ansmat = true; } else { - if (y.getVector().getLength() != n) { + if (y.getLength() != n) { error("incompatible dimensions"); } ncy = 1; @@ -749,7 +748,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { break; case 2: /* complete */ /* did na.omit in R */ - if (x.getVector().getLength() == 0) { + if (x.getLength() == 0) { error("no complete element pairs"); } break; @@ -766,14 +765,15 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { default: error("invalid 'use' (computational method)"); } - if (empty_err && x.getVector().getLength() == 0) { + if (empty_err && x.getLength() == 0) { error("'x' is empty"); } + double[] xData = getReadonlyDataNode.execute(x); double[] ans = new double[ncx * ncy]; boolean[] sd_0 = new boolean[1]; - evaluate(y, kendall, isCor, n, ncx, ncy, na_fail, everything, empty_err, pair, x, ans, sd_0); + evaluate(y, kendall, isCor, n, ncx, ncy, na_fail, everything, empty_err, pair, xData, ans, sd_0); if (sd_0[0]) { /* only in cor() */ warning(RError.Message.SD_ZERO); @@ -791,7 +791,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { if (ansmat) { /* set dimnames() when applicable */ RList newDimNames = null; if (y == null) { - RList dimNames = getDimsNamesXNode.getDimNames(x.getVector()); + RList dimNames = getDimsNamesXNode.getDimNames(x); if (dimNames != null) { Object names = dimNames.getDataAt(1); if (names != RNull.instance) { @@ -799,8 +799,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } } else { - RList dimNamesX = getDimsNamesXNode.getDimNames(x.getVector()); - RList dimNamesY = getDimsNamesYNode.getDimNames(y.getVector()); + RList dimNamesX = getDimsNamesXNode.getDimNames(x); + RList dimNamesY = getDimsNamesYNode.getDimNames(y); Object namesX = dimNamesX.getLength() >= 2 ? dimNamesX.getDataAt(1) : RNull.instance; Object namesY = dimNamesY.getLength() >= 2 ? dimNamesY.getDataAt(1) : RNull.instance; if (namesX != RNull.instance || namesY != RNull.instance) { @@ -817,67 +817,98 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - @TruffleBoundary - private static void evaluate(ReadAccessor.Double y, boolean kendall, boolean cor, int n, int ncx, int ncy, boolean na_fail, boolean everything, boolean empty_err, boolean pair, - ReadAccessor.Double x, double[] ans, boolean[] sd_0) { + private void evaluate(RDoubleVector y, boolean kendall, boolean cor, int n, int ncx, int ncy, boolean na_fail, boolean everything, boolean empty_err, boolean pair, double[] xData, + double[] ans, boolean[] sd_0) { if (y == null) { - if (everything) { /* NA's are propagated */ - double[] xm = new double[ncx]; - boolean[] ind = new boolean[ncx]; - find_na_1(n, ncx, x, /* --> has_na[] = */ ind); - cov_na_1(n, ncx, x, xm, ind, ans, sd_0, cor, kendall); - } else if (!pair) { /* all | complete "var" */ - double[] xm = new double[ncx]; - boolean[] ind = new boolean[n]; - complete1(n, ncx, x, ind, na_fail); - cov_complete1(n, ncx, x, xm, ind, ans, sd_0, cor, kendall); - if (empty_err) { - boolean indany = false; - for (int i = 0; i < n; i++) { - if (ind[i]) { - indany = true; - break; - } - } - if (!indany) { - error("no complete element pairs"); - } + evaluateXOnly(kendall, cor, n, ncx, na_fail, everything, empty_err, pair, xData, ans, sd_0); + } else { /* Co[vr] (x, y) */ + evaluateWithY(y, kendall, cor, n, ncx, ncy, na_fail, everything, empty_err, pair, xData, ans, sd_0); + } + } + + private void evaluateWithY(RDoubleVector y, boolean kendall, boolean cor, int n, int ncx, int ncy, boolean na_fail, boolean everything, boolean empty_err, boolean pair, double[] xData, + double[] ans, boolean[] sd_0) { + double[] yData = getReadonlyDataNode.execute(y); + if (everything) { + evaluateWithYEverything(kendall, cor, n, ncx, ncy, xData, ans, sd_0, yData); + } else if (!pair) { /* all | complete */ + evaluateWithYAllOrComplete(kendall, cor, n, ncx, ncy, na_fail, empty_err, xData, ans, sd_0, yData); + } else { /* pairwise */ + cov_pairwise2(n, ncx, ncy, xData, yData, ans, sd_0, cor, kendall); + } + } + + @TruffleBoundary + private static void evaluateWithYAllOrComplete(boolean kendall, boolean cor, int n, int ncx, int ncy, boolean na_fail, boolean empty_err, double[] xData, double[] ans, boolean[] sd_0, + double[] yData) { + double[] xm = new double[ncx]; + double[] ym = new double[ncy]; + boolean[] ind = new boolean[n]; + complete2(n, ncx, ncy, xData, yData, ind, na_fail); + cov_complete2(n, ncx, ncy, xData, yData, xm, ym, ind, ans, sd_0, cor, kendall); + if (empty_err) { + boolean indany = false; + for (int i = 0; i < n; i++) { + if (ind[i]) { + indany = true; + break; } - } else { /* pairwise "var" */ - cov_pairwise1(n, ncx, x, ans, sd_0, cor, kendall); } - } else { /* Co[vr] (x, y) */ - if (everything) { - double[] xm = new double[ncx]; - double[] ym = new double[ncy]; - boolean[] ind = new boolean[ncx]; - boolean[] has_na_y = new boolean[ncy]; - find_na_2(n, ncx, ncy, x, y, ind, has_na_y); - cov_na_2(n, ncx, ncy, x, y, xm, ym, ind, has_na_y, ans, sd_0, cor, kendall); - } else if (!pair) { /* all | complete */ - double[] xm = new double[ncx]; - double[] ym = new double[ncy]; - boolean[] ind = new boolean[n]; - complete2(n, ncx, ncy, x, y, ind, na_fail); - cov_complete2(n, ncx, ncy, x, y, xm, ym, ind, ans, sd_0, cor, kendall); - if (empty_err) { - boolean indany = false; - for (int i = 0; i < n; i++) { - if (ind[i]) { - indany = true; - break; - } - } - if (!indany) { - error("no complete element pairs"); - } + if (!indany) { + error("no complete element pairs"); + } + } + } + + @TruffleBoundary + private static void evaluateWithYEverything(boolean kendall, boolean cor, int n, int ncx, int ncy, double[] xData, double[] ans, boolean[] sd_0, double[] yData) { + double[] xm = new double[ncx]; + double[] ym = new double[ncy]; + boolean[] ind = new boolean[ncx]; + boolean[] has_na_y = new boolean[ncy]; + find_na_2(n, ncx, ncy, xData, yData, ind, has_na_y); + cov_na_2(n, ncx, ncy, xData, yData, xm, ym, ind, has_na_y, ans, sd_0, cor, kendall); + } + + private static void evaluateXOnly(boolean kendall, boolean cor, int n, int ncx, boolean na_fail, boolean everything, boolean empty_err, boolean pair, double[] xData, double[] ans, + boolean[] sd_0) { + if (everything) { /* NA's are propagated */ + evaluateXOnlyEverything(kendall, cor, n, ncx, xData, ans, sd_0); + } else if (!pair) { /* all | complete "var" */ + evaluateXOnlyAllOrComplete(kendall, cor, n, ncx, na_fail, empty_err, xData, ans, sd_0); + } else { /* pairwise "var" */ + cov_pairwise1(n, ncx, xData, ans, sd_0, cor, kendall); + } + } + + @TruffleBoundary + private static void evaluateXOnlyAllOrComplete(boolean kendall, boolean cor, int n, int ncx, boolean na_fail, boolean empty_err, double[] xData, double[] ans, boolean[] sd_0) { + double[] xm = new double[ncx]; + boolean[] ind = new boolean[n]; + complete1(n, ncx, xData, ind, na_fail); + cov_complete1(n, ncx, xData, xm, ind, ans, sd_0, cor, kendall); + if (empty_err) { + boolean indany = false; + for (int i = 0; i < n; i++) { + if (ind[i]) { + indany = true; + break; } - } else { /* pairwise */ - cov_pairwise2(n, ncx, ncy, x, y, ans, sd_0, cor, kendall); + } + if (!indany) { + error("no complete element pairs"); } } } + @TruffleBoundary + private static void evaluateXOnlyEverything(boolean kendall, boolean cor, int n, int ncx, double[] xData, double[] ans, boolean[] sd_0) { + double[] xm = new double[ncx]; + boolean[] ind = new boolean[ncx]; + find_na_1(n, ncx, xData, /* --> has_na[] = */ ind); + cov_na_1(n, ncx, xData, xm, ind, ans, sd_0, cor, kendall); + } + private final boolean isCor; public Covcor(boolean isCor) { @@ -893,21 +924,20 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } @Specialization - public Object call(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, int method, boolean iskendall, - @Cached("create()") VectorReadAccess.Double vecReadAccess) { - return corcov(new ReadAccessor.Double(x, vecReadAccess), null, method, iskendall); + public Object call(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, int method, boolean iskendall) { + return corcov(x.materialize(), null, methodValueProfile.profile(method), iskendall); } @Specialization - public Object call(RAbstractDoubleVector x, RAbstractDoubleVector y, int method, boolean iskendall, - @Cached("create()") VectorReadAccess.Double xReadAccess, - @Cached("create()") VectorReadAccess.Double yReadAccess) { - return corcov(new ReadAccessor.Double(x, xReadAccess), new ReadAccessor.Double(y, yReadAccess), method, iskendall); + public Object call(RAbstractDoubleVector x, RAbstractDoubleVector y, int method, boolean iskendall) { + return corcov(x.materialize(), y.materialize(), methodValueProfile.profile(method), iskendall); } private final BranchProfile naInRes = BranchProfile.create(); private final ConditionProfile matrixProfile = ConditionProfile.createBinaryProfile(); + private final ValueProfile methodValueProfile = ValueProfile.createEqualityProfile(); + @Child private GetReadonlyData.Double getReadonlyDataNode = GetReadonlyData.Double.create(); @Child private GetDimAttributeNode getDimsXNode = GetDimAttributeNode.create(); @Child private GetDimAttributeNode getDimsYNode = GetDimAttributeNode.create(); @Child private GetDimNamesAttributeNode getDimsNamesXNode = GetDimNamesAttributeNode.create(); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java index 93cd847a3d3b093e9e1a5afe3530ebe9a3290052..f8b8ad866ba0f07df2f543055be4ad89d74ca373 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java @@ -13,11 +13,11 @@ package com.oracle.truffle.r.library.stats; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue; -import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.runtime.RError.Message.INVALID_UNNAMED_ARGUMENTS; +import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER; import java.util.Arrays; @@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RDouble; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.VectorIterator; import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double; import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double; import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction3_Double; @@ -161,6 +162,9 @@ public final class RandFunctionsNodes { protected abstract static class RandFunctionIntExecutorNode extends RandFunctionExecutorBase { @Child private RandFunction3_Double function; + @Child private VectorIterator.Double aIterator = VectorIterator.Double.createWrapAround(); + @Child private VectorIterator.Double bIterator = VectorIterator.Double.createWrapAround(); + @Child private VectorIterator.Double cIterator = VectorIterator.Double.createWrapAround(); protected RandFunctionIntExecutorNode(RandFunction3_Double function) { this.function = function; @@ -180,13 +184,16 @@ public final class RandFunctionsNodes { return RDataFactory.createIntVector(nansResult, false); } + Object aIt = aIterator.init(a); + Object bIt = bIterator.init(b); + Object cIt = cIterator.init(c); boolean nans = false; int[] result = new int[length]; nodeData.loopConditionProfile.profileCounted(length); for (int i = 0; nodeData.loopConditionProfile.inject(i < length); i++) { - double aValue = a.getDataAt(i % aLength); - double bValue = b.getDataAt(i % bLength); - double cValue = c.getDataAt(i % cLength); + double aValue = aIterator.next(a, aIt); + double bValue = bIterator.next(b, bIt); + double cValue = cIterator.next(c, cIt); double value = function.execute(aValue, bValue, cValue, randProvider); if (Double.isNaN(value) || value <= Integer.MIN_VALUE || value > Integer.MAX_VALUE) { nodeData.nan.enter(); @@ -206,6 +213,9 @@ public final class RandFunctionsNodes { protected abstract static class RandFunctionDoubleExecutorNode extends RandFunctionExecutorBase { @Child private RandFunction3_Double function; + @Child private VectorIterator.Double aIterator = VectorIterator.Double.createWrapAround(); + @Child private VectorIterator.Double bIterator = VectorIterator.Double.createWrapAround(); + @Child private VectorIterator.Double cIterator = VectorIterator.Double.createWrapAround(); protected RandFunctionDoubleExecutorNode(RandFunction3_Double function) { this.function = function; @@ -225,14 +235,17 @@ public final class RandFunctionsNodes { return RDataFactory.createDoubleVector(nansResult, false); } + Object aIt = aIterator.init(a); + Object bIt = bIterator.init(b); + Object cIt = cIterator.init(c); boolean nans = false; double[] result; result = new double[length]; nodeData.loopConditionProfile.profileCounted(length); for (int i = 0; nodeData.loopConditionProfile.inject(i < length); i++) { - double aValue = a.getDataAt(i % aLength); - double bValue = b.getDataAt(i % bLength); - double cValue = c.getDataAt(i % cLength); + double aValue = aIterator.next(a, aIt); + double bValue = bIterator.next(b, bIt); + double cValue = cIterator.next(c, cIt); double value = function.execute(aValue, bValue, cValue, randProvider); if (Double.isNaN(value) || RRuntime.isNA(value)) { nodeData.nan.enter(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java index c735800f28448de09e66be4fe3eb42c86af9d703..ce8e18ff2ebd92f8acf013df7bf5e8a1b5db84fc 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java @@ -33,6 +33,7 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; +import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RComplex; @@ -43,6 +44,7 @@ import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; +import com.oracle.truffle.r.runtime.data.nodes.EnableNACheckNode; import com.oracle.truffle.r.runtime.data.nodes.VectorIterator; import com.oracle.truffle.r.runtime.interop.ForeignArray2R; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -201,11 +203,13 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { @Specialization protected Object doIntVector(RAbstractIntVector operand, boolean naRm, boolean finite, + @Cached("create()") EnableNACheckNode enableNACheckNode, + @Cached("create()") RLengthNode lengthNode, @Cached("create()") VectorIterator.Int iterator) { - RBaseNode.reportWork(this, operand.getLength()); + RBaseNode.reportWork(this, lengthNode.executeInteger(operand)); boolean profiledNaRm = naRmProfile.profile(naRm || finite); int result = semantics.getIntStart(); - na.enable(operand); + enableNACheckNode.execute(na, operand); int opCount = 0; Object it = iterator.init(operand); while (iterator.hasNext(operand, it)) { @@ -236,14 +240,16 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { @Specialization protected double doDoubleVector(RAbstractDoubleVector operand, boolean naRm, boolean finite, + @Cached("create()") EnableNACheckNode enableNACheckNode, + @Cached("create()") RLengthNode lengthNode, @Cached("create()") VectorIterator.Double iterator, @Cached("createBinaryProfile()") ConditionProfile finiteProfile, @Cached("createBinaryProfile()") ConditionProfile isInfiniteProfile) { - RBaseNode.reportWork(this, operand.getLength()); + RBaseNode.reportWork(this, lengthNode.executeInteger(operand)); boolean profiledNaRm = naRmProfile.profile(naRm || finite); boolean profiledFinite = finiteProfile.profile(finite); double result = semantics.getDoubleStart(); - na.enable(operand); + enableNACheckNode.execute(na, operand); int opCount = 0; Object it = iterator.init(operand); @@ -274,11 +280,13 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { @Specialization protected Object doLogicalVector(RAbstractLogicalVector operand, boolean naRm, @SuppressWarnings("unused") boolean finite, + @Cached("create()") EnableNACheckNode enableNACheckNode, + @Cached("create()") RLengthNode lengthNode, @Cached("create()") VectorIterator.Logical iterator) { - RBaseNode.reportWork(this, operand.getLength()); + RBaseNode.reportWork(this, lengthNode.executeInteger(operand)); boolean profiledNaRm = naRmProfile.profile(naRm); int result = semantics.getIntStart(); - na.enable(operand); + enableNACheckNode.execute(na, operand); int opCount = 0; Object it = iterator.init(operand); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/EnableNACheckNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/EnableNACheckNode.java new file mode 100644 index 0000000000000000000000000000000000000000..63fd9a46ad164623671bbc371b8546643d7d846e --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/EnableNACheckNode.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.runtime.data.nodes; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.ops.na.NACheck; + +public abstract class EnableNACheckNode extends Node { + public abstract void execute(NACheck check, RAbstractVector vector); + + public static EnableNACheckNode create() { + return EnableNACheckNodeGen.create(); + } + + @Specialization(guards = "vector.getClass() == clazz", limit = "10") + public void doEnable(NACheck check, RAbstractVector vector, + @Cached("vector.getClass()") Class<? extends RAbstractVector> clazz) { + check.enable(clazz.cast(vector)); + } + + @Fallback + public void doEnable(NACheck check, RAbstractVector vector) { + check.enable(vector); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java index 4ba40b65984ec6251ce9df5be8e02effb52d9b29..f2ffc6e80be0be8bb4e4c0e5e6056f15d3f91d51 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.nodes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -45,15 +46,16 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.GetNextNodeGen.GetNextGenericNodeGen; import com.oracle.truffle.r.runtime.data.nodes.VectorIterator.IteratorData; abstract class VectorIteratorNodeAdapter extends Node { - public static boolean hasNoNativeMemoryData(RAbstractVector vector) { - return !(vector instanceof RVector<?>) || !((RVector<?>) vector).hasNativeMemoryData(); + public static boolean hasNoNativeMemoryData(RAbstractVector vector, Class<? extends RAbstractVector> vecClass) { + return !(RVector.class.isAssignableFrom(vecClass)) || !((RVector<?>) vecClass.cast(vector)).hasNativeMemoryData(); } - public static boolean isRVector(RAbstractVector vector) { - return vector instanceof RVector<?>; + public static boolean isRVector(Class<? extends RAbstractVector> vecClass) { + return RVector.class.isAssignableFrom(vecClass); } } @@ -65,11 +67,11 @@ abstract class GetIteratorNode extends VectorIteratorNodeAdapter { return new IteratorData<>(vector.getNativeMirror(), vector.getLength()); } - @Specialization(guards = {"hasNoNativeMemoryData(vector)", "vectorClass == vector.getClass()"}) + @Specialization(guards = {"vectorClass == vector.getClass()", "hasNoNativeMemoryData(vector, vectorClass)"}, limit = "10") protected IteratorData<?> generic(RAbstractVector vector, @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { RAbstractVector profiledVec = vectorClass.cast(vector); - return new IteratorData<>(profiledVec.getInternalStore(), vector.getLength()); + return new IteratorData<>(profiledVec.getInternalStore(), profiledVec.getLength()); } @Fallback @@ -106,7 +108,7 @@ abstract class HasNextNode extends VectorIteratorNodeAdapter { return iter.index < ((String[]) iter.store).length; } - @Specialization(guards = {"!isRVector(vector)", "vectorClass == vector.getClass()"}) + @Specialization(guards = {"vectorClass == vector.getClass()", "!isRVector(vectorClass)"}, limit = "10") protected boolean generic(RAbstractVector vector, IteratorData<?> iter, @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { RAbstractVector profiledVec = vectorClass.cast(vector); @@ -183,40 +185,64 @@ abstract class GetNextNode extends VectorIteratorNodeAdapter { throw RInternalError.unimplemented("string vectors backed by native memory"); } - @Specialization(guards = "!isRVector(vector)") - protected int intVectorGeneric(RAbstractIntVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Int getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + @Child private GetNextGenericNode getNextGenericNode; - @Specialization(guards = "!isRVector(vector)") - protected double doubleVectorGeneric(RAbstractDoubleVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Double getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); + @Fallback + protected Object doGeneric(RAbstractVector vector, IteratorData<?> iter) { + // we use fallback and extra node so that we do not have to explicitly check that the vector + // is not + // RVector, DSL generates fallback guard that compares the class with the all RVector + // subclasses + // used in the specializations above, "vector instanceof RVector" would not be a leaf-check. + if (getNextGenericNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNextGenericNode = insert(GetNextGenericNode.create()); + } + return getNextGenericNode.execute(vector, iter); } - @Specialization(guards = "!isRVector(vector)") - protected String stringVectorGeneric(RAbstractStringVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.String getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + abstract static class GetNextGenericNode extends Node { + public abstract Object execute(RAbstractVector vector, IteratorData<?> iter); - @Specialization(guards = "!isRVector(vector)") - protected byte rawVectorGeneric(RAbstractRawVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Raw getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + public static GetNextGenericNode create() { + return GetNextGenericNodeGen.create(); + } - @Specialization(guards = "!isRVector(vector)") - protected byte logicalVectorGeneric(RAbstractLogicalVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Logical getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + @Specialization + protected int intVectorGeneric(RAbstractIntVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Int getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected double doubleVectorGeneric(RAbstractDoubleVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Double getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } - @Specialization(guards = "!isRVector(vector)") - protected RComplex complexVectorGeneric(RAbstractComplexVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Complex getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); + @Specialization + protected String stringVectorGeneric(RAbstractStringVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.String getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected byte rawVectorGeneric(RAbstractRawVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Raw getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected byte logicalVectorGeneric(RAbstractLogicalVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Logical getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected RComplex complexVectorGeneric(RAbstractComplexVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Complex getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } } } @@ -308,6 +334,10 @@ public abstract class VectorIterator<T> extends Node { public static Double create() { return new Double(false); } + + public static Double createWrapAround() { + return new Double(true); + } } public static final class Logical extends VectorIterator<Byte> { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/IgnoreOS.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/IgnoreOS.java index 0be605720b6299850a916cb0fb4261605df83e9d..b478fbf2a9bcd5be775eb6fcccf882037d09ad6e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/IgnoreOS.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/IgnoreOS.java @@ -44,7 +44,7 @@ public enum IgnoreOS implements TestTrait { private boolean isIgnoring() { String current = System.getProperty("os.name"); - return current != null && current.contains(osName); + return current != null && current.toLowerCase().contains(osName); } @Override