 	{
 		shRight[tid] = left[tid];
         __syncthreads();
-        if (tid1 == blockDim.x) shRight[tid] = shRight[tid-1];
+        if (tid1 == blockDim.x) shRight[tid] = shRight[tid-2];
 	}
 	else
 	{
 		shRight[tid] = left[gid+blockDim.x];
-        if (gid == 0) shLeft[tid-1] = shLeft[tid];
+        if (gid == 0) shLeft[tid] = shLeft[tid2];
 	}
 
 	if (tid < 2)


	extern __shared__ REAL share[];

	REAL *temper = (REAL*) share;
	REAL *shRight = (REAL*) &share[2*blockDim.x+4];
	REAL *shLeft = (REAL*) &share[3*blockDim.x+4];

	int gid = blockDim.x * blockIdx.x + threadIdx.x; //Global Thread ID
	int tid = threadIdx.x; //Block Thread ID

__global__ void wholeDiamond(REAL *right, REAL *left)
{

    extern __shared__ REAL share[];

	REAL *temper = (REAL*) share;
	REAL *shRight = (REAL*) &share[2*blockDim.x+4];
	REAL *shLeft = (REAL*) &share[3*blockDim.x+4];

	int gid = blockDim.x * blockIdx.x + threadIdx.x; //Global Thread ID
	int tid = threadIdx.x; //Block Thread ID
	int tid1 = tid + 1;
	int tid2 = tid + 2;
	//int height = blockDim.x/2;
	int shft_wr; //Initialize the shift to the written row of temper.
	int shft_rd; //Initialize the shift to the read row (opposite of written)
	int logic_position;
	int itr = 0;

	//int base = THREADBLK + 2;
	//int height = THREADBLK/2;

    shLeft[tid] = right[gid];

	if (blockIdx.x == (gridDim.x-1))
	{
		shRight[tid] = left[tid];
        __syncthreads();
        if (tid1 == blockDim.x) shRight[tid] = shRight[tid-1];
	}
	else
	{
		shRight[tid] = left[gid+blockDim.x];
        if (gid == 0) shLeft[tid] = shLeft[tid2];
	}

	if (tid < 2)
	{
		temper[tid] = shLeft[tid];
		temper[tid+2] = shRight[tid];
	}


    for (int k = 2; k < blockDim.x; k+=2)
	{
		logic_position = (k/2 & 1);
		shift_wr = blockDim.x*logic_position;
		//On even iterations write to second row (starts at element 32)
		shft_rd = blockDim.x*((logic_position+1) & 1);

		if (tid < 2)
		{
			temper[tid + shft_wr] = shLeft[tid+k];
			temper[tid2 + k + shft_wr] = shRight[tid+k];
		}

		if (tid < (k+2) && tid > 1)
		{
			temper[tid + shft_wr] = execFunc(temper[tid+shift_rd], temper[(tid-2)+shift_rd], temper[(tid-1)+shift_rd]);
		}
        __syncthreads();
	}

    temper[tid] = execFunc(temper[tid+blockDim.x], temper[tid2+blockDim.x], temper[tid1+blockDim.x]);

    __syncthreads(); // Then make sure each block of threads are synced.

    //-------------------TOP PART------------------------------------------

    int itr = 0;

	//The initial conditions are timeslice 0 so start k at 1.
	for (int k = 30; k>1 ; k-=2)
	{
		//Bitwise even odd. On even iterations write to first row.
		logic_position = (k/2 & 1);
		shift_wr = blockDim.x*logic_position;
		//On even iterations write to second row (starts at element 32)
		shft_rd = blockDim.x*((logic_position+1) & 1);

		//Each iteration the triangle narrows.  When k = 1, 30 points are
		//computed, k = 2, 28 points.
		if (tid <= k)
		{
			temper[tid + shft_wr] = execFunc(temper[tid+shift_rd], temper[tid2+shift_rd], temper[tid1+shift_rd]);
		}

		//Make sure the threads are synced
		__syncthreads();

		//Really tricky to get unique values with threads.
		if (shft_wr && tid < 4)
		{
			shLeft[tid+itr] = temper[(tid & 1) + (tid/2 * blockDim.x)]; // Still baroque.
			shRight[tid+itr] = temper[(right_pick[tid] + k) + (tid/2 * blockDim.x)];
			itr += 4;
		}

		__syncthreads();

	}

	//After the triangle has been computed, the right and left shared arrays are
	//stored in global memory by the global thread ID since (conveniently),
	//they're the same size as a warp!
	right[gid] = shRight[tid];
	left[gid] = shLeft[tid];

