YASK
Yet Another Stencil Kit: a software framework for creating HPC stencil code. Copyright 2014-2023 Intel Corporation.
Loading...
Searching...
No Matches
Public Types | Public Member Functions | List of all members
yask::yc_solution Class Referenceabstract

Stencil solution. More...

#include <yask_compiler_api.hpp>

Public Types

typedef std::function< void(yc_solution &soln, yask_output_ptr output)> output_hook_t
 [Advanced] Callback type for call_before_output().
 

Public Member Functions

virtual void set_debug_output (yask_output_ptr debug)=0
 Set object to receive debug output.
 
virtual std::string get_name () const =0
 Get the name of the solution.
 
virtual void set_name (std::string name)=0
 Set the name of the solution.
 
virtual std::string get_description () const =0
 Get the description of the solution.
 
virtual void set_description (std::string description)=0
 Set the description of the solution.
 
virtual std::string get_target ()=0
 Get the current output-file format.
 
virtual void set_target (const std::string &format)=0
 Set the output target.
 
virtual bool is_target_set ()=0
 Determine whether target has been set.
 
virtual int get_element_bytes () const =0
 Get current floating-point precision setting.
 
virtual void set_element_bytes (int nbytes)=0
 Set floating-point precision.
 
virtual yc_var_ptr new_var (const std::string &name, const std::vector< yc_index_node_ptr > &dims)=0
 Create an n-dimensional variable in the solution.
 
virtual yc_var_ptr new_var (const std::string &name, const std::initializer_list< yc_index_node_ptr > &dims)=0
 Create an n-dimensional variable in the solution.
 
virtual yc_var_ptr new_scratch_var (const std::string &name, const std::vector< yc_index_node_ptr > &dims)=0
 Create an n-dimensional scratch variable in the solution.
 
virtual yc_var_ptr new_scratch_var (const std::string &name, const std::initializer_list< yc_index_node_ptr > &dims)=0
 Create an n-dimensional scratch variable in the solution.
 
virtual int get_num_vars () const =0
 Get the number of vars in the solution.
 
virtual std::vector< yc_var_ptrget_vars ()=0
 Get all the vars in the solution.
 
virtual yc_var_ptr get_var (const std::string &name)=0
 Get the specified var.
 
virtual void set_fold_len (const yc_index_node_ptr dim, int len)=0
 Set the vectorization length in given dimension.
 
virtual bool is_folding_set ()=0
 Determine whether any folding has been set.
 
virtual void clear_folding ()=0
 Remove all vector-folding settings.
 
virtual int get_num_equations () const =0
 Get the number of equations in the solution.
 
virtual std::vector< yc_equation_node_ptrget_equations ()=0
 Get a list of all the defined equations.
 
virtual int get_prefetch_dist (int level)=0
 Get the current prefetch distance for the given cache.
 
virtual void set_prefetch_dist (int level, int distance)=0
 Set the prefetch distance for the given cache.
 
virtual std::string apply_command_line_options (const std::string &args)=0
 Set compiler options from a string.
 
virtual std::string apply_command_line_options (int argc, char *argv[])=0
 Set compiler options from standard C or C++ argc and argv parameters to main().
 
virtual std::string apply_command_line_options (const string_vec &args)=0
 Set compiler options from a vector of strings.
 
virtual std::string get_command_line_help ()=0
 Return a help-string for the command-line options.
 
virtual std::string get_command_line_values ()=0
 Return a description of the current settings of the command-line options.
 
virtual void output_solution (yask_output_ptr output)=0
 Optimize and the current equation(s) and write to given output object.
 
virtual void call_before_output (output_hook_t hook_fn)=0
 [Advanced] Register a function to be called before a solution is output.
 
virtual void call_after_new_solution (const std::string &code)=0
 [Advanced] Add block of custom C++ code to the kernel solution.
 
virtual void set_domain_dims (const std::vector< yc_index_node_ptr > &dims)=0
 [Advanced] Explicitly define and order the domain dimensions used in the solution.
 
virtual void set_domain_dims (const std::initializer_list< yc_index_node_ptr > &dims)=0
 [Advanced] Explicitly define and order the domain dimensions used in the solution.
 
virtual void set_step_dim (const yc_index_node_ptr dim)=0
 [Advanced] Explicitly identify the step dimension in the solution.
 
virtual void set_dependency_checker_enabled (bool enable)=0
 [Advanced] Enable or disable automatic dependency checker.
 
virtual bool is_dependency_checker_enabled () const =0
 [Advanced] Determine whether automatic dependency checker is enabled.
 
virtual void add_flow_dependency (yc_equation_node_ptr from, yc_equation_node_ptr to)=0
 [Advanced] Add a dependency between two equations.
 
virtual void clear_dependencies ()=0
 [Advanced] Remove all existing dependencies.
 
YASK_DEPRECATED void set_cluster_mult (const yc_index_node_ptr dim, int mult)
 [Deprecated] Does nothing; will be removed in future versions.
 
YASK_DEPRECATED bool is_clustering_set ()
 [Deprecated] Will be removed in future versions.
 
YASK_DEPRECATED void clear_clustering ()
 [Deprecated] Does nothing; will be removed in future versions.
 
YASK_DEPRECATED void format (const std::string &format_type, yask_output_ptr output)
 [Deprecated] Use set_target() and output_solution().
 
YASK_DEPRECATED yc_var_ptr new_grid (const std::string &name, const std::vector< yc_index_node_ptr > &dims)
 [Deprecated] Use new_var().
 
YASK_DEPRECATED yc_var_ptr new_grid (const std::string &name, const std::initializer_list< yc_index_node_ptr > &dims)
 [Deprecated] Use new_var().
 
YASK_DEPRECATED yc_var_ptr new_scratch_grid (const std::string &name, const std::vector< yc_index_node_ptr > &dims)
 [Deprecated] Use new_scratch_var().
 
YASK_DEPRECATED yc_var_ptr new_scratch_grid (const std::string &name, const std::initializer_list< yc_index_node_ptr > &dims)
 [Deprecated] Use new_scratch_var().
 
YASK_DEPRECATED int get_num_grids () const
 [Deprecated] Use get_num_vars().
 
YASK_DEPRECATED std::vector< yc_var_ptrget_grids ()
 [Deprecated] Use get_vars().
 
YASK_DEPRECATED yc_var_ptr get_grid (const std::string &name)
 [Deprecated] Use get_var().
 

Detailed Description

Stencil solution.

Objects of this type contain all the vars and equations that comprise a solution. Must be created via yc_factory::new_solution().

Member Function Documentation

◆ set_debug_output()

virtual void yask::yc_solution::set_debug_output ( yask_output_ptr  debug)
pure virtual

Set object to receive debug output.

Parameters
[out]debugPointer to object to receive debug output. See yask_output_factory.

◆ get_name()

virtual std::string yask::yc_solution::get_name ( ) const
pure virtual

Get the name of the solution.

Returns
String containing the solution name provided via new_solution() or set_name().

◆ set_name()

virtual void yask::yc_solution::set_name ( std::string  name)
pure virtual

Set the name of the solution.

Allows changing the name from what was provided via new_solution().

Parameters
[in]nameName; must be a valid C++ identifier.

◆ get_description()

virtual std::string yask::yc_solution::get_description ( ) const
pure virtual

Get the description of the solution.

See set_description().

Returns
String containing the solution description.

◆ set_description()

virtual void yask::yc_solution::set_description ( std::string  description)
pure virtual

Set the description of the solution.

By default, the solution description is the same as that provided via new_solution() or set_name(). This allows setting the description to any string.

Parameters
[in]descriptionAny descriptive phrase.

◆ get_target()

virtual std::string yask::yc_solution::get_target ( )
pure virtual

Get the current output-file format.

Returns
Current target.
Exceptions
yask_exceptionif the target hasn't been set via set_target().

◆ set_target()

virtual void yask::yc_solution::set_target ( const std::string &  format)
pure virtual

Set the output target.

Currently supported targets:

Type Output
intel64 YASK kernel for generic 64-bit C++.
avx YASK kernel for CORE AVX ISA.
avx2 YASK kernel for CORE AVX2 ISA.
avx512 YASK kernel for CORE AVX-512 ISA.
avx512-ymm YASK kernel for CORE AVX-512 ISA with 256-bit SIMD.
knl YASK kernel for MIC AVX-512 ISA.
knc YASK kernel for Knights Corner ISA.
dot DOT-language description.
dot-lite DOT-language description of var accesses only.
pseudo Human-readable pseudo-code (for debug).
pseudo-long Human-readable pseudo-code with intermediate variables.
Warning
If the target is not valid, an exception will be thrown when output_solution() is called.
Parameters
[in]formatOutput-file format from above list

◆ is_target_set()

virtual bool yask::yc_solution::is_target_set ( )
pure virtual

Determine whether target has been set.

Returns
true if set_target() has been called with a non-empty string; false otherwise.

◆ get_element_bytes()

virtual int yask::yc_solution::get_element_bytes ( ) const
pure virtual

Get current floating-point precision setting.

Returns
Number of bytes in a FP number.

◆ set_element_bytes()

virtual void yask::yc_solution::set_element_bytes ( int  nbytes)
pure virtual

Set floating-point precision.

Parameters
[in]nbytesNumber of bytes in a FP number. Should be 4 or 8.

◆ new_var() [1/2]

virtual yc_var_ptr yask::yc_solution::new_var ( const std::string &  name,
const std::vector< yc_index_node_ptr > &  dims 
)
pure virtual

Create an n-dimensional variable in the solution.

"Var" is a generic term for any n-dimensional variable. A 0-dim var is a scalar, a 1-dim var is a vector, a 2-dim var is a matrix, etc.

The dimensions of a variable are defined by providing a list of indices created via yc_node_factory::new_step_index(), yc_node_factory::new_domain_index(), and/or yc_node_factory::new_misc_index(). When a step index is used, it must be the first index. If more than one var uses a step-index, the step-indices must have the same name. For example, you cannot have one var with step-index "t" and one with step-index "time".

Example code to create a solution with an equation for a variable named "A":

yc_factory ycfac;
auto my_soln = ycfac.new_solution("my_stencil");
auto t = nfac.new_step_index("t");
auto x = nfac.new_domain_index("x");
auto y = nfac.new_domain_index("y");
auto a = ycfac.new_var("A", { t, x, y });
a->new_var_point({t+1, x, y}) EQUALS (a->new_var_point({t, x, y}) +
a->new_var_point({t, x+1, y}) +
a->new_var_point({t, x, y+1})) * (1.0/3.0);
Bootstrap factory to create objects needed to define a stencil solution.
Definition yask_compiler_api.hpp:96
virtual yc_solution_ptr new_solution(const std::string &name) const
Create a stencil solution.
Factory to create AST nodes.
Definition yc_node_api.hpp:609
virtual yc_index_node_ptr new_step_index(const std::string &name) const
Create a step-index node.
virtual yc_index_node_ptr new_domain_index(const std::string &name) const
Create a domain-index node.
#define EQUALS
Recommended macro to make the "equality" operator readable and self-explanatory.
Definition yc_node_api.hpp:1102
Returns
Pointer to the new yc_var object.
Parameters
[in]nameName of the new var; must be a valid C++ identifier and unique across vars.
[in]dimsDimensions of the var. Each dimension is identified by an associated index.

◆ new_var() [2/2]

virtual yc_var_ptr yask::yc_solution::new_var ( const std::string &  name,
const std::initializer_list< yc_index_node_ptr > &  dims 
)
pure virtual

Create an n-dimensional variable in the solution.

C++ initializer-list version with same semantics as the vector version of new_var().

Note
Not available in the Python API. Use the vector version.
Returns
Pointer to the new yc_var object.
Parameters
[in]nameName of the new var; must be a valid C++ identifier and unique across vars.
[in]dimsDimensions of the var. Each dimension is identified by an associated index.

◆ new_scratch_var() [1/2]

virtual yc_var_ptr yask::yc_solution::new_scratch_var ( const std::string &  name,
const std::vector< yc_index_node_ptr > &  dims 
)
pure virtual

Create an n-dimensional scratch variable in the solution.

A scratch variable is a temporary variable used as an intermediate value in an equation.

  • Scratch vars are not accessible via kernel APIs. Thus, they cannot be programmatically read from or written to.
  • Scratch var values must be defined from equations ultimately referencing only non-scratch var values, optionally referencing other intermediate scratch-vars.
  • Scratch vars cannot use the step-index as a dimension.

See TestScratchStencil* classes in src/stencils/SimpleTestStencils.hpp for usage examples.

Returns
Pointer to the new yc_var object.
Parameters
[in]nameName of the new var; must be a valid C++ identifier and unique across vars.
[in]dimsDimensions of the var. Each dimension is identified by an associated index.

◆ new_scratch_var() [2/2]

virtual yc_var_ptr yask::yc_solution::new_scratch_var ( const std::string &  name,
const std::initializer_list< yc_index_node_ptr > &  dims 
)
pure virtual

Create an n-dimensional scratch variable in the solution.

C++ initializer-list version with same semantics as the vector version of new_scratch_var().

Note
Not available in the Python API. Use the vector version.
Returns
Pointer to the new yc_var object.
Parameters
[in]nameName of the new var; must be a valid C++ identifier and unique across vars.
[in]dimsDimensions of the var. Each dimension is identified by an associated index.

◆ get_num_vars()

virtual int yask::yc_solution::get_num_vars ( ) const
pure virtual

Get the number of vars in the solution.

Returns
Number of vars that have been created via new_var() or new_scratch_var().

◆ get_vars()

virtual std::vector< yc_var_ptr > yask::yc_solution::get_vars ( )
pure virtual

Get all the vars in the solution.

Returns
Vector containing pointers to all vars.

◆ get_var()

virtual yc_var_ptr yask::yc_solution::get_var ( const std::string &  name)
pure virtual

Get the specified var.

Returns
Pointer to the specified var or null pointer if it does not exist.
Parameters
[in]nameName of the var.

◆ set_fold_len()

virtual void yask::yc_solution::set_fold_len ( const yc_index_node_ptr  dim,
int  len 
)
pure virtual

Set the vectorization length in given dimension.

For YASK-code generation, the product of the fold lengths should be equal to the number of elements in a HW SIMD register. The number of elements in a HW SIMD register is determined by the number of bytes in an element and the print format.

Example: For SP FP elements in AVX-512 vectors, the product of the fold lengths should be 16, e.g., x=4 and y=4.

If the product of the fold lengths is not the number of elements in a HW SIMD register, the fold lengths will be adjusted based on an internal heuristic. In this heuristic, any specified fold length is used as a hint to determine the final folding.

Parameters
[in]dimDimension of fold, e.g., "x". This must be an index created by new_domain_index().
[in]lenLength of vectorization in dim

◆ is_folding_set()

virtual bool yask::yc_solution::is_folding_set ( )
pure virtual

Determine whether any folding has been set.

Returns
true if any fold length has been specified; false if not.

◆ get_num_equations()

virtual int yask::yc_solution::get_num_equations ( ) const
pure virtual

Get the number of equations in the solution.

Equations are added when yc_node_factory::new_equation_node() is called.

Returns
Number of equations that have been created.

◆ get_equations()

virtual std::vector< yc_equation_node_ptr > yask::yc_solution::get_equations ( )
pure virtual

Get a list of all the defined equations.

Returns
Vector of containing pointers to all equations that have been created.

◆ get_prefetch_dist()

virtual int yask::yc_solution::get_prefetch_dist ( int  level)
pure virtual

Get the current prefetch distance for the given cache.

Returns
Prefetch distance in number of iterations or zero (0) if disabled.
Parameters
[in]levelCache level: 1 or 2.

◆ set_prefetch_dist()

virtual void yask::yc_solution::set_prefetch_dist ( int  level,
int  distance 
)
pure virtual

Set the prefetch distance for the given cache.

Parameters
[in]levelCache level: 1 or 2.
[in]distanceNumber of iterations ahead to prefetch data or zero (0) to disable.

◆ apply_command_line_options() [1/3]

virtual std::string yask::yc_solution::apply_command_line_options ( const std::string &  args)
pure virtual

Set compiler options from a string.

Parses the string for options as if from a command-line. Example: passing "-elem_bytes 4" sets the solution for floats. See the help message from the YASK compiler binary for documentation on the command-line options. Used to set less-common options not directly supported by the APIs above (-min-buffer-len, etc.).

Returns
Any parts of args that were not recognized by the parser as options. Thus, a non-empty returned string may be used to signal an error or interpreted by a custom application in another way.
Parameters
[in]argsString of arguments to parse.

◆ apply_command_line_options() [2/3]

virtual std::string yask::yc_solution::apply_command_line_options ( int  argc,
char *  argv[] 
)
pure virtual

Set compiler options from standard C or C++ argc and argv parameters to main().

Discards argv[0], which is the executable name. Then, parses the remaining argv values for options as described in apply_command_line_options() with a string argument.

Returns
Any parts of argv that were not recognized by the parser as options.

◆ apply_command_line_options() [3/3]

virtual std::string yask::yc_solution::apply_command_line_options ( const string_vec args)
pure virtual

Set compiler options from a vector of strings.

Parses args values for options as described in apply_command_line_options() with a string argument.

Returns
Any parts of args that were not recognized by the parser as options.

◆ get_command_line_help()

virtual std::string yask::yc_solution::get_command_line_help ( )
pure virtual

Return a help-string for the command-line options.

Returns
A multi-line string.

◆ get_command_line_values()

virtual std::string yask::yc_solution::get_command_line_values ( )
pure virtual

Return a description of the current settings of the command-line options.

Returns
A multi-line string.

◆ output_solution()

virtual void yask::yc_solution::output_solution ( yask_output_ptr  output)
pure virtual

Optimize and the current equation(s) and write to given output object.

Output will be formatted according to set_target() and all other preceding YASK compiler API calls.

Progress text will be written to the output stream set via set_debug_output().

Exceptions
yask_exceptionif the target set via set_target() is invalid.
Warning
Side effect: Applies optimizations to the equation(s), so some pointers to nodes in the original equations may refer to modified nodes or nodes that have been optimized away after calling format(). In general, do not use pointers to nodes across calls to format().
Parameters
[out]outputPointer to object to receive formatted output. See yask_output_factory.

◆ call_before_output()

virtual void yask::yc_solution::call_before_output ( output_hook_t  hook_fn)
pure virtual

[Advanced] Register a function to be called before a solution is output.

The registered functions will be called during a call to output_solution() after the equations optimizations have been applied but before the output is written.

A reference to the solution and the parameter to output_solution() are passed to the hook_fn.

If this method is called more than once, the hook functions will be called in the order registered.

Note
Not available in the Python API.
Parameters
[in]hook_fncallback function

◆ call_after_new_solution()

virtual void yask::yc_solution::call_after_new_solution ( const std::string &  code)
pure virtual

[Advanced] Add block of custom C++ code to the kernel solution.

This block of code will be executed immediately after the stencil solution is constructed in the kernel, i.e., at the end of a call to yk_factory::new_solution(). The code may access the new solution via the reference kernel_soln of type yk_solution.

Common uses of this facility include setting default run-time settings such as block sizes and registering call-back routines, e.g., via yk_solution::call_before_prepare_solution();

Unlike yk_solution::call_before_prepare_solution() and similar functions which have std::function parameters, the parameter to this function is a string because the code is not compiled (or compilable) until the kernel library is built.

Alternatively, equivalent code can be added directly to any custom application using the kernel library APIs. However, this function is useful when using the provided YASK kernel-performance utility launched via bin/yask.sh. It also provides a method to provide consistent kernel code when the kernel library is used in multiple applications.

Parameters
[in]codeCode to be inserted, using kernel_soln of type yk_solution to access the kernel solution.

◆ set_domain_dims() [1/2]

virtual void yask::yc_solution::set_domain_dims ( const std::vector< yc_index_node_ptr > &  dims)
pure virtual

[Advanced] Explicitly define and order the domain dimensions used in the solution.

The order of domain dimensions affects memory layout, looping order, vector-folding, and rank layout. This API also allows specification of the domain dimensions in the unusual case where a solution is defined without any vars containing all of the domain dimensions. Whether or not this API is called, domain dimension(s) are added when new_var() or new_scratch_var() is called with one or more domain dimensions not previously seen.

Parameters
[in]dimsDomain dimensions of the solution.

◆ set_domain_dims() [2/2]

virtual void yask::yc_solution::set_domain_dims ( const std::initializer_list< yc_index_node_ptr > &  dims)
pure virtual

[Advanced] Explicitly define and order the domain dimensions used in the solution.

C++ initializer-list version with same semantics as the vector version of new_var().

Note
Not available in the Python API. Use the vector version.
Parameters
[in]dimsDomain dimensions of the solution.

◆ set_step_dim()

virtual void yask::yc_solution::set_step_dim ( const yc_index_node_ptr  dim)
pure virtual

[Advanced] Explicitly identify the step dimension in the solution.

By default, the step dimension is defined when new_var() is called with a step index. This API allows specification of the step dimension in the unusual case where a solution is defined without any vars containing the step dimension.

Parameters
[in]dimStep dimension.

◆ set_dependency_checker_enabled()

virtual void yask::yc_solution::set_dependency_checker_enabled ( bool  enable)
pure virtual

[Advanced] Enable or disable automatic dependency checker.

Disabling the built-in dependency checker may be done when it is overly conservative. Currently, the provided checker does not allow stencils in which points in one sub-domain depend on points in another sub-domain within the same value of the step index.

Warning
If dependency checker is disabled, all dependencies must be set via add_flow_dependency().
Parameters
[in]enabletrue to enable or false to disable.

◆ is_dependency_checker_enabled()

virtual bool yask::yc_solution::is_dependency_checker_enabled ( ) const
pure virtual

[Advanced] Determine whether automatic dependency checker is enabled.

Returns
Current setting.

◆ add_flow_dependency()

virtual void yask::yc_solution::add_flow_dependency ( yc_equation_node_ptr  from,
yc_equation_node_ptr  to 
)
pure virtual

[Advanced] Add a dependency between two equations.

This function adds an arc in the data-dependency graph from one equation (node) to another one, indicating that the from equation depends on the to equation. In other words, the to expression must be evaluated before the from equation. In compiler-theory terms, this is a flow dependency, also known as a true or read-after-write (RAW) dependency. (Strictly speaking, however, equations in the YASK compiler are declarative instead of imperative, so they describe equalities rather than assignments with reads and writes. On the other hand, a C++ function created to implement one or more equations will perform analogous reads and writes.)

Additional considerations:

  • It is not necessary to connect all the equations into a single graph. For example, if A depends on B and C depends on D, there will be two disconnected subgraphs. In this example, the YASK kernel is free to 1) schedule the functions created for B** and D to run together in parallel followed by those for A** and C together in parallel, 2) run a single function that implements both B and D simultaneously followed by a single function that implements both A and C simultaneously, or 3) a combination of the implementations.
  • Only immediate dependencies should be added. In other words, each subgraph created should be a transitive reduction. For example, if A depends on B and B depends on C, it is not necessary to add the transitive dependence from A to C.
  • Only dependencies at a given step-index value should be added. For example, given equation A: A(t+1, x) EQUALS B(t+1, x) + 5 and equation B: B(t+1, x) EQUALS A(t, x) / 2, A** depends on B at some value of the step-index t. That dependency should be added if the automatic checker is disabled. (It is true that the next value of B(t+2) depends on A(t+1), but such inter-step – analgous to loop-carried – dependencies should not be added with this function.)
  • The dependencies should create one or more directed acyclic graphs (DAGs). If a cycle is created, the YASK compiler will throw an exception containing an error message about a circular dependency. This exception may not be thrown until output_solution() is called.
  • If using scratch vars, dependencies among scratch vars and between scratch equations and non-scratch equations should also be added. Each scratch equation should ultimately depend on non-scratch values.
  • This function can be used in cooperation with or instead of the built-in automatic dependency checker. When used in cooperation with the built-in checker, both dependencies from this function and the built-in checker will be considered. When the built-in checker is diabled via set_dependency_checker_enabled(false), only dependencies from this function will be considered. In this case, it is imperative that all immediate dependencies are added. If the dependency graph is incomplete, the resulting generated stencil code will contain illegal race conditions, and it will most likely produce incorrect results.
Parameters
[in]fromEquation that must be evaluated after to.
[in]toEquation that must be evaluated before from.

◆ clear_dependencies()

virtual void yask::yc_solution::clear_dependencies ( )
pure virtual

[Advanced] Remove all existing dependencies.

Removes dependencies added via add_flow_dependency().

◆ is_clustering_set()

YASK_DEPRECATED bool yask::yc_solution::is_clustering_set ( )
inline

[Deprecated] Will be removed in future versions.

Returns
false always.

The documentation for this class was generated from the following file: