From 8a693a8450e5cca633d98904a37994090a9c1720 Mon Sep 17 00:00:00 2001
From: Barney <barney@frontofficedeveloper.com>
Date: Fri, 9 Oct 2015 20:04:28 +0100
Subject: [PATCH] Adding mistakenly omitted file from previous commit for
 device configurability, plus some minor cleanups:

Reverted Kernel#finalize, now not overridden (was disposing kernel but this caused problems due to threading).

Modified Range so that where auto-creating sizes (i.e. localIsDerived) for JavaDevices sizes are sensible (size = 1 for sequential, = Runtime.getRuntime().availableProcessors() for thread pool.
---
 .../src/java/com/amd/aparapi/Kernel.java      |  6 --
 .../src/java/com/amd/aparapi/Range.java       |  9 +++
 .../internal/kernel/KernelPreferences.java    | 78 +++++++++++++++++++
 .../aparapi/internal/kernel/KernelRunner.java |  4 +-
 .../aparapi/internal/model/ClassModel.java    |  1 -
 5 files changed, 89 insertions(+), 9 deletions(-)
 create mode 100644 com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelPreferences.java

diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java b/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java
index df9f7c46..5e11cab9 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java
@@ -2154,12 +2154,6 @@ public abstract class Kernel implements Cloneable {
       }
    }
 
-   /** Automatically releases any resources associated with this Kernel when the Kernel is garbage collected. */
-   @Override
-   protected void finalize() {
-      dispose();
-   }
-
    public boolean isRunningCL() {
       return getTargetDevice() instanceof OpenCLDevice;
    }
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/Range.java b/com.amd.aparapi/src/java/com/amd/aparapi/Range.java
index 3d6aef9a..64f060bd 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/Range.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/Range.java
@@ -140,6 +140,15 @@ public class Range extends RangeJNI{
    public static Range create(Device _device, int _globalWidth) {
       final Range withoutLocal = create(_device, _globalWidth, 1);
 
+      if (_device == JavaDevice.THREAD_POOL) {
+         withoutLocal.setLocalSize_0(Runtime.getRuntime().availableProcessors());
+         withoutLocal.setLocalIsDerived(true);
+         return withoutLocal;
+      } else if (_device instanceof JavaDevice) {
+         withoutLocal.setLocalIsDerived(true);
+         return withoutLocal;
+      }
+
       if (_globalWidth == 0) {
          withoutLocal.setLocalIsDerived(true);
          return withoutLocal;
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelPreferences.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelPreferences.java
new file mode 100644
index 00000000..fd238a6d
--- /dev/null
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelPreferences.java
@@ -0,0 +1,78 @@
+package com.amd.aparapi.internal.kernel;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.device.*;
+
+import java.util.*;
+
+public class KernelPreferences {
+   private final Class<? extends Kernel> kernelClass;
+   private final KernelManager manager;
+   private volatile LinkedList<Device> preferredDevices = null;
+   private final LinkedHashSet<Device> failedDevices = new LinkedHashSet<>();
+
+   public KernelPreferences(KernelManager manager, Class<? extends Kernel> kernelClass) {
+      this.kernelClass = kernelClass;
+      this.manager = manager;
+   }
+
+   /** What Kernel subclass is this the preferences for? */
+   public Class<? extends Kernel> getKernelClass() {
+      return kernelClass;
+   }
+
+   public List<Device> getPreferredDevices(Kernel kernel) {
+      maybeSetUpDefaultPreferredDevices();
+
+      if (kernel == null) {
+         return Collections.unmodifiableList(preferredDevices);
+      }
+      List<Device> localPreferredDevices = new ArrayList<>();
+      ArrayList<Device> copy;
+      synchronized (preferredDevices) {
+         copy = new ArrayList(preferredDevices);
+      }
+      for (Device device : copy) {
+         if (kernel.isAllowDevice(device)) {
+            localPreferredDevices.add(device);
+         }
+      }
+      return Collections.unmodifiableList(localPreferredDevices);
+   }
+
+   synchronized void setPreferredDevices(LinkedHashSet<Device> _preferredDevices) {
+      if (preferredDevices != null) {
+         preferredDevices.clear();
+         preferredDevices.addAll(_preferredDevices);
+      }
+      else {
+         preferredDevices = new LinkedList<>(_preferredDevices);
+      }
+      failedDevices.clear();
+   }
+
+   public Device getPreferredDevice(Kernel kernel) {
+      List<Device> localPreferredDevices = getPreferredDevices(kernel);
+      return localPreferredDevices.isEmpty() ? null : localPreferredDevices.get(0);
+   }
+
+   synchronized void markPreferredDeviceFailed() {
+      if (preferredDevices.size() > 0) {
+         failedDevices.add(preferredDevices.remove(0));
+      }
+   }
+
+   private void maybeSetUpDefaultPreferredDevices() {
+      if (preferredDevices == null) {
+         synchronized (this) {
+            if (preferredDevices == null) {
+               preferredDevices = new LinkedList<>(manager.getDefaultPreferences().getPreferredDevices(null));
+            }
+         }
+      }
+   }
+
+   public List<Device> getFailedDevices() {
+      return new ArrayList<>(failedDevices);
+   }
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java
index 7f250d0f..453e07d9 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java
@@ -187,8 +187,8 @@ public class KernelRunner extends KernelRunnerJNI{
     * 
     * @see KernelRunnerJNI#disposeJNI(long)
     */
-   public void dispose() {
-      if (args != null || kernel.isRunningCL()) {
+   public synchronized void dispose() {
+      if (kernel.isRunningCL()) {
          disposeJNI(jniContextHandle);
       }
       // We are using a shared pool, so there's no need no shutdown it when kernel is disposed
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/model/ClassModel.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/model/ClassModel.java
index d3db6a62..5b3823e8 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/model/ClassModel.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/model/ClassModel.java
@@ -2815,7 +2815,6 @@ public class ClassModel {
          long s = System.nanoTime();
          Entrypoint entrypointWithoutKernel = entrypointCache.computeIfAbsent(key);
          long e = System.nanoTime() - s;
-         System.out.println("newMethodModel: " + e / 1000000f);
          return entrypointWithoutKernel.cloneForKernel(_k);
       } else {
          final MethodModel method = getMethodModel(_entrypointName, _descriptor);
-- 
GitLab