From ed5b74169172a5a6a6a123787307e6ed7d4a7c24 Mon Sep 17 00:00:00 2001
From: Florian Roesler <florian.roesler@wooga.net>
Date: Wed, 7 Sep 2016 12:09:39 +0200
Subject: [PATCH] make kernels of the same class eligible to be run on
 different devices

---
 CHANGELOG.md                                  |  4 ++
 CONTRIBUTORS.md                               |  1 +
 pom.xml                                       |  2 +-
 src/main/java/com/aparapi/device/Device.java  |  2 +-
 .../internal/kernel/KernelManager.java        | 16 +++++---
 .../internal/kernel/PreferencesWrapper.java   | 39 +++++++++++++++++++
 6 files changed, 56 insertions(+), 8 deletions(-)
 create mode 100644 src/main/java/com/aparapi/internal/kernel/PreferencesWrapper.java

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19fb6e00..b87a8fe9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Aparapi Change Log
 
+## 1.2.0
+
+* Kernels of the same class are now eligible to be run on different devices
+
 ## 1.1.2
 
 * Fixed a bug where OpenCL kernels were getting compiled twice.
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index c73baf79..8f78b0eb 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1,6 +1,7 @@
 # Contributors
 
 * Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
+* Florian Roesler <florian.roesler@wooga.net>
 * George Vinokhodov
 * Witold Bolt 
 * Kenneth Skovhede
diff --git a/pom.xml b/pom.xml
index 72d24fd3..3a3353ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
 
     <groupId>com.aparapi</groupId>
     <artifactId>aparapi</artifactId>
-    <version>1.1.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <properties>
diff --git a/src/main/java/com/aparapi/device/Device.java b/src/main/java/com/aparapi/device/Device.java
index 93672448..e43e90b2 100644
--- a/src/main/java/com/aparapi/device/Device.java
+++ b/src/main/java/com/aparapi/device/Device.java
@@ -177,6 +177,6 @@ public abstract class Device{
 
    @Override
    public int hashCode() {
-      return Long.hashCode(getDeviceId());
+      return Long.valueOf(getDeviceId()).hashCode();
    }
 }
diff --git a/src/main/java/com/aparapi/internal/kernel/KernelManager.java b/src/main/java/com/aparapi/internal/kernel/KernelManager.java
index e8359b93..fb1d9aad 100644
--- a/src/main/java/com/aparapi/internal/kernel/KernelManager.java
+++ b/src/main/java/com/aparapi/internal/kernel/KernelManager.java
@@ -28,7 +28,7 @@ import java.util.*;
 public class KernelManager {
 
    private static KernelManager INSTANCE = new KernelManager();
-   private LinkedHashMap<Class<? extends Kernel>, KernelPreferences> preferences = new LinkedHashMap<>();
+   private LinkedHashMap<Integer, PreferencesWrapper> preferences = new LinkedHashMap<>();
    private LinkedHashMap<Class<? extends Kernel>, KernelProfile> profiles = new LinkedHashMap<>();
    private LinkedHashMap<Class<? extends Kernel>, Kernel> sharedInstances = new LinkedHashMap<>();
 
@@ -88,8 +88,9 @@ public class KernelManager {
          builder.append(" (showing mean elapsed times in milliseconds)");
       }
       builder.append("\n\n");
-      for (Class<? extends Kernel> klass : preferences.keySet()) {
-         KernelPreferences preferences = this.preferences.get(klass);
+      for (PreferencesWrapper wrapper : preferences.values()) {
+         KernelPreferences preferences = wrapper.getPreferences();
+         Class<? extends Kernel> klass = wrapper.getKernel().getClass();
          KernelProfile profile = withProfilingInfo ? profiles.get(klass) : null;
          builder.append(klass.getName()).append(":\n\tusing ").append(preferences.getPreferredDevice(null).getShortDescription());
          List<Device> failedDevices = preferences.getFailedDevices();
@@ -139,10 +140,13 @@ public class KernelManager {
 
    public KernelPreferences getPreferences(Kernel kernel) {
       synchronized (preferences) {
-         KernelPreferences kernelPreferences = preferences.get(kernel.getClass());
-         if (kernelPreferences == null) {
+         PreferencesWrapper wrapper = preferences.get(kernel.hashCode());
+         KernelPreferences kernelPreferences;
+         if (wrapper == null) {
             kernelPreferences = new KernelPreferences(this, kernel.getClass());
-            preferences.put(kernel.getClass(), kernelPreferences);
+            preferences.put(kernel.hashCode(), new PreferencesWrapper(kernel, kernelPreferences));
+         }else{
+           kernelPreferences = preferences.get(kernel.hashCode()).getPreferences();
          }
          return kernelPreferences;
       }
diff --git a/src/main/java/com/aparapi/internal/kernel/PreferencesWrapper.java b/src/main/java/com/aparapi/internal/kernel/PreferencesWrapper.java
new file mode 100644
index 00000000..f5ee1091
--- /dev/null
+++ b/src/main/java/com/aparapi/internal/kernel/PreferencesWrapper.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016 - 2017 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.internal.kernel;
+
+import com.aparapi.Kernel;
+
+public class PreferencesWrapper {
+  
+  private Kernel kernel;
+  private KernelPreferences preferences;
+  
+  public PreferencesWrapper(Kernel kernel, KernelPreferences preferences) {
+    super();
+    this.kernel = kernel;
+    this.preferences = preferences;
+  }
+
+  public Kernel getKernel() {
+    return kernel;
+  }
+
+  public KernelPreferences getPreferences() {
+    return preferences;
+  }
+}
+
-- 
GitLab