Fixed uninitialized local variable test.

kernel void uninitialized_local_variable(global int *output)
{
  local int x;
  if (*output > 0)
    x = *output;
  *output = x;
}

kernel void uninitialized_local_variable(global int *output)
{
  local int x;
  *output = x;
}


added opencl file

added opencl file

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


Add a new data structure "clbpt_property"

1. Pack the root node address and the level together.
2. Never deem level = 1 as an exception.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/CLBplustree/CLBplustree.git/'


ocl: fix rgba access stride issue in blend kernel

each work item reads 2x2 rgba pixels, so both x and y access
stride of read_image should be 2.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/seanvk/libyami.git/'


Add missing test source file

Add missing test source file

void output(float (^op)(float))
{
  printf("op(1)=%f\n", op(1.0f));
}

kernel void test_block()
{
  // Two simple tests
  float (^add1)(float) = ^(float x) { return x + 1.0f; };
  float (^mul2)(float) = ^(float x) { return x * 2.0f; };
  output(add1);
  output(mul2);

  // Capture a pointer to a local variable
  float counter = 0.0f;
  float* counterp = &counter;
  float (^stepcounter)(float) = ^(float x) {
    return *counterp += x;
  };
  output(stepcounter);
  output(stepcounter);
}

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


add kernel csr2dense

add kernel csr2dense

#ifndef INDEX_TYPE
#error INDEX_TYPE undefined!
#endif

#ifndef VALUE_TYPE
#error VALUE_TYPE undefined!
#endif

#ifndef SIZE_TYPE
#error SIZE_TYPE undefined!
#endif

#ifndef WG_SIZE
#error WG_SIZE undefined!
#endif

#ifndef WAVE_SIZE
#define WAVE_SIZE 64
#endif

#ifndef SUBWAVE_SIZE
#define SUBWAVE_SIZE WAVE_SIZE
#endif

#if ( (SUBWAVE_SIZE > WAVE_SIZE) || (SUBWAVE_SIZE != 2 && SUBWAVE_SIZE != 4 && SUBWAVE_SIZE != 8 && SUBWAVE_SIZE != 16 && SUBWAVE_SIZE != 32 && SUBWAVE_SIZE != 64) )
# error SUBWAVE_SIZE is not  a power of two!
#endif

// Uses macro constants:
// WAVE_SIZE  - "warp size", typically 64 (AMD) or 32 (NV)
// WG_SIZE    - workgroup ("block") size, 1D representation assumed
// INDEX_TYPE - typename for the type of integer data read by the kernel,  usually unsigned int
// VALUE_TYPE - typename for the type of floating point data, usually double
// SUBWAVE_SIZE - the length of a "sub-wave", a power of 2, i.e. 1,2,4,...,WAVE_SIZE, assigned to process a single matrix row
__kernel
__attribute__((reqd_work_group_size(WG_SIZE,1,1)))
void csr2dense ( const INDEX_TYPE num_rows,
                         const INDEX_TYPE num_cols,
                __global const INDEX_TYPE * const row_offset,
                __global const INDEX_TYPE * const col,
                __global const VALUE_TYPE * const val,
                __global       VALUE_TYPE * A)
{

    const int global_id   = get_global_id(0);         // global workitem id
    const int local_id    = get_local_id(0);          // local workitem id
    const int thread_lane = local_id & (SUBWAVE_SIZE - 1);
    const int vector_id   = global_id / SUBWAVE_SIZE; // global vector id
    const int num_vectors = get_global_size(0) / SUBWAVE_SIZE;

    for(INDEX_TYPE row = vector_id; row < num_rows; row += num_vectors)
    {
        const int row_start = row_offset[row];
        const int row_end   = row_offset[row+1];

        for(int j = row_start + thread_lane; j < row_end; j += SUBWAVE_SIZE)
            A[row * num_cols + col[j]] = val[j];
    }
}

error: pathspec 'src/library/kernels/csr2dense.cl' did not match any file(s) known to git


Level >= 3 completed. Pass small tests.

Level >= 3 completed. Pass small tests.


OpenCL kernel now in file (which will be installed to plugin directory)

#if defined(cl_khr_fp64)
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#elif defined(cl_amd_fp64)
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#endif

#if defined(cl_intel_printf)
#pragma OPENCL EXTENSION cl_intel_printf : enable
#elif defined(cl_amd_printf)
#pragma OPENCL EXTENSION cl_amd_printf : enable
#endif

#ifdef DOUBLE
#ifdef COMPLEX
typedef double2 cl_mat_data_t;
#else
typedef double cl_mat_data_t;
#endif
#endif
#ifdef SINGLE
#ifdef COMPLEX
typedef float2 cl_mat_data_t;
#else
typedef float cl_mat_data_t;
#endif
#endif

kernel void CRS_kernel (global cl_mat_data_t *lhs, global cl_mat_data_t *rhs, int options, unsigned int nrows, global unsigned int *rpt, global unsigned int *col, global cl_mat_data_t *val)
{
	unsigned int i = get_global_id(0);
	if (i < nrows) {
		cl_mat_data_t svalue = 0.0;
		for(unsigned int j=rpt[i]; j<rpt[i+1]; ++j){
			svalue += val[j] * rhs[col[j]];
		}
		lhs[i] += svalue;
	}
}

error: pathspec 'libspmvm/plugins/src/crs_clkernel.cl' did not match any file(s) known to git


This file had the wrong name and so deleted.  Use LIF_update_state_localWmaxVth.cl instead.

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@3536 7c0444ca-5550-0410-9008-faecdbe78eb5

#include "LIF_params.h"
#include "cl_random.hcl"
#include "../utils/pv_random.h"

#ifndef PV_USE_OPENCL
#  include <math.h>
#  define EXP expf
#  define CL_KERNEL
#  define CL_MEM_GLOBAL
#  define CL_MEM_LOCAL
#else  /* compiling with OpenCL */
#  define EXP exp
#  define CL_KERNEL       __kernel
#  define CL_MEM_GLOBAL   __global
#  define CL_MEM_LOCAL    __local
#  include "conversions.hcl"
#endif

//
// update the state of a retinal layer (spiking)
//
//    assume called with 1D kernel
//
CL_KERNEL
void LIF_update_state_localWmaxVth(
    const float time,
    const float dt,

    const int nx,
    const int ny,
    const int nf,
    const int nb,

    const float tauWmax,
    const float tauVthRest,
    const float alphaVthRest,
    const float alphaW,
    const float averageR,

    CL_MEM_GLOBAL LIF_params * params,
    CL_MEM_GLOBAL uint4 * rnd,
    CL_MEM_GLOBAL float * V,
    CL_MEM_GLOBAL float * Vth,
    CL_MEM_GLOBAL float * G_E,
    CL_MEM_GLOBAL float * G_I,
    CL_MEM_GLOBAL float * G_IB,
    CL_MEM_GLOBAL float * phiExc,
    CL_MEM_GLOBAL float * phiInh,
    CL_MEM_GLOBAL float * phiInhB,
    CL_MEM_GLOBAL float * R,
    CL_MEM_GLOBAL float * Wmax,
    CL_MEM_GLOBAL float * VthRest,
    CL_MEM_GLOBAL float * activity)
{
   int k;

   const float exp_tauE    = EXP(-dt/params->tauE);
   const float exp_tauI    = EXP(-dt/params->tauI);
   const float exp_tauIB   = EXP(-dt/params->tauIB);
   const float exp_tauVth  = EXP(-dt/params->tauVth);

   const float dt_sec = .001 * dt;   // convert to seconds
   const float tauRate = params->tauRate;
   const float exp_tauRate = EXP(-dt/tauRate);
   const float exp_tauWmax = EXP(-dt/tauWmax);
   const float exp_tauVthRest = EXP(-dt/tauVthRest);

#ifndef PV_USE_OPENCL

for (k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
#endif

   int kex = kIndexExtended(k, nx, ny, nf, nb);

   //
   // kernel (nonheader part) begins here
   //

   // local param variables
   float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth;

   const float GMAX = 10.0;

   // local variables
   float l_activ;

   uint4 l_rnd = rnd[k];

   float l_V   = V[k];
   float l_Vth = Vth[k];
   float l_VthRest = VthRest[k];

   float l_G_E  = G_E[k];
   float l_G_I  = G_I[k];
   float l_G_IB = G_IB[k];

   float l_phiExc  = phiExc[k];
   float l_phiInh  = phiInh[k];
   float l_phiInhB = phiInhB[k];

   float l_R = R[k];
   float l_Wmax = Wmax[kex];

   // temporary arrays
   float tauInf, VmemInf;

   //
   // start of LIF2_update_exact_linear
   //

   // define local param variables
   //
   tau   = params->tau;
   Vexc  = params->Vexc;
   Vinh  = params->Vinh;
   VinhB = params->VinhB;
   Vrest = params->Vrest;

   //VthRest  = params->VthRest;
   deltaVth = params->deltaVth;

   // add noise
   //

#undef CLRANDOM

#ifdef CLRANDOM
   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqE) {
      l_rnd = cl_random_get(l_rnd);
      l_phiExc = l_phiExc + params->noiseAmpE*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqI) {
      l_rnd = cl_random_get(l_rnd);
      l_phiInh = l_phiInh + params->noiseAmpI*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqIB) {
      l_rnd = cl_random_get(l_rnd);
      l_phiInhB = l_phiInhB + params->noiseAmpIB*cl_random_prob(l_rnd);
   }
#else
   if (pv_random_prob() < dt_sec*params->noiseFreqE) {
      l_phiExc = l_phiExc + params->noiseAmpE*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqI) {
      l_phiInh = l_phiInh + params->noiseAmpI*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqIB) {
      l_phiInhB = l_phiInhB + params->noiseAmpIB*pv_random_prob();
   }
#endif
   // l_phi channels must be divided by tau_E, ... in each channel expressed in ms?!
   l_G_E  = l_phiExc  + l_G_E *exp_tauE;
   l_G_I  = l_phiInh  + l_G_I *exp_tauI;
   l_G_IB = l_phiInhB + l_G_IB*exp_tauIB;

   l_G_E  = (l_G_E  > GMAX) ? GMAX : l_G_E;
   l_G_I  = (l_G_I  > GMAX) ? GMAX : l_G_I;
   l_G_IB = (l_G_IB > GMAX) ? GMAX : l_G_IB;

   tauInf  = (dt/tau) * (1.0 + l_G_E + l_G_I + l_G_IB);
   VmemInf = (Vrest + l_G_E*Vexc + l_G_I*Vinh + l_G_IB*VinhB)
           / (1.0 + l_G_E + l_G_I + l_G_IB);

   l_V = VmemInf + (l_V - VmemInf)*EXP(-tauInf);;

   //
   // start of LIF2_update_finish
   //
   // update average rate
   l_R = (l_activ / tauRate) + l_R*exp_tauRate;
   // multiply by 1000.0 to get the firing rate per second, which is how averageR is estimated
   l_Wmax = - alphaW * (1000.0*l_R - averageR) + (l_Wmax + alphaW * (1000.0*l_R - averageR)) * exp_tauWmax;
   l_VthRest = - alphaVthRest * (1000.0*l_R - averageR) + (l_VthRest + alphaVthRest * (1000.0*l_R - averageR)) * exp_tauVthRest;
   l_Vth = l_VthRest + (l_Vth - l_VthRest)*exp_tauVth;

   //
   // start of update_f
   //

//   l_G_E  = (l_G_E  > GMAX) ? GMAX : l_G_E;
//   l_G_I  = (l_G_I  > GMAX) ? GMAX : l_G_I;
//   l_G_IB = (l_G_IB > GMAX) ? GMAX : l_G_IB;

   bool fired_flag = (l_V > l_Vth);

   l_activ = fired_flag ? 1.0f             : 0.0f;
   l_V     = fired_flag ? Vrest            : l_V;
   l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
   l_G_IB  = fired_flag ? l_G_IB + 1.0f    : l_G_IB;

   //
   // These actions must be done outside of kernel
   //    1. set activity to 0 in boundary (if needed)
   //    2. update active indices
   //

   // store local variables back to global memory
   //
   rnd[k] = l_rnd;

   activity[kex] = l_activ;

   R[k] = l_R;
   Wmax[kex] = l_Wmax;
   VthRest[k] = l_VthRest;

   V[k]   = l_V;
   Vth[k] = l_Vth;

   G_E[k]  = l_G_E;
   G_I[k]  = l_G_I;
   G_IB[k] = l_G_IB;

   phiExc[k]  = 0.0f;
   phiInh[k]  = 0.0f;
   phiInhB[k] = 0.0f;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}


Sorter is Completed

Sorter is Completed


Ajout du système expert (expert-system.cl)

;;; IA01 - TP03
;;; Erwan Normand

;;; Rgles
(defparameter R1 '(((survie satisfaite)) ((faim 6 >=) (soif 6 >=) (sante 6 >=) (danger 0 =)) "Survie satisfaite"))
(defparameter R2 '(((survie moyen)) ((faim 4 >=) (soif 4 >=) (sante 4 >=) (danger 0 =)) "Survie moyen"))

(defparameter R3 '(((faim 3 +)) ((bananes beaucoup)) "Mangez les bananes avec la peau pour ne pas gacher de vitamines !"))
(defparameter R4 '(((faim 2 +)) ((bananes moyen)) "Mangez les bananes avec la peau pour ne pas gacher de vitamines !"))
(defparameter R5 '(((faim 1 +)) ((bananes rare)) "Mangez les bananes avec la peau pour ne pas gacher de vitamines !"))
(defparameter R9 '(((faim 3 +) (recipient moyen)) ((noix_de_coco marron)) "Ouvrez la noix de coco comme vous le pouvez pour manger la pulpe. Gardez la carapace comme rcipient."))
(defparameter R10 '(((faim 2 +) (recipient moyen)) ((noix_de_coco orange)) "Ouvrez la noix de coco comme vous le pouvez pour manger la pulpe. Gardez la carapace comme rcipient."))
(defparameter R11 '(((faim 1 +) (recipient moyen)) ((noix_de_coco verte)) "Ouvrez la noix de coco comme vous le pouvez pour manger la pulpe. Gardez la carapace comme rcipient."))

(defparameter R6 '(((soif 3 +)) ((noix_de_coco marron) (couteau oui)) "Percez avec le couteau les yeux de la noix pour boire leau  l'intrieur."))
(defparameter R7 '(((soif 2 +)) ((noix_de_coco orange) (couteau oui)) "Percez avec le couteau les yeux de la noix pour boire leau  l'intrieur."))
(defparameter R8 '(((soif 1 +)) ((noix_de_coco verte) (couteau oui)) "Percez avec le couteau les yeux de la noix pour boire leau  l'intrieur, puis vous pouvez manger la pulpe."))
(defparameter R12 '(((soif 2 +)) ((recipient beaucoup) (temps pluie)) "Rcuprez leau de la pluie  laide des rcipients"))
(defparameter R13 '(((soif 1 +)) ((recipient moyen) (temps pluie)) "Rcuperez leau de la pluie  laide des rcipients"))
(defparameter R42 '(((soif 1 +)) ((grande_feuille oui) (temps pluie)) "Utilisez les plus grandes feuilles que vous voyez et placez les dans un trou pour recolter l'eau de la pluie"))
(defparameter R40 '(((eau non-potable)) ((riviere sauvage)) "Mefiez vous de l'eau de la riviere, rien ne dit qu'elle est potable.."))
(defparameter R26 '(((soif 4 +)) ((feu oui) (recipient rare) (eau non-potable)) "Faites bouillir leau pour la rendre potable"))
(defparameter R27 '(((soif 2 +) (sante 3 -)) ((eau non-potable) (soif 4 <) (sante 5 >)) "Cest mauvais de boire de leau sans avoir la certitude quelle est potable, mais si vous navez pas le choix."))
(defparameter R44 '(((soif 3 +) (emeche oui)) ((cachette rhum)) "Yo Ho !"))

(defparameter R14 '(((oriente oui)) ((ile grande)) "Reprez les lieux en marchant dans une mme direction assez longtemps. Attention, ne vous fiez pas trop  ltoile polaire si vous ntes pas sr dtre dans lhmisphre nord"))
(defparameter R18 '(((arme bonne)) ((couteau oui))))
(defparameter R19 '(((corde oui)) ((liane oui)) "Utilisez les lianes comme corde"))
(defparameter R20 '(((grande_feuille oui) (bois oui)) ((palmier present))))
(defparameter R21 '(((grande_feuille oui) (bois illimite) (liane oui)) ((vegetation abondante)) "Allez chercher des lianes et les plus grandes feuilles que vous trouvez a pourra servir"))
(defparameter R41 '(((bois oui)) ((bois illimite))))
(defparameter R22 '(((hamac confortable)) ((grande_feuille oui) (corde oui)) "Construisez un hamac avec des feuilles et des cordes"))
(defparameter R31 '(((feu oui)) ((bois oui) (couteau oui) (corde oui)) "Dcoupez une encoche dans une buche. Lovez une corde autour dun baton assez solide. Attachez les extrmits de cette corde autour dun autre baton comme si vous fabriquiez un arc. Grace  ce systme faites tourner trs vite le baton dans lencoche cela fabriquera des tincelles."))
(defparameter R32 '(((couteau oui)) ((silex trouve) (corde oui) (bois oui)) "Fabriquez un couteau nolithique  partir dun silex. Formez la lame en entrechoquant le silex et un caillou. Pour le manche il faut un bois dur. Du chne noyer ou merisier serait le mieux. Forez le manche puis attachez les deux parties avec une corde."))
(defparameter R33 '(((silex trouve) (bois oui)) ((ile grande) (oriente oui))))
(defparameter R36 '(((lance grande)) ((bois oui) (couteau oui)) "Construire une lance en taillant votre baton"))

(defparameter R15 '(((crocodile mort) (danger 1 -) (sante 2 -)) ((crocodile oui) (arme bonne) (sante 4 >)) "Ne pas fuir face  un crocodile. Pour rendre lle sre, il faut vous en dbarrasser. Prenez votre courage  deux mains et attaquez le avec votre arme! Si vous tes affam mangez le, mais cest  viter."))
(defparameter R43 '(((viande bout)) ((crocodile mort))))
(defparameter R16 '(((faim 2 +)) ((crocodile mort) (faim 4 <)) "Bon, ce crocodile na vraiment pas lair bon, mais vous tes affam..."))
(defparameter R17 '(((sante 2 +)) ((crocodile mort) (securite 3 <) (couteau oui)) "Vous avez vraiment froid.. Fabriquez vous une couverture comme vous le pouvez avec les reste du lion"))
(defparameter R28 '(((crocodile non) (danger 1 -) (faim 3 -)) ((crocodile oui) (viande bout) (faim 4 >)) "Nourrir le crocodile pour cohabiter."))
(defparameter R23 '(((fourmis_rouge non) (danger 1 -)) ((hamac confortable) (fourmis_rouge oui)) "Grace au hamac les fourmis ne vous atteindront plus!"))
(defparameter R34 '(((fourmis_rouge non)) ((feu oui) (fourmis_rouge oui)) "Le feu fait fuir les fourmis"))
(defparameter R24 '(((sante 2 -)) ((fourmis_rouge oui)) "Les fourmis vous drangent quand vous dormez..."))
(defparameter R25 '(((serpent_dangereux non) (danger 1 -)) ((serpent_dangereux oui) (viande bout) (bois oui)) "Construire des pieges  serpents en mettant un bout de viande dans une cage qui se refermera sur celui-ci."))
(defparameter R29 '(((sante 2 -)) ((feu oui) (moustique beaucoup)) "Attention les moustiques sont attirs par le feu"))
(defparameter R30 '(((sante 1 -)) ((feu oui) (moustique moyen)) "Attention les moustiques sont attirs par le feu"))

(defparameter R35 '(((poisson rare)) ((lance grande) (poisson visible) (sante 3 >)) "Essayez dattraper quelques poissons avec votre lance"))
(defparameter R37 '(((faim 3 +)) ((poisson rare))))
(defparameter R38 '(((viande bout)) ((poisson rare))))
(defparameter R39 '(((sante 1 +)) ((hamac confortable))))

(defparameter *BR* '(R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 R30 R31 R32 R33 R34 R35 R36 R37 R38 R39 R40 R41 R42 R43 R44))
;Pour accder  la i-me rgle : (eval (nth i *BR*))

;;; Jeux d'essais
(defparameter *buts* '((survie satisfaite) (survie moyen) "Survie non satisfaite : vous n'avez vraiment pas de chance, dsol"))

; Vous venez d'arriver, vous avez un peu faim et soif et les fruits sont en abondance.
(defparameter *BF* '((faim 3) (soif 4) (sante 8) (danger 0) (bananes beaucoup) (noix_de_coco verte) (temps pluie) (palmier present) (couteau oui)))
; Vous avez un nouveau compagnon, pas trs clin.
(defparameter *BF* '((faim 3) (soif 4) (sante 8) (danger 1) (bananes beaucoup) (noix_de_coco verte) (temps pluie) (palmier present) (crocodile oui)))
; Malgr votre statut de naufrag, rien de vous empche de vous lancer dans la maroquinerie : aujourd'hui, on va faire des sacs  main en crocodile.
(defparameter *BF* '((faim 3) (soif 4) (sante 8) (danger 1) (bananes beaucoup) (noix_de_coco verte) (temps pluie) (vegetation abondante) (crocodile oui) (ile grande)))

;; Lancement des moteurs, aprs choix du *BF* voulu
(declencher_moteur_avant *BR* *BF* *buts*)
(declencher_moteur_arriere *BR* *BF* *buts*)

;;; Fonctions de services

;; Fonctions des rgles
(defun actions (regle)
  (first regle))

(defun conditions (regle)
  (second regle))

(defun description (regle)
  (third regle))

;; Fonctions des faits, actions, conditions
(defun attribut (tuple) ; fait, action ou condition
  (first tuple))

(defun valeur (tuple) ; fait, action ou condition
  (second tuple))

(defun operateur (triplet) ; action ou condition
  (third triplet))

(defun type_condi (triplet) ;type de la condition : numrique s'il y a un oprateur, sinon fait
  (if (operateur triplet) 'numerique 'fait))

;; Fonctions de gestions des faits de BF
; Utilisation : la fonction ajouter_fait pour ajouter ou modifier des faits (la fonction gre ces deux cas)
(defun ajouter_faits (BF actions); retourne BF avec le nouveau fait
  (cond
   ((null actions) BF)
   ((assoc (attribut (car actions)) BF)
    (setq BF (modifier_fait BF (car actions)))
    (ajouter_faits BF (cdr actions)))
   (t
    (cons (list (attribut (car actions)) (valeur_apres_action BF (car actions)))
          (ajouter_faits BF (cdr actions)))
    )))

(defun modifier_fait (BF action) ; modifie dans BF le fait  la nouvelle valeur
  (let (BF_modifie)
    (dolist (fait BF)
      (push (copy-seq fait) BF_modifie))
    (setf (second (assoc (attribut action) BF_modifie)) (valeur_apres_action BF_modifie action))
    (reverse BF_modifie)))

(defun valeur_apres_action (BF action) ; retourne la valeur du fait aprs excution de l'action
  (if (and (assoc (attribut action) BF) ; si le fait est dj prsent
           (operateur action))          ; et si action contient un oprateur

                 (eval (list (operateur action) (valeur (assoc (attribut action) BF)) (valeur action))) ; ajout au fait de BF la valeur de action

               (valeur action))) ; sinon la valeur de l'action est utilise

(defun limite (max valeur) ; limite aux valeurs numriques possibles
  (if (realp valeur)
      (if (> valeur 0) (if (< valeur max) valeur max) 0)
    valeur))

;;Affichage
; tabulation du texte console en fonction de la profondeur
(defun tabulation (profondeur)
  (format t "~S : " profondeur)
  (dotimes (i profondeur) (princ "  ")))

; affichage des descriptions d'un ensemble de rgle
(defun affichage_description (ensemble profondeur)
  (dolist (regle ensemble)
    (when (description (eval regle))
      (tabulation profondeur)
      (format t "~S ~&" (description (eval regle))))))

;;; Fin fonctions de services

;;; Moteur en chainage avant en profondeur d'abord

; teste les buts dans l'ordre avec le moteur_avant
(defun declencher_moteur_avant (BR BF buts &optional (max 10))
  (cond
   ((stringp (car buts)) (print (car buts)))
   (T
    (let ((enregistrement_but (copy-seq (car buts))))
      (moteur_avant BR BF (car buts) max nil)
      (if (null (attribut (car buts)))
          (setf (car buts) enregistrement_but)
        (declencher_moteur_avant BR BF (cdr buts) max))))))

; vrifie si une condition numrique est vrifie par la base de fait (ex: (faim 6 >=)...)
(defun respect_regle_numerique? (condi BF)
                (if (assoc (attribut condi) BF)
                 (eval (list (operateur condi) (valeur (assoc (attribut condi) BF)) (valeur condi)))
                  ))

; vrifie si un fait est prsent dans la base de fait
(defun respect_regle_fait? (condi BF)
  (eq (valeur condi) (valeur (assoc (attribut condi) BF))))

(defun vu_ou_pas?? (regle experience)
  (if (member regle experience) NIL T))

; algorithme rcursif, si toutes les conditions de la rgle sont respectes
(defun test_conditions (condis BF)
               (cond
               ((eq (car condis) NIL) T)
               ((eq (type_condi (car condis)) 'fait)
                (if (respect_regle_fait? (car condis) BF) (test_conditions (cdr condis) BF) NIL))
               ((eq (type_condi (car condis)) 'numerique)
                (if (respect_regle_numerique? (car condis) BF) (test_conditions (cdr condis) BF) NIL))
               )
  )

; vrifie si une rgle est possible: si elle n'est pas deja faite et si les conditions sont respectes
(defun possible? (regle deja_vu max BF)
               (if (vu_ou_pas?? regle deja_vu)
                 (test_conditions (conditions (eval regle)) BF)

                  )
  )

; retourne la liste des rgles possibles
(defun regle_possible? (BR deja_vu max BF)
               (let ((liste NIL))
                 (dolist (i BR)
                   (if (possible? i deja_vu max BF)
                       (push i liste)
                     )
                   )
                 liste))

(defun moteur_avant (BR BF but &optional (max 10) (deja_fait nil))
               (cond
                ((null (car but)) NIL)		;Si le but a dj t atteint on arrte la rcursivit.
                ((assoc (attribut but) BF)    ; attribut de but dans BF et
                     (if (eq (valeur but) (valeur (assoc (attribut but) BF)))   ; valeur du but atteinte
                         (progn
                           (print 'reponse)
                           (setf (car but) NIL)	; Modifier une valeur du but change dfinitivement celui-ci
                           (dolist (i deja_fait)
                             (if (description (eval i))
                                 (print (description (eval i)))))
                           (print '____________))))
                ((null (regle_possible? BR deja_fait max BF)) NIL)
                (T (dolist (i (regle_possible? BR deja_fait max BF))
                     (moteur_avant BR (ajouter_faits BF (actions (eval i))) but max (cons i deja_fait))
                     )
                   )
                )
  )

;;; Fin moteur avant

;;; Moteur en chainage arrire en profondeur d'abord

(defun declencher_moteur_arriere (BR BF buts)
  (cond
   ((stringp (car buts)) (print (car buts)))
   (t
    (unless (moteur_arriere (car buts) BF BR 0)
      (declencher_moteur_arriere BR BF (cdr buts))))))

(defun moteur_arriere (but BF BR &optional (profondeur 0))
  (cond
   ((verifie_but? BF but BF) ; si les faits de BF vrifient le But
    (tabulation profondeur)
    (format t "But vrifi: ~S (Fait : ~S) ~&" But (assoc (attribut But) BF))
    t)

   (t
    (if (dolist (ensemble_candidat (ensemble_conflits but BF BR)) ; pour chacun des ensembles de rgles candidates

          (tabulation profondeur)
          (format t "But: ~S - Regles cherches : ~S ~&" But ensemble_candidat)

          (let ((ensemble_candidat_verifie (ensemble_verifie? ensemble_candidat But BF BR profondeur)))
            (when ensemble_candidat_verifie ; ds qu'un ensemble est vrifi, le but est vrifi
              (affichage_description ensemble_candidat_verifie profondeur)
              (tabulation profondeur)
              (format t "But vrifi: ~S (Regles : ~S) ~&" But ensemble_candidat_verifie)
              (return t)))
          )
        t ; si le but est atteint
        (let () ; si non
          (tabulation profondeur)
          (format t "But non vrifi: ~S ~&" But)))) ; sinon, s'il ny a aucun ensemble candidat ou aucun vrifi
   ))

; retourne les ensembles de rgles pouvant vrifier le but, ils ont candidats
(defun ensemble_conflits (but BF BR)
  (let ((regles_candidates)
        (ensemble_candidat))
    (dolist (regle_candidate BR  regles_candidates ensemble_candidat)
      (cond

       ; si les actions de la rgle vrifient le but: elle est candidate
       ((verifie_but? (actions (eval regle_candidate)) but BF)
        (push (list regle_candidate) regles_candidates))

       ; les rgles dont les actions peuvent seulement atteindre le but ensemble
       ((and (operateur but)
             (assoc (attribut but) (actions (eval regle_candidate))))
        (push regle_candidate ensemble_candidat)
       )
    ))

    ; retourne les ensembles de rgles candidates
    (when (not (null ensemble_candidat))
      (push (reverse ensemble_candidat) regles_candidates))
    (reverse regles_candidates)))

; prdicat : si les tuples (BF ou actions dune rgle) vrifient le but
(defun verifie_but? (tuples but BF)
  (let ((tuple (assoc (attribut but) tuples)))
    (when tuple ; si le but fait partis de la liste des tuples
      (if (operateur but)

          ; si le but comporte un oprateur, il sera utilis
          (eval (list (operateur But) (valeur_apres_action BF tuple) (valeur but)))

        ; sinon on utilise l'galit comme valeur de test
        (equal (valeur_apres_action BF tuple) (valeur But)) ))
    ))

; prdicat : si l'ensemble des rgles vrifient le but
(defun ensemble_candidat? (ensemble but BF)
  (let ((action_ensemble (list (attribut But) 0 '+)))
    (dolist (regle ensemble action_ensemble) ; la valeur obtenue par la combinaison de rgles
      (let ((action (assoc (attribut but) (actions (eval regle)))))

        (setf (second action_ensemble) (valeur_apres_action (list action_ensemble) action))
    ))
    (verifie_but? (list action_ensemble) but BF)))

; prdicat : la rgle est vrifie (c'est--dire son but vrifi) si ses conditions sont des buts vrifis
(defun regle_verifiee? (regle BF BR &optional (profondeur 0))
  (dolist (condition (conditions (eval regle)) t)
    (unless (moteur_arriere condition BF BR (+ 1 profondeur)) ; chacune des conditions de la rgles alors sont des sous-buts  tablir
        (return nil))))

; prdicat : l'ensemble est vrifi si parmis ses rgles vrifies, leurs actions atteignent le but
(defun ensemble_verifie? (ensemble but BF BR &optional (profondeur 0))
  (let (regles_verifiees)
    (when (if (= (length ensemble) 1)

              ; si l'ensemble ne contient qu'une rgle, candidate seule
              (when (regle_verifiee? (first ensemble) BF BR profondeur)
                (push (first ensemble) regles_verifiees) t)

            ; si l'ensemble contient plusieurs rgles
            (dolist (regle ensemble nil regles_verifiees)
              (when (regle_verifiee? regle BF BR (+ 1 profondeur))

                (tabulation (+ 1 profondeur))
                (format t "Buts vrifis: ~S (Regle : ~S) ~&" (actions (eval regle)) regle)

                (push regle regles_verifiees)
                (when (ensemble_candidat? regles_verifiees but BF)
                  (return t)))))

      ; s'il y a un ensemble de rgles vrifies et candidates
      (reverse regles_verifiees))))

;;; Fin moteur arrire

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


Sort with bugs

Sort with bugs

Partition fails...


Added #define assert(arg) and uncommented all assertions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/HongjianLi/idock.git/'


Initial test clisp script

Initial test clisp script

(defpackage :com.orbbec.sdk
  (:use :common-lisp))

(defstruct code funcname params returntype)

(defun partial (func &rest args1)
   (lambda (&rest args2) (apply func (append args1 args2)))
)

(defun newline ()
	(write-string (format nil "~%"))
)

(defun replace-all (string part replacement &key (test #'char=))
"Returns a new string in which all the occurences of the part
is replaced with replacement."
    (with-output-to-string (out)
      (loop with part-length = (length part)
            for old-pos = 0 then (+ pos part-length)
            for pos = (search part string
                              :start2 old-pos
                              :test test)
            do (write-string string out
                             :start old-pos
                             :end (or pos (length string)))
            when pos do (write-string replacement out)
            while pos)))

(defun formatmethod2 (lineformat funcdata)
	(format nil lineformat
		(code-returntype funcdata)
		(code-funcname funcdata)
		(code-params funcdata)
	)
)

(defun formatmethod (lineformat funcdata)
	(replace-all
		(replace-all
			(replace-all lineformat
				"^RETURN^" (code-returntype funcdata)
			)
			"^FUNC^" (code-funcname funcdata)
		)
		"^PARAMS^" (code-params funcdata)
	)
)

(defun formatmethods (lineformat funclist)
	(map 'list
		(partial #'formatmethod lineformat) funclist
	)
)

(setq c1 (make-code :returntype "sk_status"
					:funcname "open_frame"
					:params "sk_stream* stream, sk_frame** frame"
		)
)

(setq c2 (make-code :returntype "sk_status"
					:funcname "close_frame"
					:params "sk_frame** frame"
		)
)

(setq f1 "^RETURN^ ^FUNC^(^PARAMS^);
")
(setq f2 "^RETURN^ sensekit_^FUNC^(^PARAMS^) {
	return g_Context->^FUNC^(^PARAMS^);
}
")
(setq f3 "^RETURN^ (*^FUNC^)(void*, ^PARAMS^);
")

(setq funcs (list c1 c2))

(defun outputfuncs (f)
	(map nil #'write-string f)
)

(defun _ () (load "lpp.cl" :verbose nil))

(defun t ()
	;(write-string (formatmethod f1 c1))
	;(write-string (formatmethod f2 c1))
	(outputfuncs (formatmethods f1 funcs))
	(newline)
	(outputfuncs (formatmethods f2 funcs))
	(newline)
	(outputfuncs (formatmethods f3 funcs))
	(newline)
	nil
)

(t)

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


Add barebones tracer kernel

Add barebones tracer kernel

The kernel doesnt't do anything interesting at the moment but it will
help testing that the tracer can properly call the kernel.

// Global parameters that will be set via a template during compilation time.
__constant unsigned int frameW = 512;
__constant unsigned int frameH = 512;
__constant float texelStepX = 1.0 / 512.0;
__constant float texelStepY = 1.0 / 512.0;

// Emit the color of a pixel by tracing a ray through the scene.
__kernel void tracePixel(
		__global float4 *frameBuffer,
		__global float4 *frustrumCorners,
		const unsigned int blockY,
		const unsigned int samplesPerPixel,
		const float exposure
){
	// Get pixel coordinates
	unsigned int x = get_global_id(0);
	unsigned int y = blockY + get_global_id(1);
	if ( x > frameW || y > frameH ) {
		return;
	}

	// Just set target to white
	frameBuffer[y * frameW + x] = 1.0;
}

error: pathspec 'tracer/opencl/cl_tracer.cl' did not match any file(s) known to git


Create collatzGlide.cl

Create collatzGlide.cl

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/SosirisTseng/collatz-opencl.git/'


OpenCL implementation of MRG32k3a PRNG

OpenCL implementation of MRG32k3a PRNG

/******************************************************************************
 * @file     prngcl_mrg32k3a.cl
 * @author   Vadim Demchik <vadimdi@yahoo.com>
 * @version  1.1
 *
 * @brief    [PRNGCL library]
 *           contains OpenCL implementation of MRG32k3a pseudo-random number generator
 *
 *
 * @section  CREDITS
 *
 *   Pierre L'Ecuyer,
 *   "Good Parameter Sets for Combined Multiple Recursive Random Number Generators",
 *   Operations Research, 47, 1 (1999), 159--164.
 *
 *
 * @section  LICENSE
 *
 * Copyright (c) 2013, Vadim Demchik
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *    Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#ifndef PRNGCL_MRG32K3A_CL
#define PRNGCL_MRG32K3A_CL

#include "prngcl_common.cl"

#define MRG32k3a_min    (1.0/4294967088.0)
#define MRG32k3a_max    (4294967087.0/4294967088.0)
#define MRG32k3a_k      (2.3283065492957279e-010) // 1/(2^32-208)
#define MRG32k3a_left   (MRG32k3a_min+MRG32k3a_k*MRG32k3a_max)
#define MRG32k3a_right  (MRG32k3a_max+MRG32k3a_k*MRG32k3a_min)

#define MRG32k3a_m     (2.3283065492957276882397381481401e-10) // 1/(2^32-208) for MRG32k3a generator
#define MRG32k3a_m1    4294967087
#define MRG32k3a_m2    4294944443
#define MRG32k3a_a11   1403580L
#define MRG32k3a_a12   810728L
#define MRG32k3a_a21   527612L
#define MRG32k3a_a22   1370589L

//________________________________________________________________________________________________________ MRG32k3a PRNG
__attribute__((always_inline)) void
mrg32k3a_step(uint4* seed1,uint4* seed2,float* rnd)
{
    long x1n, x2n;
    long k;

    x1n = MRG32k3a_a11 * (*seed1).y - MRG32k3a_a12 * (*seed1).x;
    k = x1n / MRG32k3a_m1;
    x1n -= k * MRG32k3a_m1;
    if (x1n < 0) x1n += MRG32k3a_m1;
    (*seed1).x = (*seed1).y;
    (*seed1).y = (*seed1).z;
    (*seed1).z = x1n;

    x2n = MRG32k3a_a21 * (*seed2).z - MRG32k3a_a22 * (*seed2).x;
    k = x2n / MRG32k3a_m2;
    x2n -= k * MRG32k3a_m2;
    if (x2n < 0) x2n += MRG32k3a_m2;
    (*seed2).x = (*seed2).y;
    (*seed2).y = (*seed2).z;
    (*seed2).z = x2n;

    if (x1n>x2n) (*rnd) = (float) ((x1n - x2n) * MRG32k3a_m);
    else         (*rnd) = (float) ((x1n - x2n + MRG32k3a_m1) * MRG32k3a_m);
}

#ifdef PRECISION_DOUBLE  // if double precision is defined
__attribute__((always_inline)) hgpu_double
mrg32k3a_step_double(uint4* seed1,uint4* seed2)
{
    hgpu_double rnd_double;
    float rnd1, rnd2;
    bool flag = true;
    mrg32k3a_step(seed1,seed2,&rnd1);
    while (flag) {
        mrg32k3a_step(seed1,seed2,&rnd2);
        rnd_double = hgpu_float_to_double(rnd1,rnd2,MRG32k3a_min,MRG32k3a_max,MRG32k3a_k);
        if ((rnd_double>=MRG32k3a_left) && (rnd_double<MRG32k3a_right))
            flag = false;
        else
            rnd1 = rnd2;
    }
    return rnd_double;
}
#endif

__kernel void
mrg32k3a(__global uint4* seed_table,
         __global hgpu_float4* randoms,
            const uint N)
{
    uint giddst = GID;
#ifdef PRECISION_DOUBLE  // if double precision is defined
    float rnd;
    hgpu_double4 result;
#else
    float rnd;
    float4 result;
#endif

    uint4 seed1 = seed_table[GID];
    uint4 seed2 = seed_table[GID + GID_SIZE];

    for (uint i = 0; i < N; i++) {
#ifdef PRECISION_DOUBLE // if double precision is defined
        // MRG32k3a PRNG returns values [1;4294967087]/4294967088, or (0.0;1.0)
        result.x = mrg32k3a_step_double(&seed1,&seed2);
        result.y = mrg32k3a_step_double(&seed1,&seed2);
        result.z = mrg32k3a_step_double(&seed1,&seed2);
        result.w = mrg32k3a_step_double(&seed1,&seed2);
        randoms[giddst] = result;
#else
        mrg32k3a_step(&seed1,&seed2,&rnd);
            result.x = rnd;
        mrg32k3a_step(&seed1,&seed2,&rnd);
            result.y = rnd;
        mrg32k3a_step(&seed1,&seed2,&rnd);
            result.z = rnd;
        mrg32k3a_step(&seed1,&seed2,&rnd);
            result.w = rnd;
        randoms[giddst] = result;
#endif
        giddst += GID_SIZE;
    }
    seed_table[GID] = seed1;
    seed_table[GID + GID_SIZE] = seed2;
}

#endif

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


Implement sqrt() for half

Implement sqrt() for half

/* OpenCL built-in library: sqrt()

   Copyright (c) 2011 Erik Schnetter <eschnetter@perimeterinstitute.ca>
                      Perimeter Institute for Theoretical Physics

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "templates.h"

/* TODO:

   Clang does not recognize __builtin_sqrt* in CGBuiltin.cpp (around line 1285)
   to be a call to sqrt and cannot selectively convert it to the llvm.sqrt.*
   intrinsics with looser math flags. Therefore we have to call it as a libcall
   so it regonized it. For the double we still call the __builtin_sqrt() to
   disambiguate from the sqrt() to avoid infinite recursion. Probably the
   correct fix is to patch CGBuiltin.cpp to recognize also the call via
   __builtin_sqrt*. */

float sqrtf(float);

#ifdef cl_khr_fp16
half _CL_OVERLOADABLE sqrt(half a)
{
  return sqrtf(a);
}

half2 _CL_OVERLOADABLE sqrt(half2 a)
{
  return (half2)(sqrt(a.x), sqrt(a.y));
}

half3 _CL_OVERLOADABLE sqrt(half3 a)
{
  return (half3)(sqrt(a.x), sqrt(a.y), sqrt(a.z));
}

half4 _CL_OVERLOADABLE sqrt(half4 a)
{
  return (half4)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w));
}

half8 _CL_OVERLOADABLE sqrt(half8 a)
{
  return (half8)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w),
                 sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7));
}

half16 _CL_OVERLOADABLE sqrt(half16 a)
{
  return (half16)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w),
                  sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7),
                  sqrt(a.s8), sqrt(a.s9), sqrt(a.sa), sqrt(a.sb),
                  sqrt(a.sc), sqrt(a.sd), sqrt(a.se), sqrt(a.sf));
}
#endif

float _CL_OVERLOADABLE sqrt(float a)
{
  return sqrtf(a);
}

float2 _CL_OVERLOADABLE sqrt(float2 a)
{
  return (float2)(sqrtf(a.x), sqrtf(a.y));
}

float3 _CL_OVERLOADABLE sqrt(float3 a)
{
  return (float3)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
}

float4 _CL_OVERLOADABLE sqrt(float4 a)
{
  return (float4)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
}

float8 _CL_OVERLOADABLE sqrt(float8 a)
{
  return (float8)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w),
		  sqrtf(a.s4), sqrtf(a.s5), sqrtf(a.s6), sqrtf(a.s7));
}

float16 _CL_OVERLOADABLE sqrt(float16 a)
{
  return (float16)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w),
		   sqrtf(a.s4), sqrtf(a.s5), sqrtf(a.s6), sqrtf(a.s7),
		   sqrtf(a.s8), sqrtf(a.s9), sqrtf(a.sa), sqrtf(a.sb),
		   sqrtf(a.sc), sqrtf(a.sd), sqrtf(a.se), sqrtf(a.sf));

}

#ifdef cl_khr_fp64
double _CL_OVERLOADABLE sqrt(double a)
{
  return __builtin_sqrt(a);
}

double2 _CL_OVERLOADABLE sqrt(double2 a)
{
  return (double2)(sqrt(a.x), sqrt(a.y));
}

double3 _CL_OVERLOADABLE sqrt(double3 a)
{
  return (double3)(sqrt(a.x), sqrt(a.y), sqrt(a.z));
}

double4 _CL_OVERLOADABLE sqrt(double4 a)
{
  return (double4)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w));
}

double8 _CL_OVERLOADABLE sqrt(double8 a)
{
  return (double8)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w),
                   sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7));
}

double16 _CL_OVERLOADABLE sqrt(double16 a)
{
  return (double16)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w),
                    sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7),
                    sqrt(a.s8), sqrt(a.s9), sqrt(a.sa), sqrt(a.sb),
                    sqrt(a.sc), sqrt(a.sd), sqrt(a.se), sqrt(a.sf));
}
#endif

DEFINE_EXPR_F_F(half_sqrt, sqrt(a))
DEFINE_EXPR_F_F(native_sqrt, sqrt(a))

/* OpenCL built-in library: sqrt()

   Copyright (c) 2011 Erik Schnetter <eschnetter@perimeterinstitute.ca>
                      Perimeter Institute for Theoretical Physics

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "templates.h"

/* TODO:

   Clang does not recognize __builtin_sqrt* in CGBuiltin.cpp (around line 1285)
   to be a call to sqrt and cannot selectively convert it to the llvm.sqrt.*
   intrinsics with looser math flags. Therefore we have to call it as a libcall
   so it regonized it. For the double we still call the __builtin_sqrt() to
   disambiguate from the sqrt() to avoid infinite recursion. Probably the
   correct fix is to patch CGBuiltin.cpp to recognize also the call via
   __builtin_sqrt*. */

float sqrtf(float);

float _CL_OVERLOADABLE sqrt(float a)
{
  return sqrtf(a);
}

float2 _CL_OVERLOADABLE sqrt(float2 a)
{
  return (float2)(sqrtf(a.x), sqrtf(a.y));
}

float3 _CL_OVERLOADABLE sqrt(float3 a)
{
  return (float3)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
}

float4 _CL_OVERLOADABLE sqrt(float4 a)
{
  return (float4)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
}

float8 _CL_OVERLOADABLE sqrt(float8 a)
{
  return (float8)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w),
		  sqrtf(a.s4), sqrtf(a.s5), sqrtf(a.s6), sqrtf(a.s7));
}

float16 _CL_OVERLOADABLE sqrt(float16 a)
{
  return (float16)(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w),
		   sqrtf(a.s4), sqrtf(a.s5), sqrtf(a.s6), sqrtf(a.s7),
		   sqrtf(a.s8), sqrtf(a.s9), sqrtf(a.sa), sqrtf(a.sb),
		   sqrtf(a.sc), sqrtf(a.sd), sqrtf(a.se), sqrtf(a.sf));

}

__IF_FP64(\
    double _CL_OVERLOADABLE sqrt(double a)      \
    {                                           \
        return __builtin_sqrt(a);               \
    }                                           \
                                                \
    double2 _CL_OVERLOADABLE sqrt(double2 a)    \
    {                                           \
        return (double2)(sqrt(a.x), sqrt(a.y)); \
    }                                           \
                                                \
    double3 _CL_OVERLOADABLE sqrt(double3 a)    \
    {                                                       \
        return (double3)(sqrt(a.x), sqrt(a.y), sqrt(a.z));  \
    }                                                       \
                                                            \
    double4 _CL_OVERLOADABLE sqrt(double4 a)                \
    {                                                                   \
        return (double4)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w));   \
    }                                                                   \
                                                                        \
    double8 _CL_OVERLOADABLE sqrt(double8 a)                            \
    {                                                                   \
        return (double8)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w),    \
                         sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7)); \
    }                                                                   \
                                                                        \
    double16 _CL_OVERLOADABLE sqrt(double16 a)                          \
    {                                                                   \
        return (double16)(sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w), \
                          sqrt(a.s4), sqrt(a.s5), sqrt(a.s6), sqrt(a.s7), \
                          sqrt(a.s8), sqrt(a.s9), sqrt(a.sa), sqrt(a.sb), \
                          sqrt(a.sc), sqrt(a.sd), sqrt(a.se), sqrt(a.sf)); \
    }                                                                   \
    )

DEFINE_EXPR_F_F(half_sqrt, sqrt(a))
DEFINE_EXPR_F_F(native_sqrt, sqrt(a))


Add test case

Add test case

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


Factorial in Common Lisp

Factorial in Common Lisp

Added an implementation of factorial in Common Lisp

(defun factorial(n)
    "Returns n!"
    (if (equal n 0)
        1
        (* n (factorial (- n 1)))))

(format t "5! = ~d~&" (factorial 5))
(format t "10! = ~d~&" (factorial 10))
(format t "50! = ~d~&" (factorial 50))

error: pathspec 'math/factorial/common_lisp/factorial.cl' did not match any file(s) known to git


Change time of LCALIFLayer kernel from float to double

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@6358 7c0444ca-5550-0410-9008-faecdbe78eb5

#include "LIF_params.h"
#include "cl_random.hcl"

#ifndef PV_USE_OPENCL
#  include <math.h>
#  define EXP expf
#  define CL_KERNEL
#  define CL_MEM_GLOBAL
#  define CL_MEM_CONST
#  define CL_MEM_LOCAL
#else  /* compiling with OpenCL */
#  define EXP exp
#  define CL_KERNEL       __kernel
#  define CL_MEM_GLOBAL   __global
#  define CL_MEM_CONST    __constant
#  define CL_MEM_LOCAL    __local
#  include "conversions.hcl"
#  define CHANNEL_EXC   0
#  define CHANNEL_INH   1
#  define CHANNEL_INHB  2
#  define CHANNEL_GAP   3
#endif

//#undef USE_CLRANDOM
#ifndef USE_CLRANDOM
#  include "../utils/pv_random.h"
#endif

inline
float LCALIF_tauInf(const float tau, const float G_E, const float G_I, const float G_IB, const float sum_gap) {
   return tau/(1+G_E+G_I+G_IB+sum_gap);
}

inline
float LCALIF_VmemInf(const float Vrest, const float V_E, const float V_I, const float V_B, const float G_E, const float G_I, const float G_B, const float G_gap, const float sumgap) {
   return (Vrest + V_E*G_E + V_I*G_I + V_B*G_B + G_gap)/(1+G_E+G_I+G_B+sumgap);
}

// The commented-out code below is only used for the Heun's method integration, which works very poorly when the equation is stiff.
/*
inline
float LIFGap_Vmem_derivative(
      const float Vmem,
      const float G_E,
      const float G_I,
      const float G_IB,
      const float G_Gap,
      const float V_E,
      const float V_I,
      const float V_IB,
      const float sum_gap,
      const float Vrest,
      const float tau) {
   float totalconductance = 1.0 + G_E + G_I + G_IB + sum_gap;
   float Vmeminf = (Vrest + V_E*G_E + V_I*G_I + V_IB*G_IB + G_Gap)/totalconductance;
   return totalconductance*(Vmeminf-Vmem)/tau;
}
 */

//
// update the state of a LCALIF layer (spiking)
//
//    assume called with 1D kernel
//
// LCALIF_update_state_beginning uses a Heun scheme for V, using values of the conductances at both the beginning and end of the timestep.  Spikes in the input are applied at the beginning of the timestep.
//
CL_KERNEL
void LCALIF_update_state(
    const int numNeurons,
    const double timed,
    const double dt,

    const int nx,
    const int ny,
    const int nf,
    const int nb,

    float Vscale,
    float * Vadpt,
    float tauTHR,
    const float targetRateHz,

    pvdata_t * integratedSpikeCount,

    CL_MEM_CONST LIF_params * params,
    CL_MEM_GLOBAL uint4 * rnd,
    CL_MEM_GLOBAL float * V,
    CL_MEM_GLOBAL float * Vth,
    CL_MEM_GLOBAL float * G_E,
    CL_MEM_GLOBAL float * G_I,
    CL_MEM_GLOBAL float * G_IB,
    CL_MEM_GLOBAL float * GSynHead,
//    CL_MEM_GLOBAL float * GSynExc,
//    CL_MEM_GLOBAL float * GSynInh,
//    CL_MEM_GLOBAL float * GSynInhB,
//    CL_MEM_GLOBAL float * GSynGap,
    CL_MEM_GLOBAL float * activity,

    const float sum_gap,
    CL_MEM_GLOBAL float * G_Gap,
    CL_MEM_GLOBAL float * Vattained,
    CL_MEM_GLOBAL float * Vmeminf)
{

   // convert target rate from Hz to kHz
   float targetRatekHz = targetRateHz/1000;

   // tau parameters
   const float tauO = 1/targetRatekHz;   //Convert target rate from kHz to ms (tauO)

   const float decayE   = EXP(-dt/params->tauE);
   const float decayI   = EXP(-dt/params->tauI);
   const float decayIB  = EXP(-dt/params->tauIB);
   const float decayVth = EXP(-dt/params->tauVth);
   const float decayO   = EXP(-dt/tauO);

   //Convert dt to seconds
   const float dt_sec = .001 * dt;

#ifndef PV_USE_OPENCL

for (int k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
#endif

   int kex = kIndexExtended(k, nx, ny, nf, nb);

   //
   // kernel (nonheader part) begins here
   //

   // local param variables
   float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth;

   // const float GMAX = 10.0;

   // local variables
   float l_activ;

   uint4 l_rnd = rnd[k];

   float l_V   = V[k];
   float l_Vth = Vth[k];

   // The correction factors to the conductances are so that if l_GSyn_* is the same every timestep,
   // then the asymptotic value of l_G_* will be l_GSyn_*
   float l_G_E  = G_E[k];
   float l_G_I  = G_I[k];
   float l_G_IB = G_IB[k];
   float l_G_Gap = G_Gap[k];

   CL_MEM_GLOBAL float * GSynExc = &GSynHead[CHANNEL_EXC*numNeurons];
   CL_MEM_GLOBAL float * GSynInh = &GSynHead[CHANNEL_INH*numNeurons];
   CL_MEM_GLOBAL float * GSynInhB = &GSynHead[CHANNEL_INHB*numNeurons];
   CL_MEM_GLOBAL float * GSynGap = &GSynHead[CHANNEL_GAP*numNeurons];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];
   float l_GSynGap  = GSynGap[k];

   // define local param variables
   //
   tau        = params->tau;
   Vexc       = params->Vexc;
   Vinh       = params->Vinh;
   VinhB      = params->VinhB;
   Vrest      = params->Vrest;

   VthRest  = params->VthRest;
   deltaVth = params->deltaVth;

   // add noise
   //

#ifdef USE_CLRANDOM
   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqE) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynExc = l_GSynExc + params->noiseAmpE*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqI) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynInh = l_GSynInh + params->noiseAmpI*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqIB) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynInhB = l_GSynInhB + params->noiseAmpIB*cl_random_prob(l_rnd);
   }
#else
   if (pv_random_prob() < dt_sec*params->noiseFreqE) {
      l_GSynExc = l_GSynExc + params->noiseAmpE*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqI) {
      l_GSynInh = l_GSynInh + params->noiseAmpI*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqIB) {
      l_GSynInhB = l_GSynInhB + params->noiseAmpIB*pv_random_prob();
   }
#endif

   const float GMAX = FLT_MAX;

   // The portion of code below uses the newer method of calculating l_V.
   float G_E_initial, G_I_initial, G_IB_initial, G_E_final, G_I_final, G_IB_final;

   G_E_initial = l_G_E + l_GSynExc;
   G_I_initial = l_G_I + l_GSynInh;
   G_IB_initial = l_G_IB + l_GSynInhB;

   G_E_initial  = (G_E_initial  > GMAX) ? GMAX : G_E_initial;
   G_I_initial  = (G_I_initial  > GMAX) ? GMAX : G_I_initial;
   G_IB_initial = (G_IB_initial > GMAX) ? GMAX : G_IB_initial;

   float totalconductance = 1.0 + G_E_initial + G_I_initial + G_IB_initial + sum_gap;
   Vmeminf[k] = (Vrest + Vexc*G_E_initial + Vinh*G_I_initial + VinhB*G_IB_initial + l_GSynGap)/totalconductance;

   G_E_final = G_E_initial * decayE;
   G_I_final = G_I_initial * decayI;
   G_IB_final = G_IB_initial * decayIB;

   l_G_Gap = l_GSynGap;

   float VmemInf1 = LCALIF_VmemInf(Vrest, Vexc, Vinh, VinhB, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap, sum_gap);
   float tauInf1 = LCALIF_tauInf(tau, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap);
   // float VmemInf2 = LCALIF_VmemInf(Vrest, Vexc, Vinh, VinhB, G_E_final, G_I_final, G_IB_final, l_G_Gap, sum_gap);
   // float tauInf2 = LCALIF_tauInf(tau, G_E_final, G_I_final, G_IB_final, l_G_Gap);
   l_V = exp(-dt/tauInf1)*(l_V - VmemInf1) + VmemInf1;
   // The commented-out code works very poorly if the equation for the membrane potential is stiff, which happens if tauInf < dt
   // dV1 = LIFGap_Vmem_derivative(l_V, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap, Vexc, Vinh, VinhB, sum_gap, Vrest, tau);
   // dV2 = LIFGap_Vmem_derivative(l_V+dt*dV1, G_E_final, G_I_final, G_IB_final, l_G_Gap, Vexc, Vinh, VinhB, sum_gap, Vrest, tau);
   // dV = (dV1+dV2)*0.5;
   // l_V = l_V + dt*dV;

   l_G_E = G_E_final;
   l_G_I = G_I_final;
   l_G_IB = G_IB_final;

   //l_Vth updates according to traditional LIF rule in addition to the slow threshold adaptation
   //      See LCA_Equations.pdf in the documentation for a full description of the neuron adaptive firing threshold.

   Vadpt[k] += (dt/tauTHR) * ((integratedSpikeCount[k]/tauO) - targetRatekHz) * (Vscale/targetRatekHz);

   l_Vth = Vadpt[k] + decayVth * (l_Vth - Vadpt[k]);

   bool fired_flag = (l_V > l_Vth);

   l_activ = fired_flag ? 1.0f             : 0.0f;
   Vattained[k] = l_V; // Save the value of V before it drops due to the spike
   l_V     = fired_flag ? Vrest            : l_V;
   l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
   l_G_IB  = fired_flag ? l_G_IB + 1.0f    : l_G_IB;

   //integratedSpikeCount is the trace activity of the neuron, with an exponential decay
   integratedSpikeCount[k] = decayO * (l_activ + integratedSpikeCount[k]);

   //
   // These actions must be done outside of kernel
   //    1. set activity to 0 in boundary (if needed)
   //    2. update active indices
   //

   // store local variables back to global memory
   //
   rnd[k] = l_rnd;

   activity[kex] = l_activ;

   V[k]   = l_V;
   Vth[k] = l_Vth;

   G_E[k]  = l_G_E;
   G_I[k]  = l_G_I;
   G_IB[k] = l_G_IB;
   G_Gap[k] = l_G_Gap;

   GSynExc[k]  = 0.0f;
   GSynInh[k]  = 0.0f;
   GSynInhB[k] = 0.0f;
   GSynGap[k]  = 0.0f;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}

#include "LIF_params.h"
#include "cl_random.hcl"

#ifndef PV_USE_OPENCL
#  include <math.h>
#  define EXP expf
#  define CL_KERNEL
#  define CL_MEM_GLOBAL
#  define CL_MEM_CONST
#  define CL_MEM_LOCAL
#else  /* compiling with OpenCL */
#  define EXP exp
#  define CL_KERNEL       __kernel
#  define CL_MEM_GLOBAL   __global
#  define CL_MEM_CONST    __constant
#  define CL_MEM_LOCAL    __local
#  include "conversions.hcl"
#  define CHANNEL_EXC   0
#  define CHANNEL_INH   1
#  define CHANNEL_INHB  2
#  define CHANNEL_GAP   3
#endif

//#undef USE_CLRANDOM
#ifndef USE_CLRANDOM
#  include "../utils/pv_random.h"
#endif

inline
float LCALIF_tauInf(const float tau, const float G_E, const float G_I, const float G_IB, const float sum_gap) {
   return tau/(1+G_E+G_I+G_IB+sum_gap);
}

inline
float LCALIF_VmemInf(const float Vrest, const float V_E, const float V_I, const float V_B, const float G_E, const float G_I, const float G_B, const float G_gap, const float sumgap) {
   return (Vrest + V_E*G_E + V_I*G_I + V_B*G_B + G_gap)/(1+G_E+G_I+G_B+sumgap);
}

// The commented-out code below is only used for the Heun's method integration, which works very poorly when the equation is stiff.
/*
inline
float LIFGap_Vmem_derivative(
      const float Vmem,
      const float G_E,
      const float G_I,
      const float G_IB,
      const float G_Gap,
      const float V_E,
      const float V_I,
      const float V_IB,
      const float sum_gap,
      const float Vrest,
      const float tau) {
   float totalconductance = 1.0 + G_E + G_I + G_IB + sum_gap;
   float Vmeminf = (Vrest + V_E*G_E + V_I*G_I + V_IB*G_IB + G_Gap)/totalconductance;
   return totalconductance*(Vmeminf-Vmem)/tau;
}
 */

//
// update the state of a LCALIF layer (spiking)
//
//    assume called with 1D kernel
//
// LCALIF_update_state_beginning uses a Heun scheme for V, using values of the conductances at both the beginning and end of the timestep.  Spikes in the input are applied at the beginning of the timestep.
//
CL_KERNEL
void LCALIF_update_state(
    const int numNeurons,
    const float time,
    const float dt,

    const int nx,
    const int ny,
    const int nf,
    const int nb,

    float Vscale,
    float * Vadpt,
    float tauTHR,
    const float targetRateHz,

    pvdata_t * integratedSpikeCount,

    CL_MEM_CONST LIF_params * params,
    CL_MEM_GLOBAL uint4 * rnd,
    CL_MEM_GLOBAL float * V,
    CL_MEM_GLOBAL float * Vth,
    CL_MEM_GLOBAL float * G_E,
    CL_MEM_GLOBAL float * G_I,
    CL_MEM_GLOBAL float * G_IB,
    CL_MEM_GLOBAL float * GSynHead,
//    CL_MEM_GLOBAL float * GSynExc,
//    CL_MEM_GLOBAL float * GSynInh,
//    CL_MEM_GLOBAL float * GSynInhB,
//    CL_MEM_GLOBAL float * GSynGap,
    CL_MEM_GLOBAL float * activity,

    const float sum_gap,
    CL_MEM_GLOBAL float * G_Gap,
    CL_MEM_GLOBAL float * Vattained,
    CL_MEM_GLOBAL float * Vmeminf)
{

   // convert target rate from Hz to kHz
   float targetRatekHz = targetRateHz/1000;

   // tau parameters
   const float tauO = 1/targetRatekHz;   //Convert target rate from kHz to ms (tauO)

   const float decayE   = EXP(-dt/params->tauE);
   const float decayI   = EXP(-dt/params->tauI);
   const float decayIB  = EXP(-dt/params->tauIB);
   const float decayVth = EXP(-dt/params->tauVth);
   const float decayO   = EXP(-dt/tauO);

   //Convert dt to seconds
   const float dt_sec = .001 * dt;

#ifndef PV_USE_OPENCL

for (int k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
#endif

   int kex = kIndexExtended(k, nx, ny, nf, nb);

   //
   // kernel (nonheader part) begins here
   //

   // local param variables
   float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth;

   // const float GMAX = 10.0;

   // local variables
   float l_activ;

   uint4 l_rnd = rnd[k];

   float l_V   = V[k];
   float l_Vth = Vth[k];

   // The correction factors to the conductances are so that if l_GSyn_* is the same every timestep,
   // then the asymptotic value of l_G_* will be l_GSyn_*
   float l_G_E  = G_E[k];
   float l_G_I  = G_I[k];
   float l_G_IB = G_IB[k];
   float l_G_Gap = G_Gap[k];

   CL_MEM_GLOBAL float * GSynExc = &GSynHead[CHANNEL_EXC*numNeurons];
   CL_MEM_GLOBAL float * GSynInh = &GSynHead[CHANNEL_INH*numNeurons];
   CL_MEM_GLOBAL float * GSynInhB = &GSynHead[CHANNEL_INHB*numNeurons];
   CL_MEM_GLOBAL float * GSynGap = &GSynHead[CHANNEL_GAP*numNeurons];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];
   float l_GSynGap  = GSynGap[k];

   // define local param variables
   //
   tau        = params->tau;
   Vexc       = params->Vexc;
   Vinh       = params->Vinh;
   VinhB      = params->VinhB;
   Vrest      = params->Vrest;

   VthRest  = params->VthRest;
   deltaVth = params->deltaVth;

   // add noise
   //

#ifdef USE_CLRANDOM
   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqE) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynExc = l_GSynExc + params->noiseAmpE*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqI) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynInh = l_GSynInh + params->noiseAmpI*cl_random_prob(l_rnd);
   }

   l_rnd = cl_random_get(l_rnd);
   if (cl_random_prob(l_rnd) < dt_sec*params->noiseFreqIB) {
      l_rnd = cl_random_get(l_rnd);
      l_GSynInhB = l_GSynInhB + params->noiseAmpIB*cl_random_prob(l_rnd);
   }
#else
   if (pv_random_prob() < dt_sec*params->noiseFreqE) {
      l_GSynExc = l_GSynExc + params->noiseAmpE*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqI) {
      l_GSynInh = l_GSynInh + params->noiseAmpI*pv_random_prob();
   }

   if (pv_random_prob() < dt_sec*params->noiseFreqIB) {
      l_GSynInhB = l_GSynInhB + params->noiseAmpIB*pv_random_prob();
   }
#endif

   const float GMAX = FLT_MAX;

   // The portion of code below uses the newer method of calculating l_V.
   float G_E_initial, G_I_initial, G_IB_initial, G_E_final, G_I_final, G_IB_final;

   G_E_initial = l_G_E + l_GSynExc;
   G_I_initial = l_G_I + l_GSynInh;
   G_IB_initial = l_G_IB + l_GSynInhB;

   G_E_initial  = (G_E_initial  > GMAX) ? GMAX : G_E_initial;
   G_I_initial  = (G_I_initial  > GMAX) ? GMAX : G_I_initial;
   G_IB_initial = (G_IB_initial > GMAX) ? GMAX : G_IB_initial;

   float totalconductance = 1.0 + G_E_initial + G_I_initial + G_IB_initial + sum_gap;
   Vmeminf[k] = (Vrest + Vexc*G_E_initial + Vinh*G_I_initial + VinhB*G_IB_initial + l_GSynGap)/totalconductance;

   G_E_final = G_E_initial * decayE;
   G_I_final = G_I_initial * decayI;
   G_IB_final = G_IB_initial * decayIB;

   l_G_Gap = l_GSynGap;

   float VmemInf1 = LCALIF_VmemInf(Vrest, Vexc, Vinh, VinhB, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap, sum_gap);
   float tauInf1 = LCALIF_tauInf(tau, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap);
   // float VmemInf2 = LCALIF_VmemInf(Vrest, Vexc, Vinh, VinhB, G_E_final, G_I_final, G_IB_final, l_G_Gap, sum_gap);
   // float tauInf2 = LCALIF_tauInf(tau, G_E_final, G_I_final, G_IB_final, l_G_Gap);
   l_V = exp(-dt/tauInf1)*(l_V - VmemInf1) + VmemInf1;
   // The commented-out code works very poorly if the equation for the membrane potential is stiff, which happens if tauInf < dt
   // dV1 = LIFGap_Vmem_derivative(l_V, G_E_initial, G_I_initial, G_IB_initial, l_G_Gap, Vexc, Vinh, VinhB, sum_gap, Vrest, tau);
   // dV2 = LIFGap_Vmem_derivative(l_V+dt*dV1, G_E_final, G_I_final, G_IB_final, l_G_Gap, Vexc, Vinh, VinhB, sum_gap, Vrest, tau);
   // dV = (dV1+dV2)*0.5;
   // l_V = l_V + dt*dV;

   l_G_E = G_E_final;
   l_G_I = G_I_final;
   l_G_IB = G_IB_final;

   //l_Vth updates according to traditional LIF rule in addition to the slow threshold adaptation
   //      See LCA_Equations.pdf in the documentation for a full description of the neuron adaptive firing threshold.

   Vadpt[k] += (dt/tauTHR) * ((integratedSpikeCount[k]/tauO) - targetRatekHz) * (Vscale/targetRatekHz);

   l_Vth = Vadpt[k] + decayVth * (l_Vth - Vadpt[k]);

   bool fired_flag = (l_V > l_Vth);

   l_activ = fired_flag ? 1.0f             : 0.0f;
   Vattained[k] = l_V; // Save the value of V before it drops due to the spike
   l_V     = fired_flag ? Vrest            : l_V;
   l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
   l_G_IB  = fired_flag ? l_G_IB + 1.0f    : l_G_IB;

   //integratedSpikeCount is the trace activity of the neuron, with an exponential decay
   integratedSpikeCount[k] = decayO * (l_activ + integratedSpikeCount[k]);

   //
   // These actions must be done outside of kernel
   //    1. set activity to 0 in boundary (if needed)
   //    2. update active indices
   //

   // store local variables back to global memory
   //
   rnd[k] = l_rnd;

   activity[kex] = l_activ;

   V[k]   = l_V;
   Vth[k] = l_Vth;

   G_E[k]  = l_G_E;
   G_I[k]  = l_G_I;
   G_IB[k] = l_G_IB;
   G_Gap[k] = l_G_Gap;

   GSynExc[k]  = 0.0f;
   GSynInh[k]  = 0.0f;
   GSynInhB[k] = 0.0f;
   GSynGap[k]  = 0.0f;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}


Renamed cl_random_state to cl_random_get and fixed bug where cl_random_get was not after cl_random_prob was called in an if statement.  This meant that cl_random_prob could be called many times in row without getting a new random number.

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@3210 7c0444ca-5550-0410-9008-faecdbe78eb5

#include "Retina_params.h"
#include "cl_random.hcl"

#ifndef PI
#  define PI 3.1415926535897932
#endif

#ifndef PV_USE_OPENCL

#  include <math.h>
#  define EXP expf
#  define FMOD fmodf
#  define CL_KERNEL
#  define CL_MEM_GLOBAL
#  define CL_MEM_LOCAL

#else

#  define EXP exp
#  define FMOD __fmodf
#  define CL_KERNEL     __kernel
#  define CL_MEM_GLOBAL __global
#  define CL_MEM_LOCAL  __local
#  include "conversions.hcl"

#endif /* PV_USE_OPENCL */

/*
 * Spiking method for Retina
 * Returns 1 if an event should occur, 0 otherwise. This is a stochastic model.
 *
 * REMARKS:
 *      - During ABS_REFACTORY_PERIOD a neuron does not spike
 *      - The neurons that correspond to stimuli (on Image pixels)
 *        spike with probability probStim.
 *      - The neurons that correspond to background image pixels
 *        spike with probability probBase.
 *      - After ABS_REFACTORY_PERIOD the spiking probability
 *        grows exponentially to probBase and probStim respectively.
 *      - The burst of the retina is periodic with period T set by
 *        T = 1000/burstFreq in miliseconds
 *      - When the time t is such that mT < t < mT + burstDuration, where m is
 *        an integer, the burstStatus is set to 1.
 *      - The burstStatus is also determined by the condition that
 *        beginStim < t < endStim. These parameters are set in the input
 *        params file params.stdp
 *      - sinAmp modulates the spiking probability only when burstDuration <= 0
 *        or burstFreq = 0
 *      - probSpike is set to probBase for all neurons.
 *      - for neurons exposed to Image on pixels, probSpike increases with probStim.
 *      - When the probability is negative, the neuron does not spike.
 *
 * NOTES:
 *      - time is measured in milliseconds.
 *
 */
static inline
int spike(float time, float dt,
          float prev, float stimFactor, uint4 * rnd_state, CL_MEM_GLOBAL Retina_params * params)
{
   float probSpike;
   float burstStatus = 1;
   float sinAmp = 1.0;

   // input parameters
   //
   float probBase  = params->probBase;
   float probStim  = params->probStim * stimFactor;

   // see if neuron is in a refactory period
   //
   if ((time - prev) < params->abs_refactory_period) {
      return 0;
   }
   else {
      float delta = time - prev - params->abs_refactory_period;
      float refact = 1.0f - EXP(-delta/params->refactory_period);
      refact = (refact < 0) ? 0 : refact;
      probBase *= refact;
      probStim *= refact;
   }

   if (params->burstDuration <= 0 || params->burstFreq == 0) {
      sinAmp = cos( 2*PI*time * params->burstFreq / 1000. );
   }
   else {
      burstStatus = FMOD(time, 1000. / params->burstFreq);
      burstStatus = burstStatus <= params->burstDuration;
   }

   burstStatus *= (int) ( (time >= params->beginStim) && (time < params->endStim) );
   probSpike = probBase;

   if ((int)burstStatus) {
      probSpike += probStim * sinAmp;  // negative prob is OK
   }

   *rnd_state = cl_random_get(*rnd_state);
   int spike_flag = (cl_random_prob(*rnd_state) < probSpike);
   return spike_flag;
}

//
// update the state of a retinal layer (spiking)
//
//    assume called with 1D kernel
//
CL_KERNEL
void Retina_update_state (
    const float time,
    const float dt,

    const int nx,
    const int ny,
    const int nf,
    const int nb,

    CL_MEM_GLOBAL Retina_params * params,
    CL_MEM_GLOBAL uint4 * rnd,
    CL_MEM_GLOBAL float * phiExc,
    CL_MEM_GLOBAL float * phiInh,
    CL_MEM_GLOBAL float * activity,
    CL_MEM_GLOBAL float * prevTime)
{
   int k;
#ifndef PV_USE_OPENCL
for (k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
#endif

   int kex = kIndexExtended(k, nx, ny, nf, nb);

   //
   // kernel (nonheader part) begins here
   //

   // load local variables from global memory
   //
   uint4 l_rnd = rnd[k];
   float l_phiExc = phiExc[k];
   float l_phiInh = phiInh[k];
   float l_prev   = prevTime[kex];
   float l_activ  = activity[kex];

   l_activ = (float) spike(time, dt, l_prev, (l_phiExc - l_phiInh), &l_rnd, params);
   l_prev  = (l_activ > 0.0f) ? time : l_prev;

   l_phiExc = 0.0f;
   l_phiInh = 0.0f;

   // store local variables back to global memory
   //
   rnd[k] = l_rnd;
   phiExc[k] = l_phiExc;
   phiInh[k] = l_phiInh;
   prevTime[kex] = l_prev;
   activity[kex] = l_activ;

#ifndef PV_USE_OPENCL
   }
#endif

}

#include "Retina_params.h"
#include "cl_random.hcl"

#ifndef PI
#  define PI 3.1415926535897932
#endif

#ifndef PV_USE_OPENCL

#  include <math.h>
#  define EXP expf
#  define FMOD fmodf
#  define CL_KERNEL
#  define CL_MEM_GLOBAL
#  define CL_MEM_LOCAL

#else

#  define EXP exp
#  define FMOD __fmodf
#  define CL_KERNEL     __kernel
#  define CL_MEM_GLOBAL __global
#  define CL_MEM_LOCAL  __local
#  include "conversions.hcl"

#endif /* PV_USE_OPENCL */

/*
 * Spiking method for Retina
 * Returns 1 if an event should occur, 0 otherwise. This is a stochastic model.
 *
 * REMARKS:
 *      - During ABS_REFACTORY_PERIOD a neuron does not spike
 *      - The neurons that correspond to stimuli (on Image pixels)
 *        spike with probability probStim.
 *      - The neurons that correspond to background image pixels
 *        spike with probability probBase.
 *      - After ABS_REFACTORY_PERIOD the spiking probability
 *        grows exponentially to probBase and probStim respectively.
 *      - The burst of the retina is periodic with period T set by
 *        T = 1000/burstFreq in miliseconds
 *      - When the time t is such that mT < t < mT + burstDuration, where m is
 *        an integer, the burstStatus is set to 1.
 *      - The burstStatus is also determined by the condition that
 *        beginStim < t < endStim. These parameters are set in the input
 *        params file params.stdp
 *      - sinAmp modulates the spiking probability only when burstDuration <= 0
 *        or burstFreq = 0
 *      - probSpike is set to probBase for all neurons.
 *      - for neurons exposed to Image on pixels, probSpike increases with probStim.
 *      - When the probability is negative, the neuron does not spike.
 *
 * NOTES:
 *      - time is measured in milliseconds.
 *
 */
static inline
int spike(float time, float dt,
          float prev, float stimFactor, uint4 * rnd_state, const Retina_params * params)
{
   float probSpike;
   float burstStatus = 1;
   float sinAmp = 1.0;

   // input parameters
   //
   float probBase  = params->probBase;
   float probStim  = params->probStim * stimFactor;

   // see if neuron is in a refactory period
   //
   if ((time - prev) < params->abs_refactory_period) {
      return 0;
   }
   else {
      float delta = time - prev - params->abs_refactory_period;
      float refact = 1.0f - EXP(-delta/params->refactory_period);
      refact = (refact < 0) ? 0 : refact;
      probBase *= refact;
      probStim *= refact;
   }

   if (params->burstDuration <= 0 || params->burstFreq == 0) {
      sinAmp = cos( 2*PI*time * params->burstFreq / 1000. );
   }
   else {
      burstStatus = FMOD(time, 1000. / params->burstFreq);
      burstStatus = burstStatus <= params->burstDuration;
   }

   burstStatus *= (int) ( (time >= params->beginStim) && (time < params->endStim) );
   probSpike = probBase;

   if ((int)burstStatus) {
      probSpike += probStim * sinAmp;  // negative prob is OK
   }

   int spike_flag = (cl_random_prob(*rnd_state) < probSpike);
   *rnd_state = cl_random_state(*rnd_state);
   return spike_flag;
}

//
// update the state of a retinal layer (spiking)
//
//    assume called with 1D kernel
//
CL_KERNEL
void Retina_update_state (
    const float time,
    const float dt,

    const int nx,
    const int ny,
    const int nf,
    const int nb,

    CL_MEM_GLOBAL Retina_params * params,
    CL_MEM_GLOBAL uint4 * rnd,
    CL_MEM_GLOBAL float * phiExc,
    CL_MEM_GLOBAL float * phiInh,
    CL_MEM_GLOBAL float * activity,
    CL_MEM_GLOBAL float * prevTime)
{
   int k;
#ifndef PV_USE_OPENCL
for (k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
#endif

   int kex = kIndexExtended(k, nx, ny, nf, nb);

   //
   // kernel (nonheader part) begins here
   //

   // load local variables from global memory
   //
   uint4 l_rnd = rnd[k];
   float l_phiExc = phiExc[k];
   float l_phiInh = phiInh[k];
   float l_prev   = prevTime[kex];
   float l_activ  = activity[kex];

   l_activ = (float) spike(time, dt, l_prev, (l_phiExc - l_phiInh), &l_rnd, params);
   l_prev  = (l_activ > 0.0f) ? time : l_prev;

   l_phiExc = 0.0f;
   l_phiInh = 0.0f;

   // store local variables back to global memory
   //
   rnd[k] = l_rnd;
   phiExc[k] = l_phiExc;
   phiInh[k] = l_phiInh;
   prevTime[kex] = l_prev;
   activity[kex] = l_activ;

#ifndef PV_USE_OPENCL
   }
#endif

}


Revert "32bit Support"

Revert "32bit Support"

This reverts commit 4423eba6ae8de593f128b291e2c92c8bef0ee462.


fix hello world example

fix hello world example

error: pathspec 'example-Hello' did not match any file(s) known to git
error: pathspec 'World/data/MSAOpenCL/HelloWorld.cl' did not match any file(s) known to git


Create EFIT2D-VISCO.cl

Create EFIT2D-VISCO.cl

OpenCL EFIT2D Viscoelastic

/** Source Input Kernel
*/
__kernel void Source_EFIT2D( __global float *Txx,__global float *Tyy, __global const int *XL, __global const int *YL, const float source){

			  uint i =	get_global_id(0);
			  Txx[ind(XL[i],YL[i])] -= source;
			  Tyy[ind(XL[i],YL[i])] -= source;

}

/** Receiver Kernel
*/
__kernel void Receiver_EFIT2D( __global float *Txx, __global float *receiver, const int t,
							   __global const int *XXL, __global const int *YYL){

			  __private float _tmp = 0.0f;

			   for (int i=0; i<get_global_size(0); ++i)
		       {
				 _tmp +=  Txx[ind(XXL[i],YYL[i])];
			   }
			   receiver[t] = _tmp/(float)get_global_size(0);
}

/** Velocity Kernel (Global Memory) for Viscoelastic Case
*/
__kernel void Velocity_EFIT2D_Voigt( __global float *Txx,	__global float *Txy, __global float *Tyy,
									 __global float *vx,	__global float *vy,
									 __global float *dvx,	__global float *dvy,
									 __global const float *BX, __global const float *BY,
									 __global const float *ABS){

		  int j = get_global_id(0);
		  int i = get_global_id(1);

		  if (i <  MRI-1 && j>0){
				dvx[ind(i,j)]	 = (BX[ind(i,j)]*ddx)*( Txx[ind(i+1,j)] - Txx[ind(i,j)]	  + Txy[ind(i,j)] - Txy[ind(i,j-1)] );
				vx[ind(i,j)]	+= dt*dvx[ind(i,j)];
		  }

		  if (i > 0 &&  j< NRI-1){
				dvy[ind(i,j)]    = (BY[ind(i,j)]*ddx)*( Txy[ind(i,j)]  - Txy[ind(i-1,j)] + Tyy[ind(i,j+1)] - Tyy[ind(i,j)]		 );
				vy[ind(i,j)]	+= dt*dvy[ind(i,j)];

		  }

		   barrier(CLK_GLOBAL_MEM_FENCE);
            // Apply absorbing boundary conditions
		   vx[ind(i,j)]	  *= ABS[ind(i,j)];
		   vy[ind(i,j)]	  *= ABS[ind(i,j)];

		 }

/** Stress Kernel (Global Memory) for Viscoelastic Case
*/

__kernel void Stress_EFIT2D_Voigt(__global float *Txx, __global float *Txy, __global float *Tyy,
								  __global float *vx,  __global float *vy,
								  __global float *dvx, __global float *dvy,
								  __global const float *C11,   __global const float *C12, __global const float *C44,
								  __global const float *ETA_VS, __global const float *ETA_S, __global const float *ETA_SS,
								  __global const float *ABS) {

		int j = get_global_id(0);
		int i = get_global_id(1);

		if (i>0 &&  j>0 ){
				Txx[ind(i,j)] += (	( C11[ind(i,j)]* dtx )*(vx[ind(i,j)] - vx[ind(i-1,j)]) +
									( C12[ind(i,j)]* dtx )*(vy[ind(i,j)] - vy[ind(i,j-1)]) +
									( (ETA_VS[ind(i,j)])*dtx) * (dvx[ind(i,j)] - dvx[ind(i-1,j)]) +
									( (ETA_S [ind(i,j)])*dtx) * (dvy[ind(i,j)] - dvy[ind(i,j-1)]) );

				Tyy[ind(i,j)] += (	( C12[ind(i,j)]* dtx )*(vx[ind(i,j)] - vx[ind(i-1,j)]) +
								    ( C11[ind(i,j)]* dtx )*(vy[ind(i,j)] - vy[ind(i,j-1)]) +
									( (ETA_VS[ind(i,j)])*dtx) *(dvy[ind(i,j)] - dvy[ind(i,j-1)]) +
									( (ETA_S [ind(i,j)])*dtx) * (dvx[ind(i,j)] - dvx[ind(i-1,j)]) );
		 }

		 if (i<MRI-1  && j<NRI-1){
				Txy[ind(i,j)] +=	(  ( C44[ind(i,j)]	   * dtx )*(vx[ind(i,j+1)] - vx[ind(i,j)] + vy[ind(i+1,j)] - vy[ind(i,j)])		+
									   ( ETA_SS[ind(i,j)]  * dtx )*(dvx[ind(i,j+1)] - dvx[ind(i,j)] + dvy[ind(i+1,j)] - dvy[ind(i,j)] ) );
				 }

		  barrier(CLK_GLOBAL_MEM_FENCE);

		  Txx[ind(i,j)]	*= ABS[ind(i,j)];
		  Tyy[ind(i,j)]	*= ABS[ind(i,j)];
		  Txy[ind(i,j)]	*= ABS[ind(i,j)];

}

/** Velocity Kernel (Local Memory) for Viscoelastic Case
*/

__kernel void Velocity_Local_Voigt(__global float *Txx, __global float *Txy, __global float *Tyy,
								   __global float *vx,  __global float *vy, __global float *dvx, __global float *dvy,
								   __global const float *BX, __global const float *BY, __global const float *ABS){

		__local float local_Txx[DimLocalX+Stencil][DimLocalY+Stencil];
		__local float local_Txy[DimLocalX+Stencil][DimLocalY+Stencil];
		__local float local_Tyy[DimLocalX+Stencil][DimLocalY+Stencil];

		uint halo = Stencil/2;
		uint j	   = get_group_id(0) * get_local_size(0) + get_local_id(0);
		uint i	   = get_group_id(1) * get_local_size(1) + get_local_id(1);

		uint iBlock   = get_local_id(1)+halo;
		uint jBlock   = get_local_id(0)+halo;

		uint iField   = i + halo;
		uint jField   = j + halo;

		float D_Txx  = 0.0f;
		float Dx_Txy = 0.0f;
		float Dy_Txy = 0.0f;
		float D_Tyy  = 0.0f;
		float tabs, tdvx, tdvy, tvx, tvy;

		if (i <  MRI - Stencil && j < NRI - Stencil ){

			 barrier(CLK_LOCAL_MEM_FENCE);

		     // fill left halo of local memory
			 if (get_local_id(0) < halo )
			 {
			   local_Txx[iBlock][jBlock-halo] = Txx[iField*NRI + jField - halo];
			   local_Tyy[iBlock][jBlock-halo] = Tyy[iField*NRI + jField - halo];
			   local_Txy[iBlock][jBlock-halo] = Txy[iField*NRI + jField - halo];

			 }

			  // fill right halo of local memory
			  if (get_local_id(0) > DimLocalY - halo -1 )
			  {
				local_Txx[iBlock][jBlock+halo] = Txx[iField*NRI + jField + halo];
				local_Tyy[iBlock][jBlock+halo] = Tyy[iField*NRI + jField + halo];
				local_Txy[iBlock][jBlock+halo] = Txy[iField*NRI + jField + halo];

			  }

				// fill bottom halo of local memory
			   if (get_local_id(1) < halo )
			  {
				local_Txx[iBlock-halo][jBlock] = Txx[(iField-halo)*NRI + jField];
				local_Tyy[iBlock-halo][jBlock] = Tyy[(iField-halo)*NRI + jField];
				local_Txy[iBlock-halo][jBlock] = Txy[(iField-halo)*NRI + jField];

			  }

			  // fill top halo of local memory
			  if (get_local_id(1) > DimLocalX - halo -1 )
			   {
				 local_Txx[iBlock+halo][jBlock] = Txx[(iField+halo)*NRI + jField];
				 local_Tyy[iBlock+halo][jBlock] = Tyy[(iField+halo)*NRI + jField];
				 local_Txy[iBlock+halo][jBlock] = Txy[(iField+halo)*NRI + jField];

			   }

			     local_Txx[iBlock][jBlock]				   = Txx[iField*NRI + jField];
			     local_Tyy[iBlock][jBlock]				   = Tyy[iField*NRI + jField];
			     local_Txy[iBlock][jBlock]				   = Txy[iField*NRI + jField];

			  barrier(CLK_LOCAL_MEM_FENCE);

			  D_Txx  = 0.0f;
			  Dx_Txy = 0.0f;
			  Dy_Txy = 0.0f;
			  D_Tyy  = 0.0f;

			   if (j!=0){
			      Dy_Txy = local_Txy[iBlock][jBlock] - local_Txy[iBlock][jBlock-1];
		        }

			   if (i!=0){
			      Dx_Txy = local_Txy[iBlock][jBlock] - local_Txy[iBlock-1][jBlock];
		        }

		       D_Txx		 = local_Txx[iBlock+1][jBlock]	- local_Txx[iBlock][jBlock];
		       D_Tyy		 = local_Tyy[iBlock][jBlock+1]	- local_Tyy[iBlock][jBlock];

			   tvx = vx[iField*NRI + jField];
		       tvy = vy[iField*NRI + jField];

		       tdvx = (BX[iField*NRI+jField]*(ddx))*( D_Txx	 + Dy_Txy);
		       tvx += tdvx*dt;

		       tdvy = (BY[iField*NRI+jField]*(ddx))*( Dx_Txy + D_Tyy);
		       tvy += tdvy*dt;

			   tabs = ABS[iField*NRI + jField];
			   dvx[iField*NRI + jField]		= tdvx;
			   dvy[iField*NRI + jField]		= tdvy;
			   vx[iField*NRI + jField]		= tvx*tabs;
			   vy[iField*NRI + jField]		= tvy*tabs;
		   }

}

/** Stress Kernel (Local Memory) for Viscoelastic Case
*/

__kernel void Stress_Local_Voigt(__global float *Txx, __global float *Txy, __global float *Tyy,
								 __global float *vx,  __global float *vy,  __global float *dvx, __global float *dvy,
								 __global const float *C11, __global const float *C12, __global const float *C44,
								 __global const float *ETA_VS, __global const float *ETA_S, __global const float *ETA_SS,
								 __global const float *ABS){

					__local float local_vx[DimLocalX+Stencil][DimLocalY+Stencil];
					__local float local_vy[DimLocalX+Stencil][DimLocalY+Stencil];
					__local float local_dvx[DimLocalX+Stencil][DimLocalY+Stencil];
					__local float local_dvy[DimLocalX+Stencil][DimLocalY+Stencil];

					uint halo = Stencil/2;
					uint j	  = get_group_id(0) * get_local_size(0) + get_local_id(0);
					uint i	  = get_group_id(1) * get_local_size(1) + get_local_id(1);

					uint iBlock				  = get_local_id(1)+halo;
					uint jBlock				  = get_local_id(0)+halo;

					uint iField				  = i + halo;
					uint jField				  = j + halo;

					float D_vx	     = 0.0f;
					float D_vy		 = 0.0f;
					float Dy_vx		 = 0.0f;
					float Dx_vy		 = 0.0f;

					float D_dvx		 = 0.0f;
					float D_dvy		 = 0.0f;
					float Dy_dvx	 = 0.0f;
					float Dx_dvy	 = 0.0f;

					float tabs,tTxx, tTyy, tTxy;

					if (i <	 MRI - Stencil && j < NRI - Stencil ){

 						barrier(CLK_LOCAL_MEM_FENCE);

					   // fill left halo of local memory
					   if (get_local_id(0) < halo )
					   {
									 local_vx[iBlock][jBlock-halo]	= vx[iField*NRI + jField - halo];
									 local_vy[iBlock][jBlock-halo]	= vy[iField*NRI + jField - halo];
									 local_dvx[iBlock][jBlock-halo] = dvx[iField*NRI + jField - halo];
									 local_dvy[iBlock][jBlock-halo] = dvy[iField*NRI + jField - halo];

					   }

					   // fill right halo of local memory
					   if (get_local_id(0) > DimLocalY - halo -1 )
					   {
									 local_vx[iBlock][jBlock+halo]	= vx[iField*NRI + jField + halo];
									 local_vy[iBlock][jBlock+halo]	= vy[iField*NRI + jField + halo];
									 local_dvx[iBlock][jBlock+halo] = dvx[iField*NRI + jField + halo];
									 local_dvy[iBlock][jBlock+halo] = dvy[iField*NRI + jField + halo];

					   }

					   // fill bottom halo of local memory
					   if (get_local_id(1) < halo )
					   {
									 local_vx[iBlock-halo][jBlock]	= vx[(iField-halo)*NRI + jField];
									 local_vy[iBlock-halo][jBlock]	= vy[(iField-halo)*NRI + jField];
									 local_dvx[iBlock-halo][jBlock] = dvx[(iField-halo)*NRI + jField];
									 local_dvy[iBlock-halo][jBlock] = dvy[(iField-halo)*NRI + jField];

					   }

					   // fill top halo of local memory
					   if (get_local_id(1) > DimLocalX - halo -1 )
					   {
									 local_vx[iBlock+halo][jBlock]	= vx[(iField+halo)*NRI + jField];
									 local_vy[iBlock+halo][jBlock]	= vy[(iField+halo)*NRI + jField];
									 local_dvx[iBlock+halo][jBlock] = dvx[(iField+halo)*NRI + jField];
									 local_dvy[iBlock+halo][jBlock] = dvy[(iField+halo)*NRI + jField];

					   }

						 local_vx[iBlock][jBlock]			  = vx[iField*NRI + jField];
						 local_vy[iBlock][jBlock]			  = vy[iField*NRI + jField];
						 local_dvx[iBlock][jBlock]			  = dvx[iField*NRI + jField];
						 local_dvy[iBlock][jBlock]			  = dvy[iField*NRI + jField];

	                  barrier(CLK_LOCAL_MEM_FENCE);

					   D_vx	  = 0.0f;
					   D_vy	  = 0.0f;
					   Dy_vx  = 0.0f;
					   Dx_vy  = 0.0f;

					   if (i!= 0){
									D_vx  = local_vx[iBlock][jBlock]- local_vx[iBlock-1][jBlock];
									D_dvx = local_dvx[iBlock][jBlock]- local_dvx[iBlock-1][jBlock];
					   }

					   if (j!=0){
									D_vy  = local_vy[iBlock][jBlock] - local_vy[iBlock][jBlock-1];
									D_dvy = local_dvy[iBlock][jBlock]- local_dvy[iBlock][jBlock-1];
					   }

					    Dy_vx = local_vx[iBlock][jBlock+1] - local_vx[iBlock][jBlock];
						Dx_vy = local_vy[iBlock+1][jBlock] - local_vy[iBlock][jBlock];

						Dy_dvx = local_dvx[iBlock][jBlock+1] - local_dvx[iBlock][jBlock];
						Dx_dvy = local_dvy[iBlock+1][jBlock] - local_dvy[iBlock][jBlock];

						tTxx = Txx[iField*NRI + jField];
						tTyy = Tyy[iField*NRI + jField];
						tTxy = Txy[iField*NRI + jField];

						tTxx +=	 ( (C11[iField*NRI+jField]*dtx)*D_vx +
													     ( C12[iField*NRI+jField]*dtx)*D_vy +
													     ((ETA_VS[iField*NRI + jField])*dtx)*D_dvx +
													     ((ETA_S[iField*NRI + jField])*dtx)*D_dvy );

						tTyy +=	  ( (C12[iField*NRI+jField]*dtx)*D_vx +
														  ( C11[iField*NRI+jField]*dtx)*D_vy +
													      ((ETA_VS[iField*NRI + jField])*dtx)*D_dvy +
													      ((ETA_S[iField*NRI + jField])*dtx)*D_dvx );

						tTxy +=	  ( C44[iField*NRI+jField]*dtx)*( Dx_vy + Dy_vx ) + (ETA_SS[iField*NRI + jField]*dtx)*( Dx_dvy + Dy_dvx );

						tabs = ABS[iField*NRI + jField];

						Txx[iField*NRI + jField]	= tTxx * tabs;
						Tyy[iField*NRI + jField]    = tTyy * tabs;
						Txy[iField*NRI + jField]	= tTxy * tabs;
	     	}
}

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


Moved to kernel directory.

Moved to kernel directory.

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@3032 7c0444ca-5550-0410-9008-faecdbe78eb5

//#include <OpenCL/opencl.h>

#ifdef DEBUG_PRINT
#  include <stdio.h>
#endif

#define pvdata_t float
#define PHI_EXC 0       // which phi buffer to use
#define PHI_INH 1       // which phi buffer to use
#define PHI_INHB 2
#define PI              3.1415926535897932

// refactory period for neurons (retina for now)
#define ABS_REFACTORY_PERIOD 3
#define REFACTORY_PERIOD     5

#define PV_RANDOM_MAX       0x7fffffff
#define PV_INV_RANDOM_MAX   (1.0 / (double) PV_RANDOM_MAX)

// problems including stdlib.h
double random();

static inline double pv_random_prob()
{
   return (double) random() * PV_INV_RANDOM_MAX;
}

static inline int featureIndex(int k, int nx, int ny, int nf)
{
   return k % nf;
}

static inline int kxPos(int k, int nx, int ny, int nf)
{
   return (k/nf) % nx;
}

static inline int kyPos(int k, int nx, int ny, int nf)
{
   return k / (nx*nf);
}

static inline int kIndex(int kx, int ky, int kf, int nx, int ny, int nf)
{
   return kf + (kx + (ky * nx)) * nf;
}

static inline int kIndexRestricted(int k_ex, int nx, int ny, int nf, int nb)
{
   int kx, ky, kf;

   const int nx_ex = nx + 2*nb;
   const int ny_ex = ny + 2*nb;

   kx = kxPos(k_ex, nx_ex, ny_ex, nf) - nb;
   if (kx < 0 || kx >= nx) return -1;

   ky = kyPos(k_ex, nx_ex, ny_ex, nf) - nb;
   if (ky < 0 || ky >= ny) return -1;

   kf = featureIndex(k_ex, nx_ex, ny_ex, nf);
   return kIndex(kx, ky, kf, nx, ny, nf);
}

inline uint k_index(uint nx, uint ny)
{
   return (get_global_id(0) + nx * get_global_id(1));
}

/**
 * Returns the extended index
 *  - assumes kernel called with extended thread space
 */
inline uint k_ex_index(uint nx, uint ny, uint nPad)
{
   return (get_global_id(0) + (nx+2*nPad) * get_global_id(1));
}

inline uint kx_index()
{
   return get_global_id(0);
}

inline uint ky_index()
{
   return get_global_id(1);
}

#undef SIMPLE_SPIKE
#ifdef SIMPLE_SPIKE
int spike(float time, float dt, float prev, float probBase, float probStim, float * probSpike)
{
   return 1;
}
#else
int spike(float time, float dt, float prev, float probBase, float probStim, float * probSpike)
{
//   fileread_params * params = (fileread_params *) clayer->params;
   float burstStatus = 1;
   float sinAmp = 1.0;

   // input parameters
   // TODO - how to get these into kernel
   //
   const float beginStim = 0.0f;
   const float endStim   = 9000000.0f;
   const float burstFreq = 40.0f;
   const float burstDuration = 7.5f;

   // see if neuron is in a refactory period
   //
   if ((time - prev) < ABS_REFACTORY_PERIOD) {
      return 0;
   }
   else {
      float delta = time - prev - ABS_REFACTORY_PERIOD;
      float refact = 1.0f - expf(-delta/REFACTORY_PERIOD);
      refact = (refact < 0) ? 0 : refact;
      probBase *= refact;
      probStim *= refact;
   }

   if (burstDuration <= 0 || burstFreq == 0) {
      sinAmp = cos( 2 * PI * time * burstFreq / 1000. );
   }
   else {
      burstStatus = fmodf(time, 1000. / burstFreq);
      burstStatus = burstStatus <= burstDuration;
   }

   burstStatus *= (int) ( (time >= beginStim) && (time < endStim) );
   *probSpike = probBase;

   if ((int)burstStatus) {
      *probSpike += probStim * sinAmp;  // negative prob is OK
    }
   return ( pv_random_prob() < *probSpike );
}
#endif

//
// update the state of a retinal layer (spiking)
//
// This will be called with grid layout in extended space (nx*2*nPad)*(ny*2*nPad)
//
__kernel void update_state (
    const float time,
    const float dt,
    const float probStim,
    const float probBase,

    const uint nx,
    const uint ny,
    const uint nf,
    const uint nPad,

    __global float * phi,
    __global float * activity,
    __global float * prevActivity)
{
   //
   // Make sure threads are within bounds.
   //
   if (kx_index() >= nx+2*nPad || ky_index() >= ny+2*nPad) {
      return;
   }

   float probSpike;
   const uint numNeurons = nx * ny * nf;

   __global pvdata_t * phiExc = & phi[PHI_EXC * numNeurons];
   __global pvdata_t * phiInh = & phi[PHI_INH * numNeurons];

   const uint kex = k_ex_index(nx, ny, nPad);
   const int k = kIndexRestricted(kex, nx, ny, nf, nPad);

   const float prevTime = prevActivity[kex];

   if (k >= 0) {
      //
      // interior region
      //
      const float l_V = phiExc[k] - phiInh[k];

      phiExc[k] = 0.0f;
      phiInh[k] = 0.0f;

      const float l_activity = spike(time, dt, prevTime, probBase, probStim*l_V, &probSpike);
      activity[kex] = l_activity;
      prevActivity[kex] = (l_activity > 0.0f) ? time : prevTime;

#ifdef DEBUG_PRINT
      if (k < 6) {
         printf("k==%d kex==%d kx==%d ky==%d l_V==%f\n", k, kex, kx_index(), ky_index(), l_V);
      }
#endif
   }
   else {
      //
      // border region (background activity only)
      //
      const float l_activity = spike(time, dt, prevTime, probBase, 0.0f, &probSpike);
      activity[kex] = l_activity;
      prevActivity[kex] = (l_activity > 0.0f) ? time : prevTime;
   }
}


Fix compilation error in final_boundary_reduce_dim

the gidx was incorrectly being used as gid

/*******************************************************
 * Copyright (c) 2018, 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
 ********************************************************/

kernel void final_boundary_reduce_dim(global int *reduced_block_sizes,
                                      global Tk *oKeys, KParam oKInfo,
                                      global To *oVals, KParam oVInfo,
                                      const int n, const int nBlocksZ) {
    local int dim_ordering[4];

    const uint lid = get_local_id(0);
    const uint bid = get_group_id(0);
    const uint gid = get_global_id(0);

    const int bidy = get_group_id(1);
    const int bidz = get_group_id(2) % nBlocksZ;
    const int bidw = get_group_id(2) / nBlocksZ;

    if (lid == 0) {
        int d           = 1;
        dim_ordering[0] = DIM;
        for (int i = 0; i < 4; ++i) {
            if (i != DIM) dim_ordering[d++] = i;
        }
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    if (gid == ((bid + 1) * get_local_size(0)) - 1 &&
        bid < get_num_groups(0) - 1) {
        Tk k0 = oKeys[gid];
        Tk k1 = oKeys[gid + 1];
        if (k0 == k1) {
            To v0                    = oVals[gid];
            To v1                    = oVals[gid + 1];
            oVals[gid + 1]           = binOp(v0, v1);
            reduced_block_sizes[bid] = get_local_size(0) - 1;
        } else {
            reduced_block_sizes[bid] = get_local_size(0);
        }
    }

    // if last block, set block size to difference between n and block boundary
    if (lid == 0 && bid == get_num_groups(0) - 1) {
        reduced_block_sizes[bid] = n - (bid * get_local_size(0));
    }
}

/*******************************************************
 * Copyright (c) 2018, 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
 ********************************************************/

kernel void final_boundary_reduce_dim(global int *reduced_block_sizes,
                                      global Tk *oKeys, KParam oKInfo,
                                      global To *oVals, KParam oVInfo,
                                      const int n, const int nBlocksZ) {
    local int dim_ordering[4];

    const uint lid  = get_local_id(0);
    const uint bid  = get_group_id(0);
    const uint gidx = get_global_id(0);

    const int bidy = get_group_id(1);
    const int bidz = get_group_id(2) % nBlocksZ;
    const int bidw = get_group_id(2) / nBlocksZ;

    if (lid == 0) {
        int d           = 1;
        dim_ordering[0] = DIM;
        for (int i = 0; i < 4; ++i) {
            if (i != DIM) dim_ordering[d++] = i;
        }
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    if (gid == ((bid + 1) * get_local_size(0)) - 1 &&
        bid < get_num_groups(0) - 1) {
        Tk k0 = oKeys[gid];
        Tk k1 = oKeys[gid + 1];
        if (k0 == k1) {
            To v0                    = oVals[gid];
            To v1                    = oVals[gid + 1];
            oVals[gid + 1]           = binOp(v0, v1);
            reduced_block_sizes[bid] = get_local_size(0) - 1;
        } else {
            reduced_block_sizes[bid] = get_local_size(0);
        }
    }

    // if last block, set block size to difference between n and block boundary
    if (lid == 0 && bid == get_num_groups(0) - 1) {
        reduced_block_sizes[bid] = n - (bid * get_local_size(0));
    }
}