bench.c: add --help option and ci: move env variables #1008

pull siv2r wants to merge 2 commits into bitcoin-core:master from siv2r:bench-help changing 5 files +128 −16
  1. siv2r commented at 8:31 pm on November 8, 2021: contributor

    Fixes #1005

    Changes:

    • added --help option to bench.c
      • help() function prints the help to command-line
      • have_invalid_args() checks if the user has entered an invalid argument
    • moved secp256k1_bench_iters and secp256k1_test_iters environment variables declaration to .cirrus.yml
  2. siv2r force-pushed on Nov 8, 2021
  3. in src/bench.c:128 in a295754898 outdated
    121@@ -97,6 +122,25 @@ int main(int argc, char** argv) {
    122     int d = argc == 1;
    123     int iters = get_iters(20000);
    124 
    125+    /* Check for invalid user arguments */
    126+    char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
    127+                         "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign"};
    128+    int valid_args_size = 11;
    


    real-or-random commented at 7:30 am on November 9, 2021:
    You can just use sizeof(valid_args)
  4. in src/bench.c:136 in a295754898 outdated
    131+    if(argc > 1) {
    132+        if(have_flag(argc, argv, "-h")
    133+           || have_flag(argc, argv, "--help")
    134+           || have_flag(argc, argv, "help")) {
    135+            help(argv);
    136+            return 1;
    


    real-or-random commented at 7:32 am on November 9, 2021:
    I think it should return 0 when the it outputs the help. Other binaries do the same, e.g., try ls --help.

    siv2r commented at 9:39 am on November 9, 2021:

    ls --help does say:

    Exit status: 0 if OK, 1 if minor problems (e.g., cannot access subdirectory), 2 if serious trouble (e.g., cannot access command-line argument).

    I used return 1 here since the bench_ecmult.c followed this convention.

    Shall I also modify bench_ecmult's help to return 0?


    real-or-random commented at 12:18 pm on November 9, 2021:
    Oh indeed, I think that’s wrong in bench_ecmult too

    siv2r commented at 12:23 pm on November 9, 2021:
    Okay, will update both.
  5. in src/bench.c:131 in a295754898 outdated
    126+    char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
    127+                         "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign"};
    128+    int valid_args_size = 11;
    129+    int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);
    130+
    131+    if(argc > 1) {
    


    real-or-random commented at 7:33 am on November 9, 2021:
    We usually have a space after keywords like if and for.
  6. in src/bench.h:139 in a295754898 outdated
    134+
    135+    while (argv != NULL && argv != argm) {
    136+        check = 0;
    137+        for(i=0; i<n; i++) {
    138+            if(!strcmp(*argv, valid_arg_list[i])) {
    139+                check = 1; /* user entered a valid arg from the list */
    


    real-or-random commented at 7:50 am on November 9, 2021:
    You could break the loop here.
  7. in src/bench.h:130 in a295754898 outdated
    124@@ -125,6 +125,28 @@ int have_flag(int argc, char** argv, char *flag) {
    125     return 0;
    126 }
    127 
    128+/* check for invalid command line argument */
    129+/* valid_arg_list = list of allowed user arguments,  n = size of valid_arg_list */
    130+int have_invalid_args(int argc, char** argv, char** valid_arg_list, int n) {
    


    real-or-random commented at 7:51 am on November 9, 2021:
    I think it’s clearer to use the same name valid_args instead of valid_arg_list. (Anyway, it’s an array, not a list. :)) Also size arguments typically use type size_t. (Okay, argc is an int but that’s just C legacy…)

    siv2r commented at 9:40 am on November 9, 2021:
    Okay
  8. in src/bench.h:131 in a295754898 outdated
    124@@ -125,6 +125,28 @@ int have_flag(int argc, char** argv, char *flag) {
    125     return 0;
    126 }
    127 
    128+/* check for invalid command line argument */
    129+/* valid_arg_list = list of allowed user arguments,  n = size of valid_arg_list */
    130+int have_invalid_args(int argc, char** argv, char** valid_arg_list, int n) {
    131+    int i, check;
    


    real-or-random commented at 7:51 am on November 9, 2021:
    Maybe there’s a more descriptive name for check, e.g., found_valid.
  9. in src/bench.h:138 in a295754898 outdated
    133+    argv++;
    134+
    135+    while (argv != NULL && argv != argm) {
    136+        check = 0;
    137+        for(i=0; i<n; i++) {
    138+            if(!strcmp(*argv, valid_arg_list[i])) {
    


    real-or-random commented at 7:54 am on November 9, 2021:
    I think it’s slightly more readable to check strcmp(...) == 0 instead of !strcmp because the outputs of strcmp is not just a boolean value.
  10. in src/bench.c:138 in a295754898 outdated
    133+           || have_flag(argc, argv, "--help")
    134+           || have_flag(argc, argv, "help")) {
    135+            help(argv);
    136+            return 1;
    137+        } else if(invalid_args) {
    138+            fprintf(stderr, "%s: unrecognized argument was entered.\n\n", argv[0]);
    


    real-or-random commented at 7:58 am on November 9, 2021:
    I suggest just “unrecognized argument” or “invalid argument”… Strictly speaking, you can’t tell whether it was “entered”, (it could be coming from some script), and error message of command line tools typically are not full sentences.
  11. in src/bench.h:128 in a295754898 outdated
    124@@ -125,6 +125,28 @@ int have_flag(int argc, char** argv, char *flag) {
    125     return 0;
    126 }
    127 
    128+/* check for invalid command line argument */
    


    real-or-random commented at 8:01 am on November 9, 2021:
    You have a nice description of this function (including return values) in the commit message, but not here. Maybe move it here to a comment. It’s not that helpful in the commit message.
  12. in src/bench.c:21 in a295754898 outdated
    16+    printf("    1. ECDSA signing/verification\n");
    17+    printf("    2. ECDH key exchange (optional module)\n");
    18+    printf("    3. Public key recovery (optional module)\n");
    19+    printf("    4. Schnorr signatures (optional module)\n");
    20+    printf("\n");
    21+    printf("The default number of iterations for each benchmark is 20000. This can be customized\n");
    


    real-or-random commented at 8:03 am on November 9, 2021:
    Text looks nice here! Maybe make the default a variable and then print it here. Then whenever we change the default, the number gets updated automatically in the help text.

    siv2r commented at 9:43 am on November 9, 2021:
    Nice!

    siv2r commented at 1:57 pm on November 9, 2021:
    I initially thought of creating a macro for the default value in bench.h. The other benchmarks (like bench_ecmlult uses 10000) use a different default iteration value so, I declared a local variable in the main function for the default value.
  13. in src/bench.c:15 in a295754898 outdated
    10@@ -11,6 +11,31 @@
    11 #include "util.h"
    12 #include "bench.h"
    13 
    14+void help(char **argv) {
    15+    printf("Benchmarks the following algorithms: \n");
    


    real-or-random commented at 8:03 am on November 9, 2021:
    nit: trailing space behind the :.
  14. real-or-random commented at 8:04 am on November 9, 2021: contributor
    Thanks for the PR!
  15. siv2r force-pushed on Nov 9, 2021
  16. siv2r commented at 2:31 pm on November 9, 2021: contributor
    Incorporated all the suggestions :)
  17. real-or-random approved
  18. real-or-random commented at 2:54 pm on November 9, 2021: contributor
    ACK 89939feb33c3e3b616848f23de9d624d1bec8060
  19. siv2r commented at 2:57 pm on November 9, 2021: contributor

    There is one corner case that is not covered. The binary prints the table header if the user tries to benchmark an optional module without building it. Shall I add a check for this? Or is it too much?

    The check would look something like this:

    0#ifndef ENABLE_MODULE_SCHNORRSIG
    1    if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) { 
    2         fprintf(stderr, "%s: schnorr module not enabled.\n\n", argv[0]);
    3         return 1;
    4    }
    5#endif
    
  20. in src/bench.c:24 in da9a51abd8 outdated
    19+    printf("    4. Schnorr signatures (optional module)\n");
    20+    printf("\n");
    21+    printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
    22+    printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
    23+    printf("\n");
    24+    printf("Usage: %s [args]\n", argv[0]);
    


    real-or-random commented at 2:58 pm on November 9, 2021:

    What’s a little bit strange is that we typically run this via ./bench but this is a script to some autotools magic. So what I get here on my machine is something like Usage: /<redacted>/secp256k1/.libs/lt-bench [args]. I know using argv[0] is common but in this case, it’s rather cumbersome

    Happy to keep my ACK but if you’re motivated, I think in this case a simple: Usage: ./bench [args] is better.


    siv2r commented at 3:01 pm on November 9, 2021:
    Yeah, I was getting similar output too. I did not know why. I will hardcode the ./bench value.
  21. in src/bench.c:35 in da9a51abd8 outdated
    30+    printf("    ecdsa_verify      : ecdsa verification algorithm\n");
    31+    printf("    ecdsa_recover     : ecdsa public key recovery algorithm\n");
    32+    printf("    ecdh              : ecdh key exchange algorithm\n");
    33+    printf("    schnorrsig        : all schnorr signature algorithms (sign, verify)\n");
    34+    printf("    schnorrsig_sign   : schnorr sigining algorithm\n");
    35+    printf("    schnorrsig_verify : schnorr verification algorithm\n");
    


    real-or-random commented at 2:59 pm on November 9, 2021:
    nit: Could capitalize ECDSA, ECDH and Schnorr here in the right column if you’re on it.

    siv2r commented at 3:02 pm on November 9, 2021:
    Sure!
  22. real-or-random commented at 3:03 pm on November 9, 2021: contributor

    There is one corner case that is not covered. The binary prints the table header if the user tries to benchmark an optional module without building it. Shall I add a check for this? Or is it too much?

    It won’t hurt but yeah since this is “only” the benchmarks, it’s not really necessary (like my other two comments). This PR is clearly an improvement even without those issues addressed.

  23. siv2r commented at 3:04 pm on November 9, 2021: contributor
    Okay, I will add them just in case.
  24. siv2r force-pushed on Nov 9, 2021
  25. siv2r commented at 3:48 pm on November 9, 2021: contributor
    Updates: - check for optional modules - capitalized ECDH, ECDSA, Schnorr in help text - hardcoded ./bench value
  26. real-or-random approved
  27. real-or-random commented at 10:36 am on November 16, 2021: contributor
    ACK c69060d303604f8dd03e915e9e6a8379076633ea
  28. in src/bench.c:16 in 61b299e43a outdated
    10@@ -11,6 +11,31 @@
    11 #include "util.h"
    12 #include "bench.h"
    13 
    14+void help(int default_iters) {
    15+    printf("Benchmarks the following algorithms:\n");
    16+    printf("    1. ECDSA signing/verification\n");
    


    sipa commented at 7:35 pm on November 16, 2021:
    These lines can be surrounded with #ifdef ENABLE_MODULE_ECDH etc to make it only print the relevant ones (same below).

    real-or-random commented at 5:58 pm on November 24, 2021:
    I think when @sipa said “same below”, he meant that the same could be done in the “args:” list printed further down. This is still missing. Changes look good otherwise.

    siv2r commented at 6:09 pm on November 24, 2021:
    Oh, I forgot about the args list. Thanks!
  29. in src/bench.c:34 in 61b299e43a outdated
    19+    printf("    4. Schnorr signatures (optional module)\n");
    20+    printf("\n");
    21+    printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
    22+    printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
    23+    printf("\n");
    24+    printf("Usage: ./bench [args]\n");
    


    sipa commented at 7:36 pm on November 16, 2021:
    Common practice is to use argv[0] for printing the binary name (which keeps working if it is renamed etc, or on systems where executable have extensions).

    real-or-random commented at 11:58 pm on November 16, 2021:
    I specifically asked for the hardcoded earlier in this PR: #1008 (review)

    sipa commented at 2:28 pm on November 18, 2021:
    Ah, good point. I retract my comment.
  30. in src/bench.c:146 in 61b299e43a outdated
    142+            return 1;
    143+        }
    144+    }
    145+
    146+    /* Check if the user tries to benchmark optional module without building it */
    147+    #ifndef ENABLE_MODULE_ECDH
    


    sipa commented at 7:43 pm on November 16, 2021:

    I find it somewhat ugly that there is this much module-specific information inside main(), but I don’t have a concrete suggestion on how to cleanly do it otherwise.

    I’ll try to address this in a follow-up PR if no simple solution can be used here.


    siv2r commented at 6:17 am on November 17, 2021:
    we can create a separate functions for these checks (like int check_ecdh_enabled(argc,argv)) in the bench.h. Not sure if this is a good approach.
  31. siv2r force-pushed on Nov 22, 2021
  32. siv2r commented at 1:37 am on November 22, 2021: contributor

    Update:

    • added #ifdef ENABLE_MODULE_ECDH etc to void help(), prints only the relevant module-info.
  33. siv2r force-pushed on Nov 24, 2021
  34. siv2r commented at 7:20 pm on November 24, 2021: contributor
    • added #ifdef ENABLE_MODULE_ECDH etc to void help(), prints only the relevant module-info.

    I forgot to add these to the arg list, which has been taken care of now.

  35. real-or-random approved
  36. real-or-random commented at 8:21 pm on November 24, 2021: contributor
    ACK 8d3efeeb1de16d8051ba874a10c44c16fe379530
  37. bench: add --help option to bench.
    The following functions were created:
        1. bench.c: help()
            - prints the help to the command-line
        2. bench.h: have_invalid_args()
            - takes a list of arguments that the user is allowed to enter on the command-line
            - returns 1 if the user entered an invalid argument
            - returns 0 if all the user entered arguments are valid
    dcbe84b841
  38. ci: move test environment variable declaration to .cirrus.yml
    environment var moved:
        1. SECP256K1_TEST_ITERS (replaces TEST_ITERS)
        2. SECP256K1_BENCH_ITERS (replaces BENCH_ITERS)
    592661c22f
  39. in src/bench.h:138 in c878d08e47 outdated
    133+    size_t i;
    134+    int found_valid;
    135+    char** argm = argv + argc;
    136+    argv++;
    137+
    138+    while (argv != NULL && argv != argm) {
    


    sipa commented at 6:46 pm on December 3, 2021:
    argv will never be NULL, as it is the result of applying argv++; one or more times on the input. Did you mean to write *argv != NULL here?

    siv2r commented at 3:06 am on December 4, 2021:

    Nice catch, Thanks! I used argv != NULL since the have_flag function used the same loop condition to traverse user arguments.

    *argv != NULL should be used (as you mentioned) in both this function and the have_flag function.

    I will update it.


    siv2r commented at 3:18 am on December 4, 2021:
    I thought argv will behave as a normal 2d char array so, I assumed both argv and *argv values will be the same (i.e. base address of argument string). This does not seem to be the case. I confirmed this by printing out their values (see here).

    sipa commented at 3:24 am on December 4, 2021:
    The type of argv is char**, so it’s a pointer to pointer, not an array.
  40. siv2r force-pushed on Dec 4, 2021
  41. siv2r commented at 5:56 pm on December 4, 2021: contributor

    Update:

    • removed argv != NULL check in the while loop traversing the user arguments.

    The argv cannot have a NULL value so, *argv != NULL might be the proper check here (as suggested in #1008 (review)). Then, I realized we also don’t need the *argv != NULL check in the while loop since, argv != argm condition will take care of this. The value of *argm (or argv[argc]) will be NULL if argm == argv + argc (C89 draft)

  42. sipa commented at 4:22 am on December 5, 2021: contributor
    utACK 592661c22f56736099f83700be8cf280f8a963ff
  43. real-or-random approved
  44. real-or-random commented at 10:23 am on December 5, 2021: contributor
    ACK 592661c22f56736099f83700be8cf280f8a963ff
  45. real-or-random merged this on Dec 5, 2021
  46. real-or-random closed this on Dec 5, 2021

  47. siv2r deleted the branch on Dec 15, 2021
  48. sipa referenced this in commit 86dbc4d075 on Dec 15, 2021
  49. sipa cross-referenced this on Dec 15, 2021 from issue Update libsecp256k1 subtree to current master by sipa
  50. jonasnick cross-referenced this on Jan 2, 2022 from issue Sync Upstream by jonasnick
  51. real-or-random referenced this in commit 21e2d65b79 on Jan 5, 2022
  52. gwillen referenced this in commit 35d6112a72 on May 25, 2022
  53. janus referenced this in commit 879a9a27b9 on Jul 10, 2022
  54. patricklodder referenced this in commit 21badcf9d2 on Jul 25, 2022
  55. patricklodder referenced this in commit 03002a9013 on Jul 28, 2022
  56. backpacker69 referenced this in commit 77186f4a04 on Jan 18, 2023
  57. str4d referenced this in commit 6de4698bf9 on Apr 21, 2023
  58. vmta referenced this in commit e1120c94a1 on Jun 4, 2023
  59. vmta referenced this in commit 8f03457eed on Jul 1, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-22 21:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me