Driver File v2¶
The external interface implementation provides a series of individual processing steps that can be selected and chained by means of the JSON driver file. Within this file, each processing step is represented as a JSON object with the following properties:
kind(required, String): This is a unique identifier for every different kind of steps and therefore determines what this step will do when exectuted.id(String): Unique identifier for this particular step. This can be used to refer to (the output of) other steps.options(Object): Set of options to tune the behavior of the step as needed. Some steps don’t have options, whereas others require you to specify them. For most steps, options are optional. The properties of the options object depend on the step’s kind - see Available Processing Step Kinds.inherit_options_from(String): Theidof another step of the same kind (anywhere in thestepsarray) whose options shall be used as the base for this step’s options. The localoptions(if any) are applied on top as a JSON merge patch: nested objects are merged recursively, all other values replace the inherited ones and a value ofnullremoves the inherited option. The referenced step may itself inherit its options from yet another step.outputs(Object): This can be used to give human-readable names to individual outputs of the current step in form of name-output pairs. See Referencing Outputs - the step ID in this case is implicitly the current step’s ID and must not be included explicitly. These names are automatically propagated through the processing chain (for most kinds of steps).inputs(String or Array of Strings): Specifies the inputs of this step, which must be outputs of other steps. See Referencing Outputs. Every step requires at least one input, except for steps that produce data from scratch (such asread_input); omittinginputson a step that needs it is an error.
The different steps are listed objects in the top-level steps array. Steps are processed in order according to their order in this array.
Referencing Outputs¶
Outputs can be referenced by means of their IDs. An ID has the general format <step_id>.<output_id>. <step_id> must refer to the
id of one of the steps that have been executed before. <output_id> can be the human-readable names specified via a step’s
outputs property or an integer. In the latter case, the integer refers to the index of the output. Outputs are indexed starting from zero in
the order they are produced.
<output_id> can also be an expression enclosed in square brackets in order to refer to multiple outputs at once. This can be a comma-delimited
(no spaces!) list of output names or indices, or a range of indices which are of the form <from>-<to> like 0-5.
Examples of output IDs:
my_step.0my_step.some_namemy_step.[0-2]my_step.[0-2,some_name,5]
Finally, to refer to all outputs of a given step, just use the step’s ID without anything appended to it. That is, my_step would automatically refer to all outputs of the respective step.
How the Pipeline Executes¶
Steps are executed strictly in the order in which they appear in the steps array - there is no separate dependency resolution based on
inputs. Given IDs must be unique across the whole driver file.
Two kinds of data can flow between steps: Expression data (one or more named result expressions) and ExportTree data (the export-ready tree form
produced by the to_export_tree step). Every step kind’s documentation below states which of these it consumes and which it produces. Feeding a
step data of the wrong kind (e.g. passing plain expressions into a step that expects an ExportTree) is an error.
Not every step produces output data - they exist purely for their side effects (e.g. aborting on invalid input, printing to the console or writing
something to a file) - and therefore cannot be referenced by another step’s inputs.
Errors encountered anywhere in the pipeline (be it while parsing a step’s options or while executing it) abort the entire run; there is no partial/best-effort processing.
Templates¶
A template is a reusable, parameterized sequence of steps. It is defined once under the top-level templates object and then stamped out
wherever it is needed, so a pipeline tail that would otherwise be written out several times (differing only in a few values) is written once.
Templates are expanded into ordinary steps before the pipeline runs, so everything described above - inherit_options_from, output aliasing,
input resolution - applies unchanged to the result.
Templates can be shared between drivers by placing them in a separate file and pulling it in with $include (see
Including Other JSON Files).
Each entry of templates maps a template name to a definition with two properties:
parameters(Object): Declares the knobs the template exposes. Each entry maps a parameter name to a declaration object that must specify eitherrequired: true(the value must be supplied on every use) or adefault(any JSON value, used when the parameter is not supplied). A declaration that specifies neither is an error.steps(Array): The steps the template expands to, written just like top-level steps but allowed to contain${parameter}placeholders (see below). May itself contain template uses.
A template is used by writing, in place of a regular step, an object with a template property (naming the template) instead of a
kind. Such a step accepts only:
template(required, String): Name of the template to expand here.id(required, String): Prefix under which this use’s steps are placed (see namespacing below).parameters(Object): Binds the template’s parameters. Every key must be a declared parameter and everyrequiredparameter must be given; omitted optional parameters fall back to theirdefault.
Placeholder substitution¶
Within a template’s steps, ${name} placeholders are recognized in string values at any nesting depth (object keys are never substituted).
There are two forms:
A string that is exactly
"${name}"is replaced by the parameter’s full JSON value, with its type preserved - so a boolean stays a boolean, a number stays a number, and an array or object is spliced in as-is.A placeholder embedded in a longer string (e.g.
"file_${name}.itfaa") is substituted textually; the parameter must be a scalar (a boolean renders astrue/false).A whole-value
"${keys(name)}"or"${values(name)}"is replaced by an array holding the keys or the values, respectively, of the object parametername. Thei-th key and thei-th value belong together; otherwise their order is unspecified. These forms cannot be embedded in a longer string.
If a whole-value placeholder resolves to null, its enclosing object member is dropped (and an options object left empty this way is
removed entirely). This lets a single template serve both the “option present” and “option absent” cases: give the parameter a default of
null and pass a value only when the option is wanted. To write a literal ${, double the dollar sign: $${.
Namespacing¶
When a template is used with id P, every step inside it that has an id is renamed to P_<id>, and references to those
steps (in inputs and inherit_options_from) are updated to match. References that do not point at one of the template’s own steps -
in particular, values that came in through parameters, or an inherit_options_from pointing at a top-level step - are left untouched. The
expanded steps are therefore addressed from the outside as P_<id> (and their outputs as P_<id>.<output>), and two uses of the same
template never collide because their id prefixes differ. The prefix is joined with an underscore rather than a dot (and a use’s id
may not contain a dot) because a step ID must stay a single dot-free token for output names to propagate correctly.
Note
Only inputs and inherit_options_from are namespaced. If a template’s step refers to one of the template’s own steps from within an
option value (for example the deps of a dependencies step or the grouping of an export step), that reference is
not rewritten - keep such internal wiring in inputs, or pass the referenced name in as a parameter.
For example, the optimize + to_export_tree sequence below is factored into one template and used twice - once plainly and once
with replay enabled - without repeating the sequence or its inputs:
{
"templates": {
"optimized_tree": {
"parameters": {
"source": { "required": true },
"replay": { "default": null }
},
"steps": [
{
"id": "opt",
"kind": "optimize",
"inputs": "${source}",
"options": { "replay": "${replay}" }
},
{
"id": "tree",
"kind": "to_export_tree",
"inputs": "opt"
}
]
}
},
"steps": [
{
"template": "optimized_tree",
"id": "base",
"parameters": { "source": ["traced.en", "biorth"] }
},
{
"template": "optimized_tree",
"id": "replay",
"parameters": {
"source": ["traced.en", "biorth"],
"replay": { "volatile": "T\\d", "weight": 10 }
}
}
]
}
The base use produces steps base_opt and base_tree (its replay parameter defaults to null, so the
replay option vanishes and the now-empty options is dropped); the replay use likewise produces replay_opt and
replay_tree, with the replay option present. Subsequent steps refer to the resulting trees as base_tree and
replay_tree.
Conditional steps and optional references¶
A step inside a template (including a nested template use) may carry a when property. The step is only part of the expansion if its value
is truthy. Usually when is a whole-value placeholder such as "${replay_input}"; any other value is taken literally. Everything
except null, false and empty strings, arrays and objects is truthy. This is decided while expanding the template, so a skipped step
never exists at run time.
Steps that process the output of a skipped step would then refer to something that isn’t there. A reference (an entry of inputs, the value
of inherit_options_from, or an ID inside the grouping, merge_inputs or relative_order options) can be marked as
optional by a trailing ?. After all templates have been expanded:
An optional reference to an existing step (the part before the first
.) loses its?and is otherwise unchanged. Whether the output the reference names exists is not checked.An optional reference to a step that doesn’t exist is removed from the array or object it is part of. If nothing is left of
inputs, the whole step is removed, which in turn makes optional references to it unresolvable. If nothing is left ofinherit_options_from,grouping,merge_inputsorrelative_order, that property is omitted.References without a
?are never touched, so a misspelled ID is still an error.
Because output aliases only propagate along steps that exist, there is no implicit pass-through for a skipped step: either a downstream reference is optional, or the step is skipped for good.
Together with null defaults, this lets one template cover variants that differ in additional steps. In the following, replay_input
selects inputs that are optimized with replay and exported with the remaining ones, if there are any:
{
"templates": {
"variant": {
"parameters": {
"source": { "required": true },
"replay_input": { "default": [] },
"replay": { "default": null }
},
"steps": [
{ "id": "opt", "kind": "optimize", "inputs": "${source}" },
{ "id": "opt_replay", "kind": "optimize", "inputs": "${replay_input}",
"options": { "replay": "${replay}" }, "when": "${replay_input}" },
{ "id": "tree", "kind": "to_export_tree", "inputs": "opt" },
{ "id": "tree_replay", "kind": "to_export_tree", "inputs": "opt_replay", "when": "${replay_input}" },
{ "id": "export", "kind": "export", "inputs": ["tree", "tree_replay?"],
"options": { "language": "itf", "output": "out.itfaa" } }
]
}
}
}
Without replay_input only opt, tree and export remain, and export has the single input tree.
As IDs inside option values are not namespaced (see the note above), optional references there are meant to be passed in through parameters, e.g.
a grouping parameter containing "Init": "my_variant_opt_replay.persistent?", where my_variant is the id of the use.
Available Processing Step Kinds¶
batch_indices¶
Configures the computation of results to happen in batches over certain result indices. For every result, its indices are ranked by the size of the
index space they belong to. The smallest min_unbatched indices are always left un-batched; among the remaining indices, up to
max_batched become batch indices, chosen from the end of the size-ranked list selected by selection_strategy. This step only annotates
which indices shall be batched - whether batching is actually realized (and how) is up to whichever code-generation backend is used by the subsequent
export step, and not every backend supports it.
Input |
Output |
|---|---|
ExportTree |
ExportTree |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Minimum number of (smallest-space) indices of a given result that are always left un-batched. |
2 |
No |
|
Upper limit on the number of indices that may be selected for batching. |
unbounded |
No |
|
Which end of the size-ranked index list batching candidates are taken from. |
|
No |
canonicalize¶
Canonicalizes the input expressions.
Input |
Output |
|---|---|
Expression |
Expression |
This step does not accept any options.
cse¶
Performs common-subexpression elimination (CSE). Dependencies already recorded on the inputs (e.g. by a preceding
dependencies step) are carried over onto the corresponding results. The introduced intermediates are named only
uniquely within the entries of a single result, so a dependencies step with autodetect should run before this
step rather than after it (see the note under dependencies).
Input |
Output |
|---|---|
ExportTree |
ExportTree |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Minimum number of times a given subexpression has to be used in order to be eligible for subexpression elimination. |
2 |
No |
|
Whether multiple inputs shall be merged together in order to undergo combined rather than individual CSE.
Instead of a boolean, an array of input IDs/aliases can be given, in which case merging happens only within the
inputs matching each listed ID (matched like the groups of the |
false |
No |
density_fitting¶
Inserts the density-fitting decomposition of the two-electron integrals. Every occurrence of the tensor named by integral_label is rewritten
into a contraction of two three-index tensors (named by df_tensor_label) carrying an additional auxiliary index from auxiliary_space.
Expressions that don’t contain the targeted tensor are passed through unmodified.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Label of the index space (as declared under the top-level |
Yes |
|
|
Label of the tensor representing the two-electron integrals that shall be decomposed. |
|
No |
|
Label given to the two three-index tensors produced by the decomposition. |
|
No |
dependencies¶
Establishes hard dependencies between result trees: whenever one tree is made to depend on another, the latter is guaranteed to be computed first. The
dependencies are recorded on the inputs and consumed by the export step when it orders the results. Like export, this step is not
restricted to a single input - all inputs are considered jointly so that dependencies can be detected and declared across them. The inputs are annotated
in place and passed through unchanged, so they remain referenceable (under this step’s id) by subsequent steps. At least one of autodetect or
deps must be given.
Input |
Output |
|---|---|
ExportTree |
ExportTree |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Whether to automatically add a dependency whenever the result of one tree is used as an input in another tree. Matching is done on the tensor block (label and index spaces) and hence is insensitive to the concrete index labels. |
false |
No (but see above) |
|
Object declaring dependencies explicitly. Each key is the id/alias of the dependent tree(s); its value is a single id/alias, or an array of
them, naming the tree(s) that must be computed first. Group ids are allowed on both sides. These dependencies are added on top of any that
|
|
No (but see above) |
A dependency cycle - whether autodetected or declared - is an error and aborts the run when the export step tries to order the results.
Note
Run this step with autodetect before any cse step, not after. Common-subexpression elimination introduces
intermediate results whose names are only unique within the entries of a single result; across results the same name (e.g.
CSE1) is reused for unrelated intermediates. Since autodetection matches producers and consumers on the tensor block
(see autodetect above), running it on CSE output conflates these same-named intermediates and can wire up spurious
dependencies that form a cycle, aborting the subsequent export. Autodetecting dependencies first is safe because
cse preserves the dependencies already recorded on its inputs.
export¶
Exports the given expressions as code. Unlike most other steps, export is not restricted to a single input - if several inputs are
given, they are merged and jointly ordered before being exported together.
Input |
Output |
|---|---|
ExportTree |
None |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Target language/format to export to. Currently, the only supported value is |
Yes |
|
|
Path of the file the generated code is written to (relative to the driver file’s location, unless given as an absolute path). |
Yes |
|
|
Whether to run a further optimization pass (eliminating redundant operations) over the intermediate representation before generating code. |
true |
No |
|
Whether to verify that the generated memory operations (create, load, unload, destroy, persist) obey a stack-like order, as required by the
target language (and throw an error if they do not). The check is applied to the final operations, after |
false |
No |
|
Object mapping a group name to an input id/alias, or to an array of them. All entries belonging to any of these ids/aliases are exported as part
of the named group. An id/alias must not be associated with more than one group. Any entry not matched by any of these rules is put into an
implicit group named |
|
No |
|
Array of id/alias names giving a hint for the relative ordering of results within the generated code. Used together with the hard dependencies
among results (see the |
|
No |
|
Object mapping a serialized tensor expression to an import name. Tensor blocks matching the given expression are treated as externally supplied (imported) rather than being computed by the generated code. |
|
No |
|
Point-group symmetry (IRREP) information. If given, the IRREPs of all exported tensors are determined from the IRREPs of the input tensors and emitted into the generated code. See below for the sub-schema. |
No |
|
|
Whether to reuse the names (and thereby the storage) of intermediates introduced by the |
false |
No |
|
Additional, language-specific metadata. See below for the sub-schema accepted when |
|
No |
The irreps option accepts the following properties:
Option |
Description |
Default |
Required |
|---|---|---|---|
|
The symmetry group. Either the name of one of the abelian point groups |
Yes |
|
|
Array of names of symbolic IRREPs, i.e. IRREPs whose value is only known at runtime (e.g. the symmetry of a perturbation). Symbols remain
unevaluated in the generated code (e.g. |
|
No |
|
Array of relations between IRREPs of the form |
|
No |
|
Object mapping tensors to their IRREP(s), given as a single IRREP name or an array of names (for tensors spanning several IRREPs).
|
|
No |
|
Object mapping scalar variables to their IRREP(s), in the same format as |
|
No |
|
IRREP(s) of tensors not listed in |
|
No |
Whitespace around IRREP names, * and = is ignored ("A * B = C" equals "A*B=C"). IRREP names themselves must not
contain whitespace.
For language: itf, the IRREPs of created tensors are emitted as an irrep: entry of their !Create{...} statement, whereas the
IRREPs of imported tensors are given as a trailing comment of their declaration (for informational purposes only).
For language: itf, meta accepts the following properties:
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Object mapping an index space’s label to an object with |
|
No |
|
Non-negative integer offset that index IDs emitted into the generated ITF code start counting from. |
0 |
No |
|
Object mapping IRREP names (as used in the |
|
No |
filter¶
Filters the input expressions and assigns them into different named groups based on provided filter rules. For a summed expression, each summand is tested against every group’s rules independently; for a non-summed expression, the expression as a whole is tested. Matching summands/expressions are accumulated into their group’s output, so this step can (and typically does) produce more than one output per input - one for each configured group.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Object mapping a group name to a filter specification (see below). At least one group must be given. |
Yes |
|
|
Whether a group that ends up empty for a given input is still emitted as an (empty) output, rather than being omitted entirely. |
true |
No |
Each entry of groups is a filter specification with the following properties:
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Whether a term has to satisfy |
|
No |
|
Array of filter rules (see below) that define what this group matches. |
Yes |
Each entry of rules is an object with the following properties:
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Kind of rule. |
Yes |
|
|
If true, inverts the result of this rule. |
false |
No |
|
Serialized expression that is searched for (recursively, i.e. also within subexpressions) within the term being tested. Mutually exclusive with
|
One of |
|
|
Only used together with |
|
No |
|
One (String) or several (Array of Strings) full-match regular expressions that are matched (recursively) against the labels of subexpressions
within the term being tested. A match against any of the given patterns counts as a match for this rule. Mutually exclusive with |
One of |
|
|
Only used by |
For |
|
|
Only used by |
For |
optimize¶
Symbolically rewrites the expressions for an improved numerical evaluation. Most prominently, this factors tensor contractions into a series of binary
tensor contractions, chosen so as to minimize the configured objective.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Cost metric to minimize when factorizing contractions: |
|
No |
|
Whether summands of a sum may be reordered so that terms sharing common intermediates end up next to each other. |
true |
No |
|
Whether to perform common-subexpression elimination while searching for a single term’s evaluation order. |
|
No |
|
Per-intermediate memory-footprint penalty added to the cost of a contraction (only consulted when |
0.0 |
No |
|
Whether to prune disconnected (outer-product) subsets from the search space while looking for the best evaluation order. |
true |
No |
|
Configures the treatment of expressions that are evaluated repeatedly (e.g. once per iteration of an iterative solver), in which only some tensors (the volatile ones, e.g. amplitudes) change between evaluations. See below. |
No |
replay is an object with the following properties:
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Identifies the volatile tensors. Either a single entry or an array of entries, where each entry is a String (a full-match regular expression
for the tensor label), an object with a |
Yes |
|
|
Weight of the cost of contractions involving volatile tensors, relative to the ones that don’t (conceptually the number of evaluations). |
1.0 |
No |
|
Label prefix of the persistent intermediates (see below). Has to be unique among all |
|
No |
|
Name of the sub-ID referring to the persistent part of an output. |
|
No |
|
Name of the sub-ID referring to the volatile part of an output. |
|
No |
With replay, every largest subexpression that contains at least two tensors but no volatile one is replaced by a persistent
intermediate, which only needs to be computed once. Equal subexpressions share an intermediate across all inputs of the step. Every input then
produces two outputs: the definitions of the persistent intermediates (the persistent part) and the input’s optimized expressions, which
reference these intermediates (the volatile part). For every ID <id> under which the outputs can be referenced (including the step ID
itself), the two parts are available as <id>.persistent and <id>.volatile. <id> still refers to both parts.
The main use case is to export the persistent parts into their own code section, which is run once, before the sections that are run in every iteration:
{
"steps": [
{
"id": "opt",
"kind": "optimize",
"inputs": "biorth",
"options": {
"replay": { "volatile": "T\\d\\w*", "weight": 10 }
}
},
{
"id": "treeify",
"kind": "to_export_tree",
"inputs": "opt"
},
{
"kind": "export",
"inputs": "treeify",
"options": {
"language": "itf",
"output": "code.itfaa",
"grouping": {
"Init": "persistent",
"Residual": "res.volatile"
}
}
}
]
}
Only the steps relevant for this feature are shown.
Keep the following in mind:
A persistent intermediate that is used by several outputs is only part of the persistent part of the first of them. Use the step-wide
<step>.persistentto get all of them.There are no dependencies between the parts of an output, so exporting both into the same group gives no guarantee that the intermediates are computed before they are used. Put them into different groups.
Don’t reference both an ID and one of its sub-IDs in the
groupingof theexportstep, as it is unspecified which of them takes effect.Steps that merge their inputs (e.g.
csewithmerge_inputs) merge the parts back together if given both of them.
output¶
Outputs expressions in the chosen markup style. Mainly intended for debugging purposes.
Input |
Output |
|---|---|
Expression |
None |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Markup style to print in. |
|
No |
|
Only relevant for |
true |
No |
project¶
Performs the chosen projection with the inputs.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Projection method to apply. Currently, the only supported value is |
Yes |
Note
Unlike in the v1 driver, there is no no-op (primitive) value for method - simply omit this step if no
projection is needed.
read_input¶
Reads and parses expressions from files.
Input |
Output |
|---|---|
None |
Expression |
This step does not accept any options.
simplify¶
Simplifies the given expressions.
Input |
Output |
|---|---|
Expression |
Expression |
This step does not accept any options.
sort¶
Sorts the input expressions into lexicographic order: the summands of every sum are sorted, as are the factors of every
product insofar as they commute. Unlike the order produced by canonicalize, which is based on hash values, this
order depends only on the expressions themselves (tensors with the cardinal tensor labels of the context come first) and
is hence stable across changes of the hashing algorithm. The order of the expressions within an input is not changed.
Input |
Output |
|---|---|
Expression |
Expression |
This step does not accept any options.
spintracing¶
Spintraces the given expressions. That is, it performs spin-integration and potentially also spin-summation.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Spintracing algorithm to use. |
|
No |
Note
There is no none value for algorithm - simply omit this step if spintracing isn’t needed.
substitute¶
Makes substitutions in the given expressions. Substitution targets and their replacements are given directly as serialized expressions in the options (there is no mechanism to source them from another step’s output); they are applied in the order in which they are declared, with each rule operating on the result of the previous one.
Input |
Output |
|---|---|
Expression |
Expression |
Option |
Description |
Default |
Required |
|---|---|---|---|
|
Object mapping a serialized expression identifying what to match (the key) to a serialized expression it shall be replaced with (the value). Multiple entries are applied in order. |
Yes |
|
|
Controls how tensors are compared while matching substitution targets: |
|
No |
|
Object mapping an old result label to a new one. After substitutions have been applied to an expression, if its result label matches a key in this map, it is renamed to the associated value. |
|
No |
|
Whether an input that none of the substitutions changed is still emitted (as is), so that there is exactly one output per input, in input order. |
false |
No |
Note
Unlike most other steps, substitute does not propagate the named aliases of its inputs onto its outputs - downstream steps need to reference
its outputs via the auto-generated <step_id>.<index> scheme (or via this step’s own outputs property). Additionally, if none of the
expressions belonging to a given input end up changed by any substitution, that input is dropped from the output entirely rather than being passed
through unchanged (unless keep_unchanged is set).
to_export_tree¶
Converts the given expressions into a tree data structure suitable for exports.
Input |
Output |
|---|---|
Expression |
ExportTree |
This step does not accept any options.
validate¶
Validates the given expressions, e.g. checking that indices occur at most twice within a product, that all summands of a sum share the same external indices, and that a result’s declared indices are consistent with those actually occurring in its expression. Processing is aborted as soon as the first invalid expression is encountered.
Input |
Output |
|---|---|
Expression |
None |
This step does not accept any options.
Note
Since this step never produces any output, it is typically used without an explicit id.
Examples¶
{
"driver_format_version": 2,
"index_spaces": [
{
"label": "a",
"size": 1000,
"real_valued": true
},
{
"label": "u",
"size": 5,
"real_valued": true
},
{
"label": "i",
"size": 80,
"real_valued": true
},
{
"label": "F",
"size": 1500,
"real_valued": true
}
],
"steps": [
{
"id": "input",
"kind": "read_input",
"options": {
"file_path": [
"nevpt2/nevpt2_en0.inp",
"nevpt2/nevpt2_en.inp",
"nevpt2/nevpt2_res1_i1.inp",
"nevpt2/nevpt2_res1_s0.inp",
"nevpt2/nevpt2_res2_s1_singles.inp",
"nevpt2/nevpt2_res1_s1.inp",
"nevpt2/nevpt2_res2_p0.inp",
"nevpt2/nevpt2_res2_p2.inp",
"nevpt2/nevpt2_res2_i2.inp",
"nevpt2/nevpt2_res2_p1.inp",
"nevpt2/nevpt2_res2_s1.inp",
"nevpt2/nevpt2_res2_s2.inp"
],
"default_symmetry": "antisymmetric"
},
"outputs": {
"ecc0": "0",
"ecc": "1",
"en": "0-1",
"res1": "2-5",
"res1_i1": "2",
"res1_s0": "3",
"res2_s1_singles": "4",
"res1_s1": "5",
"res2": "6-11",
"res2_p0": "6",
"res2_p2": "7",
"res2_i2": "8",
"res2_p1": "9",
"res2_s1": "10",
"res2_s2": "11",
"res": "2-11"
}
},
{
"kind": "validate",
"inputs": "input"
},
{
"id": "DF",
"kind": "density_fitting",
"inputs": "input",
"options": {
"auxiliary_space": "F"
}
},
{
"id": "traced",
"kind": "spintracing",
"inputs": "DF",
"options": {
"algorithm": "closed_shell"
}
},
{
"id": "biorth",
"kind": "project",
"inputs": "traced.res",
"options": {
"method": "biorthogonal"
}
},
{
"id": "opt",
"kind": "optimize",
"inputs": [
"traced.en",
"biorth"
]
},
{
"id": "treeify",
"kind": "to_export_tree",
"inputs": "opt"
},
{
"kind": "export",
"inputs": "treeify",
"options": {
"language": "itf",
"optimize": true,
"output": "nevpt2_v2.itfaa",
"grouping": {
"Energy0": "ecc0",
"Energy": "ecc",
"Residual": "res"
},
"relative_order": [
"ecc0",
"ecc",
"res1_i1",
"res1_s0",
"res2_s1_singles",
"res1_s1",
"res2_p0",
"res2_p2",
"res2_i2",
"res2_p1",
"res2_s1",
"res2_s2"
],
"imports": {
"R2{a1;i1}": "R2:ec"
},
"meta": {
"index_spaces": {
"a": {
"name": "External",
"tag": "e"
},
"u": {
"name": "Active",
"tag": "a"
},
"i": {
"name": "Closed",
"tag": "c"
},
"F": {
"name": "BasisMp2Fit",
"tag": "F"
}
},
"min_index_id": 1
}
}
}
]
}
This is an abridged excerpt. The full, runnable driver file can be found at
utilities/external-interface/examples/nevpt2_v2.json; it additionally demonstrates the batch_indices step and merging several inputs
into a single export step.