[P4-dev] Queries related to primitives in json and bmv2 code

Hardik Soni hardik.soni at inria.fr
Thu Aug 10 06:11:30 EDT 2017


Hello, 

Ok, following is my understanding. If I am missing something, let me know. 
>From action definitions in json file actions_map is being created with value type as ActionFn . 
As I see in P4Objects::add_primitive_to_action all the parameters of "all" the primitives are being pushed into the same vector named params . 
Just above params , there is vector of ActionPrimitveCall named primitives . 
So, all the parameters of all the primitives are pushed into the same vector. 
ActionPrimitiveCall ctor has param_offset . However, I see it being used to slice the params vector in execution of ActionFnEntry::execute . 
And then unpack_caller in ActionPrimitiveCall calls the functors of primitive defined by the target, while unpacking the the args. 

My problem is following. 
I need (for my target) the direction and values of the parameters of the primitives stored inside the data-structures of the BMV2's code. Not as definitions. 
I do understand it is not the needed for BMV2 and P4 compiler, as they have definitions and they just pass the appropriate parameters to the primitives. 
For example, the way get_num_params deducts and stores the number of arguments, even if the source code of BMV2 already has the definitions for the core primitives. 
The values are available in params and along with primitive and param_offset , I have the access. 
For the directions, I am looking for some meta-programming construct to deduct in/out/in-out direction from the parameter pack at ActionPrimitive 
If you can suggest any approach, it will help. Thanks in advance. 

Worst case, I might have to add a pure virtual method in ActionPrimitive to force primitives to notify direction of their parameters explicitly even if they have defined it. 
Is there any other better place, where one time read of all the primitives can give directions of all the parameters of all the primitives in a data-structures inside the code?(not as reference or const references of c++) 

-Hardik 

----- Original Message -----

> From: "Hardik Soni" <hardik.soni at inria.fr>
> To: "Antonin Bas" <antonin at barefootnetworks.com>
> Cc: "p4-dev" <p4-dev at lists.p4.org>
> Sent: Thursday, 10 August, 2017 6:58:28 AM
> Subject: Re: [P4-dev] Queries related to primitives in json and bmv2 code

> Hi Antonin,

> Thank you for the answers, it helped a lot.
> From 4 and 5, can I conclude following?

> Compiler reads the primitive statement form action block of .p4 file. It
> Prepares left-to-right ordered list of parameters with their type, value
> tags in json.
> BMV2 reads the json, and as it already has the definitions of primitives, it
> pass the same ordered list, left-to-right to the operator of primitive.
> And because the the order is deterministic direction parameter implicitly
> matches, both P4 compiler and BMV2 know the definition.
> If it is the case can you point the code where ActionPrimitiveCall::execute
> being invoked(even if it is the overloaded )?
> It will save some code browsing. :)

> -Hardik

> ----- Original Message -----

> > From: "Antonin Bas" <antonin at barefootnetworks.com>
> 
> > To: "Hardik Soni" <hardik.soni at inria.fr>
> 
> > Cc: "p4-dev" <p4-dev at lists.p4.org>
> 
> > Sent: Wednesday, 9 August, 2017 11:15:39 PM
> 
> > Subject: Re: [P4-dev] Queries related to primitives in json and bmv2 code
> 

> > Q1: It is the job of the compiler to know which operations are available
> > for
> > a given architecture. Some are always available, they are referred to as
> > the
> > "core primitives" in the bmv2 JSON documentation (
> > https://github.com/p4lang/behavioral-model/blob/master/docs/JSON_format.md
> > ). For other operations, the name expected by bmv2 usually matches the name
> > in the P4 architecture file. This is the case for "truncate" (arch:
> > https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4#L141 , bmv2:
> > https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/primitives.cpp#L339
> > ). This is not the case for "random" (arch) / "modify_field_rng_uniform"
> > (bmv2). When needed the compiler is responsible for performing the
> > appropriate mapping. By being consistent when defining the architecture and
> > implement it in bmv2, one can avoid having to perform this mapping.
> > Unfortunately v1model.p4 and simple_switch were defined at different times
> > and diverge slightly.
> 
> > One important thing to remember is that bmv2 operations cannot "return"
> > values unlike P4_16 extern methods, so the compiler usually needs to
> > synthesize an "out" parameter.
> 

> > Q2: You can look at this file and see that primitives can have any number
> > of
> > parameters:
> > https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/primitives.cpp
> 

> > Q3: I think you misunderstood the comment. The comment is an open question
> > asking whether we should be able to capture all primitive parameters as
> > expressions in an efficient way.
> 

> > Q4: Yes for "assign". The order of arguments is deterministic for all
> > primitives btw.
> 

> > Q5: This information is irrelevant to bmv2 and therefore doesn't appear in
> > the JSON. bmv2 already "knows" the direction in a way based on the
> > primitive
> > definition / implementation. For example, in the case of modify_field (
> > https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/primitives.cpp#L44
> > ) the first parameter is a non-const reference ("out") while the second is
> > a
> > const reference ("in").
> 
> > The compiler is also aware of the direction of parameters based on the
> > primitive / extern method definition (
> > https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4 ).
> 

> > On Wed, Aug 9, 2017 at 7:24 AM, Hardik Soni < hardik.soni at inria.fr > wrote:
> 

> > > Hello,
> > 
> 

> > > ok, I have the answer of Q1 but there is a follow up question.
> > 
> 
> > > I forgot I took the same primitives.cpp as simple_switch.
> > 
> 
> > > There was a separate file primitves.cpp
> > 
> 

> > > Q1' : How does compiler know the opcode name of primitives for the
> > > target?
> > 
> 

> > > Q5: I need information on direction of parameters for the primitives in
> > > json
> > > or BMV2.
> > 
> 
> > > I meant is there a way to know if the parameter remains constant in the
> > > execution of primitive or gets modified.
> > 
> 
> > > Any dirtiest hack would be fine for now.
> > 
> 

> > > -Hardik
> > 
> 

> > > > From: "Hardik Soni" < hardik.soni at inria.fr >
> > > 
> > 
> 
> > > > To: "p4-dev" < p4-dev at lists.p4.org >
> > > 
> > 
> 
> > > > Sent: Wednesday, 9 August, 2017 3:41:56 PM
> > > 
> > 
> 
> > > > Subject: [P4-dev] Queries related to primitives in json and bmv2 code
> > > 
> > 
> 

> > > > Hello,
> > > 
> > 
> 

> > > > Q1. What are the possible "op" values for primitives in context of
> > > > following
> > > > json snippet?
> > > 
> > 
> 
> > > > I can see the macro, but where is the place where target writers invoke
> > > > the
> > > > macros?
> > > 
> > 
> 
> > > > Is there a set of basic primitives already defined, lets say for BMV2
> > > > simple
> > > > switch target?
> > > 
> > 
> 

> > > > ...
> > > 
> > 
> 

> > > > "primitives" : [
> > > 
> > 
> 
> > > > {
> > > 
> > 
> 
> > > > "op" : "assign",
> > > 
> > 
> 
> > > > "parameters" : [
> > > 
> > 
> 

> > > > ...
> > > 
> > 
> 

> > > > Q2. Do primitives always have two parameters? Left expression and right
> > > > expression?
> > > 
> > 
> 

> > > > Following are the two cases of "assign" primitive.
> > > 
> > 
> 

> > > > Case 1:
> > > 
> > 
> 

> > > > {
> > > 
> > 
> 
> > > > "op" : "assign",
> > > 
> > 
> 
> > > > "parameters" : [
> > > 
> > 
> 
> > > > {
> > > 
> > 
> 
> > > > "type" : "field",
> > > 
> > 
> 
> > > > "value" : ["ethernet", "srcAddr"]
> > > 
> > 
> 
> > > > },
> > > 
> > 
> 
> > > > {
> > > 
> > 
> 
> > > > "type" : "field",
> > > 
> > 
> 
> > > > "value" : ["ethernet", "dstAddr"]
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > ],
> > > 
> > 
> 
> > > > "source_info" : {
> > > 
> > 
> 
> > > > "filename" : "./input-p4s/dc.p4",
> > > 
> > 
> 
> > > > "line" : 231,
> > > 
> > 
> 
> > > > "column" : 8,
> > > 
> > 
> 
> > > > "source_fragment" : "hdr.ethernet.srcAddr = hdr.ethernet.dstAddr"
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > },
> > > 
> > 
> 

> > > > Case 2:
> > > 
> > 
> 

> > > > {
> > > 
> > 
> 
> > > > "op" : "assign",
> > > 
> > 
> 
> > > > "parameters" : [
> > > 
> > 
> 
> > > > {
> > > 
> > 
> 
> > > > "type" : "field",
> > > 
> > 
> 
> > > > "value" : ["ipv4", "ttl"]
> > > 
> > 
> 
> > > > },
> > > 
> > 
> 
> > > > {
> > > 
> > 
> 
> > > > "type" : "expression",
> > > 
> > 
> 
> > > > "value" : {
> > > 
> > 
> 
> > > > "type" : "expression",
> > > 
> > 
> 
> > > > "value" : {
> > > 
> > 
> 

> > > > "op" : "&",
> > > 
> > 
> 

> > > > "left" : {
> > > 
> > 
> 
> > > > "type" : "expression",
> > > 
> > 
> 
> > > > "value" : {
> > > 
> > 
> 
> > > > "op" : "+",
> > > 
> > 
> 
> > > > "left" : {
> > > 
> > 
> 

> > > > "type" : "field",
> > > 
> > 
> 
> > > > "value" : ["ipv4", "ttl"]
> > > 
> > 
> 

> > > > },
> > > 
> > 
> 
> > > > "right" : {
> > > 
> > 
> 
> > > > "type" : "hexstr",
> > > 
> > 
> 

> > > > "value" : "0xff"
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 

> > > > },
> > > 
> > 
> 
> > > > "right" : {
> > > 
> > 
> 
> > > > "type" : "hexstr",
> > > 
> > 
> 
> > > > "value" : "0xff"
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 

> > > > }
> > > 
> > 
> 
> > > > ],
> > > 
> > 
> 
> > > > "source_info" : {
> > > 
> > 
> 
> > > > "filename" : "./input-p4s/dc.p4",
> > > 
> > 
> 
> > > > "line" : 233,
> > > 
> > 
> 
> > > > "column" : 8,
> > > 
> > 
> 
> > > > "source_fragment" : "hdr.ipv4.ttl = hdr.ipv4.ttl - 1"
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 
> > > > }
> > > 
> > 
> 

> > > > Q3. In the function P4Objects::add_primitive_to_action(const
> > > > Json::Value
> > > > &cfg_primitive, ActionFn *action_fn)
> > > 
> > 
> 

> > > > there is a comment for "expression" type.
> > > 
> > 
> 

> > > > "// TODO(Antonin): should this make the field case (and other) obsolete
> > > 
> > 
> 

> > > > // maybe if we can optimize this case "
> > > 
> > 
> 

> > > > For future code, do you think all the primitives can be captured as
> > > > expressions?
> > > 
> > 
> 

> > > > Q4. Can I always conclude that the first parameter is left side of
> > > > assignment
> > > > operator and the second parameter is right side, given that __"op" :
> > > > "assign"__?
> > > 
> > 
> 

> > > > Best Regards,
> > > 
> > 
> 
> > > > Hardik Soni
> > > 
> > 
> 

> > > > _______________________________________________
> > > 
> > 
> 
> > > > P4-dev mailing list
> > > 
> > 
> 
> > > > P4-dev at lists.p4.org
> > > 
> > 
> 
> > > > http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
> > > 
> > 
> 
> > > _______________________________________________
> > 
> 
> > > P4-dev mailing list
> > 
> 
> > > P4-dev at lists.p4.org
> > 
> 
> > > http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
> > 
> 

> > --
> 
> > Antonin
> 

> _______________________________________________
> P4-dev mailing list
> P4-dev at lists.p4.org
> http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20170810/be3e0e2f/attachment-0002.html>


More information about the P4-dev mailing list