[P4-dev] Fwd: implementing your own hash algorithms in bmv2

Antonin Bas antonin at barefootnetworks.com
Fri Jun 17 23:39:06 EDT 2016


This email was sent a few months ago on the p4-dev mailing list (before we
lost our archives). I am forwarding it to the list since someone expressed
interest in implementing custom hash functions.

Antonin

---------- Forwarded message ----------
From: Antonin Bas <antonin at barefootnetworks.com>
Date: Tue, Nov 24, 2015 at 6:34 PM
Subject: implementing your own hash algorithms in bmv2
To: P4 Dev <p4-dev at p4.org>


Hi all,

Last week, at the first P4 Bootcamp, several people asked about how to
implement their own hash functions in bmv2 (e.g. to use in P4
"field_list_calculation"). This can be useful when a P4 program uses
several "registers", each indexed by a different field_list_calculation
(same input field_list, but different algorithm).

While this functionality has been available for a while in bmv2, we decided
to make it easier for P4 programmers to implement their own hash algorithms.

By default, bmv2 supports "crc16" and "xxh64" (
https://github.com/Cyan4973/xxHash). When you define a target, you can
define new C++ functors to implement your own hash algorithms. As an
example, I added one new hash algorithm to the simple_switch target (
https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/simple_switch.cpp#L41
):

struct hash_ex {
  uint32_t operator()(const char *buf, size_t s) const {
    const int p = 16777619;
    int hash = 2166136261;

    for (size_t i = 0; i < s; i++)
      hash = (hash ^ buf[i]) * p;

    hash += hash << 13;
    hash ^= hash >> 7;
    hash += hash << 3;
    hash ^= hash >> 17;
    hash += hash << 5;
    return static_cast<uint32_t>(hash);
  }
};

REGISTER_HASH(hash_ex);


Feel free to add your own hash algorithms to the simple_switch target (this
is the default target, which implements the standard device model described
in the P4 specification). The constraints on the functor are as follows:
- the return type needs to be some unsigned integer type (uint8_t,
uint16_t, uint32_t, uint64_t)
- the parameters have to be a "const char *" and a "size_t"
- the overloaded '()' operator needs to be const

A hash algorithm that returns 77 no matter what the input is would look
like this:

struct silly_hash {
  uint32_t operator()(const char *buf, size_t s) const {
    return 77u;
  }
};

REGISTER_HASH(silly_hash);

The name that you give to your functor (e.g. "hash_ex", "silly_hash") is
the name you have to use in the P4 program:

field_list_calculation my_calculation {
    input {
        <some_field_list>;
    }
    algorithm : silly_hash; // my own hash!
    output_width : 32; // ignored for now
}

I hope that will help a few of you in your P4 experiments.

Let us know if you have any feature suggestions for bmv2.

Thanks,

-- 
Antonin



-- 
Antonin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20160617/b0395109/attachment-0002.html>


More information about the P4-dev mailing list