         {
             if(fp->layers[k]->activation == RELU)
             {
-                lexpr_replace_relu_bounds_specialized<<<num_blocks_relu, num_threads>>>(lexpr_array, aux_lb_array, aux_ub_array, 1, num_out_neurons_current_layer);
-            }
-
-            layer_allocate_exprs<<<1, 1>>>(lexpr_array_tmp, 1, num_in_neurons_current_layer);
-
-            expr_from_previous_layer_specialized<<<num_blocks_linear, num_threads>>>(lexpr_array, lexpr_array_tmp, aux_expr_array, 1, num_out_neurons_current_layer, num_in_neurons_current_layer);
+                lexpr_replace_relu_bounds_specialized<<<num_blocks_relu, num_threads>>>(lexpr_array, aux_lb_array, aux_ub_array, num_out_neurons_last_layer, num_out_neurons_current_layer);
+            }
+
+            layer_allocate_exprs<<<num_out_neurons_last_layer, 1>>>(lexpr_array_tmp, num_out_neurons_last_layer, num_in_neurons_current_layer);
+
+            expr_from_previous_layer_specialized<<<num_blocks_linear, num_threads>>>(lexpr_array, lexpr_array_tmp, aux_expr_array, num_out_neurons_last_layer, num_out_neurons_current_layer, num_in_neurons_current_layer);
 
             std::swap(lexpr_array, lexpr_array_tmp);
 
-            free_expr_array<<<1, 1>>>(lexpr_array_tmp, num_out_neurons_current_layer);
+            free_expr_array<<<num_out_neurons_last_layer, 1>>>(lexpr_array_tmp, num_out_neurons_current_layer);
         }
         else
         {
-            lexpr_replace_maxpool_bounds<<<1, 1>>>(lexpr_array, aux_maxpool_lexpr_array, aux_maxpool_uexpr_array, aux_lb_array, aux_ub_array, 1);
+            lexpr_replace_maxpool_bounds<<<num_out_neurons_last_layer, 1>>>(lexpr_array, aux_maxpool_lexpr_array, aux_maxpool_uexpr_array, aux_lb_array, aux_ub_array, num_out_neurons_last_layer);
         }
     }
 
     if((fp->input_lexpr != nullptr) && (fp->input_uexpr != nullptr))
     {
-        replace_input_poly_cons_in_lexpr<<<1, 1>>>(lexpr_array, fp->input_inf, fp->input_sup, fp->input_lexpr, fp->input_uexpr, 1);
-    }
-
-    compute_lb_from_expr<<<1, 1>>>(lb_dev, lexpr_array, fp->input_inf, fp->input_sup, 1);
-
-    double lb;
-    cudaMemcpy(&lb, lb_dev, sizeof(double), cudaMemcpyDeviceToHost);
-
-    free_expr_array<<<1, 1>>>(lexpr_array, 1);
+        replace_input_poly_cons_in_lexpr<<<num_out_neurons_last_layer, 1>>>(lexpr_array, fp->input_inf, fp->input_sup, fp->input_lexpr, fp->input_uexpr, num_out_neurons_last_layer);
+    }
+
+    compute_lb_from_expr<<<num_out_neurons_last_layer, 1>>>(lb_dev, lexpr_array, fp->input_inf, fp->input_sup, num_out_neurons_last_layer);
+
+    double lb[num_out_neurons_last_layer];
+    cudaMemcpy(&lb, lb_dev, num_out_neurons_last_layer*sizeof(double), cudaMemcpyDeviceToHost);
+
+    free_expr_array<<<num_out_neurons_last_layer, 1>>>(lexpr_array, num_out_neurons_last_layer);
     cudaFree(lexpr_array);
     cudaFree(lexpr_array_tmp);
     cudaFree(lb_dev);
 
-    return lb;
+
+    for(size_t i = 0; i < num_out_neurons_last_layer; i++)
+    {
+        if(lb[i] < 0)
+        {
+            results[i] = true;
+        }
+        else
+        {
+            results[i] = false;
+        }
+    }
 }
 
 

    expr->inf_coeff[x] = 1.;
    expr->sup_coeff[x] = -1.;

    *sub = expr;
}


double get_lb_using_previous_layers(elina_manager_t* man, const fppoly_t* const fp, const elina_dim_t y, const elina_dim_t x)
{
    const size_t numlayers = fp->numlayers;
    fppoly_internal_t* pr = fppoly_init_from_manager(man, ELINA_FUNID_ASSIGN_LINEXPR_ARRAY);

    double* lb_dev;
    cudaMalloc((void**) &lb_dev, sizeof(double));

    expr_t** lexpr_array;
    cudaMalloc((void**) &lexpr_array, sizeof(expr_t*));

    create_sub_expr<<<1, 1>>>(lexpr_array, y, x);

    expr_t** lexpr_array_tmp;
    cudaMalloc((void**) &lexpr_array_tmp, sizeof(expr_t*));

    for(int k = numlayers - 1; k >= 0; k--)
    {

#include <chrono>


bool results[90];
bool results_calculated;
size_t output_counter;

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
