From 8215381747d5e2ced9772947b5a6a9add0c32506 Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Thu, 16 Nov 2017 16:06:56 +0100 Subject: [PATCH] convert rep_len to VectorAccess --- .../r/nodes/builtin/base/RepeatLength.java | 107 ++++++----------- .../truffle/r/test/ExpectedTestOutput.test | 108 ++++++++++-------- .../r/test/builtins/TestBuiltin_rep_len.java | 66 +++++------ 3 files changed, 128 insertions(+), 153 deletions(-) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java index cf0a608ef1..a66473e331 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java @@ -12,40 +12,44 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notIntNA; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte0; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import java.util.Arrays; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDataFactory.VectorFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; +import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator; @RBuiltin(name = "rep_len", kind = INTERNAL, parameterNames = {"x", "length.out"}, behavior = PURE) public abstract class RepeatLength extends RBuiltinNode.Arg2 { static { Casts casts = new Casts(RepeatLength.class); - casts.arg("x").allowNull().mustBe(abstractVectorValue(), RError.Message.ATTEMPT_TO_REPLICATE_NO_VECTOR); - // with default error message, SHOW_CALLER does not work - casts.arg("length.out").defaultError(RError.Message.INVALID_VALUE, "length.out").mustNotBeNull().asIntegerVector().mustBe(size(1)).findFirst().mustBe(notIntNA()); + casts.arg("x").allowNull().mustBe(abstractVectorValue().or(instanceOf(RExpression.class)), RError.Message.ATTEMPT_TO_REPLICATE_NO_VECTOR); + casts.arg("length.out").defaultError(RError.Message.INVALID_VALUE, "length.out").mustNotBeNull().asIntegerVector().mustBe(singleElement()).findFirst().mustNotBeNA().mustBe(gte0()); } @Specialization @@ -106,72 +110,33 @@ public abstract class RepeatLength extends RBuiltinNode.Arg2 { return RDataFactory.createLogicalVector(array, value != RRuntime.LOGICAL_NA); } - // - // Specialization for vector values - // - @Specialization - protected RIntVector repLen(RAbstractIntVector value, int length) { - int[] array = new int[length]; - for (int i = 0, j = 0; i < length; i++, j = Utils.incMod(j, value.getLength())) { - array[i] = value.getDataAt(j); + @Specialization(guards = "xAccess.supports(x)") + protected RAbstractVector repLenCached(RAbstractVector x, int length, + @Cached("x.access()") VectorAccess xAccess, + @Cached("createNew(xAccess.getType())") VectorAccess resultAccess, + @Cached("createBinaryProfile()") ConditionProfile emptyProfile, + @Cached("create()") VectorFactory factory) { + try (SequentialIterator xIter = xAccess.access(x)) { + if (emptyProfile.profile(xAccess.getLength(xIter) == 0)) { + return factory.createVector(xAccess.getType(), length, true); + } + RAbstractVector result = factory.createVector(xAccess.getType(), length, false); + try (SequentialIterator resultIter = resultAccess.access(result)) { + while (resultAccess.next(resultIter)) { + xAccess.nextWithWrap(xIter); + resultAccess.setFromSameType(resultIter, xAccess, xIter); + } + } + result.setComplete(x.isComplete()); + return result; } - return RDataFactory.createIntVector(array, value.isComplete()); } - @Specialization - protected RDoubleVector repLen(RDoubleVector value, int length) { - double[] array = new double[length]; - for (int i = 0, j = 0; i < length; i++, j = Utils.incMod(j, value.getLength())) { - array[i] = value.getDataAt(j); - } - return RDataFactory.createDoubleVector(array, value.isComplete()); + @Specialization(replaces = "repLenCached") + protected RAbstractVector repLenGeneric(RAbstractVector x, int length, + @Cached("createBinaryProfile()") ConditionProfile emptyProfile, + @Cached("create()") VectorFactory factory) { + return repLenCached(x, length, x.slowPathAccess(), VectorAccess.createSlowPathNew(x.getRType()), emptyProfile, factory); } - @Specialization - protected RStringVector repLen(RStringVector vectorToRepeat, int length) { - String[] result = new String[length]; - int vectorToRepeatLength = vectorToRepeat.getLength(); - for (int i = 0; i < length; i++) { - result[i] = vectorToRepeat.getDataAt(i % vectorToRepeatLength); - } - return RDataFactory.createStringVector(result, vectorToRepeat.isComplete()); - } - - @Specialization - protected RRawVector repLen(RRawVector value, int length) { - byte[] array = new byte[length]; - for (int i = 0, j = 0; i < length; i++, j = Utils.incMod(j, value.getLength())) { - array[i] = value.getRawDataAt(j); - } - return RDataFactory.createRawVector(array); - } - - @Specialization - protected RComplexVector repLen(RComplexVector value, int length) { - final int resultLength = length * 2; - double[] array = new double[resultLength]; - for (int i = 0, j = 0; i < resultLength; i += 2, j = Utils.incMod(j, value.getLength())) { - array[i] = value.getDataAt(j).getRealPart(); - array[i + 1] = value.getDataAt(j).getImaginaryPart(); - } - return RDataFactory.createComplexVector(array, value.isComplete()); - } - - @Specialization - protected RLogicalVector repLen(RLogicalVector value, int length) { - byte[] array = new byte[length]; - for (int i = 0, j = 0; i < length; i++, j = Utils.incMod(j, value.getLength())) { - array[i] = value.getDataAt(j); - } - return RDataFactory.createLogicalVector(array, value.isComplete()); - } - - @Specialization - protected RList repLen(RList list, int length) { - Object[] data = new Object[length]; - for (int i = 0; i < length; i++) { - data[i] = list.getDataAt(i % list.getLength()); - } - return RDataFactory.createList(data); - } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index a2c4cbdf10..a56d8071cf 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -51224,130 +51224,138 @@ logical(0) Levels: A B C D ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#rep_len(1L, 4L) -[1] 1 1 1 1 - -##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len("RepeatTest", 5) } +#rep_len('RepeatTest', 5) [1] "RepeatTest" "RepeatTest" "RepeatTest" "RepeatTest" "RepeatTest" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(1, 2) } +#rep_len(1, 2) [1] 1 1 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(1:4, 10) } +#rep_len(1:4, 10) [1] 1 2 3 4 1 2 3 4 1 2 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(1:4, 3) } +#rep_len(1:4, 3) [1] 1 2 3 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(1:4, 4) } +#rep_len(1:4, 4) [1] 1 2 3 4 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(2+6i, 4) } +#rep_len(1L, 4L) +[1] 1 1 1 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# +#rep_len(2+6i, 4) [1] 2+6i 2+6i 2+6i 2+6i ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(3.14159, 3) } +#rep_len(3.14159, 3) [1] 3.14159 3.14159 3.14159 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(7, "7") } +#rep_len(4, x='text') +[1] "text" "text" "text" "text" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# +#rep_len(7, '7') [1] 7 7 7 7 7 7 7 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(7, NA) } +#rep_len(7, NA) Error in rep_len(7, NA) : invalid 'length.out' value ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(7, NULL) } +#rep_len(7, NULL) Error in rep_len(7, NULL) : invalid 'length.out' value ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(7, c(7, 42)) } +#rep_len(7, c(7, 42)) Error in rep_len(7, c(7, 42)) : invalid 'length.out' value ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(7, integer()) } +#rep_len(7, integer()) Error in rep_len(7, integer()) : invalid 'length.out' value ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(TRUE, 2) } +#rep_len(TRUE, 2) [1] TRUE TRUE ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(c(2i+3, 4+2i), 4) } -[1] 3+2i 4+2i 3+2i 4+2i +#rep_len(c('abcd', 'efg'), 0) +character(0) ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ rep_len(c(3.1415, 0.8), 1) } -[1] 3.1415 - -##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen#Output.IgnoreErrorContext# -#{ rep_len(function() 42, 7) } -Error in rep_len(function() 42, 7) : attempt to replicate non-vector +#rep_len(c('abcd', 'efg'), 1) +[1] "abcd" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ x<-as.raw(16); rep_len(x, 2) } -[1] 10 10 +#rep_len(c('abcd', 'efg'), 14) + [1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" +[11] "abcd" "efg" "abcd" "efg" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{ x<-as.raw(16); y<-as.raw(5); rep_len(c(x, y), 5) } -[1] 10 05 10 05 10 +#rep_len(c('abcd', 'efg'), 2) +[1] "abcd" "efg" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(4, x="text")} -[1] "text" "text" "text" "text" +#rep_len(c('abcd', 'efg'), 7) +[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 0)} -character(0) +#rep_len(c('abcd', 'efg'), 8) +[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 1)} -[1] "abcd" +#rep_len(c(2i+3, 4+2i), 4) +[1] 3+2i 4+2i 3+2i 4+2i ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 14)} - [1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" -[11] "abcd" "efg" "abcd" "efg" +#rep_len(c(3.1415, 0.8), 1) +[1] 3.1415 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 2)} -[1] "abcd" "efg" +#rep_len(c(a=1,b=4), 4) +[1] 1 4 1 4 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 7)} -[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" +#rep_len(expression(1,4,'foo'), 7) +expression(1, 4, "foo", 1, 4, "foo", 1) -##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(c("abcd", "efg"), 8)} -[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" +##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen#Output.IgnoreErrorContext# +#rep_len(function() 42, 7) +Error in rep_len(function() 42, 7) : attempt to replicate non-vector ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(length.out=4, "text")} +#rep_len(length.out=4, 'text') [1] "text" "text" "text" "text" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(length.out=4, x=1:2)} +#rep_len(length.out=4, x=1:2) [1] 1 2 1 2 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{rep_len(x=1:2, length.out=4)} +#rep_len(x=1:2, length.out=4) [1] 1 2 1 2 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{x<-"text"; length.out<-4; rep_len(length.out=length.out, x=x)} +#x<-'text'; length.out<-4; rep_len(length.out=length.out, x=x) [1] "text" "text" "text" "text" ##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# -#{x<-"text"; length.out<-4; rep_len(x=x, length.out=length.out)} +#x<-'text'; length.out<-4; rep_len(x=x, length.out=length.out) [1] "text" "text" "text" "text" +##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# +#x<-as.raw(16); rep_len(x, 2) +[1] 10 10 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rep_len.testRepLen# +#x<-as.raw(16); y<-as.raw(5); rep_len(c(x, y), 5) +[1] 10 05 10 05 10 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_repint.testRepInt# #{ rep.int("a",3) } [1] "a" "a" "a" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep_len.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep_len.java index 40ff969ca5..d41b15d4fb 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep_len.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rep_len.java @@ -20,41 +20,43 @@ public class TestBuiltin_rep_len extends TestBase { @Test public void testRepLen() { - assertEval("{ rep_len(1, 2) }"); - assertEval("{ rep_len(3.14159, 3) }"); - assertEval("{ rep_len(\"RepeatTest\", 5) }"); - assertEval("{ rep_len(2+6i, 4) }"); - assertEval("{ rep_len(TRUE, 2) }"); - assertEval("{ x<-as.raw(16); rep_len(x, 2) }"); - - assertEval("{ rep_len(1:4, 10) }"); - assertEval("{ rep_len(1:4, 3) }"); - assertEval("{ rep_len(1:4, 4) }"); - assertEval("{ rep_len(c(3.1415, 0.8), 1) }"); - assertEval("{ rep_len(c(2i+3, 4+2i), 4) }"); - assertEval("{ x<-as.raw(16); y<-as.raw(5); rep_len(c(x, y), 5) }"); + assertEval("rep_len(1, 2)"); + assertEval("rep_len(3.14159, 3)"); + assertEval("rep_len('RepeatTest', 5)"); + assertEval("rep_len(2+6i, 4)"); + assertEval("rep_len(TRUE, 2)"); + assertEval("x<-as.raw(16); rep_len(x, 2)"); + + assertEval("rep_len(1:4, 10)"); + assertEval("rep_len(1:4, 3)"); + assertEval("rep_len(1:4, 4)"); + assertEval("rep_len(c(3.1415, 0.8), 1)"); + assertEval("rep_len(c(2i+3, 4+2i), 4)"); + assertEval("x<-as.raw(16); y<-as.raw(5); rep_len(c(x, y), 5)"); // cases with named arguments: - assertEval("{rep_len(x=1:2, length.out=4)}"); - assertEval("{rep_len(length.out=4, x=1:2)}"); - assertEval("{rep_len(length.out=4, \"text\")}"); - assertEval("{rep_len(4, x=\"text\")}"); - assertEval("{x<-\"text\"; length.out<-4; rep_len(x=x, length.out=length.out)}"); - assertEval("{x<-\"text\"; length.out<-4; rep_len(length.out=length.out, x=x)}"); + assertEval("rep_len(x=1:2, length.out=4)"); + assertEval("rep_len(length.out=4, x=1:2)"); + assertEval("rep_len(length.out=4, 'text')"); + assertEval("rep_len(4, x='text')"); + assertEval("x<-'text'; length.out<-4; rep_len(x=x, length.out=length.out)"); + assertEval("x<-'text'; length.out<-4; rep_len(length.out=length.out, x=x)"); // test string vector argument - assertEval("{rep_len(c(\"abcd\", \"efg\"), 7)}"); - assertEval("{rep_len(c(\"abcd\", \"efg\"), 14)}"); - assertEval("{rep_len(c(\"abcd\", \"efg\"), 8)}"); - assertEval("{rep_len(c(\"abcd\", \"efg\"), 0)}"); - assertEval("{rep_len(c(\"abcd\", \"efg\"), 1)}"); - assertEval("{rep_len(c(\"abcd\", \"efg\"), 2)}"); - - assertEval(Output.IgnoreErrorContext, "{ rep_len(function() 42, 7) }"); - assertEval("{ rep_len(7, \"7\") }"); - assertEval("{ rep_len(7, integer()) }"); - assertEval("{ rep_len(7, NA) }"); - assertEval("{ rep_len(7, NULL) }"); - assertEval("{ rep_len(7, c(7, 42)) }"); + assertEval("rep_len(c('abcd', 'efg'), 7)"); + assertEval("rep_len(c('abcd', 'efg'), 14)"); + assertEval("rep_len(c('abcd', 'efg'), 8)"); + assertEval("rep_len(c('abcd', 'efg'), 0)"); + assertEval("rep_len(c('abcd', 'efg'), 1)"); + assertEval("rep_len(c('abcd', 'efg'), 2)"); + + assertEval(Output.IgnoreErrorContext, "rep_len(function() 42, 7)"); + assertEval("rep_len(7, '7')"); + assertEval("rep_len(7, integer())"); + assertEval("rep_len(7, NA)"); + assertEval("rep_len(7, NULL)"); + assertEval("rep_len(7, c(7, 42))"); assertEval("rep_len(1L, 4L)"); + assertEval("rep_len(c(a=1,b=4), 4)"); + assertEval("rep_len(expression(1,4,'foo'), 7)"); } } -- GitLab