diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FFTFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FFTFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..83b1fc15f1c6e45bf5e91de0ac1cd2905e6f09fd --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FFTFunctions.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, 2014, 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.builtin.base; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; +import com.oracle.truffle.r.runtime.ffi.*; + +public abstract class FFTFunctions { + + private abstract static class FFTAdapter extends RBuiltinNode { + private static final String[] PARAMETER_NAMES = new String[]{"z", "inverse"}; + + @Override + public Object[] getParameterNames() { + return PARAMETER_NAMES; + } + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + + } + + @RBuiltin(name = "fft", kind = RBuiltinKind.SUBSTITUTE) + public abstract static class FFT extends FFTAdapter { + @Specialization + public Object doFFT(RAbstractVector zIn, byte inverse) { + @SuppressWarnings("unused") + RDerivedRFFI ffi = RFFIFactory.getRFFI().getRDerivedRFFI(); +// ffi.fft_work(a, b, nseg, n, nspn, isn, work, iwork) + return RNull.instance; + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java index f23ad6e5971810a4f872a7e05a4cd19a5043de61..b35e12cdd80ee407b5e09999ad002a3c65eb17c1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java @@ -104,7 +104,7 @@ public class ForeignFunctions { int[] rank = rankVec.getDataCopy(); double[] qraux = qrauxVec.getDataCopy(); int[] pivot = pivotVec.getDataCopy(); - RFFIFactory.getRFFI().getLinpackRFFI().dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.getDataCopy()); + RFFIFactory.getRFFI().getRDerivedRFFI().dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.getDataCopy()); // @formatter:off Object[] data = new Object[]{ RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), @@ -146,7 +146,7 @@ public class ForeignFunctions { double[] y = yVec.getDataCopy(); double[] b = bVec.getDataCopy(); int[] info = infoVec.getDataCopy(); - RFFIFactory.getRFFI().getLinpackRFFI().dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); + RFFIFactory.getRFFI().getRDerivedRFFI().dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR); coef.copyAttributesFrom(bVec); // @formatter:off diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LinpackRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RDerivedRFFI.java similarity index 75% rename from com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LinpackRFFI.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RDerivedRFFI.java index d8d5552822bdaf9e08588766dcad87202e81a05a..aa698758ee01bccf60b59e88c62d25426c4b35ea 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LinpackRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RDerivedRFFI.java @@ -23,10 +23,18 @@ package com.oracle.truffle.r.runtime.ffi; /** - * Collection of statically typed methods from Linpack that are built in to a GnuR implementation. + * Collection of statically typed methods (from Linpack and elsewhere) that are built in to a GnuR + * implementation and factored out into a separate library in FastR. */ -public interface LinpackRFFI { +public interface RDerivedRFFI { + // Linpack void dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work); void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info); + + // fft + // Checkstyle: stop method name + void fft_factor(int n, int[] pmaxf, int[] pmaxp); + + int fft_work(double[] a, double[] b, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java index 6e830dac691b8755a7cad24f5e31476c754154bf..b7e3a055afb20a2eb1abaf7a14a1d5759b35a798 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java @@ -30,7 +30,7 @@ package com.oracle.truffle.r.runtime.ffi; * package.</li> * <li>{@link LapackRFFI}: the specific, typed, foreign functions required by the built-in * {@code Lapack} functions.</li> - * <li>{@link LinpackRFFI}: the specific, typed, foreign functions required by the built-in + * <li>{@link RDerivedRFFI}: the specific, typed, foreign functions required by the built-in * {@code Linpack} functions.</li> * <li>{@link CRFFI}: {@code .C} and {@code .Fortran} call interface. * <li>{@link UserRngRFFI}: specific interface to user-supplied random number generator. @@ -44,7 +44,7 @@ public interface RFFI { LapackRFFI getLapackRFFI(); - LinpackRFFI getLinpackRFFI(); + RDerivedRFFI getRDerivedRFFI(); CRFFI getCRFFI(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java index 5a7eac768834ef76a39b50314ba206b0bda19c74..cb9041342147dd879de5e8766451c0482d03cbac 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java @@ -79,8 +79,8 @@ public abstract class RFFIFactory { return null; } - public LinpackRFFI getLinpackRFFI() { - Utils.fail("getLinpackRFFI not implemented"); + public RDerivedRFFI getRDerivedRFFI() { + Utils.fail("getRDerivedRFFI not implemented"); return null; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java index d3985e1cea326b76868351f29fdc23d76e813588..8fe543a7d40af24976ff98b800edb8491417b410 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java @@ -37,7 +37,7 @@ import com.oracle.truffle.r.runtime.ffi.*; /** * JNR-based factory. */ -public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, LinpackRFFI, LapackRFFI, UserRngRFFI { +public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDerivedRFFI, LapackRFFI, UserRngRFFI { // Base @@ -375,10 +375,12 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, Linp /* * Linpack functions + * + * TODO In order to finesse a problem that "libR" does not exists separately on Linux, the Linpack functions should be amalgamated with FFT in RDerived. */ @Override - public LinpackRFFI getLinpackRFFI() { + public RDerivedRFFI getRDerivedRFFI() { return this; } @@ -438,6 +440,62 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, Linp linpack().dqrcf_(x, RefScalars_dqrcf.n, RefScalars_dqrcf.k, qraux, y, RefScalars_dqrcf.ny, b, info); } + // fft functions + + public interface FFT { + // TODO add @In/@Out to any arrays that are known to be either @In or @Out (default is @Inout) + + // @formatter:off + void fft_factor(@In int[] n, int[] pmaxf, int[] pmaxp); + + int fft_work(double[] a, double[] b, @In int[] nseg, @In int[] n, @In int[] nspn, @In int[] isn, double[] work, int[] iwork); + } + + private static class FFTProvider { + private static FFT fft; + + @SlowPath + private static FFT createAndLoadLib() { + return LibraryLoader.create(FFT.class).load("RDerived"); + } + + static FFT fft() { + if (fft == null) { + fft = createAndLoadLib(); + } + return fft; + } + } + + private static FFT fft() { + return FFTProvider.fft(); + } + + + private static class RefScalars_fft_factor { + static int[] n = new int[1]; + } + + public void fft_factor(int n, int[] pmaxf, int[] pmaxp) { + RefScalars_fft_factor.n[0] = n; + fft().fft_factor(RefScalars_fft_factor.n, pmaxf, pmaxp); + } + + private static class RefScalars_fft_work extends RefScalars_fft_factor { + static int[] nseg = new int[1]; + static int[] nspn = new int[1]; + static int[] isn = new int[1]; + } + + public int fft_work(double[] a, double[] b, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { + RefScalars_fft_work.n[0] = n; + RefScalars_fft_work.nseg[0] = nseg; + RefScalars_fft_work.nspn[0] = nspn; + RefScalars_fft_work.isn[0] = isn; + return fft().fft_work(a, b, RefScalars_fft_work.nseg, RefScalars_fft_work.n, RefScalars_fft_work.nspn, RefScalars_fft_work.isn, work, iwork); + } + + /* * UserRng. * This is a singleton instance, although the actual library may vary from run to run.