Ilya Zakharevich on Fri, 12 Jan 2024 23:49:32 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Tuneup of optimizations in PARI


In a lot of algorithms, there is a lot of variants to select from and
a lot of continuous tuning parameters to choose.  Whoever implements
these algorithms has difficult choices

It goes without saying that the simplest strategy is to

  • Do not spend a lot of blood on this and have only “halfway reasonable” defaults.

  • Delegate the responsibility to the user for the actual choices.

One of the complications of this approach is that the implementation
may change, and these tuneups do not make sense any more!  When I
encountered this problem tuning up forprime() (about 2 decades ago)
the solution was:

  • allow dynamic creation of gp() functions from C functions in PARI;
  • make it possible to install() a special C function for tuning up the
    parameters.
  
This way, the responsibility to “match the changes in implementation”
is again delegated to the users.

⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜⁜  But is there a better way?!

Nowadays, I have something like this in mind:

  tuneup(forprime::L1cacheD, {val})  (or maybe tuneup(“forprime::L1cacheD”, {val})) 

This function never fails, so it is safe to use¹⁾ even if the
implementation changes.  Instead, it returns "N/A" on read (and the
values like -1, -2, 0 on write for NO␣SUCH␣TUNEUP, WRONG␣TUNEUP␣TYPE,
OUT␣OF␣BOUND errors).

   ¹⁾ An alternative way may be to make it fail on errors, but have a
      lightweight wrapper for the (current monstrosity of) iferr(),
      like
      
        try( tuneup( forprime::L1cacheD ) ).

The C code would just declare

  TUNEUPDEF(     double, forprime_L1cacheD, MINVAL, MAXVAL, default)

or

  TUNEUPDEF_DOCS(double, forprime_L1cacheD, MINVAL, MAXVAL, default, DOCS)

The build process would scan the C files to extract the info to make
it accessible to the tuneup() function.

What do you think?

Thanks,
Ilya