                     //printf("score for thread %d location %d is %d with prev_score %d\n", thread_idx, j, score, prev_score);
                 }
 
-                // Load current max score from shared memory.
-                max_score = maxscore[thread_idx % WARP_SIZE];
+                // While there are changes to the horizontal score values, keep updating the matrix.
+                // So loop will only run the number of time there are corrections in the matrix.
+                // The any_sync warp primitive lets us easily check if any of the threads had an update.
+                bool loop = true;
+                while(__any_sync(0xffffffff, loop))
+                {
+                    loop = false;
+                    // The shfl_up lets us grab a value from the lane below.
+                    int16_t new_score = max(__shfl_up_sync(0xffffffff << 1, score, 1) + GAP, score);
+                    if (new_score > score)
+                    {
+                        loop = true;
+                        score = new_score;
+                    }
+                }
+
+                //printf("score after shuffle operations for thread %d location %d is %d\n", thread_idx, j, score);
+
+                // Move the score of the last thread in the warp to a variable
+                // into the first thread, so in the next warp the the first thread has a valid
+                // prev value.
+                //prev_score = __shfl_down_sync(0x1, score, 31);//score;
+
+                if (thread_idx == (WARP_SIZE - 1))
+                {
+                    prev_score[0] = score;
+                }
+
+                //if (thread_idx == 0)
+                //{
+                //    printf("previous score for thread %d is %d\n", thread_idx, prev_score);
+                //}
+            }
+
+            __syncthreads();
+
+            if (thread_idx >= WARP_SIZE)
+            {
+
+                if (thread_idx == WARP_SIZE)
+                {
+                    score = max(prev_score[0] + GAP, score);
+                    //printf("score for thread %d location %d is %d with prev_score %d\n", thread_idx, j, score, prev_score);
+                }
 
                 // While there are changes to the horizontal score values, keep updating the matrix.
                 // So loop will only run the number of time there are corrections in the matrix.

        scores[j] = j * GAP;
    }


    // Initialize the values to default.
    if (thread_idx < WARP_SIZE)
    {
        maxscore[thread_idx % WARP_SIZE] = SHRT_MIN;
        maxi[thread_idx % WARP_SIZE] = -1;
        maxj[thread_idx % WARP_SIZE] = -1;
    }

    __syncthreads();

    if (thread_idx == 0)
    {

                //{
                //    printf("previous score for thread %d is %d\n", thread_idx, prev_score);
                //}
            }

            
