From 19ef5d14934814a76241329934f13db9b8e450f4 Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Thu, 3 Aug 2017 18:28:21 +0200 Subject: [PATCH] Implemented Rf_runif, Rf_qunif, Rf_punif, and Rf_dunif. --- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 23 +++++++++ .../impl/common/TracingUpCallsRFFIImpl.java | 25 ++++++++++ .../r/ffi/impl/nodes/FFIUpCallNode.java | 18 +++++++ .../r/ffi/impl/nodes/FFIUpCallRootNode.java | 8 +++ .../r/ffi/impl/nodes/RandFunctionsNodes.java | 50 +++++++++++++++++++ .../r/ffi/impl/upcalls/StdUpCallsRFFI.java | 8 +++ .../fficall/src/jni/Rmath.c | 29 ++++++++--- 7 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 384967e805..b1bd221a64 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -110,6 +110,8 @@ import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.gnur.SA_TYPE; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider; +import com.oracle.truffle.r.runtime.nmath.distr.Unif; import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @@ -1581,4 +1583,25 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { name2typeTable.put("numeric", SEXPTYPE.REALSXP.code); name2typeTable.put("name", SEXPTYPE.SYMSXP.code); } + + @Override + public double Rf_dunif(double a, double b, double c, int d) { + return new Unif.DUnif().evaluate(a, b, c, RRuntime.fromLogical((byte) d)); + } + + @Override + public double Rf_qunif(double a, double b, double c, int d, int e) { + return new Unif.QUnif().evaluate(a, b, c, RRuntime.fromLogical((byte) d), RRuntime.fromLogical((byte) e)); + } + + @Override + public double Rf_punif(double a, double b, double c, int d, int e) { + return new Unif.PUnif().evaluate(a, b, c, RRuntime.fromLogical((byte) d), RRuntime.fromLogical((byte) e)); + } + + @Override + public double Rf_runif(double a, double b) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_runif).call(a, b); + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java index cf9a072f94..4add422498 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java @@ -847,4 +847,29 @@ final class TracingUpCallsRFFIImpl implements UpCallsRFFI { RFFIUtils.traceUpCall("Rf_str2type"); return delegate.Rf_str2type(name); } + + @Override + public double Rf_dunif(double a, double b, double c, int d) { + RFFIUtils.traceUpCall("Rf_dunif", a, b, c, d); + return delegate.Rf_dunif(a, b, c, d); + } + + @Override + public double Rf_qunif(double a, double b, double c, int d, int e) { + RFFIUtils.traceUpCall("Rf_qunif", a, b, c, d, e); + return delegate.Rf_qunif(a, b, c, d, e); + } + + @Override + public double Rf_punif(double a, double b, double c, int d, int e) { + RFFIUtils.traceUpCall("Rf_punif", a, b, c, d, e); + return delegate.Rf_punif(a, b, c, d, e); + } + + @Override + public double Rf_runif(double a, double b) { + RFFIUtils.traceUpCall("Rf_runif", a, b); + return delegate.Rf_runif(a, b); + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java index b6a57e296c..5df825b06b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java @@ -62,4 +62,22 @@ public abstract class FFIUpCallNode extends Node { return 3; } } + + public abstract static class Arg4 extends FFIUpCallNode { + public abstract Object executeObject(Object arg0, Object arg1, Object arg2, Object arg3); + + @Override + protected int numArgs() { + return 4; + } + } + + public abstract static class Arg5 extends FFIUpCallNode { + public abstract Object executeObject(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4); + + @Override + protected int numArgs() { + return 5; + } + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java index a3bd560c96..ae1086a488 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java @@ -38,9 +38,13 @@ import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.LENGTHNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoNewObjectNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotAssignNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction2NodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction3_1NodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction3_2NodeGen; import com.oracle.truffle.r.ffi.impl.upcalls.RFFIUpCallTable; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.nmath.distr.Unif; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class FFIUpCallRootNode extends RootNode { @@ -105,5 +109,9 @@ public final class FFIUpCallRootNode extends RootNode { FFIUpCallRootNode.add(RFFIUpCallTable.R_do_new_object, RDoNewObjectNodeGen::create); FFIUpCallRootNode.add(RFFIUpCallTable.R_do_slot, RDoSlotNodeGen::create); FFIUpCallRootNode.add(RFFIUpCallTable.R_do_slot_assign, RDoSlotAssignNodeGen::create); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_runif, () -> RandFunction2NodeGen.create(new Unif.Runif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_dunif, () -> RandFunction3_1NodeGen.create(new Unif.DUnif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_qunif, () -> RandFunction3_2NodeGen.create(new Unif.QUnif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_punif, () -> RandFunction3_2NodeGen.create(new Unif.PUnif())); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java new file mode 100644 index 0000000000..807ff5d5c0 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java @@ -0,0 +1,50 @@ +package com.oracle.truffle.r.ffi.impl.nodes; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.runtime.nmath.MathFunctions; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider; + +public final class RandFunctionsNodes { + + public abstract static class RandFunction3_2Node extends FFIUpCallNode.Arg5 { + @Child private MathFunctions.Function3_2 inner; + + protected RandFunction3_2Node(MathFunctions.Function3_2 inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b, double c, boolean d, boolean e) { + return inner.evaluate(a, b, c, d, e); + } + } + + public abstract static class RandFunction3_1Node extends FFIUpCallNode.Arg4 { + @Child private MathFunctions.Function3_1 inner; + + protected RandFunction3_1Node(MathFunctions.Function3_1 inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b, double c, boolean d) { + return inner.evaluate(a, b, c, d); + } + } + + public abstract static class RandFunction2Node extends FFIUpCallNode.Arg2 { + @Child private RandomFunctions.RandFunction2_Double inner; + + protected RandFunction2Node(RandFunction2_Double inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b) { + return inner.execute(a, b, RandomNumberProvider.fromCurrentRNG()); + } + } + +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index 56faae246c..fe1398c447 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -295,4 +295,12 @@ public interface StdUpCallsRFFI { int Rf_str2type(@RFFICstring Object name); + double Rf_dunif(double a, double b, double c, int d); + + double Rf_qunif(double a, double b, double c, int d, int e); + + double Rf_punif(double a, double b, double c, int d, int e); + + double Rf_runif(double a, double b); + } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c b/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c index fd82bd5872..400076323a 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c @@ -22,8 +22,17 @@ */ #include <rffiutils.h> +static jmethodID Rf_runifMethodID; +static jmethodID Rf_punifMethodID; +static jmethodID Rf_qunifMethodID; +static jmethodID Rf_dunifMethodID; + void init_rmath(JNIEnv *env) { + Rf_runifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_runif", "(DD)D", 0); + Rf_punifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_punif", "(DDDII)D", 0); + Rf_qunifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_qunif", "(DDDII)D", 0); + Rf_dunifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_dunif", "(DDDI)D", 0); } double Rf_dnorm(double a, double b, double c, int d) { @@ -63,23 +72,27 @@ void Rf_pnorm_both(double a, double * b, double * c, int d, int e) { } double Rf_dunif(double a, double b, double c, int d) { - unimplemented("Rf_dunif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_dunifMethodID, a, b, c, d); } double Rf_punif(double a, double b, double c, int d, int e) { - unimplemented("Rf_punif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_punifMethodID, a, b, c, d, e); } double Rf_qunif(double a, double b, double c, int d, int e) { - unimplemented("Rf_qunif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_qunifMethodID, a, b, c, d, e); } double Rf_runif(double a, double b) { - unimplemented("Rf_runif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_runifMethodID, a, b); } double Rf_dgamma(double a, double b, double c, int d) { -- GitLab