Merge pull request #146 from gm4tr1x/master
[hashcat.git] / src / oclHashcat.c
index faa6948..4da285c 100644 (file)
@@ -3,13 +3,16 @@
  * License.....: MIT
  */
 
+#ifdef OSX
+#include <stdio.h>
+#endif
+
 #include <common.h>
 #include <shared.h>
 #include <rp_kernel_on_cpu.h>
 #include <getopt.h>
 
 const char *PROGNAME          = "oclHashcat";
-const char *VERSION_TXT       = "2.10";
 const uint  VERSION_BIN       = 210;
 const uint  RESTORE_MIN       = 210;
 
@@ -80,6 +83,7 @@ const uint  RESTORE_MIN       = 210;
 #define POWERTUNE_ENABLE        0
 #define LOGFILE_DISABLE         0
 #define SCRYPT_TMTO             0
+#define OPENCL_VECTOR_WIDTH     0
 
 #define WL_MODE_STDIN           1
 #define WL_MODE_FILE            2
@@ -214,7 +218,7 @@ static uint default_benchmark_algorithms[NUM_DEFAULT_BENCHMARK_ALGORITHMS] =
   1000,
   1100,
   2100,
- 12800,
+  12800,
   1500,
   12400,
   500,
@@ -384,17 +388,26 @@ const char *USAGE_BIG[] =
   "  -c,  --segment-size=NUM            Size in MB to cache from the wordfile",
   "       --bitmap-min=NUM              Minimum number of bits allowed for bitmaps",
   "       --bitmap-max=NUM              Maximum number of bits allowed for bitmaps",
+  #ifndef OSX
   "       --cpu-affinity=STR            Locks to CPU devices, separate with comma",
+  #else
+  "       --cpu-affinity=STR            Locks to CPU devices, separate with comma (disabled on OSX)",
+  #endif
   "       --opencl-platforms=STR        OpenCL platforms to use, separate with comma",
   "  -d,  --opencl-devices=STR          OpenCL devices to use, separate with comma",
   "       --opencl-device-types=STR     OpenCL device-types to use, separate with comma, see references below",
+  "       --opencl-vector-width=NUM     OpenCL vector-width (either 1, 2, 4 or 8), overrides value from device query",
   "  -w,  --workload-profile=NUM        Enable a specific workload profile, see references below",
   "  -n,  --kernel-accel=NUM            Workload tuning: 1, 8, 40, 80, 160",
   "  -u,  --kernel-loops=NUM            Workload fine-tuning: 8 - 1024",
+  #ifdef HAVE_HWMON
   "       --gpu-temp-disable            Disable temperature and fanspeed readings and triggers",
   "       --gpu-temp-abort=NUM          Abort session if GPU temperature reaches NUM degrees celsius",
   "       --gpu-temp-retain=NUM         Try to retain GPU temperature at NUM degrees celsius (AMD only)",
+  #ifdef HAVE_ADL
   "       --powertune-enable            Enable automatic power tuning option (AMD OverDrive 6 only)",
+  #endif
+  #endif
   "       --scrypt-tmto=NUM             Manually override automatically calculated TMTO value for scrypt",
   "",
   "* Distributed:",
@@ -841,6 +854,7 @@ void status_display_automat ()
    * temperature
    */
 
+  #ifdef HAVE_HWMON
   if (data.gpu_temp_disable == 0)
   {
     fprintf (out, "TEMP\t");
@@ -860,6 +874,7 @@ void status_display_automat ()
 
     hc_thread_mutex_unlock (mux_adl);
   }
+  #endif // HAVE_HWMON
 
   #ifdef _WIN
   fputc ('\r', out);
@@ -1101,9 +1116,9 @@ void status_display ()
     // not get new candidates it idles around but speed display would
     // show it as working.
     // if we instantly set it to 0 after reading it happens that the
-    // speed can be shown as zero if the users refreshs to fast.
+    // speed can be shown as zero if the users refreshes too fast.
     // therefore, we add a timestamp when a stat was recorded and if its
-    // to old we will not use it
+    // too old we will not use it
 
     speed_cnt[device_id] = 0;
     speed_ms[device_id]  = 0;
@@ -1352,9 +1367,7 @@ void status_display ()
 
     if (device_param->skipped) continue;
 
-    char display_dev_cur[16];
-
-    memset (display_dev_cur, 0, sizeof (display_dev_cur));
+    char display_dev_cur[16] = { 0 };
 
     strncpy (display_dev_cur, "0.00", 4);
 
@@ -1363,9 +1376,7 @@ void status_display ()
     log_info ("Speed.Dev.#%d...: %9sH/s", device_id + 1, display_dev_cur);
   }
 
-  char display_all_cur[16];
-
-  memset (display_all_cur, 0, sizeof (display_all_cur));
+  char display_all_cur[16] = { 0 };
 
   strncpy (display_all_cur, "0.00", 4);
 
@@ -1509,6 +1520,7 @@ void status_display ()
     }
   }
 
+  #ifdef HAVE_HWMON
   if (data.gpu_temp_disable == 0)
   {
     hc_thread_mutex_lock (mux_adl);
@@ -1559,6 +1571,7 @@ void status_display ()
 
     hc_thread_mutex_unlock (mux_adl);
   }
+  #endif // HAVE_HWMON
 }
 
 static void status_benchmark ()
@@ -1571,9 +1584,7 @@ static void status_benchmark ()
   u64   speed_cnt[DEVICES_MAX];
   float speed_ms[DEVICES_MAX];
 
-  uint device_id;
-
-  for (device_id = 0; device_id < data.devices_cnt; device_id++)
+  for (uint device_id = 0; device_id < data.devices_cnt; device_id++)
   {
     hc_device_param_t *device_param = &data.devices_param[device_id];
 
@@ -1618,9 +1629,7 @@ static void status_benchmark ()
 
     if (device_param->skipped) continue;
 
-    char display_dev_cur[16];
-
-    memset (display_dev_cur, 0, sizeof (display_dev_cur));
+    char display_dev_cur[16] = { 0 };
 
     strncpy (display_dev_cur, "0.00", 4);
 
@@ -1629,9 +1638,7 @@ static void status_benchmark ()
     log_info ("Speed.Dev.#%d.: %9sH/s", device_id + 1, display_dev_cur);
   }
 
-  char display_all_cur[16];
-
-  memset (display_all_cur, 0, sizeof (display_all_cur));
+  char display_all_cur[16] = { 0 };
 
   strncpy (display_all_cur, "0.00", 4);
 
@@ -1837,7 +1844,7 @@ static void check_hash (hc_device_param_t *device_param, const uint salt_pos, co
 
   // hash
 
-  char out_buf[4096]; memset (out_buf, 0, sizeof (out_buf));
+  char out_buf[4096] = { 0 };
 
   ascii_digest (out_buf, salt_pos, digest_pos);
 
@@ -2242,11 +2249,8 @@ static void save_hash ()
 {
   char *hashfile = data.hashfile;
 
-  char new_hashfile[256];
-  char old_hashfile[256];
-
-  memset (new_hashfile, 0, sizeof (new_hashfile));
-  memset (old_hashfile, 0, sizeof (old_hashfile));
+  char new_hashfile[256] = { 0 };
+  char old_hashfile[256] = { 0 };
 
   snprintf (new_hashfile, 255, "%s.new", hashfile);
   snprintf (old_hashfile, 255, "%s.old", hashfile);
@@ -2278,9 +2282,7 @@ static void save_hash ()
 
       if (data.hash_mode != 2500)
       {
-        char out_buf[4096];
-
-        memset (out_buf, 0, sizeof (out_buf));
+        char out_buf[4096] = { 0 };
 
         if (data.username == 1)
         {
@@ -2760,9 +2762,7 @@ static void run_cracker (hc_device_param_t *device_param, const uint pw_cnt, con
 
           if (run_rule_engine (data.rule_len_r, data.rule_buf_r))
           {
-            char rule_buf_out[BLOCK_SIZE];
-
-            memset (rule_buf_out, 0, sizeof (rule_buf_out));
+            char rule_buf_out[BLOCK_SIZE] = { 0 };
 
             int rule_len_out = _old_apply_rule (data.rule_buf_r, data.rule_len_r, line_buf, line_len, rule_buf_out);
 
@@ -3143,9 +3143,7 @@ static void get_next_word (wl_data_t *wl_data, FILE *fd, char **out_buf, uint *o
 
     if (run_rule_engine (data.rule_len_l, data.rule_buf_l))
     {
-      char rule_buf_out[BLOCK_SIZE];
-
-      memset (rule_buf_out, 0, sizeof (rule_buf_out));
+      char rule_buf_out[BLOCK_SIZE] = { 0 };
 
       int rule_len_out = -1;
 
@@ -3278,9 +3276,7 @@ static u64 count_words (wl_data_t *wl_data, FILE *fd, char *dictfile, dictstat_t
 
       if (run_rule_engine (data.rule_len_l, data.rule_buf_l))
       {
-        char rule_buf_out[BLOCK_SIZE];
-
-        memset (rule_buf_out, 0, sizeof (rule_buf_out));
+        char rule_buf_out[BLOCK_SIZE] = { 0 };
 
         int rule_len_out = -1;
 
@@ -3385,13 +3381,15 @@ static void *thread_monitor (void *p)
   uint runtime_check = 0;
   uint remove_check  = 0;
   uint status_check  = 0;
-  uint hwmon_check   = 0;
   uint restore_check = 0;
 
   uint restore_left = data.restore_timer;
   uint remove_left  = data.remove_timer;
   uint status_left  = data.status_timer;
 
+  #ifdef HAVE_HWMON
+  uint hwmon_check   = 0;
+
   // these variables are mainly used for fan control (AMD only)
 
   int *fan_speed_chgd = (int *) mycalloc (data.devices_cnt, sizeof (int));
@@ -3401,12 +3399,15 @@ static void *thread_monitor (void *p)
   int *temp_diff_old = (int *) mycalloc (data.devices_cnt, sizeof (int));
   int *temp_diff_sum = (int *) mycalloc (data.devices_cnt, sizeof (int));
 
+  #ifdef HAVE_ADL
   int temp_threshold = 1; // degrees celcius
 
   int fan_speed_min =  15; // in percentage
   int fan_speed_max = 100;
+  #endif // HAVE_ADL
 
   time_t last_temp_check_time;
+  #endif // HAVE_HWMON
 
   uint sleep_time = 1;
 
@@ -3430,15 +3431,20 @@ static void *thread_monitor (void *p)
     status_check = 1;
   }
 
+  #ifdef HAVE_HWMON
   if (data.gpu_temp_disable == 0)
   {
     time (&last_temp_check_time);
 
     hwmon_check = 1;
   }
+  #endif
 
-  if ((runtime_check == 0) && (remove_check == 0) && (status_check == 0) && (hwmon_check == 0) && (restore_check == 0))
+  if ((runtime_check == 0) && (remove_check == 0) && (status_check == 0) && (restore_check == 0))
   {
+    #ifdef HAVE_HWMON
+    if (hwmon_check == 0)
+    #endif
     return (p);
   }
 
@@ -3448,6 +3454,7 @@ static void *thread_monitor (void *p)
 
     if (data.devices_status != STATUS_RUNNING) continue;
 
+    #ifdef HAVE_HWMON
     if (hwmon_check == 1)
     {
       hc_thread_mutex_lock (mux_adl);
@@ -3479,6 +3486,7 @@ static void *thread_monitor (void *p)
           break;
         }
 
+        #ifdef HAVE_ADL
         const int gpu_temp_retain = data.gpu_temp_retain;
 
         if (gpu_temp_retain) // VENDOR_ID_AMD implied
@@ -3533,10 +3541,12 @@ static void *thread_monitor (void *p)
             }
           }
         }
+        #endif // HAVE_ADL
       }
 
       hc_thread_mutex_unlock (mux_adl);
     }
+    #endif // HAVE_HWMON
 
     if (restore_check == 1)
     {
@@ -3609,10 +3619,12 @@ static void *thread_monitor (void *p)
     }
   }
 
+  #ifdef HAVE_HWMON
   myfree (fan_speed_chgd);
 
   myfree (temp_diff_old);
   myfree (temp_diff_sum);
+  #endif
 
   p = NULL;
 
@@ -3637,9 +3649,7 @@ static void *thread_outfile_remove (void *p)
   int (*parse_func) (char *, uint, hash_t *)         = data.parse_func;
 
   // buffers
-  hash_t hash_buf;
-
-  memset (&hash_buf, 0, sizeof (hash_buf));
+  hash_t hash_buf = { 0, 0, 0, 0, 0 };
 
   hash_buf.digest = mymalloc (dgst_size);
 
@@ -3983,6 +3993,8 @@ static void *thread_calc_stdin (void *p)
 {
   hc_device_param_t *device_param = (hc_device_param_t *) p;
 
+  if (device_param->skipped) return NULL;
+
   const uint attack_kern = data.attack_kern;
 
   const uint kernel_blocks = device_param->kernel_blocks;
@@ -4016,9 +4028,7 @@ static void *thread_calc_stdin (void *p)
 
       if (run_rule_engine (data.rule_len_l, data.rule_buf_l))
       {
-        char rule_buf_out[BLOCK_SIZE];
-
-        memset (rule_buf_out, 0, sizeof (rule_buf_out));
+        char rule_buf_out[BLOCK_SIZE] = { 0 };
 
         int rule_len_out = -1;
 
@@ -4197,6 +4207,8 @@ static void *thread_calc (void *p)
 {
   hc_device_param_t *device_param = (hc_device_param_t *) p;
 
+  if (device_param->skipped) return NULL;
+
   const uint attack_mode = data.attack_mode;
   const uint attack_kern = data.attack_kern;
 
@@ -4343,9 +4355,7 @@ static void *thread_calc (void *p)
 
           if (run_rule_engine (data.rule_len_l, data.rule_buf_l))
           {
-            char rule_buf_out[BLOCK_SIZE];
-
-            memset (rule_buf_out, 0, sizeof (rule_buf_out));
+            char rule_buf_out[BLOCK_SIZE] = { 0 };
 
             int rule_len_out = -1;
 
@@ -4969,10 +4979,12 @@ static uint hlfmt_detect (FILE *fp, uint max_check)
 
 // wrapper around mymalloc for ADL
 
+#if defined(HAVE_HWMON) && defined(HAVE_ADL)
 void *__stdcall ADL_Main_Memory_Alloc (const int iSize)
 {
   return mymalloc (iSize);
 }
+#endif
 
 static uint generate_bitmaps (const uint digests_cnt, const uint dgst_size, const uint dgst_shifts, char *digests_buf_ptr, const uint bitmap_mask, const uint bitmap_size, uint *bitmap_a, uint *bitmap_b, uint *bitmap_c, uint *bitmap_d, const u64 collisions_max)
 {
@@ -5046,13 +5058,14 @@ int main (int argc, char **argv)
       putenv ((char *) "DISPLAY=:0");
   }
 
-  /*
   if (getenv ("GPU_MAX_ALLOC_PERCENT") == NULL)
     putenv ((char *) "GPU_MAX_ALLOC_PERCENT=100");
 
+  if (getenv ("CPU_MAX_ALLOC_PERCENT") == NULL)
+    putenv ((char *) "CPU_MAX_ALLOC_PERCENT=100");
+
   if (getenv ("GPU_USE_SYNC_OBJECTS") == NULL)
     putenv ((char *) "GPU_USE_SYNC_OBJECTS=1");
-  */
 
   /**
    * Real init
@@ -5129,18 +5142,25 @@ int main (int argc, char **argv)
   uint  increment         = INCREMENT;
   uint  increment_min     = INCREMENT_MIN;
   uint  increment_max     = INCREMENT_MAX;
+  #ifndef OSX
   char *cpu_affinity      = NULL;
+  #endif
   char *opencl_devices    = NULL;
   char *opencl_platforms  = NULL;
   char *opencl_device_types = NULL;
+  uint  opencl_vector_width = OPENCL_VECTOR_WIDTH;
   char *truecrypt_keyfiles = NULL;
   uint  workload_profile  = WORKLOAD_PROFILE;
   uint  kernel_accel      = KERNEL_ACCEL;
   uint  kernel_loops      = KERNEL_LOOPS;
+  #ifdef HAVE_HWMON
   uint  gpu_temp_disable  = GPU_TEMP_DISABLE;
   uint  gpu_temp_abort    = GPU_TEMP_ABORT;
   uint  gpu_temp_retain   = GPU_TEMP_RETAIN;
+  #ifdef HAVE_ADL
   uint  powertune_enable  = POWERTUNE_ENABLE;
+  #endif
+  #endif
   uint  logfile_disable   = LOGFILE_DISABLE;
   uint  segment_size      = SEGMENT_SIZE;
   uint  scrypt_tmto       = SCRYPT_TMTO;
@@ -5208,6 +5228,7 @@ int main (int argc, char **argv)
   #define IDX_OPENCL_DEVICES    'd'
   #define IDX_OPENCL_PLATFORMS  0xff72
   #define IDX_OPENCL_DEVICE_TYPES 0xff73
+  #define IDX_OPENCL_VECTOR_WIDTH 0xff74
   #define IDX_WORKLOAD_PROFILE  'w'
   #define IDX_KERNEL_ACCEL      'n'
   #define IDX_KERNEL_LOOPS      'u'
@@ -5285,17 +5306,24 @@ int main (int argc, char **argv)
     {"markov-classic",    no_argument,       0, IDX_MARKOV_CLASSIC},
     {"markov-threshold",  required_argument, 0, IDX_MARKOV_THRESHOLD},
     {"markov-hcstat",     required_argument, 0, IDX_MARKOV_HCSTAT},
+    #ifndef OSX
     {"cpu-affinity",      required_argument, 0, IDX_CPU_AFFINITY},
+    #endif
     {"opencl-devices",    required_argument, 0, IDX_OPENCL_DEVICES},
     {"opencl-platforms",  required_argument, 0, IDX_OPENCL_PLATFORMS},
     {"opencl-device-types", required_argument, 0, IDX_OPENCL_DEVICE_TYPES},
+    {"opencl-vector-width", required_argument, 0, IDX_OPENCL_VECTOR_WIDTH},
     {"workload-profile",  required_argument, 0, IDX_WORKLOAD_PROFILE},
     {"kernel-accel",      required_argument, 0, IDX_KERNEL_ACCEL},
     {"kernel-loops",      required_argument, 0, IDX_KERNEL_LOOPS},
+    #ifdef HAVE_HWMON
     {"gpu-temp-disable",  no_argument,       0, IDX_GPU_TEMP_DISABLE},
     {"gpu-temp-abort",    required_argument, 0, IDX_GPU_TEMP_ABORT},
     {"gpu-temp-retain",   required_argument, 0, IDX_GPU_TEMP_RETAIN},
+    #ifdef HAVE_ADL
     {"powertune-enable",  no_argument,       0, IDX_POWERTUNE_ENABLE},
+    #endif
+    #endif // HAVE_HWMON
     {"logfile-disable",   no_argument,       0, IDX_LOGFILE_DISABLE},
     {"truecrypt-keyfiles", required_argument, 0, IDX_TRUECRYPT_KEYFILES},
     {"segment-size",      required_argument, 0, IDX_SEGMENT_SIZE},
@@ -5320,12 +5348,11 @@ int main (int argc, char **argv)
 
   char **rp_files = (char **) mycalloc (argc, sizeof (char *));
 
-  int option_index;
-  int c;
+  int option_index = 0;
+  int c = -1;
 
   optind = 1;
   optopt = 0;
-  option_index = 0;
 
   while (((c = getopt_long (argc, argv, short_options, long_options, &option_index)) != -1) && optopt == 0)
   {
@@ -5355,7 +5382,7 @@ int main (int argc, char **argv)
 
   if (version)
   {
-    log_info (VERSION_TXT);
+    log_info ("%s (%s)", VERSION_TAG, VERSION_SUM);
 
     return (0);
   }
@@ -5516,8 +5543,10 @@ int main (int argc, char **argv)
   uint remove_timer_chgd    = 0;
   uint increment_min_chgd   = 0;
   uint increment_max_chgd   = 0;
-  uint gpu_temp_abort_chgd  = 0;
+  #if defined(HAVE_HWMON) && defined(HAVE_ADL)
   uint gpu_temp_retain_chgd = 0;
+  uint gpu_temp_abort_chgd  = 0;
+  #endif
 
   optind = 1;
   optopt = 0;
@@ -5588,22 +5617,36 @@ int main (int argc, char **argv)
       case IDX_HEX_CHARSET:       hex_charset       = 1;               break;
       case IDX_HEX_SALT:          hex_salt          = 1;               break;
       case IDX_HEX_WORDLIST:      hex_wordlist      = 1;               break;
+      #ifndef OSX
       case IDX_CPU_AFFINITY:      cpu_affinity      = optarg;          break;
+      #endif
       case IDX_OPENCL_DEVICES:    opencl_devices    = optarg;          break;
       case IDX_OPENCL_PLATFORMS:  opencl_platforms  = optarg;          break;
       case IDX_OPENCL_DEVICE_TYPES:
                                   opencl_device_types = optarg;        break;
+      case IDX_OPENCL_VECTOR_WIDTH:
+                                  opencl_vector_width = atoi (optarg); break;
       case IDX_WORKLOAD_PROFILE:  workload_profile  = atoi (optarg);   break;
       case IDX_KERNEL_ACCEL:      kernel_accel      = atoi (optarg);
                                   kernel_accel_chgd = 1;               break;
       case IDX_KERNEL_LOOPS:      kernel_loops      = atoi (optarg);
                                   kernel_loops_chgd = 1;               break;
+      #ifdef HAVE_HWMON
       case IDX_GPU_TEMP_DISABLE:  gpu_temp_disable  = 1;               break;
-      case IDX_GPU_TEMP_ABORT:    gpu_temp_abort_chgd = 1;
-                                  gpu_temp_abort    = atoi (optarg);   break;
-      case IDX_GPU_TEMP_RETAIN:   gpu_temp_retain_chgd = 1;
-                                  gpu_temp_retain   = atoi (optarg);   break;
+      case IDX_GPU_TEMP_ABORT:    gpu_temp_abort    = atoi (optarg);
+                                  #ifdef HAVE_ADL
+                                  gpu_temp_abort_chgd = 1;
+                                  #endif
+                                  break;
+      case IDX_GPU_TEMP_RETAIN:   gpu_temp_retain   = atoi (optarg);
+                                  #ifdef HAVE_ADL
+                                  gpu_temp_retain_chgd = 1;
+                                  #endif
+                                  break;
+      #ifdef HAVE_ADL
       case IDX_POWERTUNE_ENABLE:  powertune_enable  = 1;               break;
+      #endif
+      #endif // HAVE_HWMON
       case IDX_LOGFILE_DISABLE:   logfile_disable   = 1;               break;
       case IDX_TRUECRYPT_KEYFILES: truecrypt_keyfiles = optarg;        break;
       case IDX_SEGMENT_SIZE:      segment_size      = atoi (optarg);   break;
@@ -5644,19 +5687,19 @@ int main (int argc, char **argv)
   {
     if (benchmark == 1)
     {
-      log_info ("%s v%.2f starting in benchmark-mode...", PROGNAME, (float) VERSION_BIN / 100);
+      log_info ("%s %s (%s) starting in benchmark-mode...", PROGNAME, VERSION_TAG, VERSION_SUM);
 
       log_info ("");
     }
     else if (restore == 1)
     {
-      log_info ("%s v%.2f starting in restore-mode...", PROGNAME, (float) VERSION_BIN / 100);
+      log_info ("%s %s (%s) starting in restore-mode...", PROGNAME, VERSION_TAG, VERSION_SUM);
 
       log_info ("");
     }
     else
     {
-      log_info ("%s v%.2f starting...", PROGNAME, (float) VERSION_BIN / 100);
+      log_info ("%s %s (%s) starting...", PROGNAME, VERSION_TAG, VERSION_SUM);
 
       log_info ("");
     }
@@ -5885,6 +5928,13 @@ int main (int argc, char **argv)
     return (-1);
   }
 
+  if ((opencl_vector_width != 0) && (opencl_vector_width != 1) && (opencl_vector_width != 2) && (opencl_vector_width != 4) && (opencl_vector_width != 8))
+  {
+    log_error ("ERROR: opencl-vector-width %i not allowed", opencl_vector_width);
+
+    return (-1);
+  }
+
   if (show == 1 || left == 1)
   {
     attack_mode = ATTACK_MODE_NONE;
@@ -6307,7 +6357,9 @@ int main (int argc, char **argv)
   data.benchmark         = benchmark;
   data.skip              = skip;
   data.limit             = limit;
+  #if defined(HAVE_HWMON) && defined(HAVE_ADL)
   data.powertune_enable  = powertune_enable;
+  #endif
   data.logfile_disable   = logfile_disable;
   data.truecrypt_keyfiles = truecrypt_keyfiles;
   data.scrypt_tmto       = scrypt_tmto;
@@ -6316,10 +6368,12 @@ int main (int argc, char **argv)
    * cpu affinity
    */
 
+  #ifndef OSX
   if (cpu_affinity)
   {
     set_cpu_affinity (cpu_affinity);
   }
+  #endif
 
   if (rp_gen_seed_chgd == 0)
   {
@@ -6383,9 +6437,11 @@ int main (int argc, char **argv)
   logfile_top_uint   (force);
   logfile_top_uint   (kernel_accel);
   logfile_top_uint   (kernel_loops);
+  #ifdef HAVE_HWMON
   logfile_top_uint   (gpu_temp_abort);
   logfile_top_uint   (gpu_temp_disable);
   logfile_top_uint   (gpu_temp_retain);
+  #endif
   logfile_top_uint   (hash_mode);
   logfile_top_uint   (hex_charset);
   logfile_top_uint   (hex_salt);
@@ -6404,7 +6460,9 @@ int main (int argc, char **argv)
   logfile_top_uint   (outfile_check_timer);
   logfile_top_uint   (outfile_format);
   logfile_top_uint   (potfile_disable);
+  #if defined(HAVE_HWMON) && defined(HAVE_ADL)
   logfile_top_uint   (powertune_enable);
+  #endif
   logfile_top_uint   (scrypt_tmto);
   logfile_top_uint   (quiet);
   logfile_top_uint   (remove);
@@ -6430,7 +6488,9 @@ int main (int argc, char **argv)
   logfile_top_uint64 (limit);
   logfile_top_uint64 (skip);
   logfile_top_char   (separator);
+  #ifndef OSX
   logfile_top_string (cpu_affinity);
+  #endif
   logfile_top_string (custom_charset_1);
   logfile_top_string (custom_charset_2);
   logfile_top_string (custom_charset_3);
@@ -6439,6 +6499,7 @@ int main (int argc, char **argv)
   logfile_top_string (opencl_devices);
   logfile_top_string (opencl_platforms);
   logfile_top_string (opencl_device_types);
+  logfile_top_uint   (opencl_vector_width);
   logfile_top_string (induction_dir);
   logfile_top_string (markov_hcstat);
   logfile_top_string (outfile);
@@ -7664,6 +7725,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_NOT_SALTED
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7687,6 +7749,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_APPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7710,6 +7773,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_APPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7733,6 +7797,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_PREPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7757,6 +7822,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_PREPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7781,6 +7847,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_APPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7806,6 +7873,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_APPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7830,6 +7898,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_PREPENDED_SALT
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7847,6 +7916,7 @@ int main (int argc, char **argv)
                    parse_func  = hmacsha512_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
                    opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_NOT_ITERATED;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7865,6 +7935,7 @@ int main (int argc, char **argv)
                    parse_func  = hmacsha512_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
                    opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_NOT_ITERATED;
                    dgst_pos0   = 14;
                    dgst_pos1   = 15;
@@ -7880,7 +7951,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = sha512crypt_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8312,6 +8384,7 @@ int main (int argc, char **argv)
                    parse_func  = keccak_parse_hash;
                    sort_by_digest = sort_by_digest_8_25;
                    opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 2;
                    dgst_pos1   = 3;
@@ -8546,7 +8619,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = truecrypt_parse_hash_1k;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8561,7 +8635,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = truecrypt_parse_hash_1k;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8576,7 +8651,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = truecrypt_parse_hash_1k;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8711,7 +8787,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = sha512aix_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8786,7 +8863,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_16;
                    parse_func  = sha512osx_parse_hash;
                    sort_by_digest = sort_by_digest_8_16;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8801,7 +8879,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_16;
                    parse_func  = sha512grub_parse_hash;
                    sort_by_digest = sort_by_digest_8_16;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -8924,7 +9003,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = drupal7_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -9531,6 +9611,7 @@ int main (int argc, char **argv)
                                | OPTI_TYPE_EARLY_SKIP
                                | OPTI_TYPE_NOT_ITERATED
                                | OPTI_TYPE_NOT_SALTED
+                               | OPTI_TYPE_USES_BITS_64
                                | OPTI_TYPE_RAW_HASH;
                    dgst_pos0   = 6;
                    dgst_pos1   = 7;
@@ -9754,7 +9835,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_16;
                    parse_func  = pbkdf2_sha512_parse_hash;
                    sort_by_digest = sort_by_digest_8_16;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -9769,7 +9851,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_8;
                    parse_func  = ecryptfs_parse_hash;
                    sort_by_digest = sort_by_digest_8_8;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -9784,7 +9867,8 @@ int main (int argc, char **argv)
                    dgst_size   = DGST_SIZE_8_16;
                    parse_func  = oraclet_parse_hash;
                    sort_by_digest = sort_by_digest_8_16;
-                   opti_type   = OPTI_TYPE_ZERO_BYTE;
+                   opti_type   = OPTI_TYPE_ZERO_BYTE
+                               | OPTI_TYPE_USES_BITS_64;
                    dgst_pos0   = 0;
                    dgst_pos1   = 1;
                    dgst_pos2   = 2;
@@ -10102,9 +10186,7 @@ int main (int argc, char **argv)
      * potfile
      */
 
-    char potfile[256];
-
-    memset (potfile, 0, sizeof (potfile));
+    char potfile[256] = { 0 };
 
     snprintf (potfile, sizeof (potfile) - 1, "%s/%s.pot", session_dir, session);
 
@@ -10282,6 +10364,8 @@ int main (int argc, char **argv)
           continue;
         }
 
+        if (plain_len >= 255) continue;
+
         memcpy (pot_ptr->plain_buf, plain_buf, plain_len);
 
         pot_ptr->plain_len = plain_len;
@@ -10414,11 +10498,8 @@ int main (int argc, char **argv)
      * charsets : keep them together for more easy maintainnce
      */
 
-    cs_t mp_sys[6];
-    cs_t mp_usr[4];
-
-    memset (mp_sys, 0, sizeof (mp_sys));
-    memset (mp_usr, 0, sizeof (mp_usr));
+    cs_t mp_sys[6] = { { { 0 }, 0 } };
+    cs_t mp_usr[4] = { { { 0 }, 0 } };
 
     mp_setup_sys (mp_sys);
 
@@ -10682,11 +10763,11 @@ int main (int argc, char **argv)
 
             uint hccap_size = sizeof (hccap_t);
 
-            char in[hccap_size];
+            char *in = (char *) mymalloc (hccap_size);
 
             while (!feof (fp))
             {
-              int n = fread (&in, hccap_size, 1, fp);
+              int n = fread (in, hccap_size, 1, fp);
 
               if (n != 1)
               {
@@ -10745,6 +10826,8 @@ int main (int argc, char **argv)
             }
 
             fclose (fp);
+
+            myfree (in);
           }
           else if (hash_mode == 3000)
           {
@@ -12120,7 +12203,7 @@ int main (int argc, char **argv)
      * Some algorithm, like descrypt, can benefit from JIT compilation
      */
 
-    uint force_jit_compilation = 0;
+    int force_jit_compilation = -1;
 
     if (hash_mode == 8900)
     {
@@ -12427,12 +12510,12 @@ int main (int argc, char **argv)
     {
       cl_platform_id platform = platforms[platform_id];
 
-      char platform_vendor[INFOSZ];
-
-      memset (platform_vendor, 0, sizeof (platform_vendor));
+      char platform_vendor[INFOSZ] = { 0 };
 
       hc_clGetPlatformInfo (platform, CL_PLATFORM_VENDOR, sizeof (platform_vendor), platform_vendor, NULL);
 
+      #ifdef HAVE_HWMON
+      #if defined(HAVE_NVML) || defined(HAVE_NVAPI)
       if (strcmp (platform_vendor, CL_VENDOR_NV) == 0)
       {
         // make sure that we do not directly control the fan for NVidia
@@ -12441,6 +12524,8 @@ int main (int argc, char **argv)
 
         data.gpu_temp_retain = gpu_temp_retain;
       }
+      #endif // HAVE_NVML || HAVE_NVAPI
+      #endif
     }
 
     /**
@@ -12475,14 +12560,6 @@ int main (int argc, char **argv)
 
         device_param->platform_devices_id = platform_devices_id;
 
-        // vendor_id
-
-        cl_uint vendor_id = 0;
-
-        hc_clGetDeviceInfo (device_param->device, CL_DEVICE_VENDOR_ID, sizeof (vendor_id), &vendor_id, NULL);
-
-        device_param->vendor_id = vendor_id;
-
         // device_type
 
         cl_device_type device_type;
@@ -12493,6 +12570,14 @@ int main (int argc, char **argv)
 
         device_param->device_type = device_type;
 
+        // vendor_id
+
+        cl_uint vendor_id = 0;
+
+        hc_clGetDeviceInfo (device_param->device, CL_DEVICE_VENDOR_ID, sizeof (vendor_id), &vendor_id, NULL);
+
+        device_param->vendor_id = vendor_id;
+
         // device_name
 
         char *device_name = (char *) mymalloc (INFOSZ);
@@ -12514,13 +12599,42 @@ int main (int argc, char **argv)
           // pocl returns the real vendor_id in CL_DEVICE_VENDOR_ID which causes many problems because of hms and missing amd_bfe () etc
           // we need to overwrite vendor_id to avoid this. maybe open pocl issue?
 
-          cl_uint vendor_id = 0xffff;
+          cl_uint vendor_id = VENDOR_ID_GENERIC;
 
           device_param->vendor_id = vendor_id;
         }
 
         // max_compute_units
 
+        cl_uint vector_width;
+
+        if (opencl_vector_width == OPENCL_VECTOR_WIDTH)
+        {
+          hc_clGetDeviceInfo (device_param->device, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, sizeof (vector_width), &vector_width, NULL);
+
+          if ((vendor_id == VENDOR_ID_NV) && (strstr (device_name, " Ti") || strstr (device_name, " TI")))
+          {
+            // Yeah that's a super bad hack, but there's no other attribute we could use
+
+            if (vector_width < 2) vector_width *= 2;
+          }
+
+          if (opti_type & OPTI_TYPE_USES_BITS_64)
+          {
+            if (vector_width > 1) vector_width /= 2;
+          }
+        }
+        else
+        {
+          vector_width = opencl_vector_width;
+        }
+
+        if (vector_width > 8) vector_width = 8;
+
+        device_param->vector_width = vector_width;
+
+        // max_compute_units
+
         cl_uint device_processors;
 
         hc_clGetDeviceInfo (device_param->device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof (device_processors), &device_processors, NULL);
@@ -12564,18 +12678,17 @@ int main (int argc, char **argv)
 
         hc_clGetDeviceInfo (device_param->device, CL_DRIVER_VERSION, INFOSZ, driver_version, NULL);
 
-        if (vendor_id == VENDOR_ID_AMD)
-        {
-          sscanf (driver_version, "%*16s %*16s %*16s (%[^)]16s)", driver_version);
-        }
-
         device_param->driver_version = driver_version;
 
         // device_name_chksum
 
         char *device_name_chksum = (char *) mymalloc (INFOSZ);
 
-        snprintf (device_name_chksum, INFOSZ - 1, "%u-%s-%s-%s-%d", device_param->vendor_id, device_param->device_name, device_param->device_version, device_param->driver_version, COMPTIME);
+        #if __x86_64__
+        snprintf (device_name_chksum, INFOSZ - 1, "%u-%u-%u-%s-%s-%s-%u", 64, device_param->vendor_id, device_param->vector_width, device_param->device_name, device_param->device_version, device_param->driver_version, COMPTIME);
+        #else
+        snprintf (device_name_chksum, INFOSZ - 1, "%u-%u-%u-%s-%s-%s-%u", 32, device_param->vendor_id, device_param->vector_width, device_param->device_name, device_param->device_version, device_param->driver_version, COMPTIME);
+        #endif
 
         uint device_name_digest[4];
 
@@ -12778,11 +12891,15 @@ int main (int argc, char **argv)
      * OpenCL devices: allocate buffer for device specific information
      */
 
+    #ifdef HAVE_HWMON
     int *temp_retain_fanspeed_value = (int *) mycalloc (devices_cnt, sizeof (int));
 
+    #ifdef HAVE_ADL
     ADLOD6MemClockState *od_clock_mem_status = (ADLOD6MemClockState *) mycalloc (devices_cnt, sizeof (ADLOD6MemClockState));
 
     int *od_power_control_status = (int *) mycalloc (devices_cnt, sizeof (int));
+    #endif // ADL
+    #endif
 
     /**
      * enable custom signal handler(s)
@@ -12801,6 +12918,7 @@ int main (int argc, char **argv)
      * User-defined GPU temp handling
      */
 
+    #ifdef HAVE_HWMON
     if (gpu_temp_disable == 1)
     {
       gpu_temp_abort  = 0;
@@ -12820,6 +12938,7 @@ int main (int argc, char **argv)
     data.gpu_temp_disable = gpu_temp_disable;
     data.gpu_temp_abort   = gpu_temp_abort;
     data.gpu_temp_retain  = gpu_temp_retain;
+    #endif
 
     /**
      * inform the user
@@ -12852,6 +12971,7 @@ int main (int argc, char **argv)
        * Watchdog and Temperature balance
        */
 
+      #ifdef HAVE_HWMON
       if (gpu_temp_abort == 0)
       {
         log_info ("Watchdog: Temperature abort trigger disabled");
@@ -12869,6 +12989,7 @@ int main (int argc, char **argv)
       {
         log_info ("Watchdog: Temperature retain trigger set to %uc", gpu_temp_retain);
       }
+      #endif
     }
 
     if (data.quiet == 0) log_info ("");
@@ -12877,15 +12998,18 @@ int main (int argc, char **argv)
      * HM devices: init
      */
 
-    hm_attrs_t hm_adapters_nv[DEVICES_MAX];
-    hm_attrs_t hm_adapters_amd[DEVICES_MAX];
+    #ifdef HAVE_HWMON
+    #if defined(HAVE_NVML) || defined(HAVE_NVAPI)
+    hm_attrs_t hm_adapters_nv[DEVICES_MAX]  = { { { 0 }, 0, 0 } };
+    #endif
 
-    memset (hm_adapters_nv,  0, sizeof (hm_adapters_nv));
-    memset (hm_adapters_amd, 0, sizeof (hm_adapters_amd));
+    #ifdef HAVE_ADL
+    hm_attrs_t hm_adapters_amd[DEVICES_MAX] = { { { 0 }, 0, 0 } };
+    #endif
 
     if (gpu_temp_disable == 0)
     {
-      #ifdef WIN
+      #if defined(WIN) && defined(HAVE_NVAPI)
       if (NvAPI_Initialize () == NVAPI_OK)
       {
         HM_ADAPTER_NV nvGPUHandle[DEVICES_MAX];
@@ -12906,9 +13030,9 @@ int main (int argc, char **argv)
           if (NvAPI_GPU_GetTachReading (hm_adapters_nv[i].adapter_index.nv, &speed) != NVAPI_NOT_SUPPORTED) hm_adapters_nv[i].fan_supported = 1;
         }
       }
-      #endif
+      #endif // WIN && HAVE_NVAPI
 
-      #ifdef LINUX
+      #if defined(LINUX) && defined(HAVE_NVML)
       HM_LIB hm_dll_nv = hm_init (VENDOR_ID_NV);
 
       data.hm_dll_nv = hm_dll_nv;
@@ -12936,8 +13060,9 @@ int main (int argc, char **argv)
           }
         }
       }
-      #endif
+      #endif // LINUX && HAVE_NVML
 
+      #ifdef HAVE_ADL
       HM_LIB hm_dll_amd = hm_init (VENDOR_ID_AMD);
 
       data.hm_dll_amd = hm_dll_amd;
@@ -12982,6 +13107,7 @@ int main (int argc, char **argv)
           myfree (lpAdapterInfo);
         }
       }
+      #endif // HAVE_ADL
     }
 
     /**
@@ -13000,15 +13126,19 @@ int main (int argc, char **argv)
 
         const uint platform_devices_id = device_param->platform_devices_id;
 
+        #if defined(HAVE_NVML) || defined(HAVE_NVAPI)
         if (device_param->vendor_id == VENDOR_ID_NV)
         {
           memcpy (&data.hm_device[device_id], &hm_adapters_nv[platform_devices_id], sizeof (hm_attrs_t));
         }
+        #endif
 
+        #ifdef HAVE_ADL
         if (device_param->vendor_id == VENDOR_ID_AMD)
         {
           memcpy (&data.hm_device[device_id], &hm_adapters_amd[platform_devices_id], sizeof (hm_attrs_t));
         }
+        #endif
       }
     }
 
@@ -13020,6 +13150,7 @@ int main (int argc, char **argv)
     * Driver / ADL bug?
     */
 
+    #ifdef HAVE_ADL
     if (powertune_enable == 1)
     {
       hc_thread_mutex_lock (mux_adl);
@@ -13069,6 +13200,8 @@ int main (int argc, char **argv)
 
       hc_thread_mutex_unlock (mux_adl);
     }
+    #endif // HAVE_ADK
+    #endif // HAVE_HWMON
 
     uint kernel_blocks_all = 0;
 
@@ -13104,7 +13237,7 @@ int main (int argc, char **argv)
        * create command-queue
        */
 
-      // not support with NV
+      // not supported with NV
       // device_param->command_queue = hc_clCreateCommandQueueWithProperties (device_param->context, device_param->device, NULL);
 
       device_param->command_queue = hc_clCreateCommandQueue (device_param->context, device_param->device, 0);
@@ -13121,10 +13254,20 @@ int main (int argc, char **argv)
 
       if (device_type & CL_DEVICE_TYPE_CPU)
       {
-        // CPU still need lots of workitems, don't know why...
-        // for testing phase, lets start with this
-
-        kernel_accel = 1;
+        if (benchmark_mode == 0)
+        {
+          if (kernel_accel > 16)
+          {
+            kernel_accel = 16;
+          }
+        }
+        else
+        {
+          if (kernel_accel > 64)
+          {
+            kernel_accel = 64;
+          }
+        }
       }
 
       uint kernel_power  = device_processors * kernel_threads * kernel_accel;
@@ -13344,7 +13487,7 @@ int main (int argc, char **argv)
 
       // we don't have sm_* on vendors not NV but it doesn't matter
 
-      sprintf (build_opts, "-I%s/ -DVENDOR_ID=%d -DCUDA_ARCH=%d", shared_dir, device_param->vendor_id, (device_param->sm_major * 100) + device_param->sm_minor);
+      sprintf (build_opts, "-I%s/ -DVENDOR_ID=%d -DCUDA_ARCH=%d -DVECT_SIZE=%u -DDEVICE_TYPE=%u", shared_dir, device_param->vendor_id, (device_param->sm_major * 100) + device_param->sm_minor, device_param->vector_width, (u32) device_param->device_type);
 
       /**
        * main kernel
@@ -13355,9 +13498,7 @@ int main (int argc, char **argv)
          * kernel source filename
          */
 
-        char source_file[256];
-
-        memset (source_file, 0, sizeof (source_file));
+        char source_file[256] = { 0 };
 
         generate_source_kernel_filename (attack_exec, attack_kern, kern_type, shared_dir, source_file);
 
@@ -13374,9 +13515,7 @@ int main (int argc, char **argv)
          * kernel cached filename
          */
 
-        char cached_file[256];
-
-        memset (cached_file, 0, sizeof (cached_file));
+        char cached_file[256] = { 0 };
 
         generate_cached_kernel_filename (attack_exec, attack_kern, kern_type, profile_dir, device_name_chksum, cached_file);
 
@@ -13397,7 +13536,7 @@ int main (int argc, char **argv)
 
         const u8 **kernel_sources = (const u8 **) mymalloc (sizeof (u8 *));
 
-        if (force_jit_compilation == 0)
+        if (force_jit_compilation == -1)
         {
           if (cached == 0)
           {
@@ -13415,7 +13554,7 @@ int main (int argc, char **argv)
 
             u8 *binary = (u8 *) mymalloc (binary_size);
 
-            clGetProgramInfo (device_param->program, CL_PROGRAM_BINARIES, binary_size, &binary, NULL);
+            clGetProgramInfo (device_param->program, CL_PROGRAM_BINARIES, sizeof (binary), &binary, NULL);
 
             writeProgramBin (cached_file, binary, binary_size);
 
@@ -13486,9 +13625,7 @@ int main (int argc, char **argv)
          * kernel mp source filename
          */
 
-        char source_file[256];
-
-        memset (source_file, 0, sizeof (source_file));
+        char source_file[256] = { 0 };
 
         generate_source_kernel_mp_filename (opti_type, opts_type, shared_dir, source_file);
 
@@ -13505,9 +13642,7 @@ int main (int argc, char **argv)
          * kernel mp cached filename
          */
 
-        char cached_file[256];
-
-        memset (cached_file, 0, sizeof (cached_file));
+        char cached_file[256] = { 0 };
 
         generate_cached_kernel_mp_filename (opti_type, opts_type, profile_dir, device_name_chksum, cached_file);
 
@@ -13544,7 +13679,7 @@ int main (int argc, char **argv)
 
           u8 *binary = (u8 *) mymalloc (binary_size);
 
-          clGetProgramInfo (device_param->program_mp, CL_PROGRAM_BINARIES, binary_size, &binary, NULL);
+          clGetProgramInfo (device_param->program_mp, CL_PROGRAM_BINARIES, sizeof (binary), &binary, NULL);
 
           writeProgramBin (cached_file, binary, binary_size);
 
@@ -13599,9 +13734,7 @@ int main (int argc, char **argv)
          * kernel amp source filename
          */
 
-        char source_file[256];
-
-        memset (source_file, 0, sizeof (source_file));
+        char source_file[256] = { 0 };
 
         generate_source_kernel_amp_filename (attack_kern, shared_dir, source_file);
 
@@ -13618,9 +13751,7 @@ int main (int argc, char **argv)
          * kernel amp cached filename
          */
 
-        char cached_file[256];
-
-        memset (cached_file, 0, sizeof (cached_file));
+        char cached_file[256] = { 0 };
 
         generate_cached_kernel_amp_filename (attack_kern, profile_dir, device_name_chksum, cached_file);
 
@@ -13657,7 +13788,7 @@ int main (int argc, char **argv)
 
           u8 *binary = (u8 *) mymalloc (binary_size);
 
-          clGetProgramInfo (device_param->program_amp, CL_PROGRAM_BINARIES, binary_size, &binary, NULL);
+          clGetProgramInfo (device_param->program_amp, CL_PROGRAM_BINARIES, sizeof (binary), &binary, NULL);
 
           writeProgramBin (cached_file, binary, binary_size);
 
@@ -13948,9 +14079,7 @@ int main (int argc, char **argv)
        * kernel name
        */
 
-      char kernel_name[64];
-
-      memset (kernel_name, 0, sizeof (kernel_name));
+      char kernel_name[64] = { 0 };
 
       if (attack_exec == ATTACK_EXEC_INSIDE_KERNEL)
       {
@@ -14098,6 +14227,7 @@ int main (int argc, char **argv)
        * Store initial fanspeed if gpu_temp_retain is enabled
        */
 
+      #if defined(HAVE_HWMON) && defined(HAVE_ADL)
       int gpu_temp_retain_set = 0;
 
       if (gpu_temp_disable == 0)
@@ -14234,7 +14364,7 @@ int main (int argc, char **argv)
             int engine_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iEngineClock;
             int memory_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iMemoryClock;
 
-            // warning if profile has to low max values
+            // warning if profile has too low max values
 
             if ((engine_clock_max - engine_clock_profile_max) > warning_trigger_engine)
             {
@@ -14268,6 +14398,7 @@ int main (int argc, char **argv)
 
         hc_thread_mutex_unlock (mux_adl);
       }
+      #endif // HAVE_HWMON && HAVE_ADL
     }
 
     data.kernel_blocks_all = kernel_blocks_all;
@@ -15105,11 +15236,24 @@ int main (int argc, char **argv)
 
     if (weak_hash_threshold >= salts_cnt)
     {
+      uint first_device_id = 0;
+
+      for (uint device_id = 0; device_id < devices_cnt; device_id++)
+      {
+        hc_device_param_t *device_param = &data.devices_param[device_id];
+
+        if (device_param->skipped) continue;
+
+        first_device_id = device_id;
+
+        break;
+      }
+
       if (data.quiet == 0) log_info_nn ("Checking for weak hashes...");
 
       for (uint salt_pos = 0; salt_pos < salts_cnt; salt_pos++)
       {
-        weak_hash_check (&data.devices_param[0], salt_pos, kernel_loops);
+        weak_hash_check (&data.devices_param[first_device_id], salt_pos, kernel_loops);
       }
     }
 
@@ -15309,9 +15453,7 @@ int main (int argc, char **argv)
           data.css_cnt = css_cnt;
           data.css_buf = css_buf;
 
-          uint uniq_tbls[SP_PW_MAX][CHARSIZ];
-
-          memset (uniq_tbls, 0, sizeof (uniq_tbls));
+          uint uniq_tbls[SP_PW_MAX][CHARSIZ] = { { 0 } };
 
           mp_css_to_uniq_tbl (css_cnt, css_buf, uniq_tbls);
 
@@ -15759,9 +15901,7 @@ int main (int argc, char **argv)
 
           if (maskpos > 0 && dictpos == 0) free (masks[maskpos - 1]);
 
-          uint uniq_tbls[SP_PW_MAX][CHARSIZ];
-
-          memset (uniq_tbls, 0, sizeof (uniq_tbls));
+          uint uniq_tbls[SP_PW_MAX][CHARSIZ] = { { 0 } };
 
           mp_css_to_uniq_tbl (css_cnt, css_buf, uniq_tbls);
 
@@ -16053,8 +16193,6 @@ int main (int argc, char **argv)
         {
           hc_device_param_t *device_param = &devices_param[device_id];
 
-          if (device_param->skipped) continue;
-
           if (wordlist_mode == WL_MODE_STDIN)
           {
             hc_thread_create (c_threads[device_id], thread_calc_stdin, device_param);
@@ -16364,8 +16502,10 @@ int main (int argc, char **argv)
 
     // reset default fan speed
 
+    #ifdef HAVE_HWMON
     if (gpu_temp_disable == 0)
     {
+      #ifdef HAVE_ADL
       if (gpu_temp_retain != 0) // VENDOR_ID_AMD is implied here
       {
         hc_thread_mutex_lock (mux_adl);
@@ -16390,10 +16530,12 @@ int main (int argc, char **argv)
 
         hc_thread_mutex_unlock (mux_adl);
       }
+      #endif // HAVE_ADL
     }
 
     // reset power tuning
 
+    #ifdef HAVE_ADL
     if (powertune_enable == 1) // VENDOR_ID_AMD is implied here
     {
       hc_thread_mutex_lock (mux_adl);
@@ -16453,10 +16595,11 @@ int main (int argc, char **argv)
 
       hc_thread_mutex_unlock (mux_adl);
     }
+    #endif // HAVE_ADL
 
     if (gpu_temp_disable == 0)
     {
-      #ifdef LINUX
+      #if defined(LINUX) && defined(HAVE_NVML)
       if (data.hm_dll_nv)
       {
         hc_NVML_nvmlShutdown (data.hm_dll_nv);
@@ -16465,17 +16608,20 @@ int main (int argc, char **argv)
       }
       #endif
 
-      #ifdef WIN
+      #if defined(WIN) && (HAVE_NVAPI)
       NvAPI_Unload ();
       #endif
 
+      #ifdef HAVE_ADL
       if (data.hm_dll_amd)
       {
         hc_ADL_Main_Control_Destroy (data.hm_dll_amd);
 
         hm_close (data.hm_dll_amd);
       }
+      #endif
     }
+    #endif // HAVE_HWMON
 
     // free memory
 
@@ -16514,9 +16660,13 @@ int main (int argc, char **argv)
     local_free (bitmap_s2_c);
     local_free (bitmap_s2_d);
 
+    #ifdef HAVE_HWMON
     local_free (temp_retain_fanspeed_value);
+    #ifdef HAVE_ADL
     local_free (od_clock_mem_status);
     local_free (od_power_control_status);
+    #endif // ADL
+    #endif
 
     global_free (devices_param);