Added a test file.

Added a test file.

(*
 *  A contribution from Anne Sheets (sheets@cory)
 *
 *  Tests the arithmetic operations and various other things
 *)

class A {

   var : Int <- 0;

   value() : Int { var };

   set_var(num : Int) : SELF_TYPE {
      {
         var <- num;
         self;
      }
   };

   method1(num : Int) : SELF_TYPE {  -- same
      self
   };

   method2(num1 : Int, num2 : Int) : B {  -- plus
      (let x : Int in
	 {
            x <- num1 + num2;
	    (new B).set_var(x);
	 }
      )
   };

   method3(num : Int) : C {  -- negate
      (let x : Int in
	 {
            x <- ~num;
	    (new C).set_var(x);
	 }
      )
   };

   method4(num1 : Int, num2 : Int) : D {  -- diff
            if num2 < num1 then
               (let x : Int in
		  {
                     x <- num1 - num2;
	             (new D).set_var(x);
	          }
               )
            else
               (let x : Int in
		  {
	             x <- num2 - num1;
	             (new D).set_var(x);
		  }
               )
            fi
   };

   method5(num : Int) : E {  -- factorial
      (let x : Int <- 1 in
	 {
	    (let y : Int <- 1 in
	       while y <= num loop
	          {
                     x <- x * y;
	             y <- y + 1;
	          }
	       pool
	    );
	    (new E).set_var(x);
	 }
      )
   };

};

class B inherits A {  -- B is a number squared

   method5(num : Int) : E { -- square
      (let x : Int in
	 {
            x <- num * num;
	    (new E).set_var(x);
	 }
      )
   };

};

class C inherits B {

   method6(num : Int) : A { -- negate
      (let x : Int in
         {
            x <- ~num;
	    (new A).set_var(x);
         }
      )
   };

   method5(num : Int) : E {  -- cube
      (let x : Int in
	 {
            x <- num * num * num;
	    (new E).set_var(x);
	 }
      )
   };

};

class D inherits B {

   method7(num : Int) : Bool {  -- divisible by 3
      (let x : Int <- num in
            if x < 0 then method7(~x) else
            if 0 = x then true else
            if 1 = x then false else
	    if 2 = x then false else
	       method7(x - 3)
	    fi fi fi fi
      )
   };

};

class E inherits D {

   method6(num : Int) : A {  -- division
      (let x : Int in
         {
            x <- num / 8;
	    (new A).set_var(x);
         }
      )
   };

};

(* The following code is from atoi.cl in ~cs164/examples *)

(*
   The class A2I provides integer-to-string and string-to-integer
conversion routines.  To use these routines, either inherit them
in the class where needed, have a dummy variable bound to
something of type A2I, or simpl write (new A2I).method(argument).
*)

(*
   c2i   Converts a 1-character string to an integer.  Aborts
         if the string is not "0" through "9"
*)
class A2I {

     c2i(char : String) : Int {
	if char = "0" then 0 else
	if char = "1" then 1 else
	if char = "2" then 2 else
        if char = "3" then 3 else
        if char = "4" then 4 else
        if char = "5" then 5 else
        if char = "6" then 6 else
        if char = "7" then 7 else
        if char = "8" then 8 else
        if char = "9" then 9 else
        { abort(); 0; }  (* the 0 is needed to satisfy the
				  typchecker *)
        fi fi fi fi fi fi fi fi fi fi
     };

(*
   i2c is the inverse of c2i.
*)
     i2c(i : Int) : String {
	if i = 0 then "0" else
	if i = 1 then "1" else
	if i = 2 then "2" else
	if i = 3 then "3" else
	if i = 4 then "4" else
	if i = 5 then "5" else
	if i = 6 then "6" else
	if i = 7 then "7" else
	if i = 8 then "8" else
	if i = 9 then "9" else
	{ abort(); ""; }  -- the "" is needed to satisfy the typchecker
        fi fi fi fi fi fi fi fi fi fi
     };

(*
   a2i converts an ASCII string into an integer.  The empty string
is converted to 0.  Signed and unsigned strings are handled.  The
method aborts if the string does not represent an integer.  Very
long strings of digits produce strange answers because of arithmetic
overflow.

*)
     a2i(s : String) : Int {
        if s.length() = 0 then 0 else
	if s.substr(0,1) = "-" then ~a2i_aux(s.substr(1,s.length()-1)) else
        if s.substr(0,1) = "+" then a2i_aux(s.substr(1,s.length()-1)) else
           a2i_aux(s)
        fi fi fi
     };

(* a2i_aux converts the usigned portion of the string.  As a
   programming example, this method is written iteratively.  *)

     a2i_aux(s : String) : Int {
	(let int : Int <- 0 in
           {
               (let j : Int <- s.length() in
	          (let i : Int <- 0 in
		    while i < j loop
			{
			    int <- int * 10 + c2i(s.substr(i,1));
			    i <- i + 1;
			}
		    pool
		  )
	       );
              int;
	    }
        )
     };

(* i2a converts an integer to a string.  Positive and negative
   numbers are handled correctly.  *)

    i2a(i : Int) : String {
	if i = 0 then "0" else
        if 0 < i then i2a_aux(i) else
          "-".concat(i2a_aux(i * ~1))
        fi fi
    };

(* i2a_aux is an example using recursion.  *)

    i2a_aux(i : Int) : String {
        if i = 0 then "" else
	    (let next : Int <- i / 10 in
		i2a_aux(next).concat(i2c(i - next * 10))
	    )
        fi
    };

};

class Main inherits IO {

   char : String;
   avar : A;
   a_var : A;
   flag : Bool <- true;

   menu() : String {
      {
         out_string("\n\tTo add a number to ");
         print(avar);
         out_string("...enter a:\n");
         out_string("\tTo negate ");
         print(avar);
         out_string("...enter b:\n");
         out_string("\tTo find the difference between ");
         print(avar);
         out_string("and another number...enter c:\n");
         out_string("\tTo find the factorial of ");
         print(avar);
         out_string("...enter d:\n");
         out_string("\tTo square ");
         print(avar);
         out_string("...enter e:\n");
         out_string("\tTo cube ");
         print(avar);
         out_string("...enter f:\n");
         out_string("\tTo find out if ");
         print(avar);
         out_string("is a multiple of 3...enter g:\n");
         out_string("\tTo divide ");
         print(avar);
         out_string("by 8...enter h:\n");
	 out_string("\tTo get a new number...enter j:\n");
	 out_string("\tTo quit...enter q:\n\n");
         in_string();
      }
   };

   prompt() : String {
      {
         out_string("\n");
         out_string("Please enter a number...  ");
         in_string();
      }
   };

   get_int() : Int {
      {
	 (let z : A2I <- new A2I in
	    (let s : String <- prompt() in
	       z.a2i(s)
	    )
         );
      }
   };

   is_even(num : Int) : Bool {
      (let x : Int <- num in
            if x < 0 then is_even(~x) else
            if 0 = x then true else
	    if 1 = x then false else
	          is_even(x - 2)
	    fi fi fi
      )
   };

   class_type(var : A) : SELF_TYPE {
      case var of
	 a : A => out_string("Class type is now A\n");
	 b : B => out_string("Class type is now B\n");
	 c : C => out_string("Class type is now C\n");
	 d : D => out_string("Class type is now D\n");
	 e : E => out_string("Class type is now E\n");
	 o : Object => out_string("Oooops\n");
      esac
   };

   print(var : A) : SELF_TYPE {
     (let z : A2I <- new A2I in
	{
	   out_string(z.i2a(var.value()));
	   out_string(" ");
	}
     )
   };

   main() : Object {
      {
         avar <- (new A);
         while flag loop
            {
	       -- avar <- (new A).set_var(get_int());
	       out_string("number ");
	       print(avar);
	       if is_even(avar.value()) then
	          out_string("is even!\n")
	       else
	          out_string("is odd!\n")
	       fi;
	       -- print(avar); -- prints out answer
	       class_type(avar);
	       char <- menu();
                  if char = "a" then -- add
                     {
                        a_var <- (new A).set_var(get_int());
	                avar <- (new B).method2(avar.value(), a_var.value());
	             } else
                  if char = "b" then -- negate
                     case avar of
	                   c : C => avar <- c.method6(c.value());
	                   a : A => avar <- a.method3(a.value());
	                   o : Object => {
		                  out_string("Oooops\n");
		                  abort(); 0;
		               };
                     esac else
                  if char = "c" then -- diff
                     {
                        a_var <- (new A).set_var(get_int());
	                avar <- (new D).method4(avar.value(), a_var.value());
	             } else
                  if char = "d" then avar <- (new C)@A.method5(avar.value()) else
		          -- factorial
                  if char = "e" then avar <- (new C)@B.method5(avar.value()) else
			  -- square
                  if char = "f" then avar <- (new C)@C.method5(avar.value()) else
			  -- cube
                  if char = "g" then -- multiple of 3?
		      if ((new D).method7(avar.value()))
		                       then -- avar <- (new A).method1(avar.value())
			 {
	                    out_string("number ");
	                    print(avar);
	                    out_string("is divisible by 3.\n");
			 }
			 else  -- avar <- (new A).set_var(0)
			 {
	                    out_string("number ");
	                    print(avar);
	                    out_string("is not divisible by 3.\n");
			 }
		      fi else
                  if char = "h" then
		      (let x : A in
			 {
		            x <- (new E).method6(avar.value());
			    (let r : Int <- (avar.value() - (x.value() * 8)) in
			       {
			          out_string("number ");
			          print(avar);
			          out_string("is equal to ");
			          print(x);
			          out_string("times 8 with a remainder of ");
				  (let a : A2I <- new A2I in
				     {
			                out_string(a.i2a(r));
			                out_string("\n");
				     }
				  ); -- end let a:
			       }
                            ); -- end let r:
			    avar <- x;
		         }
		      )  -- end let x:
		      else
                  if char = "j" then avar <- (new A)
		      else
                  if char = "q" then flag <- false
		      else
                      avar <- (new A).method1(avar.value()) -- divide/8
                  fi fi fi fi fi fi fi fi fi fi;
            }
         pool;
       }
   };

};

error: pathspec 'test_files/arith.cl' did not match any file(s) known to git


Added OpenCL lookup kernel

Added OpenCL lookup kernel

/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#ifndef in_t
#define in_t float
#endif

#ifndef idx_t
#define idx_t float
#endif

#ifndef dim_type
#define dim_type int
#endif

dim_type trimIndex(dim_type idx, const dim_type len)
{
    dim_type ret_val = idx;
    dim_type offset  = abs(ret_val)%len;
    if (ret_val<0) {
        ret_val = offset-1;
    } else if (ret_val>=len) {
        ret_val = len-offset-1;
    }
    return ret_val;
}

__kernel __attribute__ ((reqd_work_group_size(32, 8, 1)))
void lookupND(global in_t * out,
              const dim_type odim0,
              const dim_type odim1,
              const dim_type odim2,
              const dim_type odim3,
              const dim_type ostride0,
              const dim_type ostride1,
              const dim_type ostride2,
              const dim_type ostride3,
              const dim_type ooffset,
              global const in_t * in,
              const dim_type idim0,
              const dim_type idim1,
              const dim_type idim2,
              const dim_type idim3,
              const dim_type istride0,
              const dim_type istride1,
              const dim_type istride2,
              const dim_type istride3,
              const dim_type ioffset,
              global const idx_t * indices,
              dim_type nBBS0,
              dim_type nBBS1,
              dim_type DIM)
{
    dim_type lx = get_local_id(0);
    dim_type ly = get_local_id(1);

    dim_type gz = get_group_id(0)/nBBS0;
    dim_type gw = get_group_id(1)/nBBS1;

    dim_type gx = get_local_size(0) * (get_group_id(0) - gz*nBBS0) + lx;
    dim_type gy = get_local_size(1) * (get_group_id(1) - gw*nBBS1) + ly;

    global const idx_t *idxPtr = indices;

    dim_type i = istride0*(DIM==0 ? trimIndex((dim_type)idxPtr[gx], idim0): gx);
    dim_type j = istride1*(DIM==1 ? trimIndex((dim_type)idxPtr[gy], idim1): gy);
    dim_type k = istride2*(DIM==2 ? trimIndex((dim_type)idxPtr[gz], idim2): gz);
    dim_type l = istride3*(DIM==3 ? trimIndex((dim_type)idxPtr[gw], idim3): gw);

    global const in_t *inPtr = in + (i+j+k+l);
    global in_t *outPtr = out + (gx*ostride0+gy*ostride1+
                                 gz*ostride2+gw*ostride3);

    if (gx<odim0 && gy<odim1 && gz<odim2 && gw<odim3) {
        outPtr[0] = inPtr[0];
    }
}

error: pathspec 'src/backend/opencl/kernel/lookup.cl' did not match any file(s) known to git


added one cl

added one cl

#define LSIZE 256
__kernel void NBody2For(
			unsigned hst_ptrForces_x_dim1, __global float * Mas, __global float * Pos,
			unsigned hst_ptrForces_y_dim1, __global float * Forces_y, __global float * Forces_x,
			unsigned hst_ptrPos_dim1) {
  __local float Pos_x_local[LSIZE];
  __local float Pos_y_local[LSIZE];
  __local float Mas_local[LSIZE];
  Pos_x_local[get_local_id(0)] = Pos[(0 * hst_ptrPos_dim1) + LSIZE*get_group_id(1) + get_local_id(0)];
  Pos_y_local[get_local_id(0)] = Pos[(1 * hst_ptrPos_dim1) + LSIZE*get_group_id(1) + get_local_id(0)];
  Mas_local[get_local_id(0)] = Mas[LSIZE*get_group_id(1) + get_local_id(0)];
  barrier(CLK_LOCAL_MEM_FENCE);
  float a_x = Pos[(0 * hst_ptrPos_dim1) + get_global_id(0)];
  float a_y = Pos[(1 * hst_ptrPos_dim1) + get_global_id(0)];
  float a_m = Mas[get_global_id(0)];
  unsigned idx = LSIZE*get_group_id(1);
  float f_x = 0.0;
  float f_y = 0.0;
  for (unsigned k = 0; k < LSIZE; k++) {
    /* float b_x = Pos[(0 * hst_ptrPos_dim1) + LSIZE*get_group_id(1) + k]; */
    /* float b_y = Pos[(1 * hst_ptrPos_dim1) + LSIZE*get_group_id(1) + k]; */
    /* float b_m = Mas[LSIZE*get_group_id(1) + k]; */
    float b_x = Pos_x_local[k];
    float b_y = Pos_y_local[k];
    float b_m = Mas_local[k];
    float r_x = b_x - a_x;
    float r_y = b_y - a_y;
    float d = (r_x * r_x) + (r_y * r_y);
    float deno = (sqrt((d * d) * d)) + (get_global_id(0) == (idx+k));
    deno = ((a_m * b_m) / deno) * (get_global_id(0) != (idx+k));
    /* f_x = deno * r_x; */
    /* f_y = deno * r_y; */
    f_x += deno * r_x;
    f_y += deno * r_y;
  }
  /* float res_x = get_local_id(0) == 0 ? f_x : 0.0; */
  /* float res_y = get_local_id(0) == 0 ? f_y : 0.0; */
  /* float res_x = get_local_id(0) == 0 ? f_x : f_x; */
  Forces_x[(get_global_id(0) * hst_ptrForces_x_dim1) + get_group_id(1)] = f_x;
  Forces_y[(get_global_id(0) * hst_ptrForces_y_dim1) + get_group_id(1)] = f_y;
  /* float res_y = get_local_id(0) == 0 ? f_y : f_y; */
  /* float res_x = f_x; */
  /* float res_y = f_y; */
  /* Forces_x[(get_global_id(1) * hst_ptrForces_x_dim1) + get_global_id(0)] = res_x; */
  /* Forces_y[(get_global_id(1) * hst_ptrForces_y_dim1) + get_global_id(0)] = res_y; */
}

error: pathspec 'test/C/NBody2/NBody2For.cl' did not match any file(s) known to git


r1771: initial import

r1771: initial import

;; tester.cl
;; A test harness for Allegro CL.
;;
;; copyright (c) 1985-1986 Franz Inc, Alameda, CA
;; copyright (c) 1986-2001 Franz Inc, Berkeley, CA - All rights reserved.
;;
;; This code is free software; you can redistribute it and/or
;; modify it under the terms of the version 2.1 of
;; the GNU Lesser General Public License as published by
;; the Free Software Foundation, as clarified by the Franz
;; preamble to the LGPL found in
;; http://opensource.franz.com/preamble.html.
;;
;; 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
;; Lesser General Public License for more details.
;;
;; Version 2.1 of the GNU Lesser General Public License can be
;; found at http://opensource.franz.com/license.html.
;; If it is not present, you can access it from
;; http://www.gnu.org/copyleft/lesser.txt (until superseded by a newer
;; version) or write to the Free Software Foundation, Inc., 59 Temple
;; Place, Suite 330, Boston, MA  02111-1307  USA
;;
;;;; from the original ACL 6.1 sources:
;; $Id: acl-compat-tester.cl,v 1.1 2002/04/08 02:46:43 kevin Exp $

(defpackage :util.test
  (:use :common-lisp)
  (:shadow #:test)
  (:export
;;;; Control variables:
   #:*break-on-test-failures*
   #:*error-protect-tests*
   #:*test-errors*
   #:*test-successes*
   #:*test-unexpected-failures*

;;;; The test macros:
   #:test
   #:test-error
   #:test-no-error
   #:test-warning
   #:test-no-warning

   #:with-tests
   ))

(in-package :util.test)

(unless (find-class 'break nil)
  (define-condition break (simple-condition) ()))

(define-condition simple-break (error simple-condition) ())

;; the if* macro used in Allegro:
;;
;; This is in the public domain... please feel free to put this definition
;; in your code or distribute it with your version of lisp.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar if*-keyword-list '("then" "thenret" "else" "elseif")))

(defmacro if* (&rest args)
   (do ((xx (reverse args) (cdr xx))
	(state :init)
	(elseseen nil)
	(totalcol nil)
	(lookat nil nil)
	(col nil))
       ((null xx)
	(cond ((eq state :compl)
	       `(cond ,@totalcol))
	      (t (error "if*: illegal form ~s" args))))
       (cond ((and (symbolp (car xx))
		   (member (symbol-name (car xx))
			   if*-keyword-list
			   :test #'string-equal))
	      (setq lookat (symbol-name (car xx)))))

       (cond ((eq state :init)
	      (cond (lookat (cond ((string-equal lookat "thenret")
				   (setq col nil
					 state :then))
				  (t (error
				      "if*: bad keyword ~a" lookat))))
		    (t (setq state :col
			     col nil)
		       (push (car xx) col))))
	     ((eq state :col)
	      (cond (lookat
		     (cond ((string-equal lookat "else")
			    (cond (elseseen
				   (error
				    "if*: multiples elses")))
			    (setq elseseen t)
			    (setq state :init)
			    (push `(t ,@col) totalcol))
			   ((string-equal lookat "then")
			    (setq state :then))
			   (t (error "if*: bad keyword ~s"
					      lookat))))
		    (t (push (car xx) col))))
	     ((eq state :then)
	      (cond (lookat
		     (error
		      "if*: keyword ~s at the wrong place " (car xx)))
		    (t (setq state :compl)
		       (push `(,(car xx) ,@col) totalcol))))
	     ((eq state :compl)
	      (cond ((not (string-equal lookat "elseif"))
		     (error "if*: missing elseif clause ")))
	      (setq state :init)))))

(defvar *break-on-test-failures* nil
  "When a test failure occurs, common-lisp:break is called, allowing
interactive debugging of the failure.")

(defvar *test-errors* 0
  "The value is the number of test errors which have occurred.")
(defvar *test-successes* 0
  "The value is the number of test successes which have occurred.")
(defvar *test-unexpected-failures* 0
  "The value is the number of unexpected test failures which have occurred.")

(defvar *error-protect-tests* nil
  "Protect each test from errors.  If an error occurs, then that will be
taken as a test failure unless test-error is being used.")

(defmacro test-values-errorset (form &optional announce catch-breaks)
  ;; internal macro
  (let ((g-announce (gensym))
	(g-catch-breaks (gensym)))
    `(let* ((,g-announce ,announce)
	    (,g-catch-breaks ,catch-breaks))
       (handler-case (cons t (multiple-value-list ,form))
	 (condition (condition)
	   (if* (and (null ,g-catch-breaks)
		     (typep condition 'simple-break))
	      then (break condition)
	    elseif ,g-announce
	      then (format *error-output* "~&Condition type: ~a~%"
			   (class-of condition))
		   (format *error-output* "~&Message: ~a~%" condition))
	   condition)))))

(defmacro test-values (form &optional announce catch-breaks)
  ;; internal macro
  (if* *error-protect-tests*
     then `(test-values-errorset ,form ,announce ,catch-breaks)
     else `(cons t (multiple-value-list ,form))))

(defmacro test (expected-value test-form
		&key (test #'eql test-given)
		     (multiple-values nil multiple-values-given)
		     (fail-info nil fail-info-given)
		     (known-failure nil known-failure-given)

;;;;;;;;;; internal, undocumented keywords:
;;;; Note about these keywords: if they were documented, we'd have a
;;;; problem, since they break the left-to-right order of evaluation.
;;;; Specifically, errorset breaks it, and I don't see any way around
;;;; that.  `errorset' is used by the old test.cl module (eg,
;;;; test-equal-errorset).
		     errorset
		     reported-form
		     (wanted-message nil wanted-message-given)
		     (got-message nil got-message-given))
  "Perform a single test.  `expected-value' is the reference value for the
test.  `test-form' is a form that will produce the value to be compared to
the expected-value.  If the values are not the same, then an error is
logged, otherwise a success is logged.

Normally the comparison of values is done with `eql'.  The `test' keyword
argument can be used to specify other comparison functions, such as eq,
equal,equalp, string=, string-equal, etc.

Normally, only the first return value from the test-form is considered,
however if `multiple-values' is t, then all values returned from test-form
are considered.

`fail-info' allows more information to be printed with a test failure.

`known-failure' marks the test as a known failure.  This allows for
programs that do regression analysis on the output from a test run to
discriminate on new versus known failures."
  `(test-check
    :expected-result ,expected-value
    :test-results
    (,(if errorset 'test-values-errorset 'test-values) ,test-form t)
    ,@(when test-given `(:predicate ,test))
    ,@(when multiple-values-given `(:multiple-values ,multiple-values))
    ,@(when fail-info-given `(:fail-info ,fail-info))
    ,@(when known-failure-given `(:known-failure ,known-failure))
    :test-form ',(if reported-form reported-form test-form)
    ,@(when wanted-message-given `(:wanted-message ,wanted-message))
    ,@(when got-message-given `(:got-message ,got-message))))

(defmethod conditionp ((thing condition)) t)
(defmethod conditionp ((thing t)) nil)

(defmacro test-error (form &key announce
				catch-breaks
				(fail-info nil fail-info-given)
				(known-failure nil known-failure-given)
				(condition-type ''simple-error)
				(include-subtypes nil include-subtypes-given)
				(format-control nil format-control-given)
				(format-arguments nil format-arguments-given))
  "Test that `form' signals an error. The order of evaluation of the
arguments is keywords first, then test form.

If `announce' is non-nil, then cause the error message to be printed.

The `catch-breaks' is non-nil then consider a call to common-lisp:break an
`error'.

`fail-info' allows more information to be printed with a test failure.

`known-failure' marks the test as a known failure.  This allows for
programs that do regression analysis on the output from a test run to
discriminate on new versus known failures.

If `condition-type' is non-nil, it should be a symbol naming a condition
type, which is used to check against the signalled condition type.  The
test will fail if they do not match.

`include-subtypes', used with `condition-type', can be used to match a
condition to an entire subclass of the condition type hierarchy.

`format-control' and `format-arguments' can be used to check the error
message itself."
  (let ((g-announce (gensym))
	(g-catch-breaks (gensym))
	(g-fail-info (gensym))
	(g-known-failure (gensym))
	(g-condition-type (gensym))
	(g-include-subtypes (gensym))
	(g-format-control (gensym))
	(g-format-arguments (gensym))
	(g-c (gensym)))
    `(let* ((,g-announce ,announce)
	    (,g-catch-breaks ,catch-breaks)
	    ,@(when fail-info-given `((,g-fail-info ,fail-info)))
	    ,@(when known-failure-given `((,g-known-failure ,known-failure)))
	    (,g-condition-type ,condition-type)
	    ,@(when include-subtypes-given
		`((,g-include-subtypes ,include-subtypes)))
	    ,@(when format-control-given
		`((,g-format-control ,format-control)))
	    ,@(when format-arguments-given
		`((,g-format-arguments ,format-arguments)))
	    (,g-c (test-values-errorset ,form ,g-announce ,g-catch-breaks)))
       (test-check
	:predicate #'eq
	:expected-result t
	:test-results
	(test-values (and (conditionp ,g-c)
			  ,@(if* include-subtypes-given
			       then `((if* ,g-include-subtypes
					 then (typep ,g-c ,g-condition-type)
					 else (eq (class-of ,g-c)
						  (find-class
						   ,g-condition-type))))
			       else `((eq (class-of ,g-c)
					  (find-class ,g-condition-type))))
			  ,@(when format-control-given
			      `((or
				 (null ,g-format-control)
				 (string=
				  (concatenate 'simple-string
				    "~1@<" ,g-format-control "~:@>")
				  (simple-condition-format-control ,g-c)))))
			  ,@(when format-arguments-given
			      `((or
				 (null ,g-format-arguments)
				 (equal
				  ,g-format-arguments
				  (simple-condition-format-arguments ,g-c))))))
		     t)
	:test-form ',form
	,@(when fail-info-given `(:fail-info ,g-fail-info))
	,@(when known-failure-given `(:known-failure ,g-known-failure))
	:condition-type ,g-condition-type
	:condition ,g-c
	,@(when include-subtypes-given
	    `(:include-subtypes ,g-include-subtypes))
	,@(when format-control-given
	    `(:format-control ,g-format-control))
	,@(when format-arguments-given
	    `(:format-arguments ,g-format-arguments))))))

(defmacro test-no-error (form &key announce
				   catch-breaks
				   (fail-info nil fail-info-given)
				   (known-failure nil known-failure-given))
  "Test that `form' does not signal an error.  The order of evaluation of
the arguments is keywords first, then test form.

If `announce' is non-nil, then cause the error message to be printed.

The `catch-breaks' is non-nil then consider a call to common-lisp:break an
`error'.

`fail-info' allows more information to be printed with a test failure.

`known-failure' marks the test as a known failure.  This allows for
programs that do regression analysis on the output from a test run to
discriminate on new versus known failures."
  (let ((g-announce (gensym))
	(g-catch-breaks (gensym))
	(g-fail-info (gensym))
	(g-known-failure (gensym))
	(g-c (gensym)))
    `(let* ((,g-announce ,announce)
	    (,g-catch-breaks ,catch-breaks)
	    ,@(when fail-info-given `((,g-fail-info ,fail-info)))
	    ,@(when known-failure-given `((,g-known-failure ,known-failure)))
	    (,g-c (test-values-errorset ,form ,g-announce ,g-catch-breaks)))
       (test-check
	:predicate #'eq
	:expected-result t
	:test-results (test-values (not (conditionp ,g-c)))
	:test-form ',form
	:condition ,g-c
	,@(when fail-info-given `(:fail-info ,g-fail-info))
	,@(when known-failure-given `(:known-failure ,g-known-failure))))))

(defvar *warn-cookie* (cons nil nil))

(defmacro test-warning (form &key fail-info known-failure)
  "Test that `form' signals a warning.  The order of evaluation of
the arguments is keywords first, then test form.

`fail-info' allows more information to be printed with a test failure.

`known-failure' marks the test as a known failure.  This allows for
programs that do regression analysis on the output from a test run to
discriminate on new versus known failures."
  (let ((g-fail-info (gensym))
	(g-known-failure (gensym))
	(g-value (gensym)))
    `(let* ((,g-fail-info ,fail-info)
	    (,g-known-failure ,known-failure)
	    (,g-value (test-values-errorset ,form nil t)))
       (test
	*warn-cookie*
	(if* (or (typep ,g-value 'simple-warning) (typep ,g-value 'warning))
	   then *warn-cookie*
	   else ;; test produced no warning
		nil)
	:test #'eq
	:reported-form ,form ;; quoted by test macro
	:wanted-message "a warning"
	:got-message "no warning"
	:fail-info ,g-fail-info
	:known-failure ,g-known-failure))))

(defmacro test-no-warning (form &key fail-info known-failure)
  "Test that `form' does not signal a warning.  The order of evaluation of
the arguments is keywords first, then test form.

`fail-info' allows more information to be printed with a test failure.

`known-failure' marks the test as a known failure.  This allows for
programs that do regression analysis on the output from a test run to
discriminate on new versus known failures."
  (let ((g-fail-info (gensym))
	(g-known-failure (gensym))
	(g-value (gensym)))
    `(let* ((,g-fail-info ,fail-info)
	    (,g-known-failure ,known-failure)
	    (,g-value (test-values-errorset ,form nil t)))
       (test
	*warn-cookie*
	(if* (or (typep ,g-value 'simple-warning) (typep ,g-value 'warning))
	   then nil ;; test produced warning
	   else *warn-cookie*)
	:test #'eq
	:reported-form ',form
	:wanted-message "no warning"
	:got-message "a warning"
	:fail-info ,g-fail-info
	:known-failure ,g-known-failure))))

(defvar *announce-test* nil) ;; if true announce each test that was done

(defmacro errorset (form &optional announce catch-breaks)
  ;; Evaluate FORM, and if there are no errors and FORM returns
  ;; values v1,v2,...,vn, then return values t,v1,v2,...,vn.  If an
  ;; error occurs while evaluating FORM, then return nil immediately.
  ;; If ANNOUNCE is t, then the error message will be printed out.
  (if catch-breaks
      `(handler-case (values-list (cons t (multiple-value-list ,form)))
         (error (condition)
           (declare (ignore-if-unused condition))
           ,@(if announce `((format *error-output* "~&Error: ~a~%" condition)))
           nil)
         (simple-break (condition)
           (declare (ignore-if-unused condition))
           ,@(if announce `((format *error-output* "~&Warning: ~a~%" condition))
)
           nil))
    `(handler-case (values-list (cons t (multiple-value-list ,form)))
       (error (condition)
         (declare (ignore-if-unused condition))
         ,@(if announce `((format *error-output* "~&Error: ~a~%" condition)))
         nil))))

(defun test-check (&key (predicate #'eql)
			expected-result test-results test-form
			multiple-values fail-info known-failure
			wanted-message got-message condition-type condition
			include-subtypes format-control format-arguments
		   &aux fail predicate-failed got wanted)
  ;; for debugging large/complex test sets:
  (when *announce-test*
    (format t "Just did test ~s~%" test-form)
    (force-output))

  ;; this is an internal function
  (flet ((check (expected-result result)
	   (let* ((results
		   (multiple-value-list
		    (errorset (funcall predicate expected-result result) t)))
		  (failed (null (car results))))
	     (if* failed
		then (setq predicate-failed t)
		     nil
		else (cadr results)))))
    (when (conditionp test-results)
      (setq condition test-results)
      (setq test-results nil))
    (when (null (car test-results))
      (setq fail t))
    (if* (and (not fail) (not multiple-values))
       then ;; should be a single result
	    ;; expected-result is the single result wanted
	    (when (not (and (cdr test-results)
			    (check expected-result (cadr test-results))))
	      (setq fail t))
	    (when (and (not fail) (cddr test-results))
	      (setq fail 'single-got-multiple))
       else ;; multiple results wanted
	    ;; expected-result is a list of results, each of which
	    ;; should be checked against the corresponding test-results
	    ;; using the predicate
	    (do ((got (cdr test-results) (cdr got))
		 (want expected-result (cdr want)))
		((or (null got) (null want))
		 (when (not (and (null want) (null got)))
		   (setq fail t)))
	      (when (not (check (car got) (car want)))
		(return (setq fail t)))))
    (if* fail
       then (when (not known-failure)
	      (format *error-output*
		      "~& * * * UNEXPECTED TEST FAILURE * * *~%")
	      (incf *test-unexpected-failures*))
	    (format *error-output* "~&Test failed: ~@[known failure: ~*~]~s~%"
		    known-failure test-form)
	    (if* (eq 'single-got-multiple fail)
	       then (format
		     *error-output*
		     "~
Reason: additional value were returned from test form.~%")
	     elseif predicate-failed
	       then (format *error-output* "Reason: predicate error.~%")
	     elseif (null (car test-results))
	       then (format *error-output* "~
Reason: an error~@[ (of type `~s')~] was detected.~%"
			    (when condition (class-of condition)))
	     elseif condition
	       then (if* (not (conditionp condition))
		       then (format *error-output* "~
Reason: expected but did not detect an error of type `~s'.~%"
				    condition-type)
		     elseif (null condition-type)
		       then (format *error-output* "~
Reason: detected an unexpected error of type `~s':
        ~a.~%"
				    (class-of condition)
				    condition)
		     elseif (not (if* include-subtypes
				    then (typep condition condition-type)
				    else (eq (class-of condition)
					     (find-class condition-type))))
		       then (format *error-output* "~
Reason: detected an incorrect condition type.~%")
			    (format *error-output*
				    "  wanted: ~s~%" condition-type)
			    (format *error-output*
				    "     got: ~s~%" (class-of condition))
		     elseif (and format-control
				 (not (string=
				       (setq got
					 (concatenate 'simple-string
					   "~1@<" format-control "~:@>"))
				       (setq wanted
					 (simple-condition-format-control
					  condition)))))
		       then ;; format control doesn't match
			    (format *error-output* "~
Reason: the format-control was incorrect.~%")
			    (format *error-output* "  wanted: ~s~%" wanted)
			    (format *error-output* "     got: ~s~%" got)
		     elseif (and format-arguments
				 (not (equal
				       (setq got format-arguments)
				       (setq wanted
					 (simple-condition-format-arguments
					  condition)))))
		       then (format *error-output* "~
Reason: the format-arguments were incorrect.~%")
			    (format *error-output* "  wanted: ~s~%" wanted)
			    (format *error-output* "     got: ~s~%" got)
		       else ;; what else????
			    (error "internal-error"))
	       else (let ((*print-length* 50)
			  (*print-level* 10))
		      (if* wanted-message
			 then (format *error-output*
				      "  wanted: ~a~%" wanted-message)
			 else (if* (not multiple-values)
				 then (format *error-output*
					      "  wanted: ~s~%"
					      expected-result)
				 else (format
				       *error-output*
				       "  wanted values: ~{~s~^, ~}~%"
				       expected-result)))
		      (if* got-message
			 then (format *error-output*
				      "     got: ~a~%" got-message)
			 else (if* (not multiple-values)
				 then (format *error-output* "     got: ~s~%"
				       (second test-results))
				 else (format
				       *error-output*
				       "     got values: ~{~s~^, ~}~%"
				       (cdr test-results))))))
	    (when fail-info
	      (format *error-output* "Additional info: ~a~%" fail-info))
	    (incf *test-errors*)
	    (when *break-on-test-failures*
	      (break "~a is non-nil." '*break-on-test-failures*))
       else (when known-failure
	      (format *error-output*
		      "~&Expected test failure for ~s did not occur.~%"
		      test-form)
	      (when fail-info
		(format *error-output* "Additional info: ~a~%" fail-info))
	      (setq fail t))
	    (incf *test-successes*))
    (not fail)))

(defmacro with-tests ((&key (name "unnamed")) &body body)
  (let ((g-name (gensym)))
    `(flet ((doit () ,@body))
       (let ((,g-name ,name)
	     (*test-errors* 0)
	     (*test-successes* 0)
	     (*test-unexpected-failures* 0))
	 (format *error-output* "Begin ~a test~%" ,g-name)
	 (if* *break-on-test-failures*
	    then (doit)
	    else (handler-case (doit)
		   (error (c)
		     (format
		      *error-output*
		      "~
~&Test ~a aborted by signalling an uncaught error:~%~a~%"
		      ,g-name c))))
	 #+allegro
	 (let ((state (sys:gsgc-switch :print)))
	   (setf (sys:gsgc-switch :print) nil)
	   (format t "~&**********************************~%" ,g-name)
	   (format t "End ~a test~%" ,g-name)
	   (format t "Errors detected in this test: ~s " *test-errors*)
	   (unless (zerop *test-unexpected-failures*)
	     (format t "UNEXPECTED: ~s" *test-unexpected-failures*))
	   (format t "~%Successes this test:~s~%" *test-successes*)
	   (setf (sys:gsgc-switch :print) state))
	 #-allegro
	 (progn
	   (format t "~&**********************************~%" ,g-name)
	   (format t "End ~a test~%" ,g-name)
	   (format t "Errors detected in this test: ~s " *test-errors*)
	   (unless (zerop *test-unexpected-failures*)
	     (format t "UNEXPECTED: ~s" *test-unexpected-failures*))
	   (format t "~%Successes this test:~s~%" *test-successes*))
	 ))))

(provide :tester #+module-versions 1.1)

error: pathspec 'test-suite/acl-compat-tester.cl' did not match any file(s) known to git


Add a test case for the 'vec_type_hint' attribute that was introduced in
r176686. I missed this file in the previous commit.

git-svn-id: ffe668792ed300d6c2daa1f6eba2e0aa28d7ec6c@176803 91177308-0d34-0410-b5e6-96231b3b80d8

// RUN: %clang_cc1 -verify %s

kernel __attribute__((vec_type_hint)) void kernel1() {} //expected-error{{attribute takes one argument}}

kernel __attribute__((vec_type_hint(not_type))) void kernel2() {} //expected-error{{unknown type name 'not_type'}}

kernel __attribute__((vec_type_hint(void))) void kernel3() {} //expected-error{{invalid attribute argument 'void' - expecting a vector or vectorizable scalar type}}

kernel __attribute__((vec_type_hint(bool))) void kernel4() {} //expected-error{{invalid attribute argument 'bool' - expecting a vector or vectorizable scalar type}}

kernel __attribute__((vec_type_hint(int))) __attribute__((vec_type_hint(float))) void kernel5() {} //expected-warning{{attribute 'vec_type_hint' is already applied with different parameters}}

kernel __attribute__((work_group_size_hint(8,16,32,4))) void kernel6() {} //expected-error{{attribute requires exactly 3 arguments}}

kernel __attribute__((work_group_size_hint(1,2,3))) __attribute__((work_group_size_hint(3,2,1))) void kernel7() {}  //expected-warning{{attribute 'work_group_size_hint' is already applied with different parameters}}

error: pathspec 'test/SemaOpenCL/invalid-kernel-attrs.cl' did not match any file(s) known to git


Added OpenCL scalar kernel

Added OpenCL scalar kernel

/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#ifndef To
#define To float
#endif

#ifndef Ti
#define Ti float
#endif

#ifndef T
#define T float
#endif

#ifndef dim_type
#define dim_type int
#endif

__kernel __attribute__ ((reqd_work_group_size(256, 1, 1)))
void scalar(__global To *out,
                 const dim_type odim0,
                 const dim_type odim1,
                 const dim_type odim2,
                 const dim_type odim3,
                 const dim_type ostride0,
                 const dim_type ostride1,
                 const dim_type ostride2,
                 const dim_type ostride3,
                 const dim_type ooffset,
                 const Ti scalar)
{
    uint groupId  = get_group_id(1) * get_num_groups(0) + get_group_id(0);
    uint threadId = get_local_id(0);

    int idx = groupId * get_local_size(0) * get_local_size(1) + threadId;

    if (idx >= odim3 * ostride3) return;

    To val = (To)scalar;

    out[idx] = val;
}

error: pathspec 'src/backend/opencl/kernel/scalar.cl' did not match any file(s) known to git


Remove untestable test case (global memory allocation in kernel)

#define SIZE (1u << 28)

kernel void largeArray(global int *res)
{
  global uchar4 A1[SIZE];          // try to allocate 2^2 * 2^28 = 2^30 = 1 GB of memory
  global uchar4 A2[SIZE];          // try to allocate 2^2 * 2^28 = 2^30 = 1 GB of memory

  global uchar8 B1[SIZE];          // try to allocate 2^3 * 2^28 = 2^31 = 2 GB of memory
  global uchar8 B2[SIZE];          // try to allocate 2^3 * 2^28 = 2^31 = 2 GB of memory

  int i = get_global_id(0);
  res[0] = A1[i].s0;
  res[1] = A2[i].s0;
  res[2] = B1[i].s0;
  res[3] = B2[i].s0;
}


test_performance.cl: added an initial version of the cl-version of test_performance.c

// Test source code is from http://musicdsp.org/archive.php?classid=0#1 and
// modified to pass clang C compiler and changed TF to be local var in main
// to support ClampPointers pass.

// FormantsAM.cpp

// Thierry Rochebois' "Formantic Synthesis by Double Amplitude Modulation"

// Based on a tutorial by Thierry Rochebois.
// Comments by Paul Sernine.

// The spectral content of the signal is obtained by adding amplitude modulated formantic
// waveforms. The amplitude modulations spectraly shift the formantic waveforms.
// Continuous spectral shift, without losing the harmonic structure, is obtained
// by using crossfaded double carriers (multiple of the base frequency).
// To avoid  unwanted interference artifacts, phase relationships must be of the
// "cosine type".

// The output is a 44100Hz 16bit stereo PCM file.

// NOTE: for now looks like -O3 cripples safe exception load/store analysis
// TODO: get times from unclamped versions and compare to clamped ones and expect perf hit to be max 30%

// RUN: TARGET_FLAGS="-target nvptx" clang -S -c $TEST_SRC -O0 -emit-llvm -S -o $OUT_FILE.ll &&
// RUN: echo "Running and verifying 'Formantic Synthesis by Double Amplitude Modulation' case" &&
// RUN: opt -S -O3 $OUT_FILE.ll -o $OUT_FILE.O3.ll &&
// RUN: opt -S -load $CLAMP_PLUGIN -clamp-pointers -allow-unsafe-exceptions $OUT_FILE.ll -o $OUT_FILE.clamped.ll &&
// RUN: opt -debug -S -load $CLAMP_PLUGIN -clamp-pointers -allow-unsafe-exceptions $OUT_FILE.O3.ll -o $OUT_FILE.O3.clamped.ll &&
// RUN: opt -S -O3 $OUT_FILE.clamped.ll -o $OUT_FILE.clamped.O3.ll &&
// RUN: echo "Running original.O0:" &&
// RUN: time lli $OUT_FILE.ll &&
// RUN: echo "Running original.O3:" &&
// RUN: time lli $OUT_FILE.O3.ll &&
// RUN: echo "Running clamped.O0:" &&
// RUN: time lli $OUT_FILE.clamped.ll &&
// RUN: echo "Running O3.clamped:" &&
// RUN: time lli $OUT_FILE.O3.clamped.ll &&
// RUN: echo "Running clamped.O3:" &&
// RUN: time lli $OUT_FILE.clamped.O3.ll

typedef int int32_t;
typedef short int16_t;

float expf(float f)
{
  return exp(f);
}

//Approximates cos(pi*x) for x in [-1,1].
float fast_cos(const float x)
{
  float x2 = x*x;
  return 1+x2*(-4+2*x2);
}

// Length of the table
#define L_TABLE (256+1) //The last entry of the table equals the first (to avoid a modulo)
// Maximal formant width
#define I_MAX 64

//Formantic function of width I (used to fill the table of formants)
float fonc_formant(float p,const float I)
{
  float a=0.5f;
  int32_t hmax=(int)(10*I)>L_TABLE/2?L_TABLE/2:(int32_t)(10*I);
  float phi=0.0f;
  for(int32_t h=1;h<hmax;h++)
    {
      phi+=3.14159265359f*p;
      float hann=0.5f+0.5f*fast_cos(h*(1.0f/hmax));
      float gaussienne=0.85f*expf(-h*h/(I*I));
      float jupe=0.15f;
      float harmonique=cosf(phi);
      a+=hann*(gaussienne+jupe)*harmonique;
    }
  return a;
}

//Initialisation of the table TF with the fonction fonc_formant.
void init_formant(float TF[])
{ float coef=2.0f/(L_TABLE-1);
  for(int32_t I=0;I<I_MAX;I++)
    for(int32_t P=0;P<L_TABLE;P++)
      TF[P+I*L_TABLE]=fonc_formant(-1+P*coef,(float)(I));
}

//This function emulates the function fonc_formant
// thanks to the table TF. A bilinear interpolation is
// performed
float formant(float p,float i, float TF[])
{
  i=i<0?0:i>I_MAX-2?I_MAX-2:i;    // width limitation
  float P=(L_TABLE-1)*(p+1)*0.5f; // phase normalisation
  int32_t P0=(int32_t)P;     float fP=P-P0;  // Integer and fractional
  int32_t I0=(int32_t)i;     float fI=i-I0;  // parts of the phase (p) and width (i).
  int32_t i00=P0+L_TABLE*I0;     int32_t i10=i00+L_TABLE;
  //bilinear interpolation.
  return (1-fI)*(TF[i00] + fP*(TF[i00+1]-TF[i00]))
    +    fI*(TF[i10] + fP*(TF[i10+1]-TF[i10]));
}

// Double carrier.
// h : position (float harmonic number)
// p : phase
float porteuse(const float h,const float p)
{
  float h0=floor(h);  //integer and
  float hf=h-h0;      //decimal part of harmonic number.
  // modulos pour ramener p*h0 et p*(h0+1) dans [-1,1]
  float phi0=fmodf(p* h0   +1+1000,2.0f)-1.0f;
  float phi1=fmodf(p*(h0+1)+1+1000,2.0f)-1.0f;
  // two carriers.
  float Porteuse0=fast_cos(phi0);  float Porteuse1=fast_cos(phi1);
  // crossfade between the two carriers.
  return Porteuse0+hf*(Porteuse1-Porteuse0);
}

__kernel void test_kernel(__global int16_t* out_val)
{
  //Formant table for various french vowels (you can add your own)
  float F1[]={  730,  200,  400,  250,  190,  350,  550,  550,  450};
  float A1[]={ 1.0f, 0.5f, 1.0f, 1.0f, 0.7f, 1.0f, 1.0f, 0.3f, 1.0f};
  float F2[]={ 1090, 2100,  900, 1700,  800, 1900, 1600,  850, 1100};
  float A2[]={ 2.0f, 0.5f, 0.7f, 0.7f,0.35f, 0.3f, 0.5f, 1.0f, 0.7f};
  float F3[]={ 2440, 3100, 2300, 2100, 2000, 2500, 2250, 1900, 1500};
  float A3[]={ 0.3f,0.15f, 0.2f, 0.4f, 0.1f, 0.3f, 0.7f, 0.2f, 0.2f};
  float F4[]={ 3400, 4700, 3000, 3300, 3400, 3700, 3200, 3000, 3000};
  float A4[]={ 0.2f, 0.1f, 0.2f, 0.3f, 0.1f, 0.1f, 0.3f, 0.2f, 0.3f};

  float f0,dp0,p0=0.0f;
  int32_t F=7; //number of the current formant preset
  float f1,f2,f3,f4,a1,a2,a3,a4;
  f1=f2=f3=f4=100.0f;a1=a2=a3=a4=0.0f;

  //Table of formants
  float TF[L_TABLE*I_MAX];

  init_formant(TF);

  for(int ns=0;ns<200*44100;ns++)
    {
      if(0==(ns%11025)){F++;F%=8;} //formant change
      f0=12*powf(2.0f,4-4*ns/(10*44100.0f)); //sweep
      f0*=(1.0f+0.01f*sinf(ns*0.0015f));        //vibrato
      dp0=f0*(1/22050.0f);
      float un_f0=1.0f/f0;
      p0+=dp0;  //phase increment
      p0-=2*(p0>1);
      { //smoothing of the commands.
        float r=0.001f;
        f1+=r*(F1[F]-f1);f2+=r*(F2[F]-f2);f3+=r*(F3[F]-f3);f4+=r*(F4[F]-f4);
        a1+=r*(A1[F]-a1);a2+=r*(A2[F]-a2);a3+=r*(A3[F]-a3);a4+=r*(A4[F]-a4);
      }

      //The f0/fn coefficients stand for a -3dB/oct spectral enveloppe
      float out=
        a1*(f0/f1)*formant(p0,100*un_f0,TF)*porteuse(f1*un_f0,p0)
        +0.7f*a2*(f0/f2)*formant(p0,120*un_f0,TF)*porteuse(f2*un_f0,p0)
        +     a3*(f0/f3)*formant(p0,150*un_f0,TF)*porteuse(f3*un_f0,p0)
        +     a4*(f0/f4)*formant(p0,300*un_f0,TF)*porteuse(f4*un_f0,p0);

      // write to volatile variable to test... (use puts to verify correctness)
      out_val[0] = (int16_t)(15000.0f*out);
    }
}

error: pathspec 'tests/test_performance.cl' did not match any file(s) known to git


OpenCL implementation of the swarm rules

typedef struct
{
	float2 position;
	float2 velocity;
} mosquito;

typedef mosquito dragonfly;

__kernel void
rule_1 (__global mosquito* _swarm, __global float2* _mass_centre,
    const unsigned int _swarm_size)
{
	unsigned int idx = get_global_id(0);
	float2 mass_centre = (float2)(0.0f, 0.0f);

	for (unsigned int i = 0; i < _swarm_size; i++)
	{
		if (i == idx) continue;
		mass_centre += _swarm[i].position;
	}

	mass_centre /= (float)(_swarm_size - 1);
	_mass_centre[idx] = mass_centre;
}

__kernel void
rule_2 (__global mosquito* _swarm, __global float2 *_centre,
    const unsigned int _swarm_size)
{
	unsigned int idx = get_global_id(0);
	float2 centre = (float2)(0.0f, 0.0f);

	for (unsigned int i = 0; i < _swarm_size; i++)
	{
		if (i == idx) continue;
		float2 difference = _swarm[i].position - _swarm[idx].position;
		if (fast_length(difference) < 20.0f)
			centre -= difference;
	}

	_centre[idx] = centre;
}

__kernel void
rule_3 (__global mosquito* _swarm, __global float2 *_velocity,
    const unsigned int _swarm_size)
{
	unsigned int idx = get_global_id(0);
	float2 velocity = (float2)(0.0f, 0.0f);

	for (unsigned int i = 0; i < _swarm_size; i++)
	{
		if (i == idx) continue;
		velocity += _swarm[i].velocity;
	}
	velocity /= (float)(_swarm_size - 1);
	velocity = _swarm[idx].velocity - velocity;
	velocity /= 2.0f;

	_velocity[idx] = velocity;
}

__kernel void
rule_4 (__global mosquito* _swarm, __global float2 *_border_force,
    const unsigned int _swarm_size)
{
	unsigned int idx = get_global_id(0);
	float2 top_velocity = (float2)(0.0f, 0.0f);
	float2 bottom_velocity = (float2)(0.0f, 0.0f);
	float2 left_velocity = (float2)(0.0f, 0.0f);
	float2 right_velocity = (float2)(0.0f, 0.0f);

	if (_swarm[idx].position.x == 0.0f
	 || _swarm[idx].position.y == 0.0f
	 || _swarm[idx].position.x == 600.0f
	 || _swarm[idx].position.y == 600.0f)
	{
		_border_force[idx] = (float2)(0.0f, 0.0f);
		return;
	}

	top_velocity.y = fabs(20.0f / _swarm[idx].position.y);
	bottom_velocity.y = -fabs(20.0f / (_swarm[idx].position.y - 600.0f));
	left_velocity.x = fabs(20.0f / _swarm[idx].position.x);
	right_velocity.x = -fabs(20.0f / (_swarm[idx].position.x - 600.0f));

	float2 result = top_velocity + bottom_velocity + left_velocity +
	    right_velocity;
	result /= 0.1f;

	_border_force[idx] = result;
}

__kernel void
rule_5 (__global mosquito* _swarm, __global float2 *_fear,
    __global dragonfly *_predator, const unsigned int _swarm_size)
{
	unsigned int idx = get_global_id(0);
	float2 result = _swarm[idx].position - _predator->position;
	result /= 60.0f;

	_fear[idx] = result;
}

__kernel void
single_step (__global mosquito* _swarm, __global float2* _rule_1,
    __global float2* _rule_2, __global float2* _rule_3,
    __global float2* _rule_4, __global float2* _rule_5,
    __global mosquito* _new_swarm)
{
	unsigned int idx = get_global_id(0);
	float2 velocity = _rule_1[idx] + _rule_2[idx] + _rule_3[idx] + _rule_4[idx]
	    + _rule_5[idx];
	velocity /= 10000.0f;

	_new_swarm[idx].velocity = _swarm[idx].velocity + velocity;
	_new_swarm[idx].position = _swarm[idx].position + _swarm[idx].velocity
	    + velocity;
}

error: pathspec 'source.cl' did not match any file(s) known to git


[..] Missing kernel file

[..] Missing kernel file

__kernel void square_cpy(
    __global float* input,
   __global float* output,
   unsigned int count)
{
    unsigned int i = get_global_id(0);
    if (i < count)
        output[i] = input[i] * input[i];
}

error: pathspec 'test/kernels/square_cpy.cl' did not match any file(s) known to git


initial add of ccl kernels

initial add of ccl kernels

#include "clcommons/image.h"

typedef int LabelT;
typedef int LDSLabelT;
typedef uint PixelT;
typedef uint LDSPixelT;
typedef uint ConnectivityPixelT;
typedef uint LDSConnectivityPixelT;

#ifndef WORKGROUP_TILE_SIZE_X
#define WORKGROUP_TILE_SIZE_X 32
#endif
#ifndef WORKGROUP_TILE_SIZE_Y
#define WORKGROUP_TILE_SIZE_Y 8
#endif

#ifndef WORKITEM_REPEAT_X
#define WORKITEM_REPEAT_X 1
#endif
#ifndef WORKITEM_REPEAT_Y
#define WORKITEM_REPEAT_Y 4
#endif

#define TILE_COLS (WORKGROUP_TILE_SIZE_X * WORKITEM_REPEAT_X)
#define TILE_ROWS (WORKGROUP_TILE_SIZE_Y * WORKITEM_REPEAT_Y)

enum ConnectivityEnum {
    UP = (1<<0),
    DOWN = (1<<2),
    LEFT = (1<<3),
    RIGHT = (1<<4),
    LEFT_UP = (1<<5),
    LEFT_DOWN = (1<<6),
    RIGHT_UP = (1<<7),
    RIGHT_DOWN = (1<<8)
};

#define BG_VALUE 0

#define isConnected(p1, p2) ((p1) == (p2))

#ifndef CONNECTIVITY
#define CONNECTIVITY 8
#endif

#define pixel_at(type, basename, r, c) image_pixel_at(type, PASTE2(basename, _p), im_rows, im_cols, PASTE2(basename, _pitch), (r), (c))

//global dimensions: divUp(image.cols, block.x), divUp(image.rows, block.y);
//__attribute__((reqd_work_group_size(WORKGROUP_TILE_SIZE_X, WORKGROUP_TILE_SIZE_Y, 1)))
//__kernel void
//make_connectivity_image(uint im_rows, uint im_cols, __global PixelT *image_p, uint image_pitch, __global ConnectivityPixelT *connectivityim_p, uint connectivityim_pitch){
//    const uint c = get_global_id(1);
//    const uint r = get_global_id(0);
//    const bool valid_pixel_task = (c < im_cols) & (r < im_rows);
//
//    if(valid_pixel_task){
//        PixelT pixel = pixel_at(PixelT, image, r, c);
//        ConnectivityPixelT connectivity = 0;
//
//#if CONNECTIVITY == 8
//        connectivity |= c > 0 && r > 0                     && isConnected(pixel, pixel_at(PixelT, image, r-1, c - 1)) ? LEFT_UP : 0
//        connectivity |= c > 0                              && isConnected(pixel, pixel_at(PixelT, image, r, c - 1)) ? LEFT : 0
//        connectivity |= c > 0 && r < im_rows - 1           && isConnected(pixel, pixel_at(PixelT, image, r+1, c - 1)) ? LEFT_DOWN : 0
//        connectivity |=          r < im_rows - 1           && isConnected(pixel, pixel_at(PixelT, image, r+1, c)) ? DOWN : 0
//        connectivity |= c < im_cols - 1 && r < im_rows - 1 && isConnected(pixel, pixel_at(PixelT, image, r+1, c + 1)) ? RIGHT_DOWN : 0
//        connectivity |= c < im_cols - 1                    && isConnected(pixel, pixel_at(PixelT, image, r, c + 1)) ? RIGHT : 0
//        connectivity |= c < im_cols - 1 && r > 0           && isConnected(pixel, pixel_at(PixelT, image, r-1, c + 1)) ? RIGHT_UP : 0
//        connectivity |=          r > 0                     && isConnected(pixel, pixel_at(PixelT, image, r-1, c)) ? UP : 0
//#else
//        connectivity |= c > 0                              && isConnected(pixel, pixel_at(PixelT, image, r, c - 1)) ? LEFT : 0
//        connectivity |=          r < im_rows - 1           && isConnected(pixel, pixel_at(PixelT, image, r+1, c)) ? DOWN : 0
//        connectivity |= c < im_cols - 1                    && isConnected(pixel, pixel_at(PixelT, image, r, c + 1)) ? RIGHT : 0
//        connectivity |=          r > 0                     && isConnected(pixel, pixel_at(PixelT, image, r-1, c)) ? UP : 0
//#endif
//
//        pixel_at(ConnectivityPixelT, connectivity, r, c) = connectivity;
//    }
//}

//global dimensions: divUp(im_cols, workgroup_tile_size_x), divUp(im_rows, workgroup_tile_size_y);
__attribute__((reqd_work_group_size(WORKGROUP_TILE_SIZE_X, WORKGROUP_TILE_SIZE_Y, 1)))
__kernel void
make_connectivity_image(uint im_rows, uint im_cols, __global PixelT *image_p, uint image_pitch, __global ConnectivityPixelT *connectivityim_p, uint connectivityim_pitch){
    const uint tile_col_blocksize = get_local_size(0);
    const uint tile_row_blocksize = get_local_size(1);
    const uint tile_col_block = get_group_id(0) + get_global_offset(0) / tile_col_blocksize;
    const uint tile_row_block = get_group_id(1) + get_global_offset(1) / tile_row_blocksize;
    const uint tile_col = get_local_id(0);
    const uint tile_row = get_local_id(1);
    const bool valid_pixel_task = (get_global_id(0) < im_cols) & (get_global_id(1) < im_rows);

    uint tile_rows = tile_row_blocksize;
    uint tile_cols = tile_col_blocksize;

    const uint tile_row_start = tile_row_blocksize * tile_rows;
    const uint tile_col_start = tile_col_blocksize * tile_cols;
    const uint tile_row_end = min((tile_row_blocksize + 1) * tile_rows, (uint) im_rows);
    const uint tile_col_end = min((tile_col_blocksize + 1) * tile_cols, (uint) im_cols);
    //adjust to true tile dimensions
    tile_rows = tile_row_end - tile_row_start;
    tile_cols = tile_col_end - tile_col_start;
    const uint n_tile_pixels = tile_rows * tile_cols;
    __local LDSPixelT im_tile[WORKGROUP_TILE_SIZE_Y][WORKGROUP_TILE_SIZE_X];
    __local ConnectivityPixelT connectivity_tile[WORKGROUP_TILE_SIZE_Y][WORKGROUP_TILE_SIZE_X];

    const uint tid = tile_row * tile_cols + tile_col;
    for(uint im_tile_fill_task_id = tid; im_tile_fill_task_id < n_tile_pixels; im_tile_fill_task_id += n_tile_pixels){
        const uint im_tile_row = im_tile_fill_task_id / tile_cols;
        const uint im_tile_col = im_tile_fill_task_id % tile_cols;
        const uint g_c = im_tile_col + tile_col_block * tile_col_blocksize;
        const uint g_r = im_tile_row + tile_row_block * tile_row_blocksize;

        im_tile[im_tile_row][im_tile_col] = pixel_at(PixelT, image, g_r, g_c);
    }
    lds_barrier();

    {
        const uint c = get_local_id(1);
        const uint r = get_local_id(0);
        const uint g_c = get_global_id(1);
        const uint g_r = get_global_id(0);
        PixelT pixel = valid_pixel_task ? pixel_at(PixelT, image, r, c) : 0;
        ConnectivityPixelT connectivity = 0;

#if CONNECTIVITY == 8
        connectivity |= c > 0 && r > 0                         && isConnected(pixel, im_tile[r-1][c - 1]) ? LEFT_UP : 0
        connectivity |= c > 0                                  && isConnected(pixel, im_tile[r][c - 1]) ? LEFT : 0
        connectivity |= c > 0 && r < tile_rows - 1             && isConnected(pixel, im_tile[r+1][c - 1]) ? LEFT_DOWN : 0
        connectivity |=          r < tile_rows - 1             && isConnected(pixel, im_tile[r+1][c]) ? DOWN : 0
        connectivity |= c < tile_cols - 1 && r < tile_rows - 1 && isConnected(pixel, im_tile[r+1][c + 1]) ? RIGHT_DOWN : 0
        connectivity |= c < tile_cols - 1                      && isConnected(pixel, im_tile[r][c + 1]) ? RIGHT : 0
        connectivity |= c < tile_cols - 1 && r > 0             && isConnected(pixel, im_tile[r-1][c + 1]) ? RIGHT_UP : 0
        connectivity |=          r > 0                         && isConnected(pixel, im_tile[r-1][c]) ? UP : 0
#else
        connectivity |= c > 0                                  && isConnected(pixel, im_tile[r][c - 1]) ? LEFT : 0
        connectivity |=          r < tile_rows - 1             && isConnected(pixel, im_tile[r+1][c]) ? DOWN : 0
        connectivity |= c < tile_cols - 1                      && isConnected(pixel, im_tile[r][c + 1]) ? RIGHT : 0
        connectivity |=          r > 0                         && isConnected(pixel, im_tile[r-1][c]) ? UP : 0
#endif
        connectivity_tile[r][c] = connectivity;

    }
    lds_barrier();

    for(uint im_tile_fill_task_id = tid; im_tile_fill_task_id < n_tile_pixels; im_tile_fill_task_id += n_tile_pixels){
        const uint im_tile_row = im_tile_fill_task_id / tile_cols;
        const uint im_tile_col = im_tile_fill_task_id % tile_cols;
        const uint g_c = im_tile_col + tile_col_block * tile_col_blocksize;
        const uint g_r = im_tile_row + tile_row_block * tile_row_blocksize;

        pixel_at(ConnectivityPixelT, connectivity, g_r, g_c) = connectivity_tile[im_tile_row][im_tile_col];
    }
}

__attribute__((reqd_work_group_size(WORKGROUP_TILE_SIZE_X, WORKGROUP_TILE_SIZE_Y, 1)))
__kernel void
label_tiles(uint im_rows, uint im_cols, __global ConnectivityPixelT *labelim_p, uint labelim_pitch, __global ConnectivityPixelT *connectivity_p, uint connectivityPitch){
    const uint get_local_id(0) = get_local_id(0);
    const uint get_local_id(1) = get_local_id(1);

    const uint x = get_local_id(0) + get_group_id(0) * TILE_COLS;
    const uint y = get_local_id(1) + get_group_id(1) * TILE_ROWS;

    //if (x >= im_rows || y >= im_rows) return;

    //currently x is 1
    //int bounds = ((y + WORKITEM_REPEAT_Y) < im_rows);

    __local LDSLabelT label_tile_im[TILE_ROWS][TILE_COLS];
    __local LDSConnectivityPixelT  edge_tile_im[TILE_ROWS][TILE_COLS];

    LDSLabelT new_labels[WORKITEM_REPEAT_Y][WORKITEM_REPEAT_X];
    LDSLabelT old_labels[WORKITEM_REPEAT_Y][WORKITEM_REPEAT_X];

    #pragma unroll
    for (int i = 0; i < WORKITEM_REPEAT_Y; ++i){
        #pragma unroll
        for (int j = 0; j < WORKITEM_REPEAT_X; ++j){
            const uint yloc = get_local_id(1) + WORKGROUP_TILE_SIZE_Y * i;
            const uint xloc = get_local_id(0) + WORKGROUP_TILE_SIZE_X * j;
            const bool valid_pixel_task = (xloc < im_cols) & (yloc < im_rows);
            ConnectivityPixelT c = valid_pixel_task ? pixel_at(ConnectivityPixelT, connectivity, y + WORKGROUP_TILE_SIZE_Y * i, x + WORKGROUP_TILE_SIZE_X * j) : 0;

            c = xloc == 0 ? c & ~(LEFT|LEFT_DOWN|LEFT_UP) : c;
            c = yloc == 0 ? c & ~(UP|LEFT_UP|RIGHT_UP) : c;

            c = xloc == TILE_COLS - 1 ? c & ~(RIGHT|RIGHT_DOWN|RIGHT_UP);
            c = yloc == TILE_ROWS - 1 ? c & ~(DOWN|LEFT_DOWN|RIGHT_DOWN) : c;

            new_labels[i][j] = yloc * TILE_COLS + xloc;
            edge_tile_im[yloc][xloc] = c;
        }
    }

    for (int k = 0; ;++k){
        //make copies
        #pragma unroll
        for (int i = 0; i < WORKITEM_REPEAT_Y; ++i){
            #pragma unroll
            for (int j = 0; j < WORKITEM_REPEAT_X; ++j){
                const uint yloc = get_local_id(1) + WORKGROUP_TILE_SIZE_Y * i;
                const uint xloc = get_local_id(0) + WORKGROUP_TILE_SIZE_X * j;

                old_labels[i][j]          = new_labels[i][j];
                label_tile_im[yloc][xloc] = new_labels[i][j];
            }
        }
        lds_barrier();

        //take minimum label of local neighboorhood - single writer, multi reader version
        #pragma unroll
        for (int i = 0; i < WORKITEM_REPEAT_Y; ++i){
            #pragma unroll
            for (int j = 0; j < WORKITEM_REPEAT_X; ++j){
                const uint yloc = get_local_id(1) + WORKGROUP_TILE_SIZE_Y * i;
                const uint xloc = get_local_id(0) + WORKGROUP_TILE_SIZE_X * j;

                const ConnectivityPixelT connectivity = edge_tile_im[yloc][xloc];
                const LDSLabelT label = new_labels[i][j];

#if CONNECTIVITY == 8
                if (connectivity & UP)
                   label = min(label, label_tile_im[yloc - 1][xloc]);
                if (connectivity & LEFT)
                   label = min(label, label_tile_im[yloc][xloc - 1]);
                if (connectivity & LEFT_UP)
                   label = min(label, label_tile_im[yloc - 1][xloc - 1]);
                if (connectivity &  LEFT_DOWN)
                   label = min(label, label_tile_im[yloc + 1][xloc - 1]);
                if (connectivity &  DOWN)
                   label = min(label, label_tile_im[yloc + 1][xloc]);
                if (connectivity & RIGHT_DOWN)
                   label = min(label, label_tile_im[yloc - 1][xloc + 1]);
                if (connectivity & RIGHT)
                   label = min(label, label_tile_im[yloc][xloc + 1]);
                if (connectivity & RIGHT_UP)
                   label = min(label, label_tile_im[yloc + 1][xloc + 1]);

#else
                if (connectivity & UP)
                   label = min(label, label_tile_im[yloc - 1][xloc]);
                if (connectivity &  DOWN)
                   label = min(label, label_tile_im[yloc + 1][xloc]);
                if (connectivity & LEFT)
                   label = min(label, label_tile_im[yloc][xloc - 1]);
                if (connectivity & RIGHT)
                   label = min(label, label_tile_im[yloc][xloc + 1]);
#endif

                new_labels[i][j] = label;
            }
        }
        lds_barrier();

        __local int changed;
        if((get_local_id(1) == 0) & (get_local_id(0) == 0)){
            changed = 0;
        }
        lds_barrier();

        const __local LDSLabelT *labels = &label_tile_im[0][0];

        int pchanged = 0;
        #pragma unroll
        for(int i = 0; i < WORKITEM_REPEAT_Y; ++i){
            #pragma unroll
            for(int j = 0; j < WORKITEM_REPEAT_X; ++j){
                if(new_labels[i][j] < old_labels[i][j]){
                    pchanged++;
                    atomic_min(labels + old_labels[i][j], new_labels[i][j]);
                }
            }
        }
        atomic_add(&changed, pchanged);
        lds_barrier();

        //if there are no updates, we are finished
        if(!changed){
            break;
        }

        //Compact paths
        #pragma unroll
        for(int i = 0; i < WORKITEM_REPEAT_Y; ++i){
            #pragma unroll
            for(int j = 0; j < WORKITEM_REPEAT_X; ++j){
                LDSLabelT label = new_labels[i][j];

                //find root label
                while(labels[label] < label){
                    label = labels[label];
                }

                new_labels[i][j] = label;
            }
        }
        lds_barrier();
    }

    //save with adjusted global (untiled) labels
    #pragma unroll
    for(int i = 0; i < WORKITEM_REPEAT_Y; ++i){
        #pragma unroll
        for(int j = 0; j < WORKITEM_REPEAT_X; ++j){
            const LabelT tile_label = new_labels[i][j];
            const uint yloc = (tile_label / TILE_COLS) + get_group_id(0) * TILE_COLS;
            const uint xloc = (tile_label % TILE_COLS) + get_group_id(1) * TILE_ROWS;

            const LabelT glabel = yloc * im_cols + xloc;
            const bool valid_pixel_task = (xloc < im_cols) & (yloc < im_rows);
            if(valid_pixel_task){
                pixel_at(LabelT, labelim, yloc, xloc) = glabel;
            }
        }
    }
}

inline
LabelT find_root_global(const __global *labelim, uint labelim_pitch, LabelT label, const uint im_rows, const uint im_cols){
    for(;;){
        const uint y = label / im_cols;
        const uint x = label % im_cols;
        const LabelT parent = pixel_at(LabelT, labelim, y, x);

        if(label == parent){
            break;
        }

        label = parent;
    }
    return label;
}

__kernel
void compact_paths_global(uint im_rows, uint im_cols, __global LabelT *labelim, uint labelim_pitch){
    const uint x = get_global_id(0);
    const uint y = get_global_id(1);

    if((x < im_cols) & (y < im_rows)){
        pixel_at(LabelT, labelim, y, x) = find_root_global(labelim, pixel_at(LabelT, labelim, y, x));
    }
}

inline
void merge_edge_labels(const uint im_rows, const uint im_cols, __global LabelT *labelim_p, const uint labelim_pitch, const LabelT l1, const LabelT l2, uint *changed){

    const LabelT r1 = find_root_global(comps, l1, im_rows, im_cols);
    const LabelT r2 = find_root_global(comps, l2, im_rows, im_cols);

    if (r1 == r2) return;

    const LabelT mi = min(r1, r2);
    const LabelT ma = max(r1, r2);

    const uint y = ma / im_cols;
    const uint x = ma % im_cols;

    atomic_min(&pixel_at(LabelT, labelim, y, x), mi);
    *changed = true;
}

__kernel
void cross_merge(
    const uint n_vert_tiles, const uint n_horz_tiles,
    uint tile_rows, uint tile_cols,
    const uint im_rows, const uint im_cols,
    const __global ConnectivityPixelT *connectivityim_p, uint connectivityim_pitch,
    const __global LabelT *labelim_p, uint labelim,
    const uint yIncomplete, uint xIncomplete
){
    const uint ngroups_x = get_num_groups(0);
    const uint ngroups_y = get_num_groups(1);

    const uint tid = get_local_linear_id();
    const uint stride = get_local_size(1) * get_local_size(0);

    const uint ybegin = get_group_id(1) * (n_vert_tiles * tile_rows);
    const uint yend   = ybegin + n_vert_tiles * tile_rows;

    if (get_group_id(1) == ngroups_y - 1){
        yend -= yIncomplete * tile_rows;
        yend -= tile_rows;
        tile_rows = (im_rows % tile_rows);

        yend += tile_rows;
    }

    const uint xbegin = get_group_id(0) * n_horz_tiles * tile_cols;
    const uint xend   = xbegin + n_horz_tiles * tile_cols;

    if(get_group_id(0) == ngroups_x - 1){
        if (xIncomplete) yend = ybegin;
        xend -= xIncomplete * tile_cols;
        xend -= tile_cols;
        tile_cols = (im_cols % tile_cols);

        xend += tile_cols;
    }

    if (get_group_id(1) == (ngroups_y - 1) && yIncomplete){
        xend = xbegin;
    }

    const uint tasksV = (n_horz_tiles - 1) * (yend - ybegin);
    const uint tasksH = (n_vert_tiles - 1) * (xend - xbegin);

    const uint total = tasksH + tasksV;

    __local uint changed;
    uint pchanged;
    do{
        pchanged = false;
        for(uint taskIdx = tid; taskIdx < total; taskIdx += stride){
            if(taskIdx < tasksH){
                const uint indexH = taskIdx;

                const uint row = indexH / (xend - xbegin);
                const uint col = indexH - % (xend - xbegin);

                const uint y = ybegin + (row + 1) * tile_rows;
                const uint x = xbegin + col;

                const ConnectivityPixelT e = pixel_at(ConnectivityPixelT, connectivityim, y, x);
                if(e & UP){
                    LabelT lc = pixel_at(LabelT, labelim, y, x);
                    LabelT lu = pixel_at(LabelT, labelim, y - 1, x);
                    merge_edge_labels(im_rows, im_cols, labelim, labelim_pitch, lc, lu, &pchanged);
                }
            }else{
                const uint indexV = taskIdx - tasksH;

                const uint col = indexV / (yend - ybegin);
                const uint row = indexV % (yend - ybegin);

                const uint x = xbegin + (col + 1) * tile_cols;
                const uint y = ybegin + row;

                const ConnectivityPixelT e = pixel_at(ConnectivityPixelT, connectivityim, y, x);
                if(e & LEFT){
                    LabelT lc = pixel_at(LabelT, labelim, y, x);
                    LabelT lu = pixel_at(LabelT, labelim, y, x - 1);
                    merge_edge_labels(im_rows, im_cols, labelim, labelim_pitch, lc, ll, &pchanged);
                }
            }
        }
        atomic_add(&changed, pchanged);
        lds_barrier();
        pchanged = changed;
    }while(pchanged);
}

__kernel
void mark_root_classes(
    uint im_rows, uint im_cols,
    __global PixelT *image_p, uint image_pitch
    __global const LabelT* labelim_p, const labelim_pitch,
    __global uint* is_root_class_image_p, const uint is_root_class_image_pitch,
){
    const uint c = get_global_id(0);
    const uint r = get_global_id(1);
    const bool valid_pixel_task = (c < im_cols) & (r < im_rows);

    const uint linear_index = c + r * im_cols;
    if(valid_pixel_task){
        const PixelT pixel = pixel_at(PixelT, image, r, c);
        const LabelT label = pixel_at(LabelT, labelim, r, c);
        pixel_at(uint, is_root_class_image, r, c) = (pixel != BG_VALUE) & (label == linear_index);
    }
}

__kernel
void relabel_with_scanline_order(
    uint im_rows, uint im_cols,
    __global LabelT* labelim_out_p, const uint labelim_out_pitch,
    __global const PixelT* image_p, const image_pitch,
    __global const LabelT* labelim_p, const labelim_pitch,
    __global uint* is_root_class_image_psum_p, const uint is_root_class_image_psum_pitch
){
    const uint c = get_global_id(0);
    const uint r = get_global_id(1);
    const bool valid_pixel_task = (c < im_cols) & (r < im_rows);
    const uint linear_index = c + r * im_cols;

    if(valid_pixelTask){
        const LabelT pixel = pixel_at(PixelT, image, r, c);
        LabelT final_label = 0;
        if(pixel != BG_VALUE){
            const LabelT label = pixel_at(LabelT, labelim, r, c);
            const uint label_r = label / im_cols;
            const uint label_c = label % im_cols;
            const uint scan_id = pixel_at(uint, is_root_class_image_psum, label_r, label_c);
            final_label = scan_id + 1;
        }
        image_pixel_at(LabelT, labelim, r, c) = final_label;
    }
}


cl: correct 3a_stats valid_count

cl: correct 3a_stats valid_count

/*
 * function: kernel_3a_stats
 * input:    image2d_t as read only
 * output:   XCamGridStat, stats results
 */

"typedef struct"
"{"
"    unsigned int avg_y;"

"    unsigned int avg_r;"
"    unsigned int avg_gr;"
"    unsigned int avg_gb;"
"    unsigned int avg_b;"
"    unsigned int valid_wb_count;"

"    unsigned int f_value1;"
"    unsigned int f_value2;"
"} XCamGridStat;\n"

"__kernel void kernel_3a_stats (__read_only image2d_t input, __global XCamGridStat *output)   "
"{                                                                                "
"    int x = get_global_id (0);                                                               "
"    int y = get_global_id (1);                                                               "
"    int w = get_global_size (0);                                                             "
"    sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; "
"                                                                                "
"    int x0 = 16 * x;                                                                         "
"    int y0 = 16 * y;                                                                         "
"    float sum_gr = 0.0f, sum_r = 0.0f, sum_b = 0.0f, sum_gb=0.0f;                            "
"    float avg_gr = 0.0f, avg_r = 0.0f, avg_b = 0.0f, avg_gb = 0.0f;                          "
"    int i = 0, j = 0;                                                                        "
"    float count = (16.0 / 2) * (16.0 / 2);                                                   "
"    float4 p[4];                                                                             "

"\n#pragma unroll\n"
"    for (j = 0; j < 16; j += 2) {                                                            "

// grid (0, 0)
"    i = 0;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    sum_gr += p[0].x;                                                                        "
"    sum_b += p[1].x;                                                                         "
"    sum_r += p[2].x;                                                                         "
"    sum_gb += p[3].x;                                                                        "

// grid (1, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    sum_gr += p[0].x;                                                                        "
"    sum_b += p[1].x;                                                                         "
"    sum_r += p[2].x;                                                                         "
"    sum_gb += p[3].x;                                                                        "

// grid (2, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (3, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (4, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (5, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (6, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (7, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i; "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

//end for loop
"    }                                                                                "

"   avg_gr = sum_gr/count;                                                                     "
"   avg_r = sum_r/count;                                                                       "
"   avg_b = sum_b/count;                                                                       "
"   avg_gb = sum_gb/count;                                                                     "

"   output[y * w + x].avg_gr = convert_uint(avg_gr * 256.0);                                   "
"   output[y * w + x].avg_r = convert_uint(avg_r * 256.0);                                     "
"   output[y * w + x].avg_b = convert_uint(avg_b * 256.0);                                     "
"   output[y * w + x].avg_gb = convert_uint(avg_gb * 256.0);                                   "
"   output[y * w + x].valid_wb_count = convert_uint(count);                                    "
"   output[y * w + x].avg_y = convert_uint(((avg_gr + avg_gb)/2.0f)*256.0);                    "
"   output[y * w + x].f_value1 = 0;                                                            "
"   output[y * w + x].f_value2 = 0;                                                            "

"}                                                                                "

/*
 * function: kernel_3a_stats
 * input:    image2d_t as read only
 * output:   XCamGridStat, stats results
 */

"typedef struct"
"{"
"    unsigned int avg_y;"

"    unsigned int avg_r;"
"    unsigned int avg_gr;"
"    unsigned int avg_gb;"
"    unsigned int avg_b;"
"    unsigned int valid_wb_count;"

"    unsigned int f_value1;"
"    unsigned int f_value2;"
"} XCamGridStat;\n"

"__kernel void kernel_3a_stats (__read_only image2d_t input, __global XCamGridStat *output)   "
"{                                                                                "
"    int x = get_global_id (0);                                                               "
"    int y = get_global_id (1);                                                               "
"    int w = get_global_size (0);                                                             "
"    sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; "
"                                                                                "
"    int x0 = 16 * x;                                                                         "
"    int y0 = 16 * y;                                                                         "
"    float sum_gr = 0.0f, sum_r = 0.0f, sum_b = 0.0f, sum_gb=0.0f;                            "
"    float avg_gr = 0.0f, avg_r = 0.0f, avg_b = 0.0f, avg_gb = 0.0f;                          "
"    int i = 0, j = 0;                                                                        "
"    float count = (16.0 / 2) * (16.0 / 2);                                                   "
"    float4 p[4];                                                                             "

"\n#pragma unroll\n"
"    for (j = 0; j < 16; j += 2) {                                                            "

// grid (0, 0)
"    i = 0;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    sum_gr += p[0].x;                                                                        "
"    sum_b += p[1].x;                                                                         "
"    sum_r += p[2].x;                                                                         "
"    sum_gb += p[3].x;                                                                        "

// grid (1, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                             "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                         "
"    sum_gr += p[0].x;                                                                        "
"    sum_b += p[1].x;                                                                         "
"    sum_r += p[2].x;                                                                         "
"    sum_gb += p[3].x;                                                                        "

// grid (2, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (3, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (4, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (5, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (6, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i;                                                                                "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

// grid (7, 0)
"    ++i;                                                                                "
"    p[0] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[1] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    ++i; "
"    p[2] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j));                              "
"    p[3] = read_imagef (input, sampler, (int2)(x0 + i, y0 + j + 1));                          "
"    sum_gr += p[0].x;                                                                         "
"    sum_b += p[1].x;                                                                          "
"    sum_r += p[2].x;                                                                          "
"    sum_gb += p[3].x;                                                                         "

//end for loop
"    }                                                                                "

"   avg_gr = sum_gr/count;                                                                     "
"   avg_r = sum_r/count;                                                                       "
"   avg_b = sum_b/count;                                                                       "
"   avg_gb = sum_gb/count;                                                                     "

"   output[y * w + x].avg_gr = convert_uint(avg_gr * 256.0);                                   "
"   output[y * w + x].avg_r = convert_uint(avg_r * 256.0);                                     "
"   output[y * w + x].avg_b = convert_uint(avg_b * 256.0);                                     "
"   output[y * w + x].avg_gb = convert_uint(avg_gb * 256.0);                                   "
"   output[y * w + x].valid_wb_count = 255;                                                    "
"   output[y * w + x].avg_y = convert_uint(((avg_gr + avg_gb)/2.0f)*256.0);                    "
"   output[y * w + x].f_value1 = 0;                                                            "
"   output[y * w + x].f_value2 = 0;                                                            "

"}                                                                                "