You have been provided with a new repository containing the initial API design from another team. Your task is to provide feedback to the library authors. The task has two parts: the first part is intended to let you try out the provided API (by creating an example application) and the second part is a review of the library and its API. The review consists of several paragraphs of coherent text (not a bullet list).
This task is done individually so that each team (including yours) receives feedback from two other students.
Part 1: example application
Use the provided API to implement a skeleton of the numactl command (see man page for details) and integrate it into the project as another example in addition to the example that should already be present. Pay attention to how the library contributed (or failed to contribute) to this task.
Keep in mind that the purpose of the task is to learn the API and use it to
write the argument-parsing part of the program, not implementing numactl
features. Your skeleton application is therefore expected to say what it
would be doing, not actually do it, just like in the following example:
args = ... // configure the arguments
args.parse(argv)
if args.has("--show"):
print("policy: default"); print("...")
elif args.has("--hardware"):
print("available: 2 nodes (0-1)"); print("...")
elif:
print("will run %s" % args.get_command())
print("CPU node bind: %s" % args.get("-C").join(","))
...
Your numactl
skeleton must support the following invocation styles:
- Without any parameters, the program should print help.
- Given the
--hardware
switch, it should emulate printing the current hardware configuration. - Given the
--show
switch, it should emulate printing the current NUMA policy. - Given options
-m
,-p
,-i
, and-C
, it should emulate running another program with the modified NUMA policy.
See below for details on the individual invocation styles.
Displaying help text
numactl
When run without any arguments, the command should print help text that summarizes the supported options, switches, commands, i.e., something along these lines:
usage: numactl [--interleave= | -i <nodes>] [--preferred= | -p <node>]
[--physcpubind= | -C <cpus>] [--membind= | -m <nodes>]
command args ...
numactl [--show | -s]
numactl [--hardware | -H]
<nodes> is a comma delimited list of node numbers or A-B ranges or all.
<cpus> is a comma delimited list of cpu numbers or A-B ranges or all.
--interleave, -i Interleave memory allocation across given nodes.
--preferred, -p Prefer memory allocations from given node.
--membind, -m Allocate memory from given nodes only.
--physcpubind, -C Run on given CPUs only.
--show, -S Show current NUMA policy.
--hardware, -H Print hardware configuration.
Ideally, this text (or most of it) would be generated by the library based on the defined options and their description.
Displaying hardware configuration
numactl --hardware
When run with the --hardware
switch (or its short alias -H
), the command
prints the system hardware configuration:
available: 2 nodes (0-1)
node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22
node 0 size: 24189 MB
node 0 free: 18796 MB
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23
node 1 size: 24088 MB
node 1 free: 16810 MB
node distances:
node 0 1
0: 10 20
1: 20 10
Displaying current configuration
numactl --show
When run with the --show
switch (or its short alias -s
), the command
prints the current configuration (policy):
policy: default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7 8
cpubind: 0 1
nodebind: 0 1
membind: 0 1
Running programs with a specific NUMA policy
numactl [policy-configuration-for-command] command args ...
Without the --hardware
or --show
options, the numactl
utility allows
running other programs under a given NUMA policy. Your skeleton implementation
does not have to run any commands, but it needs to print the final policy used
to run command
with args
.
--physcpubind|-C
accepts list of CPUs (range 0-31)--membind|-m
accepts list of NUMA nodes (range 0-3)--preferred|-p
accepts single NUMA node (0-3)--interleave|-i
accepts list of NUMA nodes (range 0-3)- options
-m
,-p
and-i
are conflicting and only one can be present command
cannot be empty,args
are optional
Note that -C
, -m
, -i
are actually lists of integers that are created
from either of the following forms:
all
1,3,8,2
1-5,8,10-17
Part 2: review
The goal of the review is to provide the library authors with feedback on the initial design of the library API and on the library itself. Your feedback is not going to cost the other team any points, so you are encouraged to provide an honest opinion (just keep your tone civil). Don’t be afraid to provide praise where you think it is due — reviewing does not mean that you are only expected to criticize.
Your review should adhere to the following (rough) outline:
-
First impression (1 paragraph)
Summarize your first impression of the library after cloning the project.
People usually expect
README.md
to contain basic information about a project, so a goodREADME.md
can go a long way in setting up the user’s expectations by answering some of the potential questions up front:- What does the project/library do?
- Which use cases can it cover (and which are beyond its scope)?
- How to use the library (short tutorial or a simple example)?
- What are the key concepts (and where can I learn more)?
- How to build the library (and what is needed for that)?
Keep in mind that this is an initial version, so not everything might be completely fleshed out, but you should not have trouble getting the library to compile or integrating your example program into the project.
-
API review (2-3 paragraphs)
Summarize the basic concepts provided by the library. At this point, you should not (need to) discuss low-level technical details (i.e., classes), but you should discuss the API style, the responsibilities assumed by the library and those expected from the user.
Consider common situations in which the library API is going to be used (i.e., parser definition, parsing the command line, access to parsed values, and error handling) and comment on the comfort of using the API in these situations.
Check the API documentation to see if it clear what the API methods expect and how they behave, and find out what the library can/cannot do in the context of the
task-1
requirements. -
Writing
numactl
(1-2 paragraphs)Describe your experience implementing the argument-processing part of the
numactl
command. Comment on how the concepts required to implement the example match the concepts offered by the library. Point out what was easy (conceptual match), difficult (conceptual mismatch but workaround possible), or impossible to implement with the help of the library.
-
Detailed comments (2-3 paragraphs)
Provide detailed comments on specific issues (or highlights). See the checklist below for sample questions (not exhaustive) that can aid in systematic API exploration.
Review checklist
-
Library API
- How does the user define parsable elements and their properties?
- Are bounded integers, enums and strings parameter types supported?
- Can the library generate help text based on user-provided documentation?
- Is it possible to parse and/or validate custom parameter types and how?
- What happens when and error (due to programmer or CLI user) occurs?
- What is needed (information, steps) to access the parsed values?
- Who is responsible for storing the parsed data and where?
- Is the API declarative or imperative, stateful or stateless?
- Does the API use mutable or immutable objects?
- Can a user define multiple independent parsers? Is there any global state?
- Is the API consistent? Can it be used in the wrong way?
- Does the naming fit the problem domain?
- Is the client code easy to read?
- … and many others …
-
External documentation
- What are the goals and non-goals of the library?
- What are the key concepts provided by the library?
- What are the key design decisions and how they reflect the library goals?
-
Source code documentation
-
Are all public classes documented?
What is the responsibility of the class and how does it fit among the other concepts provided by the library?
-
Are all public methods documented?
Is it clear what each method does, and how does it react to invalid data or invalid usage by the programmer, such as invalid parameter values? What constitutes valid and invalid parameter values?
-
Was the example program documented?
-
Was the documentation good enough for writing
numactl
or not?
-
-
Code style
- Does the code follow platform conventions (naming etc.)?
- Is the source code formatting consistent?
Submission
To submit your solution to this task, commit both the numactl
example and
the review to the master
branch of the provided repository, and tag the final
commit using the task-2-submission
tag.
-
The
numactl
example should be integrated (in a reasonable way) into the existing library, ideally as a separate sub-project. -
The review must be a markdown document named
REVIEW.md
(case sensitive) placed in the.nprg043
directory, i.e., the path to the file from the project root should be.nprg043/REVIEW.md
.Note that failure to put the review in the required location will be penalized, because such a submission needs to be handled manually.