     
     if (next) {
         
-        //TODO fix performance of this section
-        
-        int validCount = 0;
-        Board *validOutput = new Board[outCount];
+        LOG_PRINTF("starting to sort...\n");
+        thrust::host_vector<Board> h_vec(outCount);
         for (int i = 0 ; i < outCount ; i++) {
-            if (is_valid(&output[i]) == true) {
-                memcpy(&validOutput[validCount++], &output[i], sizeof(Board));
-            }
-        }
-
-        // sorts the new output so that duplicates can be removed
-        qsort(validOutput, validCount, sizeof(Board), compare_boards);
+            h_vec[i] = output[i];
+        }
+
+        // copies the host vector to the device
+        thrust::device_vector<Board> d_vec(h_vec.begin(), h_vec.end());
+        
+        // removes invalid boards
+        thrust::device_vector<Board>::iterator new_end = thrust::remove_if(
+                d_vec.begin(), d_vec.end(), is_valid_struct());
+        // erases the invalid boards
+        d_vec.erase(new_end, d_vec.end());
+        
+        // sorts the boards so duplicates are next to each other 
+        thrust::sort(d_vec.begin(), d_vec.end());
+
+        // removes the dupliates next to each other
+        new_end = thrust::unique(d_vec.begin(), d_vec.end()); 
+        d_vec.erase(new_end, d_vec.end());
+
+        // copies the device vector back to the host
+        std::vector<Board> stl_vector(d_vec.size());
+        thrust::copy(d_vec.begin(), d_vec.end(), stl_vector.begin());
+        
+        for (int i = 0 ; i < stl_vector.size() ; i++ ) {
+            print_board(&stl_vector[i], x_max, y_max);
+        }
+
+        exit(1);
+
+        qsort(output, outCount, sizeof(Board), compare_boards);
+        CUDA_CHECK_ERROR();
+
+        LOG_PRINTF("sorting done...\n");
         Board *noDuplicates = new Board[outCount];
         int dupCount = 1;
 
-        Board last = validOutput[0];
-        memcpy(&noDuplicates[0], &validOutput[0], sizeof(Board));
-        
-        for (int i = 1 ; i < validCount ; i++) {
-            if (!boards_equal(&last, &validOutput[i])) {
-                memcpy(&noDuplicates[dupCount++], &validOutput[i], sizeof(Board));
-                last = validOutput[i];
-            }
-        }
-        
-        LOG_PRINTF("valid count     : %d\n", validCount);
+        Board last = output[0];
+        memcpy(&noDuplicates[0], &output[0], sizeof(Board));
+        
+        for (int i = 1 ; i < outCount ; i++) {
+            if (is_valid(&output[i])) {
+                if (!boards_equal(&last, &output[i])) {
+                    memcpy(&noDuplicates[dupCount++], &output[i], sizeof(Board));
+                    last = output[i];
+                }
+            } else {
+                break;
+            }
+        }
         
         LOG_PRINTF("duplicate count : %d\n", dupCount);
         delete[] output;
-        delete[] validOutput;
 
         int size = 3000000;
         if (dupCount > size) {

#define CUDA_CHECK_ERROR()    __CUDA_CHECK_ERROR( __FILE__, __LINE__ )
#define GET_INDEX(y_max, x, y) (y_max * x + y)
#define LOG_PRINTF(...) do { \
    time_t ltime = time(NULL); \
    printf("%.24s: ",asctime( localtime(&ltime))); \
    printf(__VA_ARGS__); \
} while (0) 
#define LOG_FPRINTF(f, ...) do { \
    time_t ltime = time(NULL); \
    fprintf(f, "%.24s: ",asctime( localtime(&ltime))); \
    fprintf(f, __VA_ARGS__); \
} while (0) 


    
    CUDA_SAFE_CALL(cudaMemcpy(output, dev_output, outputSize, cudaMemcpyDeviceToHost));

    LOG_PRINTF("gpu done...\n");

    bool next = false;
