11#if  defined(_WIN32)
22#    include  < windows.h> 
33#else 
4+ #    include  < sys/ioctl.h> 
45#    include  < unistd.h> 
56#endif 
67
@@ -70,7 +71,7 @@ class Opt {
7071            " )\n " 
7172            "   -n, --ngl <value>\n " 
7273            "       Number of GPU layers (default: "   +
73-             std::to_string (ngl_ );
74+             std::to_string (llama_model_default_params (). n_gpu_layers );
7475        help_str_ +=
7576            " )\n " 
7677            "   -h, --help\n " 
@@ -96,8 +97,8 @@ class Opt {
9697            "   llama-run https://example.com/some-file1.gguf\n " 
9798            "   llama-run some-file2.gguf\n " 
9899            "   llama-run file://some-file3.gguf\n " 
99-             "   llama-run --ngl 99  some-file4.gguf\n " 
100-             "   llama-run --ngl 99  some-file5.gguf Hello World\n "  ;
100+             "   llama-run --ngl 999  some-file4.gguf\n " 
101+             "   llama-run --ngl 999  some-file5.gguf Hello World\n "  ;
101102    }
102103
103104    int  parse (int  argc, const  char  ** argv) {
@@ -270,9 +271,9 @@ class CurlWrapper {
270271
271272    static  std::string human_readable_size (curl_off_t  size) {
272273        static  const  char  * suffix[] = { " B"  , " KB"  , " MB"  , " GB"  , " TB"   };
273-         char          length   = sizeof (suffix) / sizeof (suffix[0 ]);
274-         int           i        = 0 ;
275-         double        dbl_size = size;
274+         char                  length   = sizeof (suffix) / sizeof (suffix[0 ]);
275+         int                   i        = 0 ;
276+         double                dbl_size = size;
276277        if  (size > 1024 ) {
277278            for  (i = 0 ; (size / 1024 ) > 0  && i < length - 1 ; i++, size /= 1024 ) {
278279                dbl_size = size / 1024.0 ;
@@ -284,6 +285,18 @@ class CurlWrapper {
284285        return  out.str ();
285286    }
286287
288+     static  int  get_terminal_width () {
289+ #    if  defined(_WIN32)
290+         CONSOLE_SCREEN_BUFFER_INFO csbi;
291+         GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
292+         return  csbi.srWindow .Right  - csbi.srWindow .Left  + 1 ;
293+ #    else 
294+         struct  winsize  w;
295+         ioctl (STDOUT_FILENO, TIOCGWINSZ, &w);
296+         return  w.ws_col ;
297+ #    endif 
298+     }
299+ 
287300    static  int  progress_callback (void  * ptr, curl_off_t  total_to_download, curl_off_t  now_downloaded, curl_off_t ,
288301                                 curl_off_t ) {
289302        progress_data * data = static_cast <progress_data *>(ptr);
@@ -293,27 +306,75 @@ class CurlWrapper {
293306
294307        total_to_download += data->file_size ;
295308        const  curl_off_t  now_downloaded_plus_file_size = now_downloaded + data->file_size ;
296-         const  curl_off_t  percentage                    = (now_downloaded_plus_file_size * 100 ) / total_to_download;
297-         const  curl_off_t  pos                           = (percentage / 5 );
309+         const  curl_off_t  percentage      = calculate_percentage (now_downloaded_plus_file_size, total_to_download);
310+         std::string      progress_prefix = generate_progress_prefix (percentage);
311+ 
312+         const  double  speed = calculate_speed (now_downloaded, data->start_time );
313+         const  double  time  = (total_to_download - now_downloaded) / speed;
314+         std::string  progress_suffix =
315+             generate_progress_suffix (now_downloaded_plus_file_size, total_to_download, speed, time);
316+ 
317+         int          progress_bar_width = calculate_progress_bar_width (progress_prefix, progress_suffix);
298318        std::string progress_bar;
299-         for  (int  i = 0 ; i < 20 ; ++i) {
300-             progress_bar.append ((i < pos) ? " █"   : "  "  );
301-         }
319+         generate_progress_bar (progress_bar_width, percentage, progress_bar);
302320
303-         //  Calculate download speed and estimated time to completion
304-         const  auto                           now             = std::chrono::steady_clock::now ();
305-         const  std::chrono::duration<double > elapsed_seconds = now - data->start_time ;
306-         const  double                         speed           = now_downloaded / elapsed_seconds.count ();
307-         const  double                         estimated_time  = (total_to_download - now_downloaded) / speed;
308-         printe (" \r %ld%% |%s| %s/%s  %.2f MB/s  %s      "  , percentage, progress_bar.c_str (),
309-                human_readable_size (now_downloaded).c_str (), human_readable_size (total_to_download).c_str (),
310-                speed / (1024  * 1024 ), human_readable_time (estimated_time).c_str ());
311-         fflush (stderr);
321+         print_progress (progress_prefix, progress_bar, progress_suffix);
312322        data->printed  = true ;
313323
314324        return  0 ;
315325    }
316326
327+     static  curl_off_t  calculate_percentage (curl_off_t  now_downloaded_plus_file_size, curl_off_t  total_to_download) {
328+         return  (now_downloaded_plus_file_size * 100 ) / total_to_download;
329+     }
330+ 
331+     static  std::string generate_progress_prefix (curl_off_t  percentage) {
332+         std::ostringstream progress_output;
333+         progress_output << percentage << " % |"  ;
334+         return  progress_output.str ();
335+     }
336+ 
337+     static  double  calculate_speed (curl_off_t  now_downloaded, const  std::chrono::steady_clock::time_point & start_time) {
338+         const  auto                           now             = std::chrono::steady_clock::now ();
339+         const  std::chrono::duration<double > elapsed_seconds = now - start_time;
340+         return  now_downloaded / elapsed_seconds.count ();
341+     }
342+ 
343+     static  std::string generate_progress_suffix (curl_off_t  now_downloaded_plus_file_size, curl_off_t  total_to_download,
344+                                                 double  speed, double  estimated_time) {
345+         std::ostringstream progress_output;
346+         progress_output << human_readable_size (now_downloaded_plus_file_size).c_str () << " /" 
347+                         << human_readable_size (total_to_download).c_str () << "  "   << std::fixed << std::setprecision (2 )
348+                         << speed / (1024  * 1024 ) << "  MB/s "   << human_readable_time (estimated_time).c_str ();
349+         return  progress_output.str ();
350+     }
351+ 
352+     static  int  calculate_progress_bar_width (const  std::string & progress_prefix, const  std::string & progress_suffix) {
353+         int  progress_bar_width = get_terminal_width () - progress_prefix.size () - progress_suffix.size () - 5 ;
354+         if  (progress_bar_width < 10 ) {
355+             progress_bar_width = 10 ;
356+         }
357+         return  progress_bar_width;
358+     }
359+ 
360+     static  std::string generate_progress_bar (int  progress_bar_width, curl_off_t  percentage,
361+                                              std::string & progress_bar) {
362+         const  curl_off_t  pos = (percentage * progress_bar_width) / 100 ;
363+         for  (int  i = 0 ; i < progress_bar_width; ++i) {
364+             progress_bar.append ((i < pos) ? " █"   : "  "  );
365+         }
366+ 
367+         return  progress_bar;
368+     }
369+ 
370+     static  void  print_progress (const  std::string & progress_prefix, const  std::string & progress_bar,
371+                                const  std::string & progress_suffix) {
372+         std::ostringstream progress_output;
373+         progress_output << progress_prefix << progress_bar << " | "   << progress_suffix;
374+         printe (" \r %s"  , progress_output.str ().c_str ());
375+         fflush (stderr);
376+     }
377+ 
317378    //  Function to write data to a file
318379    static  size_t  write_data (void  * ptr, size_t  size, size_t  nmemb, void  * stream) {
319380        FILE * out = static_cast <FILE *>(stream);
0 commit comments