From efdb83d6652b69961a970f9851e4ce2246ba6bb3 Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Fri, 13 Jun 2014 13:37:13 -0700
Subject: [PATCH] stub out fft support

---
 .../r/nodes/builtin/base/FFTFunctions.java    | 61 ++++++++++++++++++
 .../nodes/builtin/base/ForeignFunctions.java  |  4 +-
 .../{LinpackRFFI.java => RDerivedRFFI.java}   | 12 +++-
 .../oracle/truffle/r/runtime/ffi/RFFI.java    |  4 +-
 .../truffle/r/runtime/ffi/RFFIFactory.java    |  4 +-
 .../r/runtime/ffi/jnr/JNR_RFFIFactory.java    | 62 ++++++++++++++++++-
 6 files changed, 137 insertions(+), 10 deletions(-)
 create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FFTFunctions.java
 rename com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/{LinpackRFFI.java => RDerivedRFFI.java} (75%)

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 0000000000..83b1fc15f1
--- /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 f23ad6e597..b35e12cdd8 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 d8d5552822..aa698758ee 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 6e830dac69..b7e3a055af 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 5a7eac7688..cb90413421 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 d3985e1cea..8fe543a7d4 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.
-- 
GitLab