WPacket handler

WPacket handler

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/'


Part one completed and working correctly

;;;
;;; put comments here
(defun counter (ele)
	(cond
	((listp ele)
		(counter_helper ele)
	)
	((atom ele)
		NIL
	)
	( T nil)
	)
)

(defun counter_helper (ele)
	(remove '-1
		(append (list (length ele)) (mapcar (function counter_helper_2) ele))
	))

(defun counter_helper_2 (ele)
	(cond
	((listp ele)
		(counter_helper ele)
	)
	((atom ele)
		-1
	)
	(T nil)
	)
)

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


moved tau_inf_final and V_inf_final calculations to after conductances are calculated, per Pete's suggestion

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@6622 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

inline
float LIF_Vmem_derivative(
      const float Vmem,
      const float G_E,
      const float G_I,
      const float G_IB,
      const float V_E,
      const float V_I,
      const float V_IB,
      const float Vrest,
      const float tau) {
   float totalconductance = 1.0 + G_E + G_I + G_IB;
   float Vmeminf = (Vrest + V_E*G_E + V_I*G_I + V_IB*G_IB)/totalconductance;
   return totalconductance*(Vmeminf-Vmem)/tau;
}
//
// update the state of a retinal layer (spiking)
//
//    assume called with 1D kernel
//
// LIF_update_state_original uses an Euler scheme for V where the conductances over the entire timestep are taken to be the values calculated at the end of the timestep
// LIF_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.
// LIF_update_state_arma uses an auto-regressive moving average filter for V, applying the GSyn at the start of the timestep and assuming that tau_inf and V_inf vary linearly over the timestep.  See van Hateren, Journal of Vision (2005), p. 331.
//
CL_KERNEL
void LIF_update_state_original(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#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_G_E  = G_E[k];
   float l_G_I  = G_I[k];
   float l_G_IB = G_IB[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];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];

   // 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
   //

   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);
   }

   l_G_E  = l_GSynExc  + l_G_E *exp_tauE;
   l_G_I  = l_GSynInh  + l_G_I *exp_tauI;
   l_G_IB = l_GSynInhB + 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
   //

   l_Vth = VthRest + (l_Vth - VthRest)*exp_tauVth;

   //
   // start of update_f
   //

   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;

   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;

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

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}

CL_KERNEL
void LIF_update_state_beginning(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#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];

   // 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];

   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];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];

   //
   // 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
   //

   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);
   }

   // 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;
   float dV1, dV2, dV;

   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;

   G_E_final = G_E_initial*exp_tauE;
   G_I_final = G_I_initial*exp_tauI;
   G_IB_final = G_IB_initial*exp_tauIB;

   dV1 = LIF_Vmem_derivative(l_V, G_E_initial, G_I_initial, G_IB_initial, Vexc, Vinh, VinhB, Vrest, tau);
   dV2 = LIF_Vmem_derivative(l_V+dt*dV1, G_E_final, G_I_final, G_IB_final, Vexc, Vinh, VinhB, 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 = VthRest + (l_Vth - VthRest)*exp_tauVth;
   // End of code unique to newer method.

   //
   // start of update_f
   //

   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;

   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;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}

CL_KERNEL
void LIF_update_state_arma(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#ifndef PV_USE_OPENCL

   for (k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
   { // compound statement so indentation is consistent with the for loop when not using PV_USE_OPENCL
#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];

      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];
      float l_GSynExc  = GSynExc[k];
      float l_GSynInh  = GSynInh[k];
      float l_GSynInhB = GSynInhB[k];

      //
      // 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
      //

      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);
      }

      // 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;
      float tau_inf_initial, tau_inf_final, V_inf_initial, V_inf_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;
      tau_inf_initial = tau/(1+G_E_initial+G_I_initial+G_IB_initial);
      V_inf_initial = (Vrest+Vexc*G_E_initial+Vinh*G_I_initial+VinhB*G_IB_initial)/(1+G_E_initial+G_I_initial+G_IB_initial);

      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;

      G_E_final = G_E_initial*exp_tauE;
      G_I_final = G_I_initial*exp_tauI;
      G_IB_final = G_IB_initial*exp_tauIB;

      tau_inf_final = tau/(1+G_E_final+G_I_final+G_IB_initial);
      V_inf_final = (Vrest+Vexc*G_E_final+Vinh*G_I_final+VinhB*G_IB_final)/(1+G_E_final+G_I_final+G_IB_final);

      float tau_slope = (tau_inf_final-tau_inf_initial)/dt;
      float f1 = tau_slope==0.0f ? EXP(-dt/tau_inf_initial) : powf(tau_inf_final/tau_inf_initial, -1/tau_slope);
      float f2 = tau_slope==-1.0f ? tau_inf_initial/dt*logf(tau_inf_final/tau_inf_initial+1.0f) :
                                    (1-tau_inf_initial/dt*(1-f1))/(1+tau_slope);
      float f3 = 1.0f - f1 - f2;
      l_V = f1*l_V + f2*V_inf_initial + f3*V_inf_final;

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

      l_Vth = VthRest + (l_Vth - VthRest)*exp_tauVth;
      // End of code unique to newer method.

      //
      // start of update_f
      //

      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;

      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;
   }

}

#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

inline
float LIF_Vmem_derivative(
      const float Vmem,
      const float G_E,
      const float G_I,
      const float G_IB,
      const float V_E,
      const float V_I,
      const float V_IB,
      const float Vrest,
      const float tau) {
   float totalconductance = 1.0 + G_E + G_I + G_IB;
   float Vmeminf = (Vrest + V_E*G_E + V_I*G_I + V_IB*G_IB)/totalconductance;
   return totalconductance*(Vmeminf-Vmem)/tau;
}
//
// update the state of a retinal layer (spiking)
//
//    assume called with 1D kernel
//
// LIF_update_state_original uses an Euler scheme for V where the conductances over the entire timestep are taken to be the values calculated at the end of the timestep
// LIF_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.
// LIF_update_state_arma uses an auto-regressive moving average filter for V, applying the GSyn at the start of the timestep and assuming that tau_inf and V_inf vary linearly over the timestep.  See van Hateren, Journal of Vision (2005), p. 331.
//
CL_KERNEL
void LIF_update_state_original(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#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_G_E  = G_E[k];
   float l_G_I  = G_I[k];
   float l_G_IB = G_IB[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];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];

   // 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
   //

   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);
   }

   l_G_E  = l_GSynExc  + l_G_E *exp_tauE;
   l_G_I  = l_GSynInh  + l_G_I *exp_tauI;
   l_G_IB = l_GSynInhB + 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
   //

   l_Vth = VthRest + (l_Vth - VthRest)*exp_tauVth;

   //
   // start of update_f
   //

   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;

   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;

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

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}

CL_KERNEL
void LIF_update_state_beginning(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#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];

   // 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];

   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];
   float l_GSynExc  = GSynExc[k];
   float l_GSynInh  = GSynInh[k];
   float l_GSynInhB = GSynInhB[k];

   //
   // 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
   //

   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);
   }

   // 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;
   float dV1, dV2, dV;

   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;

   G_E_final = G_E_initial*exp_tauE;
   G_I_final = G_I_initial*exp_tauI;
   G_IB_final = G_IB_initial*exp_tauIB;

   dV1 = LIF_Vmem_derivative(l_V, G_E_initial, G_I_initial, G_IB_initial, Vexc, Vinh, VinhB, Vrest, tau);
   dV2 = LIF_Vmem_derivative(l_V+dt*dV1, G_E_final, G_I_final, G_IB_final, Vexc, Vinh, VinhB, 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 = VthRest + (l_Vth - VthRest)*exp_tauVth;
   // End of code unique to newer method.

   //
   // start of update_f
   //

   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;

   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;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}

CL_KERNEL
void LIF_update_state_arma(
    const int numNeurons,
    const float time,
    const float dt,

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

    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 * 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

#ifndef PV_USE_OPENCL

   for (k = 0; k < nx*ny*nf; k++) {
#else
   k = get_global_id(0);
   { // compound statement so indentation is consistent with the for loop when not using PV_USE_OPENCL
#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];

      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];
      float l_GSynExc  = GSynExc[k];
      float l_GSynInh  = GSynInh[k];
      float l_GSynInhB = GSynInhB[k];

      //
      // 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
      //

      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);
      }

      // 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;
      float tau_inf_initial, tau_inf_final, V_inf_initial, V_inf_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;
      tau_inf_initial = tau/(1+G_E_initial+G_I_initial+G_IB_initial);
      V_inf_initial = (Vrest+Vexc*G_E_initial+Vinh*G_I_initial+VinhB*G_IB_initial)/(1+G_E_initial+G_I_initial+G_IB_initial);

      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;
      tau_inf_final = tau/(1+G_E_final+G_I_final+G_IB_initial);
      V_inf_final = (Vrest+Vexc*G_E_final+Vinh*G_I_final+VinhB*G_IB_final)/(1+G_E_final+G_I_final+G_IB_final);

      G_E_final = G_E_initial*exp_tauE;
      G_I_final = G_I_initial*exp_tauI;
      G_IB_final = G_IB_initial*exp_tauIB;

      float tau_slope = (tau_inf_final-tau_inf_initial)/dt;
      float f1 = tau_slope==0.0f ? EXP(-dt/tau_inf_initial) : powf(tau_inf_final/tau_inf_initial, -1/tau_slope);
      float f2 = tau_slope==-1.0f ? tau_inf_initial/dt*logf(tau_inf_final/tau_inf_initial+1.0f) :
                                    (1-tau_inf_initial/dt*(1-f1))/(1+tau_slope);
      float f3 = 1.0f - f1 - f2;
      l_V = f1*l_V + f2*V_inf_initial + f3*V_inf_final;

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

      l_Vth = VthRest + (l_Vth - VthRest)*exp_tauVth;
      // End of code unique to newer method.

      //
      // start of update_f
      //

      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;

      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;
   }

}


LIF update function which includes local Wmax and VthRest state variables.

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@3464 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, 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
   //
   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

}

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


Solve Vector addition problem using OpenCL

#include <wb.h> //@@ wb include opencl.h for you
#include <math.h>

//@@ OpenCL Kernel
const char* vaddsrc = "__kernel void vadd(__global const float *a,__global const float *b,__global float *result){ "
                      "int id = get_global_id(0);result[id] = a[id] + b[id];}";

int main(int argc, char** argv) {
    wbArg_t args;
    int inputLength;
    float* h_A;
    float* h_B;
    float* h_O;
    cl_mem d_A;
    cl_mem d_B;
    cl_mem d_O;

    args = wbArg_read(argc, argv);
    wbTime_start(Generic, "Importing data and creating memory on host");
    h_A = (float*)wbImport(wbArg_getInputFile(args, 0), &inputLength);
    h_B = (float*)wbImport(wbArg_getInputFile(args, 1), &inputLength);
    h_O = (float*)malloc(inputLength * sizeof(float));
    wbTime_stop(Generic, "Importing data and creating memory on host");
    wbLog(TRACE, "The input length is ", inputLength);
    int size = inputLength * sizeof(float);

    //Open CL contex setup
    size_t parmsz;
    cl_int clerr;
    cl_context clctx;
    cl_command_queue clcmdq;
    cl_program clpgm;
    cl_kernel clkern;

    cl_uint numPlatforms;
    clerr = clGetPlatformIDs(0, NULL, &numPlatforms);
    cl_platform_id platforms[numPlatforms];
    clerr = clGetPlatformIDs(numPlatforms, platforms, NULL);

    cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (unsigned long)platforms[0], 0};
    clctx = clCreateContextFromType(properties, CL_DEVICE_TYPE_ALL, NULL, NULL, &clerr);

    clerr = clGetContextInfo(clctx, CL_CONTEXT_DEVICES, 0, NULL, &parmsz);
    cl_device_id* cldevs = (cl_device_id*)malloc(parmsz);

    clerr = clGetContextInfo(clctx, CL_CONTEXT_DEVICES, parmsz, cldevs, NULL);
    clcmdq = clCreateCommandQueue(clctx, cldevs[0], 0, &clerr);

    //Complie and build program, and create kernel
    clpgm = clCreateProgramWithSource(clctx, 1, &vaddsrc, NULL, &clerr);
    char clcompileflags[4096];
    sprintf(clcompileflags, "-cl-mad-enable");
    clerr = clBuildProgram(clpgm, 0, NULL, clcompileflags, NULL, NULL);
    clkern = clCreateKernel(clpgm, "vadd", &clerr);

    wbTime_start(GPU, "Allocating + copy GPU memory.");
    //@@ Allocate GPU memory here Copy memory to the GPU here
    d_A = clCreateBuffer(clctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, size, h_A, NULL);
    d_B = clCreateBuffer(clctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, size, h_B, NULL);
    d_O = clCreateBuffer(clctx, CL_MEM_WRITE_ONLY, size, NULL, NULL);
    wbTime_stop(GPU, "Allocating + copy GPU memory.");

    size_t globalSize, localSize;
    localSize = 64;
    globalSize = ceil(inputLength / (float)localSize) * localSize;

    wbTime_start(Compute, "Performing CUDA computation");
    // Give params to kernel
    clerr = clSetKernelArg(clkern, 0, sizeof(cl_mem), (void*)&d_A);
    clerr = clSetKernelArg(clkern, 1, sizeof(cl_mem), (void*)&d_B);
    clerr = clSetKernelArg(clkern, 2, sizeof(cl_mem), (void*)&d_O);
    clerr = clSetKernelArg(clkern, 3, sizeof(int), &inputLength);

    //Run kernel and wait for it to finish
    cl_event event = NULL;
    clerr = clEnqueueNDRangeKernel(clcmdq, clkern, 1, NULL, &globalSize, &localSize, 0, NULL, &event);
    clerr = clWaitForEvents(1, &event);

    wbTime_stop(Compute, "Performing CUDA computation");

    wbTime_start(Copy, "Copying output memory to the CPU");
    clerr = clEnqueueReadBuffer(clcmdq, d_O, CL_TRUE, 0, size, h_O, 0, NULL, NULL);
    wbTime_stop(Copy, "Copying output memory to the CPU");

    wbTime_start(GPU, "Freeing GPU Memory");
    //@@ Free the GPU memory here
    clReleaseMemObject(d_A);
    clReleaseMemObject(d_B);
    clReleaseMemObject(d_O);
    wbTime_stop(GPU, "Freeing GPU Memory");
    wbSolution(args, h_O, inputLength);
    free(h_A);
    free(h_B);
    free(h_O);

    return 0;
}

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


Added vglClSwapRgb.cl

Added vglClSwapRgb.cl

/** Swap R and B channels.
  */
__kernel void vglClSwapRgb(__read_only image2d_t src, __write_only image2d_t dst)
{
	int2 coords = (int2)(get_global_id(0), get_global_id(1));
	const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | //Natural coordinates
                              CLK_ADDRESS_CLAMP |           //Clamp to zeros
                              CLK_FILTER_NEAREST;           //Don't interpolate
	float4 p = read_imagef(src, smp, coords);
        float  f;

	f = p.x;
	p.x = p.z;
        p.z = f;

	write_imagef(dst, coords, p);
}

error: pathspec 'src/CL/vglClSwapRgb.cl' did not match any file(s) known to git


Add inline file

Add inline file

;; @main
(main)

;; @extend
(defclass Object () (()))

;; @Fault
(defclass Fault () ((msg :initform "Fault")))

;; @SoftwareFault;@Fault
(defclass SoftwareFault (Fault) ())

;; @catch;@SoftwareFault
(defun libbun-catch (e)
  (cond ((eq (type-of e) 'Fault) e)
        ((or (eq (type-of e) 'division-by-zero) ; sbcl
             (eq (type-of e) 'system::simple-division-by-zero)) ; clisp
         (let ((e1 (make-instance 'SoftwareFault)))
           (setf (slot-value e1 'msg) "division-by-zero")
           e1))
        (t e)))

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


Renamed cr012 to co012

Renamed cr012 to co012

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/'


how long was this not in the repo?

how long was this not in the repo?

//// MODULE_NAME: INDEX
//// MODULE_HEADER:

#define INDEX(a,b,c)	((a) + solver->gridSize.x * ((b) + solver->gridSize.y * (c)))

//// MODULE_NAME: INDEXV
//// MODULE_DEPENDS: <?=solver_t?>
//// MODULE_HEADER:

#define INDEXV(i)		indexForInt4ForSize(i, solver->gridSize.x, solver->gridSize.y, solver->gridSize.z)

//// MODULE_NAME: OOB
//// MODULE_HEADER:
// this only test for bounds of valid mesh cell

#define OOB(lhs,rhs) (index >= get_global_size(0))

//// MODULE_NAME: SETBOUNDS
//// MODULE_DEPENDS: OOB
//// MODULE_HEADER:

#define SETBOUNDS(lhs,rhs)	\
	int index = get_global_id(0); \
	int4 i = (int4)(index,0,0,0);	\
	if (OOB(0,0)) return;

//// MODULE_NAME: SETBOUNDS_NOGHOST
//// MODULE_DEPENDS: OOB
//// MODULE_HEADER:
// this uses OOB only to test if the cell is valid

#define SETBOUNDS_NOGHOST()	\
	int index = get_global_id(0); \
	int4 i = (int4)(index,0,0,0); \
	if (OOB(0,0)) return;

//// MODULE_NAME: calcFlux
//// MODULE_DEPENDS: face_t normal_t calcFluxForInterface cell_t
// boundary code, since meshsolver doesn't use gridsolver's boundary:
<?=cons_t?> reflectCons(
	<?=cons_t?> U,
	real3 n,
	float restitution
) {
<?
-- matches BoundaryMirror:getCode for vectorComponent==cartesian
for _,var in ipairs(eqn.consStruct.vars) do
	if var.type == 'real'
	or var.type == 'cplx'
	then
		-- do nothing
	elseif var.type == 'real3'
	or var.type == 'cplx3'
	then
		local field = var.name
		local scalar = var.type == 'cplx3' and 'cplx' or 'real'
		local vec3 = var.type
?>
	U.<?=field?> = <?=vec3?>_sub(
		U.<?=field?>,
		<?=vec3?>_<?=scalar?>_mul(
			<?=vec3?>_from_real3(n),
			<?=scalar?>_real_mul(
				<?=vec3?>_real3_dot(
					U.<?=field?>,
					n
				),
				restitution + 1.
			)
		)
	);
<?
	else
		error("need to support reflect() for type "..var.type)
	end
end
?>	return U;
}

void getEdgeStates(
	<?=cons_t?>* UL,
	<?=cons_t?>* UR,
	const global <?=face_t?>* e,
	const global <?=cons_t?>* UBuf,		//[numCells]
	real restitution
) {
	int iL = e->cells.s0;
	int iR = e->cells.s1;
	if (iL != -1 && iR != -1) {
		*UL = UBuf[iL];
		*UR = UBuf[iR];
	} else if (iL != -1) {
		*UL = UBuf[iL];
		//TODO
		*UR = reflectCons(*UL, e->normal, restitution);
	} else if (iR != -1) {
		*UR = UBuf[iR];
		//TODO
		*UL = reflectCons(*UR, e->normal, restitution);
	} else {	// both iL and iR are null ...
		//error
		for (int i = 0; i < numStates; ++i) {
			UL->ptr[i] = UR->ptr[i] = 0./0.;
		}
	}
}

kernel void calcFlux(
	constant <?=solver_t?>* solver,
	global <?=cons_t?>* fluxBuf,
	const global <?=cons_t?>* UBuf,
	realparam dt,
//mesh-specific parameters:
	const global <?=cell_t?>* cells,			//[numCells]
	const global <?=face_t?>* faces,			//[numFaces]
	const global int* cellFaceIndexes	//[numCellFaceIndexes]
) {
	typedef <?=cons_t?> cons_t;
	typedef <?=eigen_t?> eigen_t;
	typedef <?=waves_t?> waves_t;

	int faceIndex = get_global_id(0);
	if (faceIndex >= get_global_size(0)) return;

	global <?=cons_t?>* flux = fluxBuf + faceIndex;

	const global <?=face_t?>* face = faces + faceIndex;
	if (face->area <= 1e-7) {
		for (int j = 0; j < numStates; ++j) {
			flux->ptr[j] = 0;
		}
		return;
	}

	real3 x = face->pos;
	normal_t n = normal_forFace(face);

	<?=cons_t?> UL, UR;
	getEdgeStates(&UL, &UR, face, UBuf, solver->boundaryRestitution);

	//TODO option to rotate to align fluxes?
	// then you'd have to build a new normal_t based on the aligned (x-axis) normal.

	*flux = calcFluxForInterface(solver, UL, UR, x, n);
}

//// MODULE_NAME: calcDerivFromFlux
//// MODULE_DEPENDS: <?=solver_t?> <?=cons_t?> cell_t <?=solver_macros?> SETBOUNDS_NOGHOST

kernel void calcDerivFromFlux(
	constant <?=solver_t?>* solver,
	global <?=cons_t?>* derivBuf,
	const global <?=cons_t?>* fluxBuf,
//mesh-specific parameters:
	const global <?=cell_t?>* cells,			//[numCells]
	const global <?=face_t?>* faces,			//[numFaces]
	const global int* cellFaceIndexes	//[numCellFaceIndexes]
) {
	int cellIndex = get_global_id(0);
	if (cellIndex >= get_global_size(0)) return;

	const global <?=cell_t?>* cell = cells + cellIndex;

	global <?=cons_t?>* deriv = derivBuf + cellIndex;

	for (int i = 0; i < cell->faceCount; ++i) {
		int ei = cellFaceIndexes[i + cell->faceOffset];
		const global <?=face_t?>* e = faces + ei;

		const global <?=cons_t?>* flux = fluxBuf + ei;
		real areaOverVolume = e->area / cell->volume;

		if (cellIndex == e->cells.s0) {
//std::cout << " ... - " << *e << std::endl;
			for (int j = 0; j < numIntStates; ++j) {
				deriv->ptr[j] -= flux->ptr[j] * areaOverVolume;
			}
		} else {
//std::cout << " ... + " << *e << std::endl;
			for (int j = 0; j < numIntStates; ++j) {
				deriv->ptr[j] += flux->ptr[j] * areaOverVolume;
			}
		}
	}
}

error: pathspec 'hydro/solver/meshsolver.cl' did not match any file(s) known to git


Added safe math version for native_ functions in OpenCL

/**********************************************************************
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.

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.
********************************************************************/

/*************************************************************************
DEFINES
**************************************************************************/
#define PI 3.14159265358979323846f
#define KERNEL __kernel
#define GLOBAL __global
#define INLINE __attribute__((always_inline))
#define HIT_MARKER 1
#define MISS_MARKER -1
#define INVALID_IDX -1

/*************************************************************************
EXTENSIONS
**************************************************************************/
#ifdef AMD_MEDIA_OPS
#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable
#endif

/*************************************************************************
TYPES
**************************************************************************/

// Axis aligned bounding box
typedef struct
{
    float4 pmin;
    float4 pmax;
} bbox;

// Ray definition
typedef struct
{
    float4 o;
    float4 d;
    int2 extra;
    int2 padding;
} ray;

// Intersection definition
typedef struct
{
    int shape_id;
    int prim_id;
    int2 padding;

    float4 uvwt;
} Intersection;

/*************************************************************************
HELPER FUNCTIONS
**************************************************************************/
INLINE
int ray_get_mask(ray const* r)
{
    return r->extra.x;
}

INLINE
int ray_is_active(ray const* r)
{
    return r->extra.y;
}

INLINE
float ray_get_maxt(ray const* r)
{
    return r->o.w;
}

INLINE
float ray_get_time(ray const* r)
{
    return r->d.w;
}

/*************************************************************************
FUNCTIONS
**************************************************************************/
#ifndef APPLE
INLINE
float4 make_float4(float x, float y, float z, float w)
{
    float4 res;
    res.x = x;
    res.y = y;
    res.z = z;
    res.w = w;
    return res;
}
INLINE
float3 make_float3(float x, float y, float z)
{
    float3 res;
    res.x = x;
    res.y = y;
    res.z = z;
    return res;
}
INLINE
float2 make_float2(float x, float y)
{
    float2 res;
    res.x = x;
    res.y = y;
    return res;
}
INLINE
int2 make_int2(int x, int y)
{
    int2 res;
    res.x = x;
    res.y = y;
    return res;
}
INLINE
int3 make_int3(int x, int y, int z)
{
    int3 res;
    res.x = x;
    res.y = y;
    res.z = z;
    return res;
}
#endif

INLINE float min3(float a, float b, float c)
{
#ifdef AMD_MEDIA_OPS
    return amd_min3(a, b, c);
#else
    return min(min(a,b), c);
#endif
}

INLINE float max3(float a, float b, float c)
{
#ifdef AMD_MEDIA_OPS
    return amd_max3(a, b, c);
#else
    return max(max(a,b), c);
#endif
}

// Intersect ray against a triangle and return intersection interval value if it is in
// (0, t_max], return t_max otherwise.
INLINE
float fast_intersect_triangle(ray r, float3 v1, float3 v2, float3 v3, float t_max)
{
    float3 const e1 = v2 - v1;
    float3 const e2 = v3 - v1;
    float3 const s1 = cross(r.d.xyz, e2);

	#ifdef USE_SAFE_MATH
	float const invd = 1.0/(dot(s1, e1));
	#else
    float const invd = native_recip(dot(s1, e1));
	#endif

    float3 const d = r.o.xyz - v1;
    float const b1 = dot(d, s1) * invd;
    float3 const s2 = cross(d, e1);
    float const b2 = dot(r.d.xyz, s2) * invd;
    float const temp = dot(e2, s2) * invd;

    if (b1 < 0.f || b1 > 1.f || b2 < 0.f || b1 + b2 > 1.f || temp < 0.f || temp > t_max)
    {
        return t_max;
    }
    else
    {
        return temp;
    }
}

INLINE
float3 safe_invdir(ray r)
{
#ifdef USE_SAFE_MATH
    float const dirx = r.d.x;
    float const diry = r.d.y;
    float const dirz = r.d.z;
    float const ooeps = exp2(-80.0f); // Avoid div by zero.
    float3 invdir;
    invdir.x = 1.0f / (fabs(dirx) > ooeps ? dirx : copysign(ooeps, dirx));
    invdir.y = 1.0f / (fabs(diry) > ooeps ? diry : copysign(ooeps, diry));
    invdir.z = 1.0f / (fabs(dirz) > ooeps ? dirz : copysign(ooeps, dirz));
    return invdir;
#else
    return native_recip(r.d.xyz);
#endif
}

// Intersect rays vs bbox and return intersection span.
// Intersection criteria is ret.x <= ret.y
INLINE
float2 fast_intersect_bbox1(bbox box, float3 invdir, float3 oxinvdir, float t_max)
{
    float3 const f = mad(box.pmax.xyz, invdir, oxinvdir);
    float3 const n = mad(box.pmin.xyz, invdir, oxinvdir);
    float3 const tmax = max(f, n);
    float3 const tmin = min(f, n);
    float const t1 = min(min3(tmax.x, tmax.y, tmax.z), t_max);
    float const t0 = max(max3(tmin.x, tmin.y, tmin.z), 0.f);
    return make_float2(t0, t1);
}

// Given a point in triangle plane, calculate its barycentrics
INLINE
float2 triangle_calculate_barycentrics(float3 p, float3 v1, float3 v2, float3 v3)
{
    float3 const e1 = v2 - v1;
    float3 const e2 = v3 - v1;
    float3 const e = p - v1;
    float const d00 = dot(e1, e1);
    float const d01 = dot(e1, e2);
    float const d11 = dot(e2, e2);
    float const d20 = dot(e, e1);
    float const d21 = dot(e, e2);

	#ifdef USE_SAFE_MATH
		float const invdenom = 1.0 / (d00 * d11 - d01 * d01);
	#else
		float const invdenom = native_recip(d00 * d11 - d01 * d01);
	#endif

    float const b1 = (d11 * d20 - d01 * d21) * invdenom;
    float const b2 = (d00 * d21 - d01 * d20) * invdenom;
    return make_float2(b1, b2);
}

/**********************************************************************
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.

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.
********************************************************************/

/*************************************************************************
DEFINES
**************************************************************************/
#define PI 3.14159265358979323846f
#define KERNEL __kernel
#define GLOBAL __global
#define INLINE __attribute__((always_inline))
#define HIT_MARKER 1
#define MISS_MARKER -1
#define INVALID_IDX -1

/*************************************************************************
EXTENSIONS
**************************************************************************/
#ifdef AMD_MEDIA_OPS
#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable
#endif

/*************************************************************************
TYPES
**************************************************************************/

// Axis aligned bounding box
typedef struct
{
    float4 pmin;
    float4 pmax;
} bbox;

// Ray definition
typedef struct
{
    float4 o;
    float4 d;
    int2 extra;
    int2 padding;
} ray;

// Intersection definition
typedef struct
{
    int shape_id;
    int prim_id;
    int2 padding;

    float4 uvwt;
} Intersection;

/*************************************************************************
HELPER FUNCTIONS
**************************************************************************/
INLINE
int ray_get_mask(ray const* r)
{
    return r->extra.x;
}

INLINE
int ray_is_active(ray const* r)
{
    return r->extra.y;
}

INLINE
float ray_get_maxt(ray const* r)
{
    return r->o.w;
}

INLINE
float ray_get_time(ray const* r)
{
    return r->d.w;
}

/*************************************************************************
FUNCTIONS
**************************************************************************/
#ifndef APPLE
INLINE
float4 make_float4(float x, float y, float z, float w)
{
    float4 res;
    res.x = x;
    res.y = y;
    res.z = z;
    res.w = w;
    return res;
}
INLINE
float3 make_float3(float x, float y, float z)
{
    float3 res;
    res.x = x;
    res.y = y;
    res.z = z;
    return res;
}
INLINE
float2 make_float2(float x, float y)
{
    float2 res;
    res.x = x;
    res.y = y;
    return res;
}
INLINE
int2 make_int2(int x, int y)
{
    int2 res;
    res.x = x;
    res.y = y;
    return res;
}
INLINE
int3 make_int3(int x, int y, int z)
{
    int3 res;
    res.x = x;
    res.y = y;
    res.z = z;
    return res;
}
#endif

INLINE float min3(float a, float b, float c)
{
#ifdef AMD_MEDIA_OPS
    return amd_min3(a, b, c);
#else
    return min(min(a,b), c);
#endif
}

INLINE float max3(float a, float b, float c)
{
#ifdef AMD_MEDIA_OPS
    return amd_max3(a, b, c);
#else
    return max(max(a,b), c);
#endif
}

// Intersect ray against a triangle and return intersection interval value if it is in
// (0, t_max], return t_max otherwise.
INLINE
float fast_intersect_triangle(ray r, float3 v1, float3 v2, float3 v3, float t_max)
{
    float3 const e1 = v2 - v1;
    float3 const e2 = v3 - v1;
    float3 const s1 = cross(r.d.xyz, e2);
    float const invd = native_recip(dot(s1, e1));
    float3 const d = r.o.xyz - v1;
    float const b1 = dot(d, s1) * invd;
    float3 const s2 = cross(d, e1);
    float const b2 = dot(r.d.xyz, s2) * invd;
    float const temp = dot(e2, s2) * invd;

    if (b1 < 0.f || b1 > 1.f || b2 < 0.f || b1 + b2 > 1.f || temp < 0.f || temp > t_max)
    {
        return t_max;
    }
    else
    {
        return temp;
    }
}

INLINE
float3 safe_invdir(ray r)
{
#ifdef USE_SAFE_MATH
    float const dirx = r.d.x;
    float const diry = r.d.y;
    float const dirz = r.d.z;
    float const ooeps = exp2(-80.0f); // Avoid div by zero.
    float3 invdir;
    invdir.x = 1.0f / (fabs(dirx) > ooeps ? dirx : copysign(ooeps, dirx));
    invdir.y = 1.0f / (fabs(diry) > ooeps ? diry : copysign(ooeps, diry));
    invdir.z = 1.0f / (fabs(dirz) > ooeps ? dirz : copysign(ooeps, dirz));
    return invdir;
#else
    return native_recip(r.d.xyz);
#endif
}

// Intersect rays vs bbox and return intersection span.
// Intersection criteria is ret.x <= ret.y
INLINE
float2 fast_intersect_bbox1(bbox box, float3 invdir, float3 oxinvdir, float t_max)
{
    float3 const f = mad(box.pmax.xyz, invdir, oxinvdir);
    float3 const n = mad(box.pmin.xyz, invdir, oxinvdir);
    float3 const tmax = max(f, n);
    float3 const tmin = min(f, n);
    float const t1 = min(min3(tmax.x, tmax.y, tmax.z), t_max);
    float const t0 = max(max3(tmin.x, tmin.y, tmin.z), 0.f);
    return make_float2(t0, t1);
}

// Given a point in triangle plane, calculate its barycentrics
INLINE
float2 triangle_calculate_barycentrics(float3 p, float3 v1, float3 v2, float3 v3)
{
    float3 const e1 = v2 - v1;
    float3 const e2 = v3 - v1;
    float3 const e = p - v1;
    float const d00 = dot(e1, e1);
    float const d01 = dot(e1, e2);
    float const d11 = dot(e2, e2);
    float const d20 = dot(e, e1);
    float const d21 = dot(e, e2);
    float const invdenom = native_recip(d00 * d11 - d01 * d01);
    float const b1 = (d11 * d20 - d01 * d21) * invdenom;
    float const b2 = (d00 * d21 - d01 * d20) * invdenom;
    return make_float2(b1, b2);
}


Implement half_sqrt and native_sqrt in x86_64 kernel code as well

/* OpenCL built-in library: sqrt()

   Copyright (c) 2011 Universidad Rey Juan Carlos

   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"

#define IMPLEMENT_DIRECT(NAME, TYPE, EXPR)      \
  TYPE _cl_overloadable NAME(TYPE a)            \
  {                                             \
    typedef TYPE type;                          \
    return EXPR;                                \
  }

#define IMPLEMENT_UPCAST(NAME, TYPE, UPTYPE, LO)        \
  TYPE _cl_overloadable NAME(TYPE a)                    \
  {                                                     \
    return NAME(*(UPTYPE*)&a).LO;                       \
  }

#define IMPLEMENT_SPLIT(NAME, TYPE, LO, HI)     \
  TYPE _cl_overloadable NAME(TYPE a)            \
  {                                             \
    return (TYPE)(NAME(a.LO), NAME(a.HI));      \
  }

#define IMPLEMENT_SQRT_DIRECT_FLOAT  __builtin_sqrtf(a)
#define IMPLEMENT_SQRT_DIRECT_DOUBLE __builtin_sqrt(a)
#define IMPLEMENT_SQRT_SSE_FLOAT                \
  ({                                            \
    __asm__ ("sqrtss %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE_FLOAT4               \
  ({                                            \
    __asm__ ("sqrtps %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_AVX_FLOAT8               \
  ({                                            \
    __asm__ ("sqrtps256 %[dst], %[dst]" :       \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE2_DOUBLE              \
  ({                                            \
    __asm__ ("sqrtsd %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE2_DOUBLE2             \
  ({                                            \
    __asm__ ("sqrtpd %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_AVX_DOUBLE4              \
  ({                                            \
    __asm__ ("sqrtpd256 %[dst], %[dst]" :       \
             [dst] "+x" (a));                   \
    a;                                          \
  })

#ifdef __SSE__
IMPLEMENT_DIRECT(sqrt, float  , IMPLEMENT_SQRT_SSE_FLOAT)
IMPLEMENT_UPCAST(sqrt, float2 , float4, lo)
IMPLEMENT_UPCAST(sqrt, float3 , float4, s012)
IMPLEMENT_DIRECT(sqrt, float4 , IMPLEMENT_SQRT_SSE_FLOAT4)
#  ifdef __AVX__
IMPLEMENT_DIRECT(sqrt, float8 , IMPLEMENT_SQRT_AVX_FLOAT8)
#  else
IMPLEMENT_SPLIT (sqrt, float8 , lo, hi)
#  endif
#else
IMPLEMENT_DIRECT(sqrt, float  , IMPLEMENT_SQRT_DIRECT_FLOAT)
IMPLEMENT_SPLIT (sqrt, float2 , lo, hi)
IMPLEMENT_SPLIT (sqrt, float3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, float4 , lo, hi)
IMPLEMENT_SPLIT (sqrt, float8 , lo, hi)
#endif
IMPLEMENT_SPLIT (sqrt, float16, lo, hi)

#ifdef __SSE2__
IMPLEMENT_DIRECT(sqrt, double  , IMPLEMENT_SQRT_SSE2_DOUBLE)
IMPLEMENT_DIRECT(sqrt, double2 , IMPLEMENT_SQRT_SSE2_DOUBLE2)
#  ifdef __AVX__
IMPLEMENT_UPCAST(sqrt, double3 , double4, s012)
IMPLEMENT_DIRECT(sqrt, double4 , IMPLEMENT_SQRT_AVX_DOUBLE4)
#  else
IMPLEMENT_SPLIT (sqrt, double3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, double4 , lo, hi)
#  endif
#else
IMPLEMENT_DIRECT(sqrt, double  , IMPLEMENT_SQRT_DIRECT_DOUBLE)
IMPLEMENT_SPLIT (sqrt, double2 , lo, hi)
IMPLEMENT_SPLIT (sqrt, double3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, double4 , lo, hi)
#endif
IMPLEMENT_SPLIT (sqrt, double8 , lo, hi)
IMPLEMENT_SPLIT (sqrt, double16, lo, hi)

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

/* OpenCL built-in library: sqrt()

   Copyright (c) 2011 Universidad Rey Juan Carlos

   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.
*/

#define IMPLEMENT_DIRECT(NAME, TYPE, EXPR)      \
  TYPE _cl_overloadable NAME(TYPE a)            \
  {                                             \
    typedef TYPE type;                          \
    return EXPR;                                \
  }

#define IMPLEMENT_UPCAST(NAME, TYPE, UPTYPE, LO)        \
  TYPE _cl_overloadable NAME(TYPE a)                    \
  {                                                     \
    return NAME(*(UPTYPE*)&a).LO;                       \
  }

#define IMPLEMENT_SPLIT(NAME, TYPE, LO, HI)     \
  TYPE _cl_overloadable NAME(TYPE a)            \
  {                                             \
    return (TYPE)(NAME(a.LO), NAME(a.HI));      \
  }

#define IMPLEMENT_SQRT_DIRECT_FLOAT  __builtin_sqrtf(a)
#define IMPLEMENT_SQRT_DIRECT_DOUBLE __builtin_sqrt(a)
#define IMPLEMENT_SQRT_SSE_FLOAT                \
  ({                                            \
    __asm__ ("sqrtss %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE_FLOAT4               \
  ({                                            \
    __asm__ ("sqrtps %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_AVX_FLOAT8               \
  ({                                            \
    __asm__ ("sqrtps256 %[dst], %[dst]" :       \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE2_DOUBLE              \
  ({                                            \
    __asm__ ("sqrtsd %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_SSE2_DOUBLE2             \
  ({                                            \
    __asm__ ("sqrtpd %[dst], %[dst]" :          \
             [dst] "+x" (a));                   \
    a;                                          \
  })
#define IMPLEMENT_SQRT_AVX_DOUBLE4              \
  ({                                            \
    __asm__ ("sqrtpd256 %[dst], %[dst]" :       \
             [dst] "+x" (a));                   \
    a;                                          \
  })

#ifdef __SSE__
IMPLEMENT_DIRECT(sqrt, float  , IMPLEMENT_SQRT_SSE_FLOAT)
IMPLEMENT_UPCAST(sqrt, float2 , float4, lo)
IMPLEMENT_UPCAST(sqrt, float3 , float4, s012)
IMPLEMENT_DIRECT(sqrt, float4 , IMPLEMENT_SQRT_SSE_FLOAT4)
#  ifdef __AVX__
IMPLEMENT_DIRECT(sqrt, float8 , IMPLEMENT_SQRT_AVX_FLOAT8)
#  else
IMPLEMENT_SPLIT (sqrt, float8 , lo, hi)
#  endif
#else
IMPLEMENT_DIRECT(sqrt, float  , IMPLEMENT_SQRT_DIRECT_FLOAT)
IMPLEMENT_SPLIT (sqrt, float2 , lo, hi)
IMPLEMENT_SPLIT (sqrt, float3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, float4 , lo, hi)
IMPLEMENT_SPLIT (sqrt, float8 , lo, hi)
#endif
IMPLEMENT_SPLIT (sqrt, float16, lo, hi)

#ifdef __SSE2__
IMPLEMENT_DIRECT(sqrt, double  , IMPLEMENT_SQRT_SSE2_DOUBLE)
IMPLEMENT_DIRECT(sqrt, double2 , IMPLEMENT_SQRT_SSE2_DOUBLE2)
#  ifdef __AVX__
IMPLEMENT_UPCAST(sqrt, double3 , double4, s012)
IMPLEMENT_DIRECT(sqrt, double4 , IMPLEMENT_SQRT_AVX_DOUBLE4)
#  else
IMPLEMENT_SPLIT (sqrt, double3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, double4 , lo, hi)
#  endif
#else
IMPLEMENT_DIRECT(sqrt, double  , IMPLEMENT_SQRT_DIRECT_DOUBLE)
IMPLEMENT_SPLIT (sqrt, double2 , lo, hi)
IMPLEMENT_SPLIT (sqrt, double3 , lo, s2)
IMPLEMENT_SPLIT (sqrt, double4 , lo, hi)
#endif
IMPLEMENT_SPLIT (sqrt, double8 , lo, hi)
IMPLEMENT_SPLIT (sqrt, double16, lo, hi)


added cl code

added cl code

void __kernel unary_plus(__global double * a, __global double * b, __const int n){
  int i = get_global_id(0);
  if (i > n) return;
  a[i] += b[i];
}

void __kernel unary_minus(__global double * a, __global double * b, __const int n){
  int i = get_global_id(0);
  if (i > n) return;
  a[i] -= b[i];
}

void __kernel unary_times(__global double * a, __global double * b, __const int n){
  int i = get_global_id(0);
  if (i > n) return;
  a[i] *= b[i];
}

void __kernel unary_divide(__global double * a, __global double * b, __const int n){
  int i = get_global_id(0);
  if (i > n) return;
  a[i] /= b[i];
}

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


Fixed bug in name of l_activ

Fixed bug in name of l_activ

git-svn-id: 602a26e73ae9f2a14e2bb95676f2e137fcc39919@3369 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_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(
    const float time,
    const float dt,

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

    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 * activity)
{
   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
   //

   // local param variables
   float tau, tauE, tauI, tauIB, tauRate, Vrest, VthRest, Vexc, Vinh, VinhB, tauVth, deltaVth;

   float dt_sec;
   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_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];

   // temporary arrays
   float tauInf, VmemInf;

   //
   // start of LIF2_update_exact_linear
   //

   // define local param variables
   //
   tau   = params->tau;
   tauE  = params->tauE;
   tauI  = params->tauI;
   tauIB = params->tauIB;

   Vrest = params->Vrest;
   Vexc  = params->Vexc;
   Vinh  = params->Vinh;
   VinhB = params->VinhB;

   tauRate  = params->tauRate;
   tauVth   = params->tauVth;
   VthRest  = params->VthRest;
   deltaVth = params->deltaVth;

   // add noise
   //
   dt_sec = .001 * dt;   // convert to seconds

   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);
   }

   l_G_E  = l_phiExc  + l_G_E *EXP(-dt/tauE );
   l_G_I  = l_phiInh  + l_G_I *EXP(-dt/tauI );
   l_G_IB = l_phiInhB + l_G_IB*EXP(-dt/tauIB);

   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
   //

   l_phiExc  = 0.0f;
   l_phiInh  = 0.0f;
   l_phiInhB = 0.0f;

   l_Vth = VthRest + (l_Vth - VthRest)*EXP(-dt/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;

   l_activ = activity[kex];

   l_activ = (l_V > l_Vth) ? 1.0f           : 0.0f;
   l_V     = (l_V > l_Vth) ? Vrest          : l_V;
   l_Vth   = (l_V > l_Vth) ? l_Vth + deltaVth : l_Vth;
   l_G_IB  = (l_V > l_Vth) ? l_G_IB + 1.0f    : l_G_IB;

   // update average rate
   l_R = l_activ + l_R*EXP(-dt/tauRate);

   //
   // 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
   //
   activity[kex] = l_activ;

   R[k] = l_R;

   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]  = l_phiExc;
   phiInh[k]  = l_phiInh;
   phiInhB[k] = l_phiInhB;

#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_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(
    const float time,
    const float dt,

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

    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 * activity)
{
   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
   //

   // local param variables
   float tau, tauE, tauI, tauIB, tauRate, Vrest, VthRest, Vexc, Vinh, VinhB, tauVth, deltaVth;

   float dt_sec;
   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_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];

   // temporary arrays
   float tauInf, VmemInf;

   //
   // start of LIF2_update_exact_linear
   //

   // define local param variables
   //
   tau   = params->tau;
   tauE  = params->tauE;
   tauI  = params->tauI;
   tauIB = params->tauIB;

   Vrest = params->Vrest;
   Vexc  = params->Vexc;
   Vinh  = params->Vinh;
   VinhB = params->VinhB;

   tauRate  = params->tauRate;
   tauVth   = params->tauVth;
   VthRest  = params->VthRest;
   deltaVth = params->deltaVth;

   // add noise
   //
   dt_sec = .001 * dt;   // convert to seconds

   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);
   }

   l_G_E  = l_phiExc  + l_G_E *EXP(-dt/tauE );
   l_G_I  = l_phiInh  + l_G_I *EXP(-dt/tauI );
   l_G_IB = l_phiInhB + l_G_IB*EXP(-dt/tauIB);

   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
   //

   l_phiExc  = 0.0f;
   l_phiInh  = 0.0f;
   l_phiInhB = 0.0f;

   l_Vth = VthRest + (l_Vth - VthRest)*EXP(-dt/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;

   l_activ = activity[kex];

   l_activ = (l_V > l_Vth) ? 1.0f           : 0.0f;
   l_V     = (l_V > l_Vth) ? Vrest          : l_V;
   l_Vth   = (l_V > l_Vth) ? l_Vth + deltaVth : l_Vth;
   l_G_IB  = (l_V > l_Vth) ? l_G_IB + 1.0f    : l_G_IB;

   // update average rate
   l_R = l_active + l_R*EXP(-dt/tauRate);

   //
   // 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
   //
   activity[kex] = l_activ;

   R[k] = l_R;

   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]  = l_phiExc;
   phiInh[k]  = l_phiInh;
   phiInhB[k] = l_phiInhB;

#ifndef PV_USE_OPENCL
   } // loop over k
#endif

}


fixed xyBlend

fixed xyBlend

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/Saytiras/Massively-Parallel-Algorithms.git/'


Updated cl filename. Expecting use of multiple types in future

inline int get_index(int nelems, int index ) {
/* Fetch a linear index to work on given # of elements
 * and previous index. -1 if start
 */

  if (index == -1)  {
    index = get_global_id(0);
  } else {
    index += get_global_size(0);
  }

  if (index >= nelems) index = -1;

  return index;
}

__kernel void add(__global float *out, __global const float *x, __global const float *y, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] + y[id];
    id = get_index(N, id);
  }
}

__kernel void minus(__global float *out, __global const float *x, __global const float *y, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] - y[id];
    id = get_index(N, id);
  }
}

__kernel void divide(__global float *out, __global const float *x, __global const float *y, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] /  y[id];
    id = get_index(N, id);
  }
}

__kernel void times(__global float *out, __global const float *x, __global const float *y, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] *  y[id];
    id = get_index(N, id);
  }
}

__kernel void scalar_times(__global float *out, float w, global const float *x, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = w * x[id];
    id = get_index(N, id);
  }
}

__kernel void scalar_add(__global float *out, float w, global const float *x, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = w + x[id];
    id = get_index(N, id);
  }
}

__kernel void scalar_minus(__global float *out, float w, global const float *x, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = w - x[id];
    id = get_index(N, id);
  }
}

__kernel void minus_scalar(__global float *out, global const float *x, float w, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] - w;
    id = get_index(N, id);
  }
}

__kernel void scalar_divide(__global float *out, float w, global const float *x, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = w / x[id];
    id = get_index(N, id);
  }
}

__kernel void divide_scalar(__global float *out, global const float *x, float w, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = x[id] / w;
    id = get_index(N, id);
  }
}

__kernel void exponential(__global float *out, __global const float *x, int N) {
  int id = get_index(N, -1);
  while(id >= 0) {
    out[id] = exp(x[id]);
    id = get_index(N, id);
  }
}

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


Added William Halliburton <whalliburton@gmail.com>'s tracing macro to extras folder.

;; Tracing macro courtesy of William Halliburton
;; <whalliburton@gmail.com>, logs to Firebug console

;; On a happier note here is a macro I wrote to enable
;; tracing-ala-cl. Works with firebug. You'll need to (defvar
;; *trace-level*). I don't do indentation but that would be an easy
;; addition.

(defpsmacro console (&rest rest)
  `(console.log ,@rest))

(defpsmacro defun-trace (name args &rest body)
  (let* ((sname (ps::symbol-to-js name))
         (tname (ps-gensym name))
         (arg-names (loop for arg in args
                       unless (eq arg '&optional)
                       collect (if (consp arg) (car arg) arg)))
         (argpairs
          (loop for arg in arg-names
             nconc (list (ps::symbol-to-js arg) arg))))
    `(progn
       (defun ,name ,arg-names
         (console *trace-level* ,sname ":" ,@argpairs)
         (incf *trace-level*)
         (let* ((rtn (,tname ,@arg-names)))
           (decf *trace-level*)
           (console *trace-level* ,sname "returned" rtn)
           (return rtn)))
       (defun ,tname ,args
         ,@body))))

error: pathspec 'extras/firebug-tracing.cl' did not match any file(s) known to git


OpenCL implementation of XOR128 PRNG

OpenCL implementation of XOR128 PRNG

/******************************************************************************
 * @file     prngcl_xor128.cl
 * @author   Vadim Demchik <vadimdi@yahoo.com>
 * @version  1.1
 *
 * @brief    [PRNGCL library]
 *           contains OpenCL implementation of XOR128 pseudo-random number generator
 *
 *
 * @section  CREDITS
 *
 *   George Marsaglia,
 *   "Xorshift RNGs",
 *   Journal of Statistical Software, 8, 14 (2003), 1--6.
 *
 *
 * @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_XOR128_CL
#define PRNGCL_XOR128_CL

#include "prngcl_common.cl"

#define XOR128_m_FP   (4294967296.0f)
#define XOR128_min    1
#define XOR128_max    4294967295
#define XOR128_min_FP (1.0/4294967296.0)
#define XOR128_max_FP (4294967295.0/4294967296.0)
#define XOR128_k      (2.3283064365386962890625E-10) // 1/2^32
#define XOR128_left   (XOR128_min_FP+XOR128_k*XOR128_max_FP)
#define XOR128_right  (XOR128_max_FP+XOR128_k*XOR128_min_FP)

//________________________________________________________________________________________________________ XOR128 PRNG
__attribute__((always_inline)) uint4
xor128_step(uint4 seed)
{
    uint4 result;
    uint t = (seed.x^(seed.x<<11));

	result.x = seed.y;
	result.y = seed.z;
	result.z = seed.w;
	result.w = (seed.w^(seed.w>>19))^(t^(t>>8));

    return result;
}

#ifdef PRECISION_DOUBLE  // if double precision is defined
__attribute__((always_inline)) hgpu_double
xor128_step_double(uint4* seed)
{
    hgpu_double result;
    uint rnd1, rnd2;
    uint4 sed = (*seed);
    bool flag = true;
    sed = xor128_step(sed);
    rnd1 = sed.w;
    while (flag) {
        sed = xor128_step(sed);
        rnd2 = sed.w;
        result = hgpu_uint_to_double(rnd1,rnd2,XOR128_min,XOR128_max,XOR128_k);
        if ((result>=XOR128_left) && (result<XOR128_right))
            flag = false;
        else
            rnd1 = rnd2;
    }
    (*seed) = sed;
    return result;
}
#endif

__kernel void
xor128(__global uint4* seed_table,
                     __global hgpu_float4* randoms,
                     const uint N)
{
    uint giddst = GID;
#ifdef PRECISION_DOUBLE  // if double precision is defined
    hgpu_double4 result;
#else
    float4 result;
    float4 normal = (float4) XOR128_m_FP;
#endif
    uint4 seed = seed_table[GID];
    for (uint i = 0; i < N; i++) {
#ifdef PRECISION_DOUBLE // if double precision is defined
        result.x = xor128_step_double(&seed);
        result.y = xor128_step_double(&seed);
        result.z = xor128_step_double(&seed);
        result.w = xor128_step_double(&seed);
        randoms[giddst] = result;
#else
        seed = xor128_step(seed);
        result.x = (float) seed.w;
        seed = xor128_step(seed);
        result.y = (float) seed.w;
        seed = xor128_step(seed);
        result.z = (float) seed.w;
        seed = xor128_step(seed);
        result.w = (float) seed.w;
        randoms[giddst] = result / normal;
#endif
        giddst += GID_SIZE;
    }
    seed_table[GID] = seed;
}

#endif

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


modify define

modify define