From fa9bd1b0fc8ae064545ad192146020a3298d69c2 Mon Sep 17 00:00:00 2001
From: Toon Baeyens <toon.baeyens@gmail.com>
Date: Fri, 26 Jan 2018 00:38:49 +0100
Subject: [PATCH] feat(kernel): popcount (Long.bitCount) and clz
 (Long.numberOfLeadingZeros)

ISSUES CLOSED: #47
---
 src/main/java/com/aparapi/Kernel.java         | 57 +++++++++++++++++++
 .../aparapi/codegen/test/MathFallThru.java    | 12 +++-
 .../codegen/test/MathFallThruTest.java        |  4 ++
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/aparapi/Kernel.java b/src/main/java/com/aparapi/Kernel.java
index f697ff4a..72bac0ca 100644
--- a/src/main/java/com/aparapi/Kernel.java
+++ b/src/main/java/com/aparapi/Kernel.java
@@ -1316,7 +1316,64 @@ public abstract class Kernel implements Cloneable {
       return Math.abs(_f);
    }
 
+
    /**
+    * Delegates to either {@link java.lang.Integer#bitCount(int)} (Java) or <code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(int)</a></code> (OpenCL).
+     *
+     * @param _i value to delegate to {@link java.lang.Integer#bitCount(int)}/<code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(int)</a></code>
+     * @return {@link java.lang.Integer#bitCount(int)}/<code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(int)</a></code>
+     * @see java.lang.Integer#bitCount(int)
+     * @see <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/popcount.html">popcount(int)</a></code>
+     */
+   @OpenCLMapping(mapTo = "popcount")
+   protected int popcount(int _i) {
+      return Integer.bitCount(_i);
+   }
+
+   /**
+    * Delegates to either {@link java.lang.Long#bitCount(long)} (Java) or <code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(long)</a></code> (OpenCL).
+     *
+     * @param _i value to delegate to {@link java.lang.Long#bitCount(long)}/<code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(long)</a></code>
+     * @return {@link java.lang.Long#bitCount(long)}/<code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/popcount.html">popcount(long)</a></code>
+     * @see java.lang.Long#bitCount(long)
+     * @see <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/popcount.html">popcount(long)</a></code>
+     */
+   @OpenCLMapping(mapTo = "popcount")
+   protected long popcount(long _i) {
+      return Long.bitCount(_i);
+   }
+
+   /**
+    * Delegates to either {@link java.lang.Integer#numberOfLeadingZeros(int)} (Java) or <code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clz.html">clz(int)</a></code> (OpenCL).
+     *
+     * @param _i value to delegate to {@link java.lang.Integer#numberOfLeadingZeros(int)}/<code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(int)</a></code>
+     * @return {@link java.lang.Integer#numberOfLeadingZeros(int)}/<code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(int)</a></code>
+     * @see java.lang.Integer#numberOfLeadingZeros(int)
+     * @see <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(int)</a></code>
+     */
+
+   @OpenCLMapping(mapTo = "clz")
+   protected int clz(int _i) {
+      return Integer.numberOfLeadingZeros(_i);
+   }
+
+
+   /**
+    * Delegates to either {@link java.lang.Long#numberOfLeadingZeros(long)} (Java) or <code><a href="https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clz.html">clz(long)</a></code> (OpenCL).
+     *
+     * @param _l value to delegate to {@link java.lang.Long#numberOfLeadingZeros(long)}/<code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(long)</a></code>
+     * @return {@link java.lang.Long#numberOfLeadingZeros(long)}/<code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(long)</a></code>
+     * @see java.lang.Long#numberOfLeadingZeros(long)
+     * @see <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clz.html">clz(long)</a></code>
+     */
+
+
+   @OpenCLMapping(mapTo = "clz")
+   protected long clz(long _l) {
+      return Long.numberOfLeadingZeros(_l);
+   }
+
+    /**
     * Delegates to either {@link java.lang.Math#abs(double)} (Java) or <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/fabs.html">fabs(double)</a></code> (OpenCL).
      *
      * User should note the differences in precision between Java and OpenCL's implementation of arithmetic functions to determine whether the difference in precision is acceptable.
diff --git a/src/test/java/com/aparapi/codegen/test/MathFallThru.java b/src/test/java/com/aparapi/codegen/test/MathFallThru.java
index d6b6875d..76a2dd89 100644
--- a/src/test/java/com/aparapi/codegen/test/MathFallThru.java
+++ b/src/test/java/com/aparapi/codegen/test/MathFallThru.java
@@ -19,14 +19,18 @@ import com.aparapi.Kernel;
 
 public class MathFallThru extends Kernel {
 
-    long longout[] = new long[1];
-    int intout[] = new int[1];
+    long longout[] = new long[3];
+    int intout[] = new int[3];
 
     public void run() {
         float f1 = 1.0f;
         double d1 = 1.0;
         longout[0] = round(ceil(cos(exp(floor(log(pow(d1, d1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(d1, d1)))))))));
+        longout[1] = popcount(longout[0]);
+        longout[2] = clz(longout[0]);
         intout[0] = round(ceil(cos(exp(floor(log(pow(f1, f1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(f1, f1)))))))));
+        intout[1] = popcount(intout[0]);
+        intout[2] = clz(intout[0]);
         @SuppressWarnings("unused") boolean pass = false;
     }
 }
@@ -56,7 +60,11 @@ public class MathFallThru extends Kernel {
  float f1 = 1.0f;
  double d1 = 1.0;
  this->longout[0]  = round((ceil(cos(exp(floor(log(pow(d1, d1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(d1, d1))))))))));
+ this->longout[1]  = popcount(this->longout[0]);
+ this->longout[2]  = clz(this->longout[0]);
  this->intout[0]  = round((ceil(cos(exp(floor(log(pow(f1, f1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(f1, f1))))))))));
+ this->intout[1]  = popcount(this->intout[0]);
+ this->intout[2]  = clz(this->intout[0]);
  char pass = 0;
  return;
  }
diff --git a/src/test/java/com/aparapi/codegen/test/MathFallThruTest.java b/src/test/java/com/aparapi/codegen/test/MathFallThruTest.java
index ced44207..0c7f2893 100644
--- a/src/test/java/com/aparapi/codegen/test/MathFallThruTest.java
+++ b/src/test/java/com/aparapi/codegen/test/MathFallThruTest.java
@@ -44,7 +44,11 @@ public class MathFallThruTest extends com.aparapi.codegen.CodeGenJUnitBase {
 " float f1 = 1.0f;\n" +
 " double d1 = 1.0;\n" +
 " this->longout[0]  = round((ceil(cos(exp(floor(log(pow(d1, d1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(d1, d1))))))))));\n" +
+" this->longout[1]  = popcount(this->longout[0]);\n" +
+" this->longout[2]  = clz(this->longout[0]);\n" +
 " this->intout[0]  = round((ceil(cos(exp(floor(log(pow(f1, f1)))))) + tan(sqrt(sin(rint(acos(asin(atan(atan2(f1, f1))))))))));\n" +
+" this->intout[1]  = popcount(this->intout[0]);\n" +
+" this->intout[2]  = clz(this->intout[0]);\n" +
 " char pass = 0;\n" +
 " return;\n" +
 " }\n" +
-- 
GitLab