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 384967e80570a75ac52aa6a705fdd7597bd54f70..b1bd221a649b614f071bc770a5829fc546d236fd 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 cf9a072f94d83cd0030b19079852f66b8d6c479a..4add422498be6360d4a9c71c67c701640fdc94b1 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 b6a57e296c0af9ffb0e1a1d6a3c079b2a0906937..5df825b06b78e80c37dfb663f2f3b2c4c311a156 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 a3bd560c96916a5e325b4b4ed02a458e5c6e9eb0..ae1086a488b99ba126b44bc1a4d22c6632dcb730 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 0000000000000000000000000000000000000000..807ff5d5c02f0a023355413ed340371041235a92 --- /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 56faae246c87ac1abc19e78cd8908aeb2c9476cf..fe1398c447c571d73cd806fb54b37c0d5d4fd0ed 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 fd82bd58721f03a9131a6453dd480dec48096d7e..400076323adf70436f97874c84e925d54fa812a7 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) {