I’m trying to better understand how the P4 compiler assigns IDs to pipeline objects (such as tables, actions, counters, meters, etc.) when generating artifacts like:
dash_pipeline.json
dash_pipeline_p4rt.json
dash_pipeline_ir.json
In these files, each object is given a unique integer ID. My questions are:
What is the mechanism or logic or algorithm by which the compiler assigns these IDs?
Are the IDs stable across different compilations of the same P4 program (assuming no code changes)?
Is there a reference in the P4Runtime or bmv2 documentation that explains this ID assignment process?
I want to understand whether these IDs are generated deterministically (e.g., based on program order, hashing of names, etc.) or if they can change between compiler runs.
Any pointers to documentation or explanations would be greatly appreciated!
First, if you want to guarantee that a particular id is used in the P4Runtime info output file of the P4 compiler p4c, you may use an annotation @id. Examples for a P4 program used for the PINS project can be found here:
@id annotations can be used on other P4 objects other than tables and actions, too, e.g. instantiations of extern objects.
See the section titled “ID Allocation for P4Info Objects“ of the P4Runtime API specification for some notes about how the 32-bit id values have the most significant 8 bits equal to a constant value that identifies the type of P4 object it is.
The least significant 24 bits are by default calculated by the P4 compiler at compile time, but can be overridden by an @id annotation. The open source p4c compiler calculates the least significant 24 bits via a hash function that I believe is based upon the name of the instance, so that at least usually the value will be consistent across compilation runs if you do not change the name of the object. However, even if you do not change the names, if you add new names that happen to collide in the value of that 24-bit hash, then one of them will be changed to avoid the collision, and it might be the instance that was added to the program earlier, rather than the one that was added later.
The @id annotation can be used to prevent such reassignment of values, both for the reason of avoiding hash collisions, and even if you rename the object the @id annotation will keep the value the same as before.
Note, all of my earlier answers were specifically about the P4Runtime API id values, which are most likely in the file named dash_pipeline_p4rt.json that you mentioned. There is no universally-accepted file name that the P4Info file is stored in, but p4rt is a very likely sign that such a file contains P4Info data.
The file you call dash_pipeline.json is likely a BMv2 JSON data file, output by the BMv2 back end of p4c, and read by simple_switch and simple_switch_grpc executable programs as the “binary blob” describing the behavior of the compiled P4 program.
The file you named dash_pipeline_ir.json I am not certain what that is, but given ir in the name, it might be data describing the IR (Intermediate Representation) of the p4c compiler for a P4 program, used by p4c developers to debug its behavior.