Skip to content

Named Parameters

Calin Cascaval edited this page Apr 16, 2018 · 8 revisions

Named parameters

The goal of this proposal is to extend the syntax of P4_16 to support named parameters to controls, tables, actions, externs, and packages. The main motivation is to enable optional parameters to enable reducing the overhead of listing all parameters and limit the ordering constraints.

Status quo

The p4c compiler currently supports optional parameters as an experimental feature. This is enabled by the @optional annotation followed by an ordered list of arguments. That is, if an optional argument is present, all preceeding arguments (non-optional and optional) must be present. Optional arguments apply to extern methods.

Design

We propose the following changes:

  • Calls specify parameters by name. By default, all parameters must be specified.
  • Optional parameters are specified by assigning a default parameter value: param_modifier param_type name = default_parameter_value
  • We allow specifying _ as the default value and the compiler will initialize the optional parameter with an appropriate value.
  • Mandatory parameters must preceed all optional parameters and all parameters must be called in the order in which they were declared. This is similar to C++, except that preceeding optional parameters can be fully omitted (as in Python).
  • We only allow optional parameters for some kinds of functions:
    • Constructors, including extern constructors and package constructors, controls, and parsers
    • Extern methods
  • The proposal is restricted to entities that are not exposed at runtime, i.e., control plane APIs do not support optional parameters
  • Optional parameters must be either in or directionless

Discussion on 4/16:

  • explicitly say controls and parser at runtime
  • why do we restrict to non-control plane APIs visible entities?
    • requires language bindings in the API
    • done for simplicity
  • where are the default (don't care) values defined.
  • expand the example for to include control
  • action params: what does the '_' mean?
  • how about things that produce an out value?
  • mixing named/unnamed parameters -- clear description of restrictions
    • examples on invocations
  • overloading
  • Mihai to give some examples

If accepted, the current @optional experimental feature will be deprecated in favor of this proposal.

Open issues

  • The need for defining a None value.

Examples

Controls

Current declarations of IngressParser in PSA:

parser IngressParser<H, M, RESUBM, RECIRCM>(
    packet_in buffer,
    out H parsed_hdr,
    inout M user_meta,
    in psa_ingress_parser_input_metadata_t istd,
    in RESUBM resubmit_meta,
    in RECIRCM recirculate_meta);

Implementation of IngressParser in psa-example-counters.p4, when the parser does not handle resubmit or recirculate:


parser IngressParserImpl(
    packet_in buffer,
    out headers parsed_hdr,
    inout metadata user_meta,
    in psa_ingress_parser_input_metadata_t istd,
    in empty_metadata_t resubmit_meta,
    in empty_metadata_t recirculate_meta)

Implementation of IngressParser in psa-example-resubmit.p4, when the parser only implements resubmit:

parser IngressParserImpl(
    packet_in buffer,
    out headers parsed_hdr,
    inout metadata user_meta,
    in psa_ingress_parser_input_metadata_t istd,
    in resubmit_metadata_t resub_meta,
    in empty_metadata_t recirculate_meta) { ... }

With proposed named parameters, the declaration makes the resubmit_meta and recirculate_meta named parameters, with default values.

Declaration:

parser IngressParser<H, M, RESUBM, RECIRCM>(
    packet_in buffer,
    out H parsed_hdr,
    inout M user_meta,
    in psa_ingress_parser_input_metadata_t istd,
    in RESUBM resubmit_meta = _,
    in RECIRCM recirculate_meta = _);

The counter example implementation declaration becomes:

parser IngressParserImpl(
    packet_in buffer,
    out headers parsed_hdr,
    inout metadata user_meta,
    in psa_ingress_parser_input_metadata_t istd) { ... }

The resubmit example implementation declaration becomes:

parser IngressParserImpl(
    packet_in buffer,
    out headers parsed_hdr,
    inout metadata user_meta,
    in psa_ingress_parser_input_metadata_t istd)
    in resubmit_metadata_t resubmit_meta) { ... }

Externs

The Register extern in PSA is declared as:

extern Register<T, S> {
  Register(bit<32> size);
  Register(bit<32> size, T initial_value);
}

With named parameters, the definition can become:

extern Register<T, S> {
  Register(bit<32> size, T initial_value = 0);
}

Package definitions

The PSA package definition is:

package PSA_Switch<IH, IM, EH, EM, NM, CI2EM, CE2EM, RESUBM, RECIRCM> (
    IngressPipeline<IH, IM, NM, CI2EM, RESUBM, RECIRCM> ingress,
    PacketReplicationEngine pre,
    EgressPipeline<EH, EM, NM, CI2EM, CE2EM, RECIRCM> egress,
    BufferingQueueingEngine bqe);

If we want a PSA-compatible program without an egress pipeline, we still have to declare all the Egress related controls (as empty) and instantiate an egress pipeline. With named arguments, the declaration can be:

package PSA_Switch<IH, IM, EH, EM, NM, CI2EM, CE2EM, RESUBM, RECIRCM> (
    IngressPipeline<IH, IM, NM, CI2EM, RESUBM, RECIRCM> ingress,
    PacketReplicationEngine pre = _,
    EgressPipeline<EH, EM, NM, CI2EM, CE2EM, RECIRCM> egress = _,
    BufferingQueueingEngine bqe = _);

And thus one can instantiate any combination of the pipeline without the need of instantiating all the controls:

PSA_Switch(my_ingress) main;

Moreover, since the pre and bqe are instantiated by default by the architecture, we can remove the need of macro hacks, and declare the switch:

PSA_Switch(ingress = my_ingress, egress = my_egress) main;
Clone this wiki locally