thrust doesn't provided the expected result using thrust::minimum - cuda

consider the following code, when p is a pointer allocated GPU-side.
thrust::device_ptr<float> pWrapper(p);
thrust::device_ptr<float> fDevPos = thrust::min_element(pWrapper, pWrapper + MAXX * MAXY, thrust::minimum<float>());
fRes = *fDevPos;
*fDicVal = fRes;
after applying the same thing on cpu side.
float *hVec = new float[MAXX * MAXY];
cudaMemcpy(hVec, p, MAXX*MAXY*sizeof(float), cudaMemcpyDeviceToHost);
float min = 999;
int index = -1;
for(int i = 0 ; i < MAXX* MAXY; i++)
{
if(min > hVec[i])
{
min = hVec[i];
index = i;
}
}
printf("index :%d a wrapper : %f, as vectorDevice : %f\n",index, fRes, min);
delete hVec;
i get that min != fRes. what am i doing wrong here?

thrust::minimum_element requires the user to supply a comparison predicate. That is, a function which answers the yes-or-no question "is x smaller than y?"
thrust::minimum is not a predicate; it answers the question "which of x or y is smaller?".
To find the smallest element using minimum_element, pass the thrust::less predicate:
ptr_to_smallest_value = thrust::min_element(first, last, thrust::less<T>());
Alternatively, don't pass anything. thrust::less is the default:
ptr_to_smallest_value = thrust::min_element(first, last);
If all you're interested in is the value of the smallest element (not an iterator pointing to the smallest element), you can combine thrust::minimum with thrust::reduce:
smallest_value = thrust::reduce(first, last, std::numeric_limits<T>::max(), thrust::minimum<T>());

Related

Tackling imbalanced class members in Caffe: weight contribution of each instance to loss value

I have a highly imbalanced data, I know that some users suggesting using InfoGainLoss loss function, however, I am facing few errors when I tried to add this function to Caffe layers.
I have the following questions, I really appreciate if someone guides me:
How can I add this layer to Caffe? Does anyone know any sources/ codes of this layer?
I want to apply it for image segmentation and the proportion of some classes varies. How can I create the H matrix (a stack of weights) for my images? And how infoGainLoss layer can read a specific weight matrix (H) related to that specific image?
After adding the cpp and cu version of InforGainLoss layer to caffe, should I remake Caffe?
I am sorry for few question, but all are my concern and related to each other. I will be thankful to get some help and support.
Thanks
1.If you copy from current infogain_loss_layer.cpp you can easily adapt. For forward pass change line 59-66 like:
// assuming num = batch size, dim = label size, image_dim = image height * width
Dtype loss = 0;
for (int i = 0; i < num; ++i) {
for(int k = 0; k < image_dim; k++) {
int label = static_cast<int>(bottom_label[i*image_dim+k]);
for (int j = 0; j < dim; ++j) {
Dtype prob = std::max(bottom_data[i *image_dim *dim+ k * dim + j], Dtype(kLOG_THRESHOLD));
loss -= infogain_mat[label * dim + j] * log(prob);
}
}
}
Similarly for backward pass you could change line 95-101 like:
for (int i = 0; i < num; ++i) {
for(int k = 0; k < image_dim; k++) {
const int label = static_cast<int>(bottom_label[i*image_dim+k]);
for (int j = 0; j < dim; ++j) {
Dtype prob = std::max(bottom_data[i *image_dim *dim+ k * dim + j], Dtype(kLOG_THRESHOLD));
bottom_diff[i *image_dim *dim+ k * dim + j] = scale * infogain_mat[label * dim + j] / prob;
}
}
}
This is kind of naive. I don't seem to find any option for optimization. You will also need to change some setup code in reshape.
2.In this PR suggestion is that for diagonal entries in H put min_count/|i| where |i| is the number of samples has label i. Everything else as 0. Also see this . As for loading the weight matrix H is fixed for all input. You can load it as lmdb file or in other ways.
3.Yes you will need to rebuild.
Update:
As Shai pointed out the infogain pull for this has already been approved this week. So current version of caffe supports pixelwise infogain loss.

Matrix Multiplication of matrix and its transpose in Cuda

I am relatively new to CUDA programming so there are some unsolved issues for which I hope I can get some hints in the right direction.
So the case is that I want to multiply a 2D array with its transpose and to be precise I want to execute the operation ATA.
I have already used the cublas Dgemm function and now I am trying to do the same operation with a tiled algorithm, very similar to the one from CUDA guide.
The case is that while the initial algorithm runs properly, I want to calculate only the upper triangular matrix of the product hoping that I could achieve a better time for the operation, and I am not sure on how to extract tiles/blocks which will have the respective elements.
So if you could enlighten me on this, or give any hint I would be grateful, cause I have stuck on that for a while.
This is the code of the kernel
__shared__ double Ads1[TILE_WIDTH][TILE_WIDTH];
__shared__ double Ads2[TILE_WIDTH][TILE_WIDTH];
//block row and column
//we save in registers for faster access
int by = blockIdx.y;
int bx = blockIdx.x;
int ty = threadIdx.y;
int tx = threadIdx.x;
int row = by * TILE_WIDTH + ty;
int col = bx * TILE_WIDTH + tx;
double Rvalue = 0;
if(row >= width || col >= width) return;
//Each thread block computes one sub-matrix Rsub of result R
for (int i=0; i<(int) ceil(((double) height/TILE_WIDTH)); ++i)
{
Ads1[tx][ty] = Ad[(i * TILE_WIDTH + ty)*width + col];
Ads2[tx][ty] = Ad[(i * TILE_WIDTH + tx)*width + row];
__syncthreads();
for (int j = 0; j < TILE_WIDTH; ++j)
{
if ((i*TILE_WIDTH + j) > height ) break; //in order not to exceed the matrix's height
Rvalue+=Ads1[j][tx]*Ads2[ty][j];
}
__syncthreads();
}
Rd [row * width + col] = Rvalue;
You may want to use the batch dgemm API function described here recursely dividing your output matrix with block diagonal and corner. You also want to balance smallest block size versus overhead in compute to avoid small invokes. Finally, note that matrix multiply turns memory bound at some stage, which can be on modern GPU somewhat large.

CUDA and Monte Carlo with local behavior defined

I have a question about a strange behavior In CUDA.
I am currently developing a Monte Carlo simulation on particles trajectories and I am doing the following the thing.
The position p(n) of my particle at a given date t(n) depends on the position t(n-1) of my particle at the previous date t(n-1). Indeed, let’s say the value v(n) is computed from the value p(n-1). Here is a simplified example of my code:
__device__ inline double calculateStep( double drift, double vol, double dt, double randomWalk, double S_t){
return exp((drift - vol*vol*0.5)*dt + randomWalk*vol*sqrt(dt))*S_t;
}
__device__ double doSomethingWhith(double v_n, ….) {
...
Return v_n*exp(t)*S
}
__global__ myMCsimulation( double* matrice, double * randomWalk, int nbreSimulation, int nPaths, double drift, ……) {
double dt = T/nPaths;
unsigned int tid = threadIdx.x + blockDim.x * blockIdx.x;
unsigned int stride = blockDim.x*gridDim.x;
unsigned int index = tid;
double mydt = (index - nbreSimulation)/nbreSimulation*dt + dt;
for ( index = tid; index < nbreSimulation*nPaths; index += stride) {
if (index >= nbreSimulation)
{
double v_n = DoSomethingWith(drift,dt, matrice[index – nbreSimulation]);
matrice[index] = matrice[index - nbreSimulation ] * calculateStep(drift,v_n,dt,randomWalk[index]); //
}
...}
The last code line :
matrice[index] = matrice[index - nbreSimulation ] * calculateStep(drift,v_n,dt,randomWalk[index]);
enables me to fill in only the second row of the matrix matrice. I don’t know why.
When I change the code line by :
matrice[index] = DoSomethingWith(drift,dt, matrice[index – nbreSimulation]);
My matrix is well filled in and I have all my values changed, then I am able to get back the matrice[index – nbreSimulation].
I think this is a concurrent access but I am not sure, I tried __syncthreads() but it did not work.
Could someone please help on this point?
Many thanks
I have changed my code by the following thing and now it works perfectly.
if (index < nbreSimulation) {
matrice[index] = S0;
for (workingCol=1; workingCol< nPaths; workingCol++) {
previousMove = index;
index = index + nbreSimulation;
................
matrice[index] = calculateStep(drift,vol_int[index],dt,randomWalk[index], matrice[previousMove]); }
}
}
I have tried the following thing :
I have declared a shared variable (an array of doubles) which contains the value computed at each iteration :
__shared__ double mat[];
......
for ( index = tid; index < nbreSimulation*nPaths; index += stride) {
.....
mat[index] = computedValue;
......
}
Without success. Does anyone see the issue?

Removal of every 'kth' person from a circle. Find the last remaining person

As part of a recent job application I was asked to code a solution to this problem.
Given,
n = number of people standing in a circle.
k = number of people to count over each time
Each person is given a unique (incrementing) id. Starting with the first person (the lowest id), they begin counting from 1 to k.
The person at k is then removed and the circle closes up. The next remaining person (following the eliminated person) resumes counting at 1. This process repeats until only one person is left, the winner.
The solution must provide:
the id of each person in the order they are removed from the circle
the id of the winner.
Performance constraints:
Use as little memory as possible.
Make the solution run as fast as possible.
I remembered doing something similar in my CS course from years ago but could not recall the details at the time of this test. I now realize it is a well known, classic problem with multiple solutions. (I will not mention it by name yet as some may just 'wikipedia' an answer).
I've already submitted my solution so I'm absolutely not looking for people to answer it for me. I will provide it a bit later once/if others have provided some answers.
My main goal for asking this question is to see how my solution compares to others given the requirements and constraints.
(Note the requirements carefully as I think they may invalidate some of the 'classic' solutions.)
Manuel Gonzalez noticed correctly that this is the general form of the famous Josephus problem.
If we are only interested in the survivor f(N,K) of a circle of size N and jumps of size K, then we can solve this with a very simple dynamic programming loop (In linear time and constant memory). Note that the ids start from 0:
int remaining(int n, int k) {
int r = 0;
for (int i = 2; i <= n; i++)
r = (r + k) % i;
return r;
}
It is based on the following recurrence relation:
f(N,K) = (f(N-1,K) + K) mod N
This relation can be explained by simulating the process of elimination, and after each elimination re-assigning new ids starting from 0. The old indices are the new ones with a circular shift of k positions. For a more detailed explanation of this formula, see http://blue.butler.edu/~phenders/InRoads/MathCounts8.pdf.
I know that the OP asks for all the indices of the eliminated items in their correct order. However, I believe that the above insight can be used for solving this as well.
You can do it using a boolean array.
Here is a pseudo code:
Let alive be a boolean array of size N. If alive[i] is true then ith person is alive else dead. Initially it is true for every 1>=i<=N
Let numAlive be the number of persons alive. So numAlive = N at start.
i = 1 # Counting starts from 1st person.
count = 0;
# keep looping till we've more than 1 persons.
while numAlive > 1 do
if alive[i]
count++
end-if
# time to kill ?
if count == K
print Person i killed
numAlive --
alive[i] = false
count = 0
end-if
i = (i%N)+1 # Counting starts from next person.
end-while
# Find the only alive person who is the winner.
while alive[i] != true do
i = (i%N)+1
end-while
print Person i is the winner
The above solution is space efficient but not time efficient as the dead persons are being checked.
To make it more efficient time wise you can make use of a circular linked list. Every time you kill a person you delete a node from the list. You continue till a single node is left in the list.
The problem of determining the 'kth' person is called the Josephus Problem.
Armin Shams-Baragh from Ferdowsi University of Mashhad published some formulas for the Josephus Problem and the extended version of it.
The paper is available at: http://www.cs.man.ac.uk/~shamsbaa/Josephus.pdf
This is my solution, coded in C#. What could be improved?
public class Person
{
public Person(int n)
{
Number = n;
}
public int Number { get; private set; }
}
static void Main(string[] args)
{
int n = 10; int k = 4;
var circle = new List<Person>();
for (int i = 1; i <= n; i++)
{
circle.Add(new Person(i));
}
var index = 0;
while (circle.Count > 1)
{
index = (index + k - 1) % circle.Count;
var person = circle[index];
circle.RemoveAt(index);
Console.WriteLine("Removed {0}", person.Number);
}
Console.ReadLine();
}
Console.WriteLine("Winner is {0}", circle[0].Number);
Essentially the same as Ash's answer, but with a custom linked list:
using System;
using System.Linq;
namespace Circle
{
class Program
{
static void Main(string[] args)
{
Circle(20, 3);
}
static void Circle(int k, int n)
{
// circle is a linked list representing the circle.
// Each element contains the index of the next member
// of the circle.
int[] circle = Enumerable.Range(1, k).ToArray();
circle[k - 1] = 0; // Member 0 follows member k-1
int prev = -1; // Used for tracking the previous member so we can delete a member from the list
int curr = 0; // The member we're currently inspecting
for (int i = 0; i < k; i++) // There are k members to remove from the circle
{
// Skip over n members
for (int j = 0; j < n; j++)
{
prev = curr;
curr = circle[curr];
}
Console.WriteLine(curr);
circle[prev] = circle[curr]; // Delete the nth member
curr = prev; // Start counting again from the previous member
}
}
}
}
Here is a solution in Clojure:
(ns kthperson.core
(:use clojure.set))
(defn get-winner-and-losers [number-of-people hops]
(loop [people (range 1 (inc number-of-people))
losers []
last-scan-start-index (dec hops)]
(if (= 1 (count people))
{:winner (first people) :losers losers}
(let [people-to-filter (subvec (vec people) last-scan-start-index)
additional-losers (take-nth hops people-to-filter)
remaining-people (difference (set people)
(set additional-losers))
new-losers (concat losers additional-losers)
index-of-last-removed-person (* hops (count additional-losers))]
(recur remaining-people
new-losers
(mod last-scan-start-index (count people-to-filter)))))))
Explanation:
start a loop, with a collection of people 1..n
if there is only one person left, they are the winner and we return their ID, as well as the IDs of the losers (in order of them losing)
we calculate additional losers in each loop/recur by grabbing every N people in the remaining list of potential winners
a new, shorter list of potential winners is determined by removing the additional losers from the previously-calculated potential winners.
rinse & repeat (using modulus to determine where in the list of remaining people to start counting the next time round)
This is a variant of the Josephus problem.
General solutions are described here.
Solutions in Perl, Ruby, and Python are provided here. A simple solution in C using a circular doubly-linked list to represent the ring of people is provided below. None of these solutions identify each person's position as they are removed, however.
#include <stdio.h>
#include <stdlib.h>
/* remove every k-th soldier from a circle of n */
#define n 40
#define k 3
struct man {
int pos;
struct man *next;
struct man *prev;
};
int main(int argc, char *argv[])
{
/* initialize the circle of n soldiers */
struct man *head = (struct man *) malloc(sizeof(struct man));
struct man *curr;
int i;
curr = head;
for (i = 1; i < n; ++i) {
curr->pos = i;
curr->next = (struct man *) malloc(sizeof(struct man));
curr->next->prev = curr;
curr = curr->next;
}
curr->pos = n;
curr->next = head;
curr->next->prev = curr;
/* remove every k-th */
while (curr->next != curr) {
for (i = 0; i < k; ++i) {
curr = curr->next;
}
curr->prev->next = curr->next;
curr->next->prev = curr->prev;
}
/* announce last person standing */
printf("Last person standing: #%d.\n", curr->pos);
return 0;
}
Here's my answer in C#, as submitted. Feel free to criticize, laugh at, ridicule etc ;)
public static IEnumerable<int> Move(int n, int k)
{
// Use an Iterator block to 'yield return' one item at a time.
int children = n;
int childrenToSkip = k - 1;
LinkedList<int> linkedList = new LinkedList<int>();
// Set up the linked list with children IDs
for (int i = 0; i < children; i++)
{
linkedList.AddLast(i);
}
LinkedListNode<int> currentNode = linkedList.First;
while (true)
{
// Skip over children by traversing forward
for (int skipped = 0; skipped < childrenToSkip; skipped++)
{
currentNode = currentNode.Next;
if (currentNode == null) currentNode = linkedList.First;
}
// Store the next node of the node to be removed.
LinkedListNode<int> nextNode = currentNode.Next;
// Return ID of the removed child to caller
yield return currentNode.Value;
linkedList.Remove(currentNode);
// Start again from the next node
currentNode = nextNode;
if (currentNode== null) currentNode = linkedList.First;
// Only one node left, the winner
if (linkedList.Count == 1) break;
}
// Finally return the ID of the winner
yield return currentNode.Value;
}

Cummulative array summation using OpenCL

I'm calculating the Euclidean distance between n-dimensional points using OpenCL. I get two lists of n-dimensional points and I should return an array that contains just the distances from every point in the first table to every point in the second table.
My approach is to do the regular doble loop (for every point in Table1{ for every point in Table2{...} } and then do the calculation for every pair of points in paralell.
The euclidean distance is then split in 3 parts:
1. take the difference between each dimension in the points
2. square that difference (still for every dimension)
3. sum all the values obtained in 2.
4. Take the square root of the value obtained in 3. (this step has been omitted in this example.)
Everything works like a charm until I try to accumulate the sum of all differences (namely, executing step 3. of the procedure described above, line 49 of the code below).
As test data I'm using DescriptorLists with 2 points each:
DescriptorList1: 001,002,003,...,127,128; (p1)
129,130,131,...,255,256; (p2)
DescriptorList2: 000,001,002,...,126,127; (p1)
128,129,130,...,254,255; (p2)
So the resulting vector should have the values: 128, 2064512, 2130048, 128
Right now I'm getting random numbers that vary with every run.
I appreciate any help or leads on what I'm doing wrong. Hopefully everything is clear about the scenario I'm working in.
#define BLOCK_SIZE 128
typedef struct
{
//How large each point is
int length;
//How many points in every list
int num_elements;
//Pointer to the elements of the descriptor (stored as a raw array)
__global float *elements;
} DescriptorList;
__kernel void CompareDescriptors_deb(__global float *C, DescriptorList A, DescriptorList B, int elements, __local float As[BLOCK_SIZE])
{
int gpidA = get_global_id(0);
int featA = get_local_id(0);
//temporary array to store the difference between each dimension of 2 points
float dif_acum[BLOCK_SIZE];
//counter to track the iterations of the inner loop
int loop = 0;
//loop over all descriptors in A
for (int i = 0; i < A.num_elements/BLOCK_SIZE; i++){
//take the i-th descriptor. Returns a DescriptorList with just the i-th
//descriptor in DescriptorList A
DescriptorList tmpA = GetDescriptor(A, i);
//copy the current descriptor to local memory.
//returns one element of the only descriptor in DescriptorList tmpA
//and index featA
As[featA] = GetElement(tmpA, 0, featA);
//wait for all the threads to finish copying before continuing
barrier(CLK_LOCAL_MEM_FENCE);
//loop over all the descriptors in B
for (int k = 0; k < B.num_elements/BLOCK_SIZE; k++){
//take the difference of both current points
dif_acum[featA] = As[featA]-B.elements[k*BLOCK_SIZE + featA];
//wait again
barrier(CLK_LOCAL_MEM_FENCE);
//square value of the difference in dif_acum and store in C
//which is where the results should be stored at the end.
C[loop] = 0;
C[loop] += dif_acum[featA]*dif_acum[featA];
loop += 1;
barrier(CLK_LOCAL_MEM_FENCE);
}
}
}
Your problem lies in these lines of code:
C[loop] = 0;
C[loop] += dif_acum[featA]*dif_acum[featA];
All threads in your workgroup (well, actually all your threads, but lets come to to that later) are trying to modify this array position concurrently without any synchronization whatsoever. Several factors make this really problematic:
The workgroup is not guaranteed to work completely in parallel, meaning that for some threads C[loop] = 0 can be called after other threads have already executed the next line
Those that execute in parallel all read the same value from C[loop], modify it with their increment and try to write back to the same address. I'm not completely sure what the result of that writeback is (I think one of the threads succeeds in writing back, while the others fail, but I'm not completely sure), but its wrong either way.
Now lets fix this:
While we might be able to get this to work on global memory using atomics, it won't be fast, so lets accumulate in local memory:
local float* accum;
...
accum[featA] = dif_acum[featA]*dif_acum[featA];
barrier(CLK_LOCAL_MEM_FENCE);
for(unsigned int i = 1; i < BLOCKSIZE; i *= 2)
{
if ((featA % (2*i)) == 0)
accum[featA] += accum[featA + i];
barrier(CLK_LOCAL_MEM_FENCE);
}
if(featA == 0)
C[loop] = accum[0];
Of course you can reuse other local buffers for this, but I think the point is clear (btw: Are you sure that dif_acum will be created in local memory, because I think I read somewhere that this wouldn't be put in local memory, which would make preloading A into local memory kind of pointless).
Some other points about this code:
Your code is seems to be geared to using only on workgroup (you aren't using either groupid nor global id to see which items to work on), for optimal performance you might want to use more then that.
Might be personal preferance, but I to me it seems better to use get_local_size(0) for the workgroupsize than to use a Define (since you might change it in the host code without realizing you should have changed your opencl code to)
The barriers in your code are all unnecessary, since no thread accesses an element in local memory which is written by another thread. Therefore you don't need to use local memory for this.
Considering the last bullet you could simply do:
float As = GetElement(tmpA, 0, featA);
...
float dif_acum = As-B.elements[k*BLOCK_SIZE + featA];
This would make the code (not considering the first two bullets):
__kernel void CompareDescriptors_deb(__global float *C, DescriptorList A, DescriptorList B, int elements, __local float accum[BLOCK_SIZE])
{
int gpidA = get_global_id(0);
int featA = get_local_id(0);
int loop = 0;
for (int i = 0; i < A.num_elements/BLOCK_SIZE; i++){
DescriptorList tmpA = GetDescriptor(A, i);
float As = GetElement(tmpA, 0, featA);
for (int k = 0; k < B.num_elements/BLOCK_SIZE; k++){
float dif_acum = As-B.elements[k*BLOCK_SIZE + featA];
accum[featA] = dif_acum[featA]*dif_acum[featA];
barrier(CLK_LOCAL_MEM_FENCE);
for(unsigned int i = 1; i < BLOCKSIZE; i *= 2)
{
if ((featA % (2*i)) == 0)
accum[featA] += accum[featA + i];
barrier(CLK_LOCAL_MEM_FENCE);
}
if(featA == 0)
C[loop] = accum[0];
barrier(CLK_LOCAL_MEM_FENCE);
loop += 1;
}
}
}
Thanks to Grizzly, I have now a working kernel. Some things I needed to modify based in the answer of Grizzly:
I added an IF statement at the beginning of the routine to discard all threads that won't reference any valid position in the arrays I'm using.
if(featA > BLOCK_SIZE){return;}
When copying the first descriptor to local (shared) memory (i.g. to Bs), the index has to be specified since the function GetElement returns just one element per call (I skipped that on my question).
Bs[featA] = GetElement(tmpA, 0, featA);
Then, the SCAN loop needed a little tweaking because the buffer is being overwritten after each iteration and one cannot control which thread access the data first. That is why I'm 'recycling' the dif_acum buffer to store partial results and that way, prevent inconsistencies throughout that loop.
dif_acum[featA] = accum[featA];
There are also some boundary control in the SCAN loop to reliably determine the terms to be added together.
if (featA >= j && next_addend >= 0 && next_addend < BLOCK_SIZE){
Last, I thought it made sense to include the loop variable increment within the last IF statement so that only one thread modifies it.
if(featA == 0){
C[loop] = accum[BLOCK_SIZE-1];
loop += 1;
}
That's it. I still wonder how can I make use of group_size to eliminate that BLOCK_SIZE definition and if there are better policies I can adopt regarding thread usage.
So the code looks finally like this:
__kernel void CompareDescriptors(__global float *C, DescriptorList A, DescriptorList B, int elements, __local float accum[BLOCK_SIZE], __local float Bs[BLOCK_SIZE])
{
int gpidA = get_global_id(0);
int featA = get_local_id(0);
//global counter to store final differences
int loop = 0;
//auxiliary buffer to store temporary data
local float dif_acum[BLOCK_SIZE];
//discard the threads that are not going to be used.
if(featA > BLOCK_SIZE){
return;
}
//loop over all descriptors in A
for (int i = 0; i < A.num_elements/BLOCK_SIZE; i++){
//take the gpidA-th descriptor
DescriptorList tmpA = GetDescriptor(A, i);
//copy the current descriptor to local memory
Bs[featA] = GetElement(tmpA, 0, featA);
//loop over all the descriptors in B
for (int k = 0; k < B.num_elements/BLOCK_SIZE; k++){
//take the difference of both current descriptors
dif_acum[featA] = Bs[featA]-B.elements[k*BLOCK_SIZE + featA];
//square the values in dif_acum
accum[featA] = dif_acum[featA]*dif_acum[featA];
barrier(CLK_LOCAL_MEM_FENCE);
//copy the values of accum to keep consistency once the scan procedure starts. Mostly important for the first element. Two buffers are necesarry because the scan procedure would override values that are then further read if one buffer is being used instead.
dif_acum[featA] = accum[featA];
//Compute the accumulated sum (a.k.a. scan)
for(int j = 1; j < BLOCK_SIZE; j *= 2){
int next_addend = featA-(j/2);
if (featA >= j && next_addend >= 0 && next_addend < BLOCK_SIZE){
dif_acum[featA] = accum[featA] + accum[next_addend];
}
barrier(CLK_LOCAL_MEM_FENCE);
//copy As to accum
accum[featA] = GetElementArray(dif_acum, BLOCK_SIZE, featA);
barrier(CLK_LOCAL_MEM_FENCE);
}
//tell one of the threads to write the result of the scan in the array containing the results.
if(featA == 0){
C[loop] = accum[BLOCK_SIZE-1];
loop += 1;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
}
}