-
Notifications
You must be signed in to change notification settings - Fork 446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
p4c compiler driver #378
p4c compiler driver #378
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. Needs some polishing, but this is going in the right direction.
Note that it would be useful to add a readme with the install instructions and adding a new arch-target-platform.
Also, please add copyright notices.
Unfortunately, I couldn't get it to run the compiler:
First, it requires P4C_INCLUDE_PATH env var to be defined:
p4c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
error: P4C_INCLUDE_PATH undefined.
Then, couldn't find the backend:
p4c> export P4C_INCLUDE_PATH=`pwd`/p4include
P4C_INCLUDE_PATH=/Users/cascaval/Barefoot/Projects/P4/src/p4c/p4include
p4c> p4c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
clang: error: no input files
p4c/build> p4c -c -b p4c-bm2-ss testdata/p4_16_samples/arith1-bmv2.p4
Unknown target: p4c-bm2-ss
p4c/build> p4c -debug -c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
running cpp -E -x c -o ./arith1-bmv2.p4i testdata/p4_16_samples/arith1-bmv2.p4
clang: error: no input files
p4c/build> p4c -### -debug -c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
preprocessor: cpp -E -x c -o ./arith1-bmv2.p4i testdata/p4_16_samples/arith1-bmv2.p4
p4c-bm2-ss: command not found
oh well, it's not looking in the current dir:
p4c/build> ls -l p4c-bm2-ss
-rwxr-xr-x 1 cascaval staff 18376136 Mar 21 18:16 p4c-bm2-ss
p4c/build> PATH=.:$PATH p4c -### -debug -c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
preprocessor: cpp -E -x c -o ./arith1-bmv2.p4i testdata/p4_16_samples/arith1-bmv2.p4
compiler: p4c-bm2-ss --p4v=16 -o ./arith1-bmv2.json ./arith1-bmv2.p4i
Now, dry run finds it! but the real run does not:
p4c/build> PATH=.:$PATH p4c -debug -c -b bmv2 testdata/p4_16_samples/arith1-bmv2.p4
running cpp -E -x c -o ./arith1-bmv2.p4i testdata/p4_16_samples/arith1-bmv2.p4
clang: error: no input files
tools/driver/p4c/main.py
Outdated
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("-v", "--version", dest="show_version", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we use -V for version and -v for debug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
tools/driver/p4c/main.py
Outdated
metavar="<arg>", | ||
help="Pass <arg> to the linker", | ||
action="append", default=[]) | ||
parser.add_argument("-b", dest="backend", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
backend is not sufficiently specified. Think about bmv2, it may support multiple targets. In fact we have 3 factors determining the backend:
- the architecture (PSA, TSA, etc.)
- the target (simple switch, FPGA, Tofino, etc.)
- and the platform (bmv2, cycle accurate model, hardware)
Similar to one of the gnu triples to specify host-os-arch, we need to have an arch-target-platform triple to specify a configuration for which we want to compile, e.g., psa-ss-bmv2.
Also it would be very useful to have an option that list all the supported configurations (the equivalent of --target-help):
gcc --target-help
The following options are target specific:
-m128bit-long-double sizeof(long double) is 16
-m16 Generate 16bit i386 code
-m32 Generate 32bit i386 code
-m3dnow Support 3DNow! built-in functions
-m64 Generate 64bit x86-64 code
-m80387 Use hardware fp
[...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also worth noting that the include path for different architectures may be different, so we may want to let the configurations determine it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
used target-arch-vendor triplet for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code still needs a bit more work to actually use the triplet info. We can probably do that after the psa work is in.
tools/driver/p4c/main.py
Outdated
|
||
# default search path | ||
for path in os.environ['P4C_INCLUDE_PATH'].split(':'): | ||
if (opts.language == 'p4-16' and os.path.isdir(path + '/p4include')): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to surface the language as a top level option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
language is already a top level options (-x p4-14 or p4-16)
tools/driver/p4c/p4c.site.cfg
Outdated
|
||
import os | ||
|
||
def config_preprocessor(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tofino should live in its backend and the install script should search the extensions folder for backend specific configurations and install them with the rest of the default configurations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
tools/driver/p4c/util.py
Outdated
# top-down find, good for deployment | ||
def find_bin(exe): | ||
found_path = None | ||
for pp in os.environ['PATH'].split(':'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might need to add the current directory to the path (see below).
You should add a link to the documentation in the toplevel README.md, or add documentation in docs/README.md. |
tools/driver/p4c/main.py
Outdated
options = cfg.options[opts.backend][step] | ||
cmd = cmd + options | ||
# convert ['-a -b', '-c', '-d'] to ['-a', '-b', '-c', '-d'] | ||
cmd = list(itertools.chain.from_iterable(el.split() for el in cmd)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't handle quotes right. =) Try this:
tools/driver/p4c/main.py
Outdated
sys.exit(p.returncode) | ||
|
||
if opts.debug: | ||
print out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not print stdout all the time? Seems like a footgun.
tools/driver/p4c/util.py
Outdated
for root, dirs, files in os.walk(pp): | ||
for ff in files: | ||
if ff == exe: | ||
found_path = pp + '/' + ff |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idiomatic thing here would be os.path.join(pp, ff)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(There's at least one more occurrence of this.)
tools/driver/p4c/run.py
Outdated
@@ -0,0 +1 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this is just an empty file?
tools/driver/p4c/config.py
Outdated
|
||
def __init__(self, config_prefix): | ||
self.config_prefix = config_prefix or 'p4c' | ||
self.site_config_name = '%s.site.cfg' % (self.config_prefix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You never refer to this.
In general, there are a lot of comments that suggest that site.cfg
is special, but it seems like the code now just searches for .cfg
files. You should update the comments and clarify what's happening.
tools/driver/p4c/main.py
Outdated
|
||
def save_options(cmd, options): | ||
for opt in options: | ||
opt_split = opt.split(' ') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment elsewhere about this not handling quotes right.
tools/driver/p4c/main.py
Outdated
commands['preprocessor'].insert(0, cfg.get_preprocessor(opts.backend)) | ||
commands['compiler'].insert(0, cfg.get_compiler(opts.backend)) | ||
commands['assembler'].insert(0, cfg.get_assembler(opts.backend)) | ||
commands['linker'].insert(0, cfg.get_linker(opts.backend)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems closely related to what save_options()
does. Since we split()
the options again later, when we actually run the commands, maybe you could just use this approach for command line options too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be highly desirable to have the ste.cfg files set up in such a way that it would be easy to run things out of their individual build directories for debugging, as well as out of the install dir/prefix for post-installation.
tools/driver/p4c.py
Outdated
from p4c.main import main | ||
|
||
if __name__ == '__main__': | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The p4c
driver program should not have a .py extension (so it can be invoked directly as p4c ...args
, rather than p4c.py ...args
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after installation python setup.py install
, user is able to call p4c
to invoke the driver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
quick question: since the rest of the repo is using autotools, why not use autotools to install the driver as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, i will add it in.
tools/driver/p4c/main.py
Outdated
|
||
# default search path | ||
for path in os.environ['P4C_INCLUDE_PATH'].split(':'): | ||
if (opts.language == 'p4-16' and os.path.isdir(path + '/p4include')): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the way it is used, P4C_INCLUDE_PATH should probably be replaced by P4C_INSTALL_PREFIX, and should be specified .cfg file (possibly per target?) rather than in an envvar
tools/driver/p4c/p4c.site.cfg
Outdated
config.add_compiler_option("tofino", "{}/{}.p4i".format(output_dir, source_basename)) | ||
|
||
def config_assembler(): | ||
config.add_assembler_option("tofino", "-vvvl") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-vvvvl
is really only for debugging the compiler/assembler combo in a way that stores the verbose output in the assembler output dir. For futurre release, we might not want all of the -v
options and might want to leave off the -l
as well -- with no -l
logging output will go to stderr, and with no -v
, the only log output will be assembler internal ERROR
messages which almost always mean the resulting config is corrupt.
But for now, this is a reasonble way of configuring things.
tools/driver/setup.py
Outdated
version = p4c.__version__, | ||
|
||
author = p4c.__author__, | ||
license = "BSD", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually all the software we put on p4.org is Apache 2.0.
I was talking to @sethfowler and he thinks we're about ready to try to generate APIs from the compiler (even if they are not yet correct). So let's add an option to do the generation as well. |
- installing p4c using autotools - use target-arch-vendor triplet to specify backend - generate p4runtime api in bmv2 - clean up
All comments should be addressed now. Please take another look. |
config.add_compiler_option("bmv2-*-p4org", "{}/{}.p4i".format(output_dir, source_basename)) | ||
# generate api has part of the compilation | ||
config.add_compiler_option("bmv2-*-p4org", "--p4runtime-file"); | ||
config.add_compiler_option("bmv2-*-p4org", "{}/{}.p4rt".format(output_dir, source_basename)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor issues, but overall works.
We should add a blurb in docs/README.md to document its existence.
parser.add_argument("-v", dest="debug", | ||
help="verbose", | ||
action="store_true", default=False) | ||
parser.add_argument("-###", dest="dry_run", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this option was brilliant!
# -*- Python -*- | ||
|
||
def config_preprocessor(): | ||
config.add_preprocessor_option("bmv2-*-p4org", "-E -x c -o") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for some reason, this cpp command does not work on Mac. Works fine on Linux.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to cc
os.makedirs(opts.output_directory) | ||
|
||
commands['preprocessor'].insert(0, cfg.get_preprocessor(backend)) | ||
commands['compiler'].insert(0, cfg.get_compiler(backend)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the compiler is just built in the current directory and one does not have the current dir in the path, then it can not find the compiler, unless run with:
PATH=.:$PATH ./p4c -v ../testdata/p4_16_samples/arith-bmv2.p4
I wonder whether we should force the current directory in the path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
Compiler driver for bmv2, ebpf and third-party backends.
Installing the driver:
Usage