 
     __shared__ int16_t prev_score[1];
 
-    // Storing max score, i and j for every thread.
-    // The values will be replicated across threads to
-    // minimize bank confliects when reading the values.
-    __shared__ int16_t maxscore[WARP_SIZE];
-    __shared__ int16_t maxi[WARP_SIZE];
-    __shared__ int16_t maxj[WARP_SIZE];
-
     uint32_t thread_idx = threadIdx.x;
 
     long long int start = clock64();

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

                // Only update max score if we reach the end of the read.
                bool update = false;
                if (j == read_count && out_edge_count == 0)
                {
                    if (max_score < score)
                    {
                        update = true;
                        //printf("thread_idx %d i %d j %d\n", thread_idx,i, j);
                    }
                }

                // If max score is updated in any of the threads, then write
                // out that max score into all banks of the smem
                // so that each thread can access it in parallel. Otherwise
                // if they are written to the same location, there will be
                // bank conflicts and it will serialize the access
                // to the variable.
                if (__any_sync(0xffffffff, update))
                {
                    uint32_t val_thread = (read_count - 1) % WARP_SIZE;
                    max_score = __shfl_sync(0xffffffff, score, val_thread);
                    maxscore[thread_idx % WARP_SIZE] = max_score;
                    maxi[thread_idx % WARP_SIZE] = __shfl_sync(0xffffffff, i, val_thread);
                    maxj[thread_idx % WARP_SIZE] = __shfl_sync(0xffffffff, j, val_thread);

                }
            }

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

                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;
                uint8_t count = 0;
                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;
                    }
                    count++;
                }

                //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 == (2 * WARP_SIZE - 1))
                {
                    prev_score[0] = score;
                }

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

                // Only update max score if we reach the end of the read.
                bool update = false;
                if (j == read_count && out_edge_count == 0)
                {
                    if (max_score < score)
                    {
                        update = true;
                        //printf("thread_idx %d i %d j %d\n", thread_idx,i, j);
                    }
                }

                if (__any_sync(0xffffffff, update))
                {
                    uint32_t val_thread = (read_count - 1) % WARP_SIZE;
                    max_score = __shfl_sync(0xffffffff, score, val_thread);
                    maxscore[thread_idx % WARP_SIZE] = max_score;
                    maxi[thread_idx % WARP_SIZE] = __shfl_sync(0xffffffff, i, val_thread);
                    maxj[thread_idx % WARP_SIZE] = __shfl_sync(0xffffffff, j, val_thread);

                }
            }

            

        scores[j] = j * GAP;
    }


    if (thread_idx == 0)
    {
