Other Traits#

The traits below are derived from the function description and help verify shared memory requirements or select tuned launch parameters. Which traits are available depends on the execution operator:

Table 5 Trait availability by execution operator#

Trait

Block

Cluster

Thread

Notes

is_supported<Description, Arch>

Yes

Yes

Yes

Always true for thread descriptions; for block and cluster descriptions, checks per-block shared memory budget.

Description::suggested_block_dim

Yes

Yes

No

Default for BlockDim when not set explicitly.

Description::suggested_batches_per_block

Yes

No

No

Only applicable with Block Operator.

Description::suggested_tile_size

No

Yes

No

Only applicable with Cluster Operator; default for TileSize.

See Execution Traits for additional descriptor traits such as block_dim, shared_memory_size, blocks_per_cluster, and tile_size.

Trait

Description

is_supported<Description, Arch>

Verifies if a given Solver operation is supported on the provided CUDA architecture Arch.

Description::suggested_block_dim

Recommended number of threads per CTA for optimal performance.

Description::suggested_batches_per_block

Recommended number of batches per block for optimal performance (block execution only).

Description::suggested_tile_size

Recommended tile size for cluster POTRF (cluster execution only).

is_supported Trait#

// true if Solver is supported on the provided CUDA architecture
cusolverdx::is_supported<Solver, Arch>::value;
cusolverdx::is_supported_v<Solver, Arch>;

cusolverdx::is_supported checks whether a Solver operation is supported on CUDA architecture Arch, based on the shared memory size requirement for the operation when executed in shared memory.

Execution operator support: available for descriptions built with Block Operator, Cluster Operator, or Thread Operator.

Requirements of using the trait:

Behavior:

  • Thread execution: always returns true. Users are responsible for register and shared memory usage.

  • Cluster execution: always returns true. Whether the tiled DSMEM workspace actually fits is checked at compile time when the description is complete (see Solver::shared_memory_size and cluster POTRF static_assert messages).

  • Block execution: returns true only if the per-block shared memory required by the descriptor fits within the shared memory limit of architecture Arch.

Example

using namespace cusolverdx;

using Solver = decltype(Size<160>() + Function<potrf>() + Type<type::real>() +
                        Block() + Precision<double>());
cusolverdx::is_supported<Solver, 1000>::value; // true
cusolverdx::is_supported<Solver,  900>::value; // true
cusolverdx::is_supported<Solver,  800>::value; // false

The shared memory size required to run Cholesky decomposition for a 160x160 double matrix is 200 KB, while the maximum amount of shared memory per thread block for Ampere, Hopper, and Blackwell is 163, 227, and 227 KB, respectively (see CUDA compute capability).

Important

For thread execution, the trait always returns true; see behavior above. For cluster execution, use Solver::shared_memory_size per CTA and compile-time checks in addition to this trait when sizing the DSMEM tile workspace.

Suggested Block Dim Trait#

// dim3(X, Y==1, Z==1)
Solver::suggested_block_dim

Execution operator support: Block Operator and Cluster Operator only. Using this trait with Thread Operator is a compile error.

Recommended number of threads per CTA for a Solver description. For block execution, the value depends on size, data type, GPU architecture, and BatchesPerBlock. For cluster execution (POTRF), the value additionally depends on TileSize, BlocksPerCluster, and architecture tuning tables.

Note that the suggested block dim is effectively a 1D value.

The suggested block dim is used if the BlockDim operator is not explicitly defined by the user.

Important

The suggested block dimensions lead to optimal performance for the cuSolverDx function in most cases, but if the function is fused with other operations, we recommend measuring the performance of the kernel first, then experimenting with different values (see Performance).

Suggested Batches Per Block Trait#

// unsigned int
Solver::suggested_batches_per_block

Execution operator support: Block Operator only. Not available for Cluster Operator or Thread Operator.

Recommended optimal batches per block for a Solver description.

The following example shows how to use the trait:

  • First define a complete execution descriptor with required operators, including size, data type, function, SM, and the block operator;

  • Then form a second descriptor by adding the BatchesPerBlock operator using the trait.

Example

using Base = decltype(Size<14, 14>() + Precision<double>() + Type<type::complex>() +
              Block() + Function<posv>() + SM<Arch>());

using POSV = decltype(Base() +
                      BatchesPerBlock<Base::suggested_batches_per_block>() +
                      FillMode<fill_mode::lower>() +
                      Arrangement<arrangement::row_major>());

Important

The suggested number of batches per block leads to optimal performance for the cuSolverDx function in most cases, but if the function is fused with other operations, we recommend measuring the performance of the kernel first, then experimenting with different values (see Performance).

Suggested Tile Size Trait#

// unsigned int
Solver::suggested_tile_size

Execution operator support: Cluster Operator only. Using this trait with Block Operator or Thread Operator results in a compile error.

Recommended tile size for cluster POTRF, based on matrix size N, data type, BlocksPerCluster, and architecture. Used as the default when TileSize is not set explicitly.

The runtime trait Solver::tile_size returns the tile size used by the descriptor (defined TileSize value or suggested_tile_size).

Example

#include <cusolverdx_cluster.hpp>

using namespace cusolverdx;

using Base = decltype(Size<288>() + Precision<float>() + Type<type::real>() +
                      Function<function::potrf>() + FillMode<fill_mode::lower>() +
                      Cluster() + BlocksPerCluster<4>() + SM<900>());

using POTRF = decltype(Base() + TileSize<Base::suggested_tile_size>());

Important

Suggested tile sizes are tuned for SM 9.0 and later. Measure kernel performance and use different optimal values when fusing cluster POTRF with custom load/store or other work (see Performance).