Skip to content
Snippets Groups Projects
Commit 05bcd266 authored by stepan's avatar stepan
Browse files

Prod: returns 1 for empty vectors

parent ec415eb1
No related branches found
No related tags found
No related merge requests found
......@@ -24,6 +24,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.RComplex;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RTypedValue;
import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
......@@ -62,8 +63,8 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
CompilerDirectives.transferToInterpreterAndInvalidate();
prodRecursive = insert(ProdNodeGen.create());
}
Object ret = prodRecursive.executeObject(args.getArgument(0));
if (argsLen != 1) {
Object ret = 1d;
if (argsLen > 0) {
double prodReal;
double prodImg;
boolean complex;
......@@ -77,7 +78,7 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
prodImg = 0d;
complex = false;
}
for (int i = 1; i < argsLen; i++) {
for (int i = 0; i < argsLen; i++) {
Object aProd = prodRecursive.executeObject(args.getArgument(i));
double aProdReal;
double aProdImg;
......@@ -108,8 +109,8 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
@Specialization
protected double prod(RAbstractDoubleVector x) {
RAbstractDoubleVector profiledVec = intVecProfile.profile(x);
double product = profiledVec.getDataAt(0);
for (int k = 1; k < profiledVec.getLength(); k++) {
double product = 1;
for (int k = 0; k < profiledVec.getLength(); k++) {
product = prod.op(product, profiledVec.getDataAt(k));
}
return product;
......@@ -118,8 +119,8 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
@Specialization
protected double prod(RAbstractIntVector x) {
RAbstractIntVector profiledVec = intVecProfile.profile(x);
double product = profiledVec.getDataAt(0);
for (int k = 1; k < profiledVec.getLength(); k++) {
double product = 1;
for (int k = 0; k < profiledVec.getLength(); k++) {
product = prod.op(product, profiledVec.getDataAt(k));
}
return product;
......@@ -128,8 +129,8 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
@Specialization
protected double prod(RAbstractLogicalVector x) {
RAbstractLogicalVector profiledVec = intVecProfile.profile(x);
double product = profiledVec.getDataAt(0);
for (int k = 1; k < profiledVec.getLength(); k++) {
double product = 1;
for (int k = 0; k < profiledVec.getLength(); k++) {
product = prod.op(product, profiledVec.getDataAt(k));
}
return product;
......@@ -138,8 +139,8 @@ public abstract class Prod extends RBuiltinNode.Arg2 {
@Specialization
protected RComplex prod(RAbstractComplexVector x) {
RAbstractComplexVector profiledVec = intVecProfile.profile(x);
RComplex product = profiledVec.getDataAt(0);
for (int k = 1; k < profiledVec.getLength(); k++) {
RComplex product = RDataFactory.createComplexRealOne();
for (int k = 0; k < profiledVec.getLength(); k++) {
RComplex a = profiledVec.getDataAt(k);
product = prod.op(product.getRealPart(), product.getImaginaryPart(), a.getRealPart(), a.getImaginaryPart());
}
......
......@@ -405,6 +405,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
@Cached("create()") ClassHierarchyNode classHierarchyNodeY,
@Cached("createWithException()") S3FunctionLookupNode dispatchLookupY,
@Cached("createIdentityProfile()") ValueProfile builtinProfile,
@Cached("createBinaryProfile()") ConditionProfile emptyArgumentsProfile,
@Cached("createBinaryProfile()") ConditionProfile implicitTypeProfileX,
@Cached("createBinaryProfile()") ConditionProfile implicitTypeProfileY,
@Cached("createBinaryProfile()") ConditionProfile mismatchProfile,
......@@ -420,6 +421,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
Object[] args = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getArguments() : callArguments.evaluateFlattenObjects(frame, lookupVarArgs(frame));
ArgumentsSignature argsSignature = explicitArgs != null ? ((RArgsValuesAndNames) explicitArgs.execute(frame)).getSignature() : callArguments.flattenNames(lookupVarArgs(frame));
if (emptyArgumentsProfile.profile(args.length == 0)) {
// nothing to dispatch on, this is a valid situation, e.g. prod() == 1
return call.execute(frame, function, new RArgsValuesAndNames(args, argsSignature), null, null);
}
RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin());
RDispatch dispatch = builtin.getDispatch();
......
......@@ -44965,6 +44965,22 @@ age 0.00561 0.012 0.00872 0.22 1.0 0.64000
sex -1.65487 0.483 0.38527 11.74 1.0 0.00061
frailty(id, dist = 't', c 20.33 13.9 0.12000
 
##com.oracle.truffle.r.test.builtins.TestBuiltin_prod.testProd#
#prod()
[1] 1
##com.oracle.truffle.r.test.builtins.TestBuiltin_prod.testProd#
#prod(complex())
[1] 1+0i
##com.oracle.truffle.r.test.builtins.TestBuiltin_prod.testProd#
#prod(numeric())
[1] 1
##com.oracle.truffle.r.test.builtins.TestBuiltin_prod.testProd#
#{ foo <- function(...) prod(...); foo(); }
[1] 1
##com.oracle.truffle.r.test.builtins.TestBuiltin_prod.testProd#
#{prod('a')}
Error in prod("a") : invalid 'type' (character) of argument
......@@ -92,6 +92,10 @@ public class TestBuiltin_prod extends TestBase {
assertEval("{prod(42,2+3i)}");
assertEval("{prod('a')}");
assertEval("{prod(list())}");
assertEval("prod()");
assertEval("prod(numeric())");
assertEval("prod(complex())");
assertEval("{ foo <- function(...) prod(...); foo(); }");
}
@Test
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment