From 94e313d15c5185002263c0af2e153f077f3830f3 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Mon, 28 Aug 2017 17:59:40 +0200 Subject: [PATCH] Use new nodes for vector operations --- .../r/ffi/impl/nodes/ListAccessNodes.java | 11 +- .../oracle/truffle/r/library/stats/Cdist.java | 24 +- .../truffle/r/library/stats/Covcor.java | 156 ++++++------ .../truffle/r/library/stats/Cutree.java | 10 +- .../truffle/r/library/stats/DoubleCentre.java | 12 +- .../r/library/stats/RMultinomNode.java | 22 +- .../r/library/stats/StatsFunctionsNodes.java | 16 +- .../builtin/base/ConnectionFunctions.java | 2 +- .../r/nodes/builtin/base/CrossprodCommon.java | 10 +- .../r/nodes/builtin/base/GrepFunctions.java | 5 +- .../r/nodes/builtin/base/LaFunctions.java | 21 +- .../truffle/r/nodes/builtin/base/MatMult.java | 10 +- .../truffle/r/nodes/builtin/base/Merge.java | 10 +- .../truffle/r/nodes/builtin/base/Split.java | 38 +-- .../truffle/r/nodes/builtin/base/Sum.java | 6 +- .../r/nodes/builtin/base/Transpose.java | 93 ++++---- .../base/printer/ValuePrinterNode.java | 7 +- .../vector/PositionCheckSubsetNode.java | 23 +- .../access/vector/SearchFirstStringNode.java | 2 +- .../SpecialAttributesFunctions.java | 16 +- .../function/ImplicitClassHierarchyNode.java | 5 +- .../r/nodes/primitive/BinaryMapNode.java | 222 +++++++++--------- .../r/nodes/primitive/UnaryMapNode.java | 118 ++++------ .../truffle/r/nodes/primitive/Utils.java | 71 ++++++ .../unary/UnaryArithmeticReduceNode.java | 79 ++----- .../r/runtime/data/nodes/VectorIterator.java | 4 +- .../r/runtime/nmath/distr/RMultinom.java | 4 +- 27 files changed, 509 insertions(+), 488 deletions(-) create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/Utils.java diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java index 0bce74744d..a5a57f7b33 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java @@ -22,8 +22,6 @@ */ package com.oracle.truffle.r.ffi.impl.nodes; -import java.util.Arrays; - import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -45,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypes; +import com.oracle.truffle.r.runtime.data.nodes.GetDataCopy; /** * Nodes that implement {@code CAR}, {@code CDR}, etc. N.B. GNU R does not error check the @@ -114,17 +113,17 @@ public final class ListAccessNodes { @Specialization protected Object cdr(RList list, + @Cached("create()") GetDataCopy.String getDataCopyNode, @Cached("create()") GetNamesAttributeNode getNamesNode, @Cached("create()") SetNamesAttributeNode setNamesNode) { if (list.getLength() == 1) { return RNull.instance; } - Object[] dataCopy = list.getDataWithoutCopying(); RStringVector names = getNamesNode.getNames(list); - RList copy = RDataFactory.createList(Arrays.copyOfRange(dataCopy, 1, list.getLength())); + RList copy = RDataFactory.createList(list.getDataCopy()); if (names != null) { - String[] dataWithoutCopying = names.getDataWithoutCopying(); - setNamesNode.setNames(copy, RDataFactory.createStringVector(Arrays.copyOfRange(dataWithoutCopying, 1, names.getLength()), true)); + String[] namesDataCopy = getDataCopyNode.execute(names); + setNamesNode.setNames(copy, RDataFactory.createStringVector(namesDataCopy, true)); } return copy; } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java index e9b73da151..cffbaad71f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java @@ -25,6 +25,8 @@ import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.data.nodes.ReadAccessor; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -32,8 +34,6 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector.DoubleAccessor; import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class Cdist extends RExternalBuiltinNode.Arg4 { @@ -51,7 +51,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { @Specialization(guards = "method == cachedMethod") protected RDoubleVector cdist(RAbstractDoubleVector x, @SuppressWarnings("unused") int method, RList list, double p, @SuppressWarnings("unused") @Cached("method") int cachedMethod, - @Cached("new()") AccessVector.Double xAccess, + @Cached("create()") VectorReadAccess.Double xAccess, @Cached("getMethod(method)") Method methodObj, @Cached("create()") SetAttributeNode setAttrNode, @Cached("create()") SetClassAttributeNode setClassAttrNode, @@ -61,7 +61,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { int n = nr * (nr - 1) / 2; /* avoid int overflow for N ~ 50,000 */ double[] ans = new double[n]; RDoubleVector xm = x.materialize(); - rdistance(new DoubleAccessor(x, xAccess), nr, nc, ans, false, methodObj, p); + rdistance(new ReadAccessor.Double(x, xAccess), nr, nc, ans, false, methodObj, p); RDoubleVector result = RDataFactory.createDoubleVector(ans, naCheck.neverSeenNA()); DynamicObject resultAttrs = result.initAttributes(); @@ -96,7 +96,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { return Method.values()[method - 1]; } - private void rdistance(DoubleAccessor xAccess, int nr, int nc, double[] d, boolean diag, Method method, double p) { + private void rdistance(ReadAccessor.Double xAccess, int nr, int nc, double[] d, boolean diag, Method method, double p) { int ij; /* can exceed 2^31 - 1, but Java can't handle that */ // if (method == Method.MINKOWSKI) { @@ -119,7 +119,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { public enum Method { EUCLIDEAN { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; double dev; @@ -152,7 +152,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { }, MAXIMUM { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; double dev; @@ -184,7 +184,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { }, MANHATTAN { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; double dev; @@ -217,7 +217,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { }, CANBERRA { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; double dev; @@ -258,7 +258,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { }, BINARY { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; int total; @@ -300,7 +300,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { }, MINKOWSKI { @Override - public double dist(DoubleAccessor xAccess, int nr, int nc, final int i1in, final int i2in, double p) { + public double dist(ReadAccessor.Double xAccess, int nr, int nc, final int i1in, final int i2in, double p) { int i1 = i1in; int i2 = i2in; double dev; @@ -331,6 +331,6 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { } }; - public abstract double dist(DoubleAccessor xAccess, int nr, int nc, int i1, int i2, double p); + public abstract double dist(ReadAccessor.Double xAccess, int nr, int nc, int i1, int i2, double p); } } 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 283a18303f..5b1928a954 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,6 +16,7 @@ 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; @@ -33,6 +34,8 @@ 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.nmath.RMath; /* @@ -70,20 +73,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, double[] x, 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, ReadAccessor.Double x, ReadAccessor.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[xx + k]) || ISNAN(y[yy + k]))) { + if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { nobs++; - xmean += x[xx + k]; - ymean += y[yy + k]; + xmean += x.getDataAt(xx + k); + ymean += y.getDataAt(yy + k); } } } else /* kendall */ for (int k = 0; k < n; k++) { - if (!(ISNAN(x[xx + k]) || ISNAN(y[yy + k]))) { + if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { nobs++; } } @@ -97,10 +100,10 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { n1 = nobs - 1; } for (int k = 0; k < n; k++) { - if (!(ISNAN(x[xx + k]) || ISNAN(y[yy + k]))) { + if (!(ISNAN(x.getDataAt(xx + k)) || ISNAN(y.getDataAt(yy + k)))) { if (!kendall) { - double xm = x[xx + k] - xmean; - double ym = y[yy + k] - ymean; + double xm = x.getDataAt(xx + k) - xmean; + double ym = y.getDataAt(yy + k) - ymean; sum += xm * ym; if (cor) { @@ -111,9 +114,9 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { else { /* Kendall's tau */ for (n1 = 0; n1 < k; 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]); + 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)); sum += xm * ym; if (cor) { @@ -148,7 +151,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_pairwise1(int n, int ncx, double[] x, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + private static void cov_pairwise1(int n, int ncx, ReadAccessor.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++) { @@ -161,7 +164,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_pairwise2(int n, int ncx, int ncy, double[] x, double[] y, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + 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) { for (int i = 0; i < ncx; i++) { int xx = i * n; for (int j = 0; j < ncy; j++) { @@ -177,14 +180,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { */ /* This uses two passes for better accuracy */ - private static void MEAN(int n, int ncx, double[] x, double[] xm, boolean[] ind, int nobs) { + private static void MEAN(int n, int ncx, ReadAccessor.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[xx + k]; + sum += x.getDataAt(xx + k); } } double tmp = sum / nobs; @@ -192,7 +195,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (x[xx + k] - tmp); + sum += (x.getDataAt(xx + k) - tmp); } } tmp = tmp + sum / nobs; @@ -202,7 +205,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } /* This uses two passes for better accuracy */ - private static void MEAN_(int n, int ncx, double[] x, double[] xm, boolean[] has_na) { + private static void MEAN_(int n, int ncx, ReadAccessor.Double x, double[] xm, boolean[] has_na) { /* variable means (has_na) */ for (int i = 0; i < ncx; i++) { double tmp; @@ -212,13 +215,13 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { int xx = i * n; double sum = 0; for (int k = 0; k < n; k++) { - sum += x[xx + k]; + sum += x.getDataAt(xx + k); } tmp = sum / n; if (Double.isFinite(tmp)) { sum = 0; for (int k = 0; k < n; k++) { - sum += (x[xx + k] - tmp); + sum += (x.getDataAt(xx + k) - tmp); } tmp = tmp + sum / n; } @@ -227,7 +230,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void cov_complete1(int n, int ncx, double[] x, double[] xm, boolean[] ind, double[] ans, boolean[] sd_0, boolean cor, boolean kendall) { + 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) { int n1 = -1; /* total number of complete observations */ @@ -261,7 +264,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double sum = 0; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (x[xx + k] - xxm) * (x[yy + k] - yym); + sum += (x.getDataAt(xx + k) - xxm) * (x.getDataAt(yy + k) - yym); } } double result = sum / n1; @@ -276,7 +279,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { if (ind[k]) { for (n1 = 0; n1 < n; n1++) { if (ind[n1]) { - sum += RMath.sign(x[xx + k] - x[xx + n1]) * RMath.sign(x[yy + k] - x[yy + n1]); + sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(x.getDataAt(yy + k) - x.getDataAt(yy + n1)); } } } @@ -313,7 +316,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - 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) { + 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) { int n1 = -1; if (n <= 1) { /* too many missing */ for (int i = 0; i < ncx; i++) { @@ -348,7 +351,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double yym = xm[j]; double sum = 0; for (int k = 0; k < n; k++) { - sum += (x[xx + k] - xxm) * (x[yy + k] - yym); + sum += (x.getDataAt(xx + k) - xxm) * (x.getDataAt(yy + k) - yym); } double result = sum / n1; ANS(ans, ncx, j, i, result); @@ -365,7 +368,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[xx + k] - x[xx + n1]) * RMath.sign(x[yy + k] - x[yy + n1]); + sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(x.getDataAt(yy + k) - x.getDataAt(yy + n1)); } } ANS(ans, ncx, j, i, sum); @@ -406,7 +409,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void COV_SDEV1(int n, int n1, int nc, double[] array, double[] m, boolean[] ind, boolean kendall) { + private static void COV_SDEV1(int n, int n1, int nc, ReadAccessor.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; @@ -414,7 +417,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double xxm = m[i]; for (int k = 0; k < n; k++) { if (ind[k]) { - sum += (array[xx + k] - xxm) * (array[xx + k] - xxm); + sum += (array.getDataAt(xx + k) - xxm) * (array.getDataAt(xx + k) - xxm); } } sum /= n1; @@ -422,7 +425,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[xx + k] != array[xx + n1_]) { + if (ind[n1_] && array.getDataAt(xx + k) != array.getDataAt(xx + n1_)) { sum++; /* = sign(. - .)^2 */ } } @@ -433,7 +436,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - 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) { + 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) { int n1 = -1; /* total number of complete observations */ @@ -467,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[xx + k] - xxm) * (y[yy + k] - yym); + sum += (x.getDataAt(xx + k) - xxm) * (y.getDataAt(yy + k) - yym); } } ANS(ans, ncx, i, j, sum / n1); @@ -480,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[xx + k] - x[xx + n1]) * RMath.sign(y[yy + k] - y[yy + n1]); + sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(y.getDataAt(yy + k) - y.getDataAt(yy + n1)); } } } @@ -515,7 +519,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void COV_SDEV2(int n, int n1, int nc, double[] array, double[] m, boolean[] has_na, boolean kendall) { + private static void COV_SDEV2(int n, int n1, int nc, ReadAccessor.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; @@ -523,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[xx + k] - xxm) * (array[xx + k] - xxm); + sum += (array.getDataAt(xx + k) - xxm) * (array.getDataAt(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[xx + k] != array[xx + n1_]) { + if (array.getDataAt(xx + k) != array.getDataAt(xx + n1_)) { sum++; /* = sign(. - .)^2 */ } } @@ -540,7 +544,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - 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, + 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, boolean kendall) { int n1 = -1; if (n <= 1) {/* too many missing */ @@ -574,7 +579,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { double yym = ym[j]; double sum = 0; for (int k = 0; k < n; k++) { - sum += (x[xx + k] - xxm) * (y[yy + k] - yym); + sum += (x.getDataAt(xx + k) - xxm) * (y.getDataAt(yy + k) - yym); } ANS(ans, ncx, i, j, sum / n1); } @@ -588,7 +593,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[xx + k] - x[xx + n1]) * RMath.sign(y[yy + k] - y[yy + n1]); + sum += RMath.sign(x.getDataAt(xx + k) - x.getDataAt(xx + n1)) * RMath.sign(y.getDataAt(yy + k) - y.getDataAt(yy + n1)); } } ANS(ans, ncx, i, j, sum); @@ -636,9 +641,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, double[] x, boolean[] ind, boolean na_fail) { + private static void NA_LOOP(int n, int z, ReadAccessor.Double x, boolean[] ind, boolean na_fail) { for (int i = 0; i < n; i++) { - if (ISNAN(x[z + i])) { + if (ISNAN(x.getDataAt(z + i))) { if (na_fail) { error("missing observations in cov/cor"); } else { @@ -648,7 +653,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - private static void complete1(int n, int ncx, double[] x, boolean[] ind, boolean na_fail) { + private static void complete1(int n, int ncx, ReadAccessor.Double x, boolean[] ind, boolean na_fail) { for (int i = 0; i < n; i++) { ind[i] = true; } @@ -658,7 +663,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void complete2(int n, int ncx, int ncy, double[] x, double[] y, boolean[] ind, boolean na_fail) { + static void complete2(int n, int ncx, int ncy, ReadAccessor.Double x, ReadAccessor.Double y, boolean[] ind, boolean na_fail) { complete1(n, ncx, x, ind, na_fail); for (int j = 0; j < ncy; j++) { @@ -667,12 +672,12 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void find_na_1(int n, int ncx, double[] x, boolean[] has_na) { + static void find_na_1(int n, int ncx, ReadAccessor.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[z + i])) { + if (ISNAN(x.getDataAt(z + i))) { has_na[j] = true; break; } @@ -680,7 +685,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } - static void find_na_2(int n, int ncx, int ncy, double[] x, double[] y, boolean[] has_na_x, boolean[] has_na_y) { + 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) { find_na_1(n, ncx, x, has_na_x); find_na_1(n, ncy, y, has_na_y); } @@ -689,36 +694,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(RDoubleVector x, RDoubleVector y, int method, boolean kendall) throws RError { + public RDoubleVector corcov(ReadAccessor.Double x, ReadAccessor.Double y, int method, boolean kendall) throws RError { int n, ncx, ncy; /* Arg.1: x */ - if (isFactorX.executeIsFactor(x)) { + if (isFactorX.executeIsFactor(x.getVector())) { 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); + int[] xDims = getDimsXNode.getDimensions(x.getVector()); boolean ansmat = matrixProfile.profile(GetDimAttributeNode.isMatrix(xDims)); if ((ansmat)) { n = xDims[0]; ncx = xDims[1]; } else { - n = x.getLength(); + n = x.getVector().getLength(); ncx = 1; } /* Arg.2: y */ if (y == null) {/* y = x : var() */ ncy = ncx; } else { - if (isFactorY.executeIsFactor(y)) { + if (isFactorY.executeIsFactor(y.getVector())) { 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); + int[] yDims = getDimsYNode.getDimensions(y.getVector()); if (GetDimAttributeNode.isMatrix(yDims)) { if (yDims[0] != n) { error("incompatible dimensions"); @@ -726,7 +731,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { ncy = yDims[1]; ansmat = true; } else { - if (y.getLength() != n) { + if (y.getVector().getLength() != n) { error("incompatible dimensions"); } ncy = 1; @@ -744,7 +749,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { break; case 2: /* complete */ /* did na.omit in R */ - if (x.getLength() == 0) { + if (x.getVector().getLength() == 0) { error("no complete element pairs"); } break; @@ -761,15 +766,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { default: error("invalid 'use' (computational method)"); } - if (empty_err && x.getLength() == 0) { + if (empty_err && x.getVector().getLength() == 0) { error("'x' is empty"); } - double[] xData = x.getDataWithoutCopying(); 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, xData, ans, sd_0); + evaluate(y, kendall, isCor, n, ncx, ncy, na_fail, everything, empty_err, pair, x, ans, sd_0); if (sd_0[0]) { /* only in cor() */ warning(RError.Message.SD_ZERO); @@ -787,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); + RList dimNames = getDimsNamesXNode.getDimNames(x.getVector()); if (dimNames != null) { Object names = dimNames.getDataAt(1); if (names != RNull.instance) { @@ -795,8 +799,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } } else { - RList dimNamesX = getDimsNamesXNode.getDimNames(x); - RList dimNamesY = getDimsNamesYNode.getDimNames(y); + RList dimNamesX = getDimsNamesXNode.getDimNames(x.getVector()); + RList dimNamesY = getDimsNamesYNode.getDimNames(y.getVector()); 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) { @@ -814,19 +818,19 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } @TruffleBoundary - private static 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) { + 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) { if (y == null) { if (everything) { /* NA's are propagated */ 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); + 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, xData, ind, na_fail); - cov_complete1(n, ncx, xData, xm, ind, ans, sd_0, cor, kendall); + 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++) { @@ -840,23 +844,22 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } } else { /* pairwise "var" */ - cov_pairwise1(n, ncx, xData, ans, sd_0, cor, kendall); + cov_pairwise1(n, ncx, x, ans, sd_0, cor, kendall); } } else { /* Co[vr] (x, y) */ - double[] yData = y.getDataWithoutCopying(); 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, 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); + 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, xData, yData, ind, na_fail); - cov_complete2(n, ncx, ncy, xData, yData, xm, ym, ind, ans, sd_0, cor, kendall); + 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++) { @@ -870,7 +873,7 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } } } else { /* pairwise */ - cov_pairwise2(n, ncx, ncy, xData, yData, ans, sd_0, cor, kendall); + cov_pairwise2(n, ncx, ncy, x, y, ans, sd_0, cor, kendall); } } } @@ -890,13 +893,16 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { } @Specialization - public Object call(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, int method, boolean iskendall) { - return corcov(x.materialize(), null, method, iskendall); + 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); } @Specialization - public Object call(RAbstractDoubleVector x, RAbstractDoubleVector y, int method, boolean iskendall) { - return corcov(x.materialize(), y.materialize(), method, iskendall); + 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); } private final BranchProfile naInRes = BranchProfile.create(); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java index 4bb86b4814..0a07a8b78c 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java @@ -20,7 +20,7 @@ import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; // translated from library/stats/src/hclust_utils.c @@ -34,8 +34,8 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { @Specialization protected RIntVector cutree(RAbstractIntVector merge, RAbstractIntVector which, - @Cached("new()") AccessVector.Int mergeAccess, - @Cached("new()") AccessVector.Int whichAccess, + @Cached("create()") VectorReadAccess.Int mergeAccess, + @Cached("create()") VectorReadAccess.Int whichAccess, @Cached("create()") GetDimAttributeNode getDimNode) { int whichLen = which.getLength(); @@ -59,8 +59,8 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { int[] z = new int[n]; int[] iAns = new int[n * whichLen]; - Object mergeStore = mergeAccess.init(merge); - Object whichStore = whichAccess.init(which); + Object mergeStore = mergeAccess.getDataStore(merge); + Object whichStore = whichAccess.getDataStore(which); // for (k = 1; k <= n; k++) { for (k = 0; k < n; k++) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java index b1b5b7c187..62883376e1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java @@ -20,7 +20,8 @@ import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { @@ -31,11 +32,12 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { @Specialization protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs, - @Cached("new()") AccessVector.Double aAccess, + @Cached("create()") VectorReadAccess.Double aAccess, + @Cached("create()") SetDataAt.Double aSetter, @Cached("create()") GetDimAttributeNode getDimNode) { RDoubleVector aVec = aVecAbs.materialize(); int n = getDimNode.nrows(aVec); - Object aStore = aAccess.init(aVec); + Object aStore = aAccess.getDataStore(aVec); for (int i = 0; i < n; i++) { double sum = 0; for (int j = 0; j < n; j++) { @@ -44,7 +46,7 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { sum /= n; for (int j = 0; j < n; j++) { double val = aAccess.getDataAt(aVec, aStore, i + j * n); - aAccess.setDataAt(aVec, aStore, i + j * n, val - sum); + aSetter.setDataAt(aVec, aStore, i + j * n, val - sum); } } for (int j = 0; j < n; j++) { @@ -55,7 +57,7 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { sum /= n; for (int i = 0; i < n; i++) { double val = aAccess.getDataAt(aVec, aStore, i + j * n); - aAccess.setDataAt(aVec, aStore, i + j * n, val - sum); + aSetter.setDataAt(aVec, aStore, i + j * n, val - sum); } } return aVec; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java index 8167a7610c..56fa2752f5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java @@ -36,8 +36,9 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntVector; 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.AccessVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector.DoubleAccessor; +import com.oracle.truffle.r.runtime.data.nodes.ReadAccessor; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider; import com.oracle.truffle.r.runtime.nmath.distr.RMultinom; import com.oracle.truffle.r.runtime.nmath.distr.Rbinom; @@ -68,7 +69,8 @@ public abstract class RMultinomNode extends RExternalBuiltinNode.Arg3 { @Specialization protected RIntVector doMultinom(int n, int size, RAbstractDoubleVector probsVec, - @Cached("new()") AccessVector.Double probsAccess, + @Cached("create()") VectorReadAccess.Double probsAccess, + @Cached("create()") SetDataAt.Double probsSetter, @Cached("create()") ReuseNonSharedNode reuseNonSharedNode, @Cached("createClassProfile()") ValueProfile randGeneratorClassProfile, @Cached("createBinaryProfile()") ConditionProfile hasAttributesProfile, @@ -76,12 +78,12 @@ public abstract class RMultinomNode extends RExternalBuiltinNode.Arg3 { @Cached("createNames()") GetFixedAttributeNode getNamesNode, @Cached("createDimNames()") SetFixedAttributeNode setDimNamesNode) { RDoubleVector nonSharedProbs = ((RAbstractDoubleVector) reuseNonSharedNode.execute(probsVec)).materialize(); - DoubleAccessor probs = new DoubleAccessor(nonSharedProbs, probsAccess); - fixupProb(nonSharedProbs, probs.store, probsAccess); + ReadAccessor.Double probs = new ReadAccessor.Double(nonSharedProbs, probsAccess); + fixupProb(nonSharedProbs, probs, probsSetter); RRNG.getRNGState(); RandomNumberProvider rand = new RandomNumberProvider(randGeneratorClassProfile.profile(RRNG.currentGenerator()), RRNG.currentNormKind()); - int k = probs.vector.getLength(); + int k = nonSharedProbs.getLength(); int[] result = new int[k * n]; boolean isComplete = true; for (int i = 0, ik = 0; i < n; i++, ik += k) { @@ -100,12 +102,12 @@ public abstract class RMultinomNode extends RExternalBuiltinNode.Arg3 { return resultVec; } - private void fixupProb(RDoubleVector p, Object pStore, AccessVector.Double pAccess) { + private void fixupProb(RDoubleVector p, ReadAccessor.Double pAccess, SetDataAt.Double pSetter) { double sum = 0.0; int npos = 0; int pLength = p.getLength(); for (int i = 0; i < pLength; i++) { - double prob = pAccess.getDataAt(p, pStore, i); + double prob = pAccess.getDataAt(i); if (!Double.isFinite(prob)) { throw error(NA_IN_PROB_VECTOR); } @@ -121,8 +123,8 @@ public abstract class RMultinomNode extends RExternalBuiltinNode.Arg3 { throw error(NO_POSITIVE_PROBABILITIES); } for (int i = 0; i < pLength; i++) { - double prob = pAccess.getDataAt(p, pStore, i); - pAccess.setDataAt(p, pStore, i, prob / sum); + double prob = pAccess.getDataAt(i); + pSetter.setDataAt(p, pAccess.getStore(), i, prob / sum); } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java index ee14351e7b..ebba5274ac 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java @@ -46,8 +46,8 @@ import com.oracle.truffle.r.runtime.data.RDouble; import com.oracle.truffle.r.runtime.data.RDoubleVector; 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.AccessVector; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector.DoubleAccessor; +import com.oracle.truffle.r.runtime.data.nodes.ReadAccessor; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1; import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2; import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1; @@ -376,8 +376,8 @@ public final class StatsFunctionsNodes { @Specialization protected RDoubleVector approx(RAbstractDoubleVector x, RAbstractDoubleVector y, RAbstractDoubleVector v, int method, double yl, double yr, double f, - @Cached("new()") AccessVector.Double xAccess, - @Cached("new()") AccessVector.Double yAccess) { + @Cached("create()") VectorReadAccess.Double xAccess, + @Cached("create()") VectorReadAccess.Double yAccess) { int nx = x.getLength(); int nout = v.getLength(); double[] yout = new double[nout]; @@ -390,8 +390,8 @@ public final class StatsFunctionsNodes { apprMeth.yhigh = yr; naCheck.enable(true); - DoubleAccessor xAccessor = new DoubleAccessor(x, xAccess); - DoubleAccessor yAccessor = new DoubleAccessor(y, yAccess); + ReadAccessor.Double xAccessor = new ReadAccessor.Double(x, xAccess); + ReadAccessor.Double yAccessor = new ReadAccessor.Double(y, yAccess); for (int i = 0; i < nout; i++) { double xouti = v.getDataAt(i); yout[i] = RRuntime.isNAorNaN(xouti) ? xouti : approx1(xouti, xAccessor, yAccessor, nx, apprMeth); @@ -408,8 +408,8 @@ public final class StatsFunctionsNodes { int kind; } - private static double approx1(double v, DoubleAccessor x, DoubleAccessor y, int n, - ApprMeth apprMeth) { + private static double approx1(double v, ReadAccessor.Double x, ReadAccessor.Double y, int n, + ApprMeth apprMeth) { /* Approximate y(v), given (x,y)[i], i = 0,..,n-1 */ int i; int j; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java index 792abffb0e..0a8f312ca4 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java @@ -1005,7 +1005,7 @@ public abstract class ConnectionFunctions { chars = new byte[1]; chars[0] = ((RRaw) vec).getRawDataAt(0); } else { - chars = ((RRawVector) vec).getDataWithoutCopying(); + chars = ((RRawVector) vec).getReadonlyData(); } strings.add(new String(chars, 0, n)); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CrossprodCommon.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CrossprodCommon.java index 0b0041f6e7..e88dada037 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CrossprodCommon.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CrossprodCommon.java @@ -44,7 +44,7 @@ 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.model.RAbstractVector; -import com.oracle.truffle.r.runtime.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; /** * Implements the basic logic for {@code crossprod} and {@code tcrossprod}. Either the first matrix @@ -102,7 +102,7 @@ public abstract class CrossprodCommon extends RBuiltinNode.Arg2 { @Specialization(guards = "x.isMatrix()") protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, - @Cached("create()") VectorToArray vectorToArrayNode, + @Cached("create()") GetReadonlyData.Double getReadonlyData, @Cached("create()") GetDimAttributeNode getDimsNode, @Cached("create()") GetDimAttributeNode getResultDimsNode) { int[] xDims = getDimsNode.getDimensions(x); @@ -113,7 +113,7 @@ public abstract class CrossprodCommon extends RBuiltinNode.Arg2 { RDoubleVector result = mirror( matMult.doubleMatrixMultiply(x, x, xRows, xCols, yRows, yCols, getXRowStride(xDims[0]), getXColStride(xDims[0]), getYRowStride(xDims[0]), getYColStride(xDims[0]), true), getResultDimsNode, - vectorToArrayNode); + getReadonlyData); return copyDimNames(x, x, result); } @@ -172,13 +172,13 @@ public abstract class CrossprodCommon extends RBuiltinNode.Arg2 { return result; } - private static RDoubleVector mirror(RDoubleVector result, GetDimAttributeNode getResultDimsNode, VectorToArray vectorToArrayNode) { + private static RDoubleVector mirror(RDoubleVector result, GetDimAttributeNode getResultDimsNode, GetReadonlyData.Double getReadonlyData) { // Mirroring the result is not only good for performance, but it is also required to produce // the same result as GNUR. int[] resultDims = getResultDimsNode.getDimensions(result); assert result.isMatrix() && resultDims[0] == resultDims[1]; int size = resultDims[0]; - double[] data = vectorToArrayNode.getReadonly(result); + double[] data = getReadonlyData.execute(result); for (int row = 0; row < size; row++) { int destIndex = row * size + row + 1; int sourceIndex = (row + 1) * size + row; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java index 2df8eb6037..ea9010d63e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java @@ -1103,10 +1103,11 @@ public class GrepFunctions { RIntVector res; if (pattern.length() == 0) { String txt = vector.getDataAt(i); - res = RDataFactory.createIntVector(txt.length()); + int[] resData = new int[txt.length()]; for (int j = 0; j < txt.length(); j++) { - res.setDataAt(res.getInternalStore(), j, j + 1); + resData[j] = j + 1; } + res = RDataFactory.createIntVector(resData, RDataFactory.COMPLETE_VECTOR); setMatchLengthAttrNode.execute(res, RDataFactory.createIntVector(txt.length())); if (useBytes) { setUseBytesAttrNode.execute(res, RRuntime.LOGICAL_TRUE); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java index 8902a830b0..ec52c0c753 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java @@ -62,7 +62,7 @@ import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; import com.oracle.truffle.r.runtime.ffi.LapackRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -321,8 +321,8 @@ public class LaFunctions { @Specialization protected RDoubleVector doQrCoefReal(RList qIn, RAbstractDoubleVector b, - @Cached("create()") VectorToArray qrToArrayNode, - @Cached("create()") VectorToArray tauToArrayNode, + @Cached("create()") GetReadonlyData.Double qrToArrayNode, + @Cached("create()") GetReadonlyData.Double tauToArrayNode, @Cached("create()") GetDimAttributeNode getBDimsNode, @Cached("create()") GetDimAttributeNode getQDimsNode, @Cached("create()") LapackRFFI.DormqrNode dormqrNode, @@ -341,8 +341,8 @@ public class LaFunctions { int nrhs = bDims[1]; double[] work = new double[1]; // qr and tau do not really need copying - double[] qrData = qrToArrayNode.getReadonly(qr); - double[] tauData = tauToArrayNode.getReadonly(tau); + double[] qrData = qrToArrayNode.execute(qr); + double[] tauData = tauToArrayNode.execute(tau); // this will be the result, we are going to modify this array double[] bData = b.materialize().getDataCopy(); // ask for optimal size of work array @@ -387,7 +387,7 @@ public class LaFunctions { @Specialization protected RList doDetGeReal(RAbstractDoubleVector aIn, boolean useLog, - @Cached("create()") VectorToArray vectorToArrayNode, + @Cached("create()") GetReadonlyData.Double vectorToArrayNode, @Cached("create()") GetDimAttributeNode getDimsNode, @Cached("create()") LapackRFFI.DgetrfNode dgetrfNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); @@ -395,7 +395,7 @@ public class LaFunctions { int n = aDims[0]; int[] ipiv = new int[n]; double modulus = 0; - double[] aData = vectorToArrayNode.getReadonly(a); + double[] aData = vectorToArrayNode.execute(a); int info = dgetrfNode.execute(n, n, aData, n, ipiv); int sign = 1; if (info < 0) { @@ -656,7 +656,10 @@ public class LaFunctions { bData = bin.materialize().getDataNonShared(); } else { bData = new double[n]; - System.arraycopy(bin.getInternalStore(), 0, bData, 0, n * p); + // TODO: length for arraycopy is n*p, but bData is new double[n] ?? Should be + // rewritten to manually copy using getDataAt, or using a new node in + // c.o.t.r.runtime.data.nodes (the same in the "else" branch) + System.arraycopy(bin.materialize().getReadonlyData(), 0, bData, 0, n * p); } b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); setBDimsNode.setDimensions(b, new int[]{n, p}); @@ -680,7 +683,7 @@ public class LaFunctions { bData = bin.materialize().getDataNonShared(); } else { bData = new double[n]; - System.arraycopy(bin.getInternalStore(), 0, bData, 0, n * p); + System.arraycopy(bin.materialize().getReadonlyData(), 0, bData, 0, n * p); } b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); if (aDn != null) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java index bddcb8ae9d..53a2fe0007 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java @@ -58,7 +58,7 @@ 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.model.RAbstractVector; -import com.oracle.truffle.r.runtime.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -151,8 +151,8 @@ public abstract class MatMult extends RBuiltinNode.Arg2 { private final BranchProfile incompleteProfile = BranchProfile.create(); @CompilationFinal private boolean seenLargeMatrix; - @Child private VectorToArray aToArrayNode = VectorToArray.create(); - @Child private VectorToArray bToArrayNode = VectorToArray.create(); + @Child private GetReadonlyData.Double aToArrayNode = GetReadonlyData.Double.create(); + @Child private GetReadonlyData.Double bToArrayNode = GetReadonlyData.Double.create(); private RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols) { return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, 1, aRows, 1, bRows, false); @@ -180,8 +180,8 @@ public abstract class MatMult extends RBuiltinNode.Arg2 { if (aCols != bRows) { throw error(RError.Message.NON_CONFORMABLE_ARGS); } - double[] dataA = aToArrayNode.getReadonly(a.materialize()); - double[] dataB = bToArrayNode.getReadonly(b.materialize()); + double[] dataA = aToArrayNode.execute(a.materialize()); + double[] dataB = bToArrayNode.execute(b.materialize()); double[] result = new double[aRows * bCols]; if (!seenLargeMatrix && (aRows > BLOCK_SIZE || aCols > BLOCK_SIZE || bRows > BLOCK_SIZE || bCols > BLOCK_SIZE)) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Merge.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Merge.java index c7f2e01661..d5a57d1dff 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Merge.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Merge.java @@ -31,7 +31,7 @@ import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; /** * Note: invoked from merge.data.frame. @@ -82,8 +82,8 @@ public abstract class Merge extends RBuiltinNode.Arg4 { @Specialization RList merge(RAbstractIntVector xIndsAbstract, RAbstractIntVector yIndsAbstract, boolean allX, boolean allY, - @Cached("create()") VectorToArray xIndsToArray, - @Cached("create()") VectorToArray yIndsToArray) { + @Cached("create()") GetReadonlyData.Int xIndsToArray, + @Cached("create()") GetReadonlyData.Int yIndsToArray) { RIntVector xInds = xIndsAbstract.materialize(); RIntVector yInds = yIndsAbstract.materialize(); @@ -98,8 +98,8 @@ public abstract class Merge extends RBuiltinNode.Arg4 { for (int i = 0; i < ny; i++) { iy[i] = i + 1; } - int[] xIndsData = xIndsToArray.getReadonly(xInds); - int[] yIndsData = yIndsToArray.getReadonly(yInds); + int[] xIndsData = xIndsToArray.execute(xInds); + int[] yIndsData = yIndsToArray.execute(yInds); isortWithIndex(xIndsData, ix, nx); isortWithIndex(yIndsData, iy, ny); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java index 57d232e5c9..0a06e7de94 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java @@ -44,7 +44,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; 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.AccessVector; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; /** * The {@code split} internal. Internal version of 'split' is invoked from 'split.default' function @@ -64,7 +64,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @SuppressWarnings("unused") private final ConditionProfile noStringLevels = ConditionProfile.createBinaryProfile(); private final ConditionProfile namesProfile = ConditionProfile.createBinaryProfile(); - @Child private AccessVector.Int factorAccess = new AccessVector.Int(); + @Child private VectorReadAccess.Int factorAccess = VectorReadAccess.Int.create(); private static final int INITIAL_SIZE = 5; private static final int SCALE_FACTOR = 2; @@ -75,7 +75,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RAbstractListVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -89,7 +89,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector Object[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -109,7 +110,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RAbstractIntVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -123,7 +124,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector int[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -143,7 +145,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RAbstractDoubleVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -157,7 +159,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector double[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -177,7 +180,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RAbstractStringVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -191,7 +194,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector String[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -211,7 +215,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RAbstractLogicalVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -225,7 +229,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector byte[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -245,7 +250,7 @@ public abstract class Split extends RBuiltinNode.Arg2 { @Specialization protected RList split(RRawVector x, RAbstractIntVector f) { - Object fStore = factorAccess.init(f); + Object fStore = factorAccess.getDataStore(f); RStringVector names = getLevelNode.execute(f); final int nLevels = getNLevels(names); @@ -259,7 +264,8 @@ public abstract class Split extends RBuiltinNode.Arg2 { // perform split int factorLen = f.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(f, fStore, fi) - 1; // a factor is a 1-based + // int vector byte[] collect = collectResults[resultIndex]; if (collect.length == collectResultSize[resultIndex]) { collectResults[resultIndex] = Arrays.copyOf(collect, collect.length * SCALE_FACTOR); @@ -287,7 +293,9 @@ public abstract class Split extends RBuiltinNode.Arg2 { } int factorLen = factor.getLength(); for (int i = 0, fi = 0; i < x.getLength(); ++i, fi = Utils.incMod(fi, factorLen)) { - int resultIndex = factorAccess.getDataAt(factor, fStore, fi) - 1; // a factor is a 1-based int vector + int resultIndex = factorAccess.getDataAt(factor, fStore, fi) - 1; // a factor is a + // 1-based int + // vector namesArr[resultIndex][resultNamesIdxs[resultIndex]++] = xNames.getDataAt(i); } RStringVector[] resultNames = new RStringVector[nLevels]; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java index aa0cd2a7d0..24a3fbadbb 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java @@ -42,7 +42,7 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; import com.oracle.truffle.r.runtime.ffi.MiscRFFI; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -75,7 +75,7 @@ public abstract class Sum extends RBuiltinNode.Arg2 { @Specialization(guards = {"FULL_PRECISION", "args.getLength() == 1", "isRDoubleVector(args.getArgument(0))", "naRm == cachedNaRm"}) protected double sumLengthOneRDoubleVector(RArgsValuesAndNames args, @SuppressWarnings("unused") boolean naRm, - @Cached("create()") VectorToArray vectorToArrayNode, + @Cached("create()") GetReadonlyData.Double vectorToArrayNode, @Cached("naRm") boolean cachedNaRm, @Cached("create()") VectorLengthProfile lengthProfile, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @@ -86,7 +86,7 @@ public abstract class Sum extends RBuiltinNode.Arg2 { int length = lengthProfile.profile(vector.getLength()); if (needsExactSumProfile.profile(length >= 3)) { - return exactSumNode.execute(vectorToArrayNode.getReadonly(vector), !vector.isComplete(), cachedNaRm); + return exactSumNode.execute(vectorToArrayNode.execute(vector), !vector.isComplete(), cachedNaRm); } else { na.enable(vector); loopProfile.profileCounted(length); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java index 6bfbaee476..b61abc3dc0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java @@ -19,6 +19,7 @@ import java.util.function.BiFunction; import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives; +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.profiles.BranchProfile; @@ -53,6 +54,8 @@ 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.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorReadAccess; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @RBuiltin(name = "t.default", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE) @@ -117,7 +120,7 @@ public abstract class Transpose extends RBuiltinNode.Arg1 { return r; } - protected RVector<?> transposeSquareMatrixInPlace(RVector<?> vector, Swap swapper) { + protected RVector<?> transposeSquareMatrixInPlace(RVector<?> vector, Object store, VectorReadAccess readAccess, SetDataAt setter, Swap swap) { int length = lengthProfile.profile(vector.getLength()); assert vector.isMatrix(); int[] dims = getDimensions(vector); @@ -129,7 +132,16 @@ public abstract class Transpose extends RBuiltinNode.Arg1 { loopProfile.profileCounted(length); for (int i = 0; loopProfile.inject(i < dim); i++) { for (int j = 0; j < i; j++) { - swapper.swap(i * dim + j, j * dim + i); + int swapi = i * dim + j; + int swapj = j * dim + i; + if (swap != null) { + swap.swap(swapi, swapj); + } else { + Object tmp = readAccess.getDataAtAsObject(vector, store, swapi); + Object jVal = readAccess.getDataAtAsObject(vector, store, swapj); + setter.setDataAtAsObject(vector, store, swapi, jVal); + setter.setDataAtAsObject(vector, store, swapj, tmp); + } } } // don't need to set new dimensions; it is a square matrix @@ -156,68 +168,55 @@ public abstract class Transpose extends RBuiltinNode.Arg1 { } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractIntVector x) { + protected RVector<?> transposeSquare(RAbstractIntVector x, + @Cached("create()") VectorReadAccess.Int readAccess, + @Cached("create()") SetDataAt.Int setter) { RIntVector reused = (RIntVector) reuseNonShared.execute(x).materialize(); - int[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - int tmp = store[i]; - store[i] = store[j]; - store[j] = tmp; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractLogicalVector x) { + protected RVector<?> transposeSquare(RAbstractLogicalVector x, + @Cached("create()") VectorReadAccess.Logical readAccess, + @Cached("create()") SetDataAt.Logical setter) { RLogicalVector reused = (RLogicalVector) reuseNonShared.execute(x).materialize(); - byte[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - byte tmp = store[i]; - store[i] = store[j]; - store[j] = tmp; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractDoubleVector x) { + protected RVector<?> transposeSquare(RAbstractDoubleVector x, + @Cached("create()") VectorReadAccess.Double readAccess, + @Cached("create()") SetDataAt.Double setter) { RDoubleVector reused = (RDoubleVector) reuseNonShared.execute(x).materialize(); - double[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - double tmp = store[i]; - store[i] = store[j]; - store[j] = tmp; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractComplexVector x) { + protected RVector<?> transposeSquare(RAbstractComplexVector x, + @Cached("create()") VectorReadAccess.Complex readAccess, + @Cached("create()") SetDataAt.Complex setter) { RComplexVector reused = (RComplexVector) reuseNonShared.execute(x).materialize(); - double[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - double tmpReal = store[i * 2]; - double tmpImg = store[i * 2 + 1]; - store[i * 2] = store[j * 2]; - store[i * 2 + 1] = store[j * 2 + 1]; - store[j * 2] = tmpReal; - store[j * 2 + 1] = tmpImg; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractStringVector x) { + protected RVector<?> transposeSquare(RAbstractStringVector x, + @Cached("create()") VectorReadAccess.String readAccess, + @Cached("create()") SetDataAt.String setter) { RStringVector reused = (RStringVector) reuseNonShared.execute(x).materialize(); - String[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - String tmp = store[i]; - store[i] = store[j]; - store[j] = tmp; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = "isSquare(x)") protected RVector<?> transposeSquare(RAbstractListVector x) { RList reused = (RList) reuseNonShared.execute(x).materialize(); Object[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { + return transposeSquareMatrixInPlace(reused, store, null, null, (i, j) -> { Object tmp = store[i]; store[i] = store[j]; store[j] = tmp; @@ -225,14 +224,12 @@ public abstract class Transpose extends RBuiltinNode.Arg1 { } @Specialization(guards = "isSquare(x)") - protected RVector<?> transposeSquare(RAbstractRawVector x) { + protected RVector<?> transposeSquare(RAbstractRawVector x, + @Cached("create()") VectorReadAccess.Raw readAccess, + @Cached("create()") SetDataAt.Raw setter) { RRawVector reused = (RRawVector) reuseNonShared.execute(x).materialize(); - byte[] store = reused.getDataWithoutCopying(); - return transposeSquareMatrixInPlace(reused, (i, j) -> { - byte tmp = store[i]; - store[i] = store[j]; - store[j] = tmp; - }); + Object reusedStore = readAccess.getDataStore(reused); + return transposeSquareMatrixInPlace(reused, reusedStore, readAccess, setter, null); } @Specialization(guards = {"x.isMatrix()", "!isSquare(x)"}) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java index aefbeedf3e..333012b046 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java @@ -281,10 +281,13 @@ public final class ValuePrinterNode extends RBaseNode { if (keys != null) { int size = (Integer) ForeignAccess.sendGetSize(getSizeNode, keys); RAbstractStringVector abstractNames = new RStringWrapper(size, keys); - RStringVector names = RDataFactory.createStringVector(size); + String[] namesData = new String[size]; + boolean namesComplete = true; for (int i = 0; i < size; i++) { - names.setDataAt(names.getInternalStore(), i, abstractNames.getDataAt(i)); + namesData[i] = abstractNames.getDataAt(i); + namesComplete &= RRuntime.isNA(namesData[i]); } + RStringVector names = RDataFactory.createStringVector(namesData, namesComplete); return new RListWrapper(size, names); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java index 2549c6cfcd..46379181ea 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java @@ -40,6 +40,7 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -143,14 +144,7 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { @Cached("createCountingProfile()") LoopConditionProfile lengthProfile, @Cached("create()") GetNamesAttributeNode getNamesNode, @Cached("create()") SetNamesAttributeNode setNamesNode) { - RAbstractIntVector intPosition = RDataFactory.createIntVector(positionLength); - // requires names preservation - RStringVector names = hasNamesProfile.profile(getNamesNode.getNames(position)); - if (names != null) { - setNamesNode.setNames(intPosition, names); - } - Object convertedStore = intPosition.getInternalStore(); - + int[] intPosition = new int[positionLength]; positionNACheck.enable(position); boolean hasSeenPositive = false; boolean hasSeenNegative = false; @@ -201,10 +195,17 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { intPositionValue--; } } - intPosition.setDataAt(convertedStore, i, intPositionValue); + intPosition[i] = intPositionValue; } - intPosition.setComplete(!hasSeenNA); - return doIntegerProfiled(profile, dimensionLength, intPosition, positionLength, hasSeenPositive, hasSeenNegative, hasSeenNA, outOfBoundsCount, zeroCount, maxOutOfBoundsIndex); + + RIntVector intPositionVec = RDataFactory.createIntVector(intPosition, !hasSeenNA); + // requires names preservation + RStringVector names = hasNamesProfile.profile(getNamesNode.getNames(position)); + if (names != null) { + setNamesNode.setNames(intPositionVec, names); + } + + return doIntegerProfiled(profile, dimensionLength, intPositionVec, positionLength, hasSeenPositive, hasSeenNegative, hasSeenNA, outOfBoundsCount, zeroCount, maxOutOfBoundsIndex); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/SearchFirstStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/SearchFirstStringNode.java index b1baf683b5..e197f4dd5e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/SearchFirstStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/SearchFirstStringNode.java @@ -110,7 +110,7 @@ final class SearchFirstStringNode extends Node { if (exactMatch) { RAbstractIntVector genericResult = searchGeneric(target, targetLength, elements, elementsLength, -1, true, names); if (genericResult != null) { - return (int[]) genericResult.getInternalStore(); + return genericResult.materialize().getReadonlyData(); } } return null; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java index aa5ab4daaf..523657c936 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -614,6 +614,12 @@ public final class SpecialAttributesFunctions { return GetDimAttributeNodeGen.create(); } + // TODO: getDimensions returns a naked array, which is in many places used to create a fresh + // vector ignoring the reference counting. This should really return a vector and the users + // should increment its ref-count if they want to put it into other + // attributes/list/environment/... This way, we wouldn't need to call getReadonlyData, which + // may copy the contents. + public final int[] getDimensions(Object x) { // Let's handle the following two types directly so as to avoid wrapping and unwrapping // RIntVector. The getContainerDims spec would be invoked otherwise. @@ -626,7 +632,7 @@ public final class SpecialAttributesFunctions { return ((RPairList) x).getDimensions(); } RIntVector dims = (RIntVector) execute(x); - return nullDimsProfile.profile(dims == null) ? null : dims.getInternalStore(); + return nullDimsProfile.profile(dims == null) ? null : dims.getReadonlyData(); } public static boolean isArray(int[] dimensions) { @@ -637,6 +643,14 @@ public final class SpecialAttributesFunctions { return dimensions != null && dimensions.length == 2; } + public static boolean isArray(RIntVector dimensions) { + return dimensions != null && dimensions.getLength() > 0; + } + + public static boolean isMatrix(RIntVector dimensions) { + return dimensions != null && dimensions.getLength() == 2; + } + public final boolean isArray(RAbstractVector vector) { RIntVector dims = (RIntVector) execute(vector); return nullDimsProfile.profile(dims == null) ? false : dims.getLength() > 0; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java index 11da744043..728001f28b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java @@ -138,10 +138,9 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { RAttributable attributable = (RAttributable) value; RIntVector dim = (RIntVector) attributable.getAttr(RRuntime.DIM_ATTR_KEY); if (dim != null) { - int[] dimArray = dim.getInternalStore(); - if (GetDimAttributeNode.isMatrix(dimArray)) { + if (GetDimAttributeNode.isMatrix(dim)) { return implicitMatrixClass; - } else if (GetDimAttributeNode.isArray(dimArray)) { + } else if (GetDimAttributeNode.isArray(dim)) { return implicitArrayClass; } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java index 164d40610d..a77f74f63d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java @@ -23,6 +23,7 @@ package com.oracle.truffle.r.nodes.primitive; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; @@ -36,7 +37,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RScalarVector; @@ -49,6 +49,9 @@ 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.GetDataStore; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorIterator; import com.oracle.truffle.r.runtime.nodes.RBaseNode; /** @@ -251,16 +254,15 @@ public final class BinaryMapNode extends RBaseNode { } if (target == null) { int maxLength = maxLengthProfile.profile(leftLength >= rightLength) ? leftLength : rightLength; - target = createOrShareVector(leftLength, left, rightLength, right, maxLength); - Object store = target.getInternalStore(); + RVector<?> targetVec = createOrShareVector(leftLength, left, rightLength, right, maxLength); + target = targetVec; assert left.getLength() == leftLength; assert right.getLength() == rightLength; assert leftCast.getRType() == argumentType; assert rightCast.getRType() == argumentType; - assert isStoreCompatible(store, resultType, leftLength, rightLength); - vectorNode.execute(function, store, leftCast, leftLength, rightCast, rightLength); + vectorNode.execute(function, targetVec, leftCast, leftLength, rightCast, rightLength); RBaseNode.reportWork(this, maxLength); target.setComplete(function.isComplete()); } @@ -270,111 +272,60 @@ public final class BinaryMapNode extends RBaseNode { return target; } - private RAbstractVector createOrShareVector(int leftLength, RAbstractVector left, int rightLength, RAbstractVector right, int maxLength) { - if (mayShareLeft && left.getRType() == resultType && shareLeft.profile(leftLength == maxLength && ((RShareable) left).isTemporary())) { - return left; + private RVector<?> createOrShareVector(int leftLength, RAbstractVector left, int rightLength, RAbstractVector right, int maxLength) { + if (mayShareLeft && left.getRType() == resultType && shareLeft.profile(leftLength == maxLength && ((RShareable) left).isTemporary()) && left instanceof RVector<?>) { + return (RVector<?>) left; } - if (mayShareRight && right.getRType() == resultType && shareRight.profile(rightLength == maxLength && ((RShareable) right).isTemporary())) { - return right; + if (mayShareRight && right.getRType() == resultType && shareRight.profile(rightLength == maxLength && ((RShareable) right).isTemporary()) && right instanceof RVector<?>) { + return (RVector<?>) right; } return resultType.create(maxLength, false); } - private static boolean isStoreCompatible(Object store, RType resultType, int leftLength, int rightLength) { - int maxLength = Math.max(leftLength, rightLength); - switch (resultType) { - case Raw: - assert store instanceof byte[] && ((byte[]) store).length == maxLength; - return true; - case Logical: - assert store instanceof byte[] && ((byte[]) store).length == maxLength; - return true; - case Integer: - assert store instanceof int[] && ((int[]) store).length == maxLength; - return true; - case Double: - assert store instanceof double[] && ((double[]) store).length == maxLength; - return true; - case Complex: - assert store instanceof double[] && ((double[]) store).length >> 1 == maxLength; - return true; - case Character: - assert store instanceof String[] && ((String[]) store).length == maxLength; - return true; - default: - throw RInternalError.shouldNotReachHere(); - } - } - + @ImportStatic(Utils.class) protected abstract static class VectorMapBinaryInternalNode extends RBaseNode { - private static final MapBinaryIndexedAction<byte[], RAbstractLogicalVector> LOGICAL_LOGICAL = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractIntVector> LOGICAL_INTEGER = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractDoubleVector> LOGICAL_DOUBLE = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractComplexVector> LOGICAL_COMPLEX = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractStringVector> LOGICAL_CHARACTER = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractRawVector> LOGICAL_RAW = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyLogical(RRuntime.raw2int(left.getRawDataAt(leftIndex)), RRuntime.raw2int(right.getRawDataAt(rightIndex))); - }; - private static final MapBinaryIndexedAction<byte[], RAbstractRawVector> RAW_RAW = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyRaw(left.getRawDataAt(leftIndex), right.getRawDataAt(rightIndex)); - }; - - private static final MapBinaryIndexedAction<int[], RAbstractIntVector> INTEGER_INTEGER = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyInteger(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - - private static final MapBinaryIndexedAction<double[], RAbstractIntVector> DOUBLE_INTEGER = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyDouble(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - - private static final MapBinaryIndexedAction<double[], RAbstractDoubleVector> DOUBLE = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyDouble(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - - private static final MapBinaryIndexedAction<double[], RAbstractComplexVector> COMPLEX = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - RComplex value = arithmetic.applyComplex(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - result[resultIndex << 1] = value.getRealPart(); - result[(resultIndex << 1) + 1] = value.getImaginaryPart(); - }; - private static final MapBinaryIndexedAction<String[], RAbstractStringVector> CHARACTER = // - (arithmetic, result, resultIndex, left, leftIndex, right, rightIndex) -> { - result[resultIndex] = arithmetic.applyCharacter(left.getDataAt(leftIndex), right.getDataAt(rightIndex)); - }; - - private final MapBinaryIndexedAction<Object, RAbstractVector> indexedAction; + private static final MapBinaryIndexedAction<Byte> LOGICAL_LOGICAL = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(leftVal, rightVal); + private static final MapBinaryIndexedAction<Integer> LOGICAL_INTEGER = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(leftVal, rightVal); + private static final MapBinaryIndexedAction<Double> LOGICAL_DOUBLE = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(leftVal, rightVal); + private static final MapBinaryIndexedAction<RComplex> LOGICAL_COMPLEX = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(leftVal, rightVal); + private static final MapBinaryIndexedAction<String> LOGICAL_CHARACTER = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(leftVal, rightVal); + private static final MapBinaryIndexedAction<Byte> LOGICAL_RAW = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyLogical(RRuntime.raw2int(leftVal), RRuntime.raw2int(rightVal)); + private static final MapBinaryIndexedAction<Byte> RAW_RAW = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyRaw(leftVal, rightVal); + private static final MapBinaryIndexedAction<Integer> INTEGER_INTEGER = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyInteger(leftVal, rightVal); + private static final MapBinaryIndexedAction<Integer> DOUBLE_INTEGER = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyDouble(leftVal, rightVal); + private static final MapBinaryIndexedAction<Double> DOUBLE = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyDouble(leftVal, rightVal); + private static final MapBinaryIndexedAction<RComplex> COMPLEX = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyComplex(leftVal, rightVal); + private static final MapBinaryIndexedAction<String> CHARACTER = // + (arithmetic, leftVal, rightVal) -> arithmetic.applyCharacter(leftVal, rightVal); + + private final MapBinaryIndexedAction<Object> indexedAction; + + @Child private GetDataStore getTargetDataStore = GetDataStore.create(); + @Child private SetDataAt targetSetDataAt; @SuppressWarnings("unchecked") protected VectorMapBinaryInternalNode(RType resultType, RType argumentType) { - this.indexedAction = (MapBinaryIndexedAction<Object, RAbstractVector>) createIndexedAction(resultType, argumentType); + this.indexedAction = (MapBinaryIndexedAction<Object>) createIndexedAction(resultType, argumentType); + this.targetSetDataAt = Utils.createSetDataAtNode(resultType); } public static VectorMapBinaryInternalNode create(RType resultType, RType argumentType) { return VectorMapBinaryInternalNodeGen.create(resultType, argumentType); } - private static MapBinaryIndexedAction<? extends Object, ? extends RAbstractVector> createIndexedAction(RType resultType, RType argumentType) { + private static MapBinaryIndexedAction<?> createIndexedAction(RType resultType, RType argumentType) { switch (resultType) { case Raw: assert argumentType == RType.Raw; @@ -419,41 +370,66 @@ public final class BinaryMapNode extends RBaseNode { } } - public abstract void execute(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength); + public abstract void execute(BinaryMapFunctionNode node, RVector<?> store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength); @Specialization(guards = {"leftLength == 1", "rightLength == 1"}) @SuppressWarnings("unused") - protected void doScalarScalar(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength) { - indexedAction.perform(node, store, 0, left, 0, right, 0); + protected void doScalarScalar(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIterator()") VectorIterator.Generic leftIterator, + @Cached("createIterator()") VectorIterator.Generic rightIterator) { + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, getTargetDataStore.execute(result), 0, value); } @Specialization(replaces = "doScalarScalar", guards = {"leftLength == 1"}) @SuppressWarnings("unused") - protected void doScalarVector(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doScalarVector(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIterator()") VectorIterator.Generic leftIterator, + @Cached("createIterator()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile profile) { profile.profileCounted(rightLength); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); + Object leftValue = leftIterator.next(left, itLeft); for (int i = 0; profile.inject(i < rightLength); ++i) { - indexedAction.perform(node, store, i, left, 0, right, i); + Object value = indexedAction.perform(node, leftValue, rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, resultStore, i, value); } } @Specialization(replaces = "doScalarScalar", guards = {"rightLength == 1"}) @SuppressWarnings("unused") - protected void doVectorScalar(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doVectorScalar(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIterator()") VectorIterator.Generic leftIterator, + @Cached("createIterator()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile profile) { profile.profileCounted(leftLength); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); + Object rightValue = rightIterator.next(right, itRight); for (int i = 0; profile.inject(i < leftLength); ++i) { - indexedAction.perform(node, store, i, left, i, right, 0); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightValue); + targetSetDataAt.setDataAtAsObject(result, resultStore, i, value); } } @Specialization(guards = {"leftLength == rightLength"}) @SuppressWarnings("unused") - protected void doSameLength(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doSameLength(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIterator()") VectorIterator.Generic leftIterator, + @Cached("createIterator()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile profile) { profile.profileCounted(leftLength); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); for (int i = 0; profile.inject(i < leftLength); ++i) { - indexedAction.perform(node, store, i, left, i, right, i); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, resultStore, i, value); } } @@ -462,30 +438,42 @@ public final class BinaryMapNode extends RBaseNode { } @Specialization(replaces = {"doVectorScalar", "doScalarVector", "doSameLength"}, guards = {"multiplesMinMax(leftLength, rightLength)"}) - protected void doMultiplesLeft(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doMultiplesLeft(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIteratorWrapAround()") VectorIterator.Generic leftIterator, + @Cached("createIterator()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile leftProfile, @Cached("createCountingProfile()") LoopConditionProfile rightProfile) { int j = 0; rightProfile.profileCounted(rightLength / leftLength); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); while (rightProfile.inject(j < rightLength)) { leftProfile.profileCounted(leftLength); for (int k = 0; leftProfile.inject(k < leftLength); k++) { - indexedAction.perform(node, store, j, left, k, right, j); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, resultStore, j, value); j++; } } } @Specialization(replaces = {"doVectorScalar", "doScalarVector", "doSameLength"}, guards = {"multiplesMinMax(rightLength, leftLength)"}) - protected void doMultiplesRight(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doMultiplesRight(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIterator()") VectorIterator.Generic leftIterator, + @Cached("createIteratorWrapAround()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile leftProfile, @Cached("createCountingProfile()") LoopConditionProfile rightProfile) { int j = 0; leftProfile.profileCounted(leftLength / rightLength); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); while (leftProfile.inject(j < leftLength)) { rightProfile.profileCounted(rightLength); for (int k = 0; rightProfile.inject(k < rightLength); k++) { - indexedAction.perform(node, store, j, left, j, right, k); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, resultStore, j, value); j++; } } @@ -505,26 +493,26 @@ public final class BinaryMapNode extends RBaseNode { } @Specialization(guards = {"!multiples(leftLength, rightLength)"}) - protected void doNoMultiples(BinaryMapFunctionNode node, Object store, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + protected void doNoMultiples(BinaryMapFunctionNode node, RVector<?> result, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength, + @Cached("createIteratorWrapAround()") VectorIterator.Generic leftIterator, + @Cached("createIteratorWrapAround()") VectorIterator.Generic rightIterator, @Cached("createCountingProfile()") LoopConditionProfile profile, @Cached("createBinaryProfile()") ConditionProfile leftIncModProfile, @Cached("createBinaryProfile()") ConditionProfile rightIncModProfile) { - int j = 0; - int k = 0; int max = Math.max(leftLength, rightLength); profile.profileCounted(max); + Object itLeft = leftIterator.init(left); + Object itRight = rightIterator.init(right); + Object resultStore = getTargetDataStore.execute(result); for (int i = 0; profile.inject(i < max); ++i) { - indexedAction.perform(node, store, i, left, j, right, k); - j = Utils.incMod(j, leftLength, leftIncModProfile); - k = Utils.incMod(k, rightLength, rightIncModProfile); + Object value = indexedAction.perform(node, leftIterator.next(left, itLeft), rightIterator.next(right, itRight)); + targetSetDataAt.setDataAtAsObject(result, resultStore, i, value); } RError.warning(this, RError.Message.LENGTH_NOT_MULTI); } - private interface MapBinaryIndexedAction<A, V extends RAbstractVector> { - - void perform(BinaryMapFunctionNode action, A store, int resultIndex, V left, int leftIndex, V right, int rightIndex); - + private interface MapBinaryIndexedAction<V> { + Object perform(BinaryMapFunctionNode action, V left, V right); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java index b901cd6780..aaa72efdec 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java @@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.primitive; 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.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; @@ -46,8 +47,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; 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.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.GetDataStore; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorIterator; import com.oracle.truffle.r.runtime.nodes.RBaseNode; public final class UnaryMapNode extends RBaseNode { @@ -150,9 +153,9 @@ public final class UnaryMapNode extends RBaseNode { target = scalarNode.tryFoldConstantTime(operandCast, operandLength); } if (target == null) { - target = createOrShareVector(operandLength, operand); - Object store = target.getInternalStore(); - vectorNode.apply(scalarNode, store, operandCast, operandLength); + RVector<?> targetVec = createOrShareVector(operandLength, operand); + target = targetVec; + vectorNode.apply(scalarNode, targetVec, operandCast, operandLength); RBaseNode.reportWork(this, operandLength); target.setComplete(scalarNode.isComplete()); } @@ -162,10 +165,10 @@ public final class UnaryMapNode extends RBaseNode { return target; } - private RAbstractVector createOrShareVector(int operandLength, RAbstractVector operand) { + private RVector<?> createOrShareVector(int operandLength, RAbstractVector operand) { RType resultType = getResultType(); - if (mayShareOperand && operand.getRType() == resultType && shareOperand.profile(((RShareable) operand).isTemporary())) { - return operand; + if (mayShareOperand && operand.getRType() == resultType && shareOperand.profile(((RShareable) operand).isTemporary()) && operand instanceof RVector<?>) { + return (RVector<?>) operand; } return resultType.create(operandLength, false); } @@ -211,50 +214,29 @@ public final class UnaryMapNode extends RBaseNode { result.copyNamesFrom(attributeSource); } - @SuppressWarnings("unused") + @ImportStatic(Utils.class) protected abstract static class MapUnaryVectorInternalNode extends RBaseNode { - private static final MapIndexedAction<byte[], RAbstractLogicalVector> LOGICAL = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - result[resultIndex] = arithmetic.applyLogical(left.getDataAt(leftIndex)); - }; - - private static final MapIndexedAction<int[], RAbstractIntVector> INTEGER = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - result[resultIndex] = arithmetic.applyInteger(left.getDataAt(leftIndex)); - }; - - private static final MapIndexedAction<double[], RAbstractDoubleVector> DOUBLE = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - result[resultIndex] = arithmetic.applyDouble(left.getDataAt(leftIndex)); - }; - - private static final MapIndexedAction<double[], RAbstractComplexVector> COMPLEX = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - RComplex value = arithmetic.applyComplex(left.getDataAt(leftIndex)); - result[resultIndex << 1] = value.getRealPart(); - result[(resultIndex << 1) + 1] = value.getImaginaryPart(); - }; - - private static final MapIndexedAction<double[], RAbstractComplexVector> DOUBLE_COMPLEX = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - result[resultIndex] = arithmetic.applyDouble(left.getDataAt(leftIndex)); - }; - - private static final MapIndexedAction<String[], RAbstractStringVector> CHARACTER = // - (arithmetic, result, resultIndex, left, leftIndex) -> { - result[resultIndex] = arithmetic.applyCharacter(left.getDataAt(leftIndex)); - }; - - private final MapIndexedAction<Object, RAbstractVector> indexedAction; + private static final MapIndexedAction<Byte> LOGICAL = (arithmetic, value) -> arithmetic.applyLogical(value); + private static final MapIndexedAction<Integer> INTEGER = (arithmetic, value) -> arithmetic.applyInteger(value); + private static final MapIndexedAction<Double> DOUBLE = (arithmetic, value) -> arithmetic.applyDouble(value); + private static final MapIndexedAction<RComplex> COMPLEX = (arithmetic, value) -> arithmetic.applyComplex(value); + private static final MapIndexedAction<RComplex> DOUBLE_COMPLEX = (arithmetic, value) -> arithmetic.applyDouble(value); + private static final MapIndexedAction<String> CHARACTER = (arithmetic, value) -> arithmetic.applyCharacter(value); + + private final MapIndexedAction<Object> indexedAction; private final RType argumentType; private final RType resultType; + @Child private GetDataStore getTargetDataStore = GetDataStore.create(); + @Child private SetDataAt targetSetDataAt; + @SuppressWarnings("unchecked") protected MapUnaryVectorInternalNode(RType resultType, RType argumentType) { - this.indexedAction = (MapIndexedAction<Object, RAbstractVector>) createIndexedAction(resultType, argumentType); + this.indexedAction = (MapIndexedAction<Object>) createIndexedAction(resultType, argumentType); this.argumentType = argumentType; this.resultType = resultType; + this.targetSetDataAt = Utils.createSetDataAtNode(resultType); } public RType getArgumentType() { @@ -269,7 +251,7 @@ public final class UnaryMapNode extends RBaseNode { return MapUnaryVectorInternalNodeGen.create(resultType, argumentType); } - private static MapIndexedAction<? extends Object, ? extends RAbstractVector> createIndexedAction(RType resultType, RType argumentType) { + private static MapIndexedAction<?> createIndexedAction(RType resultType, RType argumentType) { switch (argumentType) { case Logical: return LOGICAL; @@ -300,56 +282,38 @@ public final class UnaryMapNode extends RBaseNode { } } - private void apply(UnaryMapFunctionNode scalarAction, Object store, RAbstractVector operand, int operandLength) { + private void apply(UnaryMapFunctionNode scalarAction, RVector<?> target, RAbstractVector operand, int operandLength) { assert operand.getLength() == operandLength; assert operand.getRType() == argumentType; - assert isStoreCompatible(store, resultType, operandLength); - - executeInternal(scalarAction, store, operand, operandLength); - } - - private static boolean isStoreCompatible(Object store, RType resultType, int operandLength) { - switch (resultType) { - case Logical: - assert store instanceof byte[] && ((byte[]) store).length == operandLength; - return true; - case Integer: - assert store instanceof int[] && ((int[]) store).length == operandLength; - return true; - case Double: - assert store instanceof double[] && ((double[]) store).length == operandLength; - return true; - case Complex: - assert store instanceof double[] && ((double[]) store).length >> 1 == operandLength; - return true; - case Character: - assert store instanceof String[] && ((String[]) store).length == operandLength; - return true; - default: - throw RInternalError.shouldNotReachHere(); - } + executeInternal(scalarAction, target, operand, operandLength); } protected abstract void executeInternal(UnaryMapFunctionNode node, Object store, RAbstractVector operand, int operandLength); @Specialization(guards = {"operandLength == 1"}) - protected void doScalar(UnaryMapFunctionNode node, Object store, RAbstractVector operand, int operandLength) { - indexedAction.perform(node, store, 0, operand, 0); + protected void doScalar(UnaryMapFunctionNode node, RVector<?> target, RAbstractVector operand, int operandLength, + @Cached("createIterator()") VectorIterator.Generic iterator) { + Object it = iterator.init(operand); + Object targetStore = getTargetDataStore.execute(target); + Object value = iterator.next(operand, it); + targetSetDataAt.setDataAtAsObject(target, targetStore, 0, indexedAction.perform(node, value)); } @Specialization(replaces = "doScalar") - protected void doScalarVector(UnaryMapFunctionNode node, Object store, RAbstractVector operand, int operandLength, + protected void doScalarVector(UnaryMapFunctionNode node, RVector<?> target, RAbstractVector operand, int operandLength, + @Cached("createIterator()") VectorIterator.Generic iterator, @Cached("createCountingProfile()") LoopConditionProfile profile) { + Object targetStore = getTargetDataStore.execute(target); + Object it = iterator.init(operand); profile.profileCounted(operandLength); for (int i = 0; profile.inject(i < operandLength); ++i) { - indexedAction.perform(node, store, i, operand, i); + Object value = indexedAction.perform(node, iterator.next(operand, it)); + targetSetDataAt.setDataAtAsObject(target, targetStore, i, value); } } - private interface MapIndexedAction<A, V extends RAbstractVector> { - - void perform(UnaryMapFunctionNode action, A store, int resultIndex, V operand, int operandIndex); - + private interface MapIndexedAction<V> { + Object perform(UnaryMapFunctionNode action, V val); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/Utils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/Utils.java new file mode 100644 index 0000000000..3ec6b0e3b7 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/Utils.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017, 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.nodes.primitive; + +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.VectorIterator; + +abstract class Utils { + private Utils() { + } + + static SetDataAt createSetDataAtNode(RType type) { + switch (type) { + case Raw: + return SetDataAt.Raw.create(); + case Logical: + return SetDataAt.Logical.create(); + case Integer: + return SetDataAt.Int.create(); + case Double: + return SetDataAt.Double.create(); + case Complex: + return SetDataAt.Complex.create(); + case Character: + return SetDataAt.String.create(); + default: + throw RInternalError.shouldNotReachHere("BinaryMapNode unexpected result type " + type); + } + } + + static final class VecStore<T extends RAbstractVector> { + public final T vector; + public final Object store; + + VecStore(T vector, Object store) { + this.vector = vector; + this.store = store; + } + } + + public static VectorIterator.Generic createIterator() { + return VectorIterator.Generic.create(); + } + + public static VectorIterator.Generic createIteratorWrapAround() { + return VectorIterator.Generic.createWrapAround(); + } +} 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 b6ecdaa12c..181686e7ab 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 @@ -37,15 +37,13 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypes; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector; +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.VectorIterator; import com.oracle.truffle.r.runtime.interop.ForeignArray2R; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; @@ -202,16 +200,16 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { } @Specialization - protected int doIntVector(RIntVector operand, boolean naRm, boolean finite, - @Cached("new()") AccessVector.Int access) { + protected Object doIntVector(RAbstractIntVector operand, boolean naRm, boolean finite, + @Cached("create()") VectorIterator.Int iterator) { RBaseNode.reportWork(this, operand.getLength()); boolean profiledNaRm = naRmProfile.profile(naRm || finite); int result = semantics.getIntStart(); na.enable(operand); int opCount = 0; - Object store = access.init(operand); - for (int i = 0; i < operand.getLength(); i++) { - int d = access.getDataAt(operand, store, i); + Object it = iterator.init(operand); + while (iterator.hasNext(operand, it)) { + int d = iterator.next(operand, it); if (na.check(d)) { if (profiledNaRm) { continue; @@ -237,8 +235,8 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { } @Specialization - protected double doDoubleVector(RDoubleVector operand, boolean naRm, boolean finite, - @Cached("new()") AccessVector.Double access, + protected double doDoubleVector(RAbstractDoubleVector operand, boolean naRm, boolean finite, + @Cached("create()") VectorIterator.Double iterator, @Cached("createBinaryProfile()") ConditionProfile finiteProfile, @Cached("createBinaryProfile()") ConditionProfile isInfiniteProfile) { RBaseNode.reportWork(this, operand.getLength()); @@ -247,9 +245,10 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { double result = semantics.getDoubleStart(); na.enable(operand); int opCount = 0; - Object store = access.init(operand); - for (int i = 0; i < operand.getLength(); i++) { - double d = access.getDataAt(operand, store, i); + + Object it = iterator.init(operand); + while (iterator.hasNext(operand, it)) { + double d = iterator.next(operand, it); if (na.checkNAorNaN(d)) { if (profiledNaRm) { continue; // ignore NA/NaN @@ -274,16 +273,17 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { } @Specialization - protected int doLogicalVector(RLogicalVector operand, boolean naRm, @SuppressWarnings("unused") boolean finite, - @Cached("new()") AccessVector.Logical access) { + protected Object doLogicalVector(RAbstractLogicalVector operand, boolean naRm, @SuppressWarnings("unused") boolean finite, + @Cached("create()") VectorIterator.Logical iterator) { RBaseNode.reportWork(this, operand.getLength()); boolean profiledNaRm = naRmProfile.profile(naRm); int result = semantics.getIntStart(); na.enable(operand); int opCount = 0; - Object store = access.init(operand); - for (int i = 0; i < operand.getLength(); i++) { - byte d = access.getDataAt(operand, store, i); + + Object it = iterator.init(operand); + while (iterator.hasNext(operand, it)) { + byte d = iterator.next(operand, it); if (na.check(d)) { if (profiledNaRm) { continue; @@ -308,43 +308,6 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { return result; } - @Specialization - protected Object doIntSequence(RIntSequence operand, @SuppressWarnings("unused") boolean naRm, @SuppressWarnings("unused") boolean finite) { - RBaseNode.reportWork(this, operand.getLength()); - int result = semantics.getIntStart(); - int current = operand.getStart(); - for (int i = 0; i < operand.getLength(); i++) { - result = arithmetic.op(result, current); - if (RRuntime.isNA(result)) { - naResultWarning(); - return RRuntime.INT_NA; - } - current += operand.getStride(); - } - if (operand.getLength() == 0) { - emptyWarning(); - if (semantics.isUseDoubleStartForEmptyVector()) { - return semantics.getDoubleStart(); - } - } - return result; - } - - @Specialization - protected double doDoubleSequence(RDoubleSequence operand, @SuppressWarnings("unused") boolean naRm, @SuppressWarnings("unused") boolean finite) { - RBaseNode.reportWork(this, operand.getLength()); - double result = semantics.getDoubleStart(); - double current = operand.getStart(); - for (int i = 0; i < operand.getLength(); i++) { - result = arithmetic.op(result, current); - current += operand.getStride(); - } - if (operand.getLength() == 0) { - emptyWarning(); - } - return result; - } - @Specialization(guards = "supportComplex") protected RComplex doComplexVector(RComplexVector operand, boolean naRm, boolean finite) { RBaseNode.reportWork(this, operand.getLength()); 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 d87792ed94..4ba40b6598 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 @@ -49,11 +49,11 @@ 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(); + return !(vector instanceof RVector<?>) || !((RVector<?>) vector).hasNativeMemoryData(); } public static boolean isRVector(RAbstractVector vector) { - return vector instanceof RVector; + return vector instanceof RVector<?>; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java index 2a79a1339b..1acc54576b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java @@ -18,7 +18,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.nodes.AccessVector.DoubleAccessor; +import com.oracle.truffle.r.runtime.data.nodes.ReadAccessor; import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider; public final class RMultinom { @@ -32,7 +32,7 @@ public final class RMultinom { * prob[j]) , sum_j rN[j] == n, sum_j prob[j] == 1. */ @TruffleBoundary - public static boolean rmultinom(int nIn, DoubleAccessor prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand, Rbinom rbinom) { + public static boolean rmultinom(int nIn, ReadAccessor.Double prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand, Rbinom rbinom) { /* * This calculation is sensitive to exact values, so we try to ensure that the calculations * are as accurate as possible so different platforms are more likely to give the same -- GitLab