How to use hash function in pna?

The function is defined in pna.p4 as follows.

// BEGIN:Hash_extern
extern Hash<O> {
  /// Constructor
  Hash(PNA_HashAlgorithm_t algo);

  /// Compute the hash for data.
  /// @param data The data over which to calculate the hash.
  /// @return The hash value.
  O get_hash<D>(in D data);

  /// Compute the hash for data, with modulo by max, then add base.
  /// @param base Minimum return value.
  /// @param data The data over which to calculate the hash.
  /// @param max The hash value is divided by max to get modulo.
  ///        An implementation may limit the largest value supported,
  ///        e.g. to a value like 32, or 256, and may also only
  ///        support powers of 2 for this value.  P4 developers should
  ///        limit their choice to such values if they wish to
  ///        maximize portability.
  /// @return (base + (h % max)) where h is the hash value.
  O get_hash<T, D>(in T base, in D data, in T max);
}
// END:Hash_extern

And I try to write the following code. Are there any errors? Thanks for your reply.

    action compute_hashes(bit<32> ipAddr1, 
                          bit<32> ipAddr2, 
                          bit<16> port1, 
                          bit<16> port2,
                          bit<32> register_position){
        PNA_HashAlgorithm_t hashAlgorithm = ONES_COMPLEMENT16;
        Hash<bit<32>> hash(hashAlgorithm);
        register_position = hash.get_hash({ipAddr1, ipAddr2, port1, port2});
    }

That looks correct to me, except for one thing: In the P4 language (not only for the PNA archtitecture, but any architecture), all parameters to extern object constructor methods must be compile-time known values, e.g. a literal constant, not the value of a run-time variable.

Thus I would recommend replacing these lines:

        PNA_HashAlgorithm_t hashAlgorithm = ONES_COMPLEMENT16;
        Hash<bit<32>> hash(hashAlgorithm);

with this:

        Hash<bit<32>> hash(PNA_HashAlgorithm_t.ONES_COMPLEMENT16);

Hello @yangyetlin ,

In addition to @andyfingerhut 's reply, I also want to point out that the current version of the language specification does not allow writing into the action data. In the code you quoted, register_position parameter is directionless, meaning that it is read from the match-action table to be used in the computations. It cannot be written back (see Section 14.1 or the current spec).

I also want to mention that even though the current spec allows instantiating externs inside the actions, many targets do not support that. Instead, it is recommended to instantiate those outside of an action, in the control. The reason is that externs might have their own control plane APIs and instantiating them inside actions makes generating those APIs a lot more problematic.

Happy hacking,
Vladimir

Sorry for not replying to your message for days.
I tried Andy’s code, but the p4c-dpdk compiler reported a syntax error.

/root/examples/first_pkt_decide_register/first_pkt_decide_register.p4(129):syntax error, unexpected (, expecting ;
    Hash<bit<32>> hash(
                      ^
[--Werror=overlimit] error: 1 errors encountered, aborting compilation

So I made some small changes to the code as follows.

Hash<bit<32>>(PNA_HashAlgorithm_t.ONES_COMPLEMENT16) hash1;

But more errors occurred. :upside_down_face:

/root/examples/first_pkt_decide_register/first_pkt_decide_register.p4(127): [--Werror=type-error] error: PNA_HashAlgorithm_t.ONES_COMPLEMENT16: Invalid enum tag
    Hash<bit<32>>(PNA_HashAlgorithm_t.ONES_COMPLEMENT16) hash1;
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/root/examples/first_pkt_decide_register/first_pkt_decide_register.p4(127): [--Werror=type-error] error: hash1
    Hash<bit<32>>(PNA_HashAlgorithm_t.ONES_COMPLEMENT16) hash1;
                                                         ^^^^^
  ---- Actual error:
  /root/p4c/install/share/p4c/p4include/dpdk/../pna.p4(273): Cannot cast implicitly type 'Type(PNA_HashAlgorithm_t)' to type 'PNA_HashAlgorithm_t'
  enum PNA_HashAlgorithm_t {
       ^^^^^^^^^^^^^^^^^^^
  ---- Originating from:
  /root/examples/first_pkt_decide_register/first_pkt_decide_register.p4(127): Type of argument 'PNA_HashAlgorithm_t.ONES_COMPLEMENT16' (Type(PNA_HashAlgorithm_t)) does not match type of parameter 'algo' (PNA_HashAlgorithm_t)
      Hash<bit<32>>(PNA_HashAlgorithm_t.ONES_COMPLEMENT16) hash1;
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  /root/p4c/install/share/p4c/p4include/dpdk/../pna.p4(282)
    Hash(PNA_HashAlgorithm_t algo);
                             ^^^^
  /root/p4c/install/share/p4c/p4include/dpdk/../pna.p4(273)
  enum PNA_HashAlgorithm_t {
       ^^^^^^^^^^^^^^^^^^^
  ---- Originating from:
  /root/examples/first_pkt_decide_register/first_pkt_decide_register.p4(127): Constructor invocation <Method call> does not match constructor declaration Hash
      Hash<bit<32>>(PNA_HashAlgorithm_t.ONES_COMPLEMENT16) hash1;
                                                           ^^^^^
  /root/p4c/install/share/p4c/p4include/dpdk/../pna.p4(282)
    Hash(PNA_HashAlgorithm_t algo);
    ^^^^

There may be other requirements for the syntax of the code. :cry: