The top-level package file

The goal of the top-level package file is to make as many function of the MPFQ API reachable. The top-level package file also must define a Perl object. We discuss by example the file provided in the MPFQ distribution as an example, under src/gf7/gf7.pm.

We proceed through this file line by line (comments, which exist in the file, are stripped off here).

package gf7;

use strict;
use warnings;

Not much to say about the first fragment above. The package name must match the file name.

use Mpfq::engine::handler;
our @ISA = qw/Mpfq::engine::handler/;
sub new { return bless({},shift); }

Here we set up the object mechanism. Not much (well actually nothing) is conveyed within the object in terms of data[1]. The main use of the object is to contain a reference to a given package.

use Mpfq::defaults;
use Mpfq::defaults::flatdata;
use Mpfq::defaults::poly;
our @parents = qw/
    Mpfq::defaults
    Mpfq::defaults::flatdata
    Mpfq::defaults::poly
/;

The fragment above lists the parents of the given package. All package files may mention such parents.

our $resolve_conflicts = {
    vec_set => 'Mpfq::defaults::flatdata',
    vec_ur_set => 'Mpfq::defaults::flatdata',
};

This is optional, and is used to disambiguate possible conflicts.

sub code_for_add { return [ 'inline(K!, z, x, y)', "z = (x+y)%7;" ]; }

This is one of the code generation functions expected in this file.

sub code_for_sub_helper {
    return {
        kind=>'inline(z, x, y)',
        name=>'sub_helper',
        requirements=>'dst_elt src_elt src_elt',
        code=>'z = x-y;',
    };
}
# The function called by the automatic generator should return as usual
# its proto and its code, but additionnally a hash describing the helper
# function (there might be several of them).
sub code_for_sub {
    my $proto = 'inline(k, z, x, y)';
    my $code = '';
    $code .= "@!sub_helper(z, x, y);\n";
    $code .= "if ((long)z < 0)\n";
    $code .= "      z += 7;\n";
    return [ $proto, $code ], code_for_sub_helper();
}

This example is slightly more complicated and uses the extended syntax allowed for code_for_xxx, where dependencies between functions are possible.

sub init_handler {
  my $types = {
    elt =>      "typedef unsigned long @!elt\[1\];",
    dst_elt =>  "typedef unsigned long * @!dst_elt;",
    src_elt =>  "typedef const unsigned long * @!src_elt;",

    elt_ur =>   "typedef unsigned long @!elt_ur\[1\];",
    dst_elt_ur =>       "typedef unsigned long * @!dst_elt_ur;",
    src_elt_ur =>       "typedef const unsigned long * @!src_elt_ur;",

    field       =>      'typedef void * @!field;',
    dst_field   =>      'typedef void * @!dst_field;',
  };
  return { types => $types };
}
1;

This finished the package file (note the 1;). The init_handler provides some typedefs to be included in the generated code.



[1] But this could evolve otherwise in the future.