     using namespace warpdrive;
     using namespace std;
 
-    // type decls
-    using plan_t  = plans::BasicPlan<>;
+    cout << "==========WARPDRIVE TEST/BENCHMARK==========" << endl;
 
-    using data_p     = plan_t::data_p;
-    using failure_p  = plan_t::failure_p;
+    if (argc < 9)
+    {
+        cerr << "ERROR: Not enough parameters (read \"PARAMS\" section inside the main function)" << endl;
+        return -1;
+    }
 
-    using index_t = plan_t::index_t;
-    using data_t  = data_p::data_t;
-    using key_t   = data_p::key_t;
+    //the global index type to use
+    using index_t = uint64_t;
 
-    // params
-    const index_t len_data = 1UL << atoi(argv[1]);
-    const float   load     = atof(argv[2]);
+    //PARAMS
+    //the size of the thread groups (must be available at compile time)
+    static constexpr index_t group_size = 16;
+    //output verbosity (must be available at compile time)
+    static constexpr index_t verbosity = 1;
+    //filename for test data (dumped with binary_io.h)
+    const string  filename = argv[1];
+    //length of test data
+    const index_t len_data = atoi(argv[2]);
+    //load factor of the hash table
+    const float   load     = atof(argv[3]);
+    //capacity of the hash table
     const index_t capacity = len_data/load;
-    const index_t lvl1_max = atoi(argv[3]);
-    const index_t lvl2_max = atoi(argv[4]);
-    const index_t blocks_per_grid = (atoi(argv[5]) != 0) ? atoi(argv[5]): std::numeric_limits<index_t>::max();
-    const index_t threads_per_block = atoi(argv[6]);   
- 
+    //max chaotic probing attempts
+    const index_t lvl1_max = atoi(argv[4]);
+    //max linear probing attempts
+    const index_t lvl2_max = atoi(argv[5]);
+    //number of CUDA blocks per grid
+    const index_t blocks_per_grid = (atoi(argv[6]) != 0) ? atoi(argv[6]): std::numeric_limits<index_t>::max();
+    //number of threads per CUDA block (must be multiple of group_size)
+    const index_t threads_per_block = atoi(argv[7]);
+    //id of selected CUDA device
+    const index_t device_id = atoi(argv[8]);
+
+    if (verbosity > 0)
+    {
+        cout << "================== PARAMS =================="
+             << "\n(static) group_size=" << group_size
+             << "\n(static) verbosity=" << verbosity
+             << "\nfilename=" << filename
+             << "\nlen_data=" << len_data
+             << "\nload=" << load
+             << "\ncapacity=" << capacity
+             << "\nlvl1_max=" << lvl1_max
+             << "\nlvl2_max=" << lvl2_max
+             << "\nblocks_per_grid=" << blocks_per_grid
+             << "\nthreads_per_block=" << threads_per_block
+             << "\ndevice_id=" << device_id
+             << endl;
+    }
+
+    //DECLS
+    //data policy
+    using data_p    = warpdrive::policies::PackedPairDataPolicy<>;
+    //failure policy
+    using failure_p = std::conditional<(verbosity > 1),
+                                       warpdrive::policies::PrintIdFailurePolicy,
+                                       warpdrive::policies::IgnoreFailurePolicy>::type;
+
+   //data types
+   using data_t    = data_p::data_t;
+   using key_t     = data_p::key_t;
+   using value_t   = data_p::value_t;
+
+    //plan (the meat)
+    using plan_t = plans::BasicPlan<data_p,
+                                    index_t,    //index type to use
+                                    group_size, //size of parallel probing group
+                                    failure_p>;
+
+    //config struct (probing lengths and kernel launch config)
     plan_t::config_t config(lvl1_max,
                             lvl2_max,
                             blocks_per_grid,
                             threads_per_block);
 
-    cudaSetDevice(atoi(argv[7])); CUERR
+    //set the selected CUDA device
+    cudaSetDevice(device_id); CUERR
 
+    //load random keys
+    key_t * keys_h = (key_t*)malloc(sizeof(key_t)*len_data);
+    load_binary(keys_h, len_data, filename);
+
+    free(keys_h);
+    /*
     // generate data
     data_t * data1_h = new data_t[len_data];
     data_t * data2_h = new data_t[len_data];

#include <iostream>

#include "../include/warpdrive.cuh"

DEVICEQUALIFIER INLINEQUALIFIER
void print_bits_32(uint32_t x)

    cudaFree(data1_d); CUERR
    cudaFree(data2_d); CUERR
    cudaFree(hash_table_d); CUERR
    */
}
