CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
453 lines
20 KiB
ReStructuredText
453 lines
20 KiB
ReStructuredText
.. meta::
|
|
:description: rocBLAS design and usage notes
|
|
:keywords: rocBLAS, ROCm, API, Linear Algebra, documentation, design, usage notes
|
|
|
|
.. _rocblas-design-notes:
|
|
|
|
********************************************************************
|
|
rocBLAS design and usage notes
|
|
********************************************************************
|
|
|
|
This topic covers the structure, organization, and concepts underlying rocBLAS. It also includes some notes on how
|
|
to use rocBLAS effectively.
|
|
|
|
.. _rocblas-tensile-hipblaslt:
|
|
|
|
Use of Tensile and hipBLASLt
|
|
============================
|
|
|
|
The rocBLAS library uses :doc:`Tensile <tensile:src/index>` and :doc:`hipBLASLt <hipblaslt:index>` internally, which
|
|
supply high-performance implementations of GEMM. Tensile is installed as part of the rocBLAS package, while hipBLASLt is
|
|
available as a separate package. By default, the rocBLAS library is built with Tensile and depends on the
|
|
external hipBLASLt library.
|
|
|
|
rocBLAS uses CMake for building, which by default downloads the Tensile component during library configuration and automatically
|
|
builds it as an integrated part of the rocBLAS build. No further set-up work is required by the
|
|
user. For hermetic builds, the Tensile component can be built from a local path installation (see command line options).
|
|
Note that external facing APIs for Tensile are not provided.
|
|
|
|
The choice of whether to use the embedded Tensile backend or hipBLASLt is handled automatically based on the architecture and problem.
|
|
For instance, hipBLASLt is used as the default backend for problems on the gfx12 architecture. Source code GEMMs internal to the rocBLAS library also
|
|
allow rocBLAS to be built without Tensile or hipBLASLt.
|
|
They can potentially be used as fallbacks for problems that are not supported by the Tensile or hipBLASLt backends.
|
|
|
|
The environment variables ``ROCBLAS_USE_HIPBLASLT`` and ``ROCBLAS_USE_HIPBLASLT_BATCHED`` are provided to manually control which GEMM backend is used. ``ROCBLAS_USE_HIPBLASLT`` is for non-batched, _strided_batched and _batched GEMM. ``ROCBLAS_USE_HIPBLASLT_BATCHED`` only affects _batched GEMM. ``ROCBLAS_USE_HIPBLASLT_BATCHED`` is deprecated, should no longer be required, and is planned for removal in a future release. These provide the following settings:
|
|
|
|
* ``ROCBLAS_USE_HIPBLASLT`` and ``ROCBLAS_USE_HIPBLASLT_BATCHED`` are not set: the GEMM backend is automatically selected.
|
|
* ``ROCBLAS_USE_HIPBLASLT=0``: Tensile is always used as the GEMM backend.
|
|
* ``ROCBLAS_USE_HIPBLASLT_BATCHED=0``: Tensile is always used as the GEMM _batched backend. This setting is deprecated.
|
|
* ``ROCBLAS_USE_HIPBLASLT=1``: hipBLASLt is preferred as the GEMM backend, but the backend will fall back to Tensile for problems for which hipBLASLt does not provide a solution or if errors are encountered using the hipBLASLt backend.
|
|
|
|
.. note::
|
|
|
|
The hipBLASLt backend for rocBLAS is currently not supported on static builds,
|
|
and is not included if building without Tensile.
|
|
|
|
rocBLAS API and legacy BLAS functions
|
|
=====================================
|
|
|
|
rocBLAS is initialized by calling ``rocblas_create_handle`` and is terminated by calling ``rocblas_destroy_handle``.
|
|
The ``rocblas_handle`` is persistent and contains:
|
|
|
|
* The HIP stream
|
|
* The temporary device workspace
|
|
* The mode for enabling or disabling logging (the default is logging disabled)
|
|
|
|
rocBLAS functions run on the host. They call HIP to launch rocBLAS kernels that run on the device in a HIP stream.
|
|
The kernels are asynchronous unless:
|
|
|
|
* The function returns a scalar result from device to host
|
|
* Temporary device memory is allocated
|
|
|
|
In both cases above, the launch can be made asynchronous by:
|
|
|
|
* Using ``rocblas_pointer_mode_device`` to keep the scalar result on the device. Only the following Level-1 BLAS functions return a scalar result: ``Xdot``, ``Xdotu``, ``Xdotc``, ``Xnrm2``, ``Xasum``, ``iXamax``, and ``iXamin``.
|
|
* Using the device memory functions provided to allocate persistent device memory in the handle. Note that most rocBLAS functions do not allocate temporary device memory.
|
|
|
|
Before calling a rocBLAS function, arrays must be copied to the device. Integer scalars like m, n, and k are stored on the host. Floating point scalars like alpha and beta can be on the host or device.
|
|
|
|
Error handling is performed by returning a ``rocblas_status``. Functions conform to the legacy BLAS argument checking.
|
|
|
|
|
|
Rules for obtaining the rocBLAS API from legacy BLAS functions
|
|
--------------------------------------------------------------
|
|
|
|
#. The legacy BLAS routine name is changed to lowercase and prefixed by ``rocblas_<function>``.
|
|
For example, the legacy BLAS routine ``SSCAL``, which scales a vector by a constant value, is replaced with ``rocblas_sscal``.
|
|
|
|
#. An initial argument of ``rocblas_handle`` handle is added to all rocBLAS functions.
|
|
|
|
#. Input arguments are declared with the ``const`` modifier.
|
|
|
|
#. Character arguments are replaced with enumerated types defined in
|
|
``rocblas_types.h``. They are passed by value on the host.
|
|
|
|
#. Array arguments are passed by reference on the device.
|
|
|
|
#. Scalar arguments are passed by value on the host with the following
|
|
exceptions. See the :ref:`pointer-mode` section for more information:
|
|
|
|
* Scalar values alpha and beta are passed by reference on either the
|
|
host or the device.
|
|
* When legacy BLAS functions have return values, the return value is
|
|
instead added as the last function argument. It is returned by
|
|
reference on either the host or the device. This applies to the
|
|
following functions: ``xDOT``, ``xDOTU``, ``xDOTC``, ``xNRM2``, ``xASUM``, ``IxAMAX``, and ``IxAMIN``.
|
|
|
|
#. The return value of all functions is ``rocblas_status``, which is defined in
|
|
``rocblas_types.h``. It is used to check for errors.
|
|
|
|
|
|
rocBLAS example code
|
|
====================
|
|
|
|
Below is a simple example for calling the function ``rocblas_sscal``:
|
|
|
|
.. code-block:: c++
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include "hip/hip_runtime_api.h"
|
|
#include "rocblas.h"
|
|
|
|
using namespace std;
|
|
|
|
int main()
|
|
{
|
|
rocblas_int n = 10240;
|
|
float alpha = 10.0;
|
|
|
|
vector<float> hx(n);
|
|
vector<float> hz(n);
|
|
float* dx;
|
|
|
|
rocblas_handle handle;
|
|
rocblas_create_handle(&handle);
|
|
|
|
// allocate memory on device
|
|
hipMalloc(&dx, n * sizeof(float));
|
|
|
|
// Initial Data on CPU,
|
|
srand(1);
|
|
for( int i = 0; i < n; ++i )
|
|
{
|
|
hx[i] = rand() % 10 + 1; //generate a integer number between [1, 10]
|
|
}
|
|
|
|
// copy array from host memory to device memory
|
|
hipMemcpy(dx, hx.data(), sizeof(float) * n, hipMemcpyHostToDevice);
|
|
|
|
// call rocBLAS function
|
|
rocblas_status status = rocblas_sscal(handle, n, &alpha, dx, 1);
|
|
|
|
// check status for errors
|
|
if(status == rocblas_status_success)
|
|
{
|
|
cout << "status == rocblas_status_success" << endl;
|
|
}
|
|
else
|
|
{
|
|
cout << "rocblas failure: status = " << status << endl;
|
|
}
|
|
|
|
// copy output from device memory to host memory
|
|
hipMemcpy(hx.data(), dx, sizeof(float) * n, hipMemcpyDeviceToHost);
|
|
|
|
hipFree(dx);
|
|
rocblas_destroy_handle(handle);
|
|
return 0;
|
|
}
|
|
|
|
|
|
LP64 interface
|
|
--------------
|
|
|
|
The rocBLAS library default implementations are LP64, so ``rocblas_int`` arguments are 32 bit and
|
|
``rocblas_stride`` arguments are 64 bit.
|
|
|
|
.. _ILP64 API:
|
|
|
|
ILP64 interface
|
|
---------------
|
|
|
|
The rocBLAS library functions are also available with ILP64 interfaces. With these interfaces,
|
|
all ``rocblas_int`` arguments are replaced by the type name
|
|
``int64_t``. These ILP64 function names all end with the suffix ``_64``. The only output arguments that change are for
|
|
``xMAX`` and ``xMIN``, where the index is now ``int64_t``. Performance should match the LP64 API when problem sizes don't require additional
|
|
precision. Function-level documentation is not repeated for these APIs because they are identical in behavior to the LP64 versions.
|
|
However, functions which support this alternate API include the line:
|
|
``This function supports the 64-bit integer interface (ILP64)``.
|
|
When parameters exceeding the internal maximum supported size are provided
|
|
the functions will return ``rocblas_status_invalid_size``. This is most often for symmetric matrix dimensions larger than the ``int32_t`` max value,
|
|
for which such large memory allocation is not practical.
|
|
|
|
Column-major storage and 1-based indexing
|
|
-----------------------------------------
|
|
|
|
rocBLAS uses column-major storage for 2D arrays, and 1-based indexing
|
|
for the functions ``xMAX`` and ``xMIN``. This is the same as legacy BLAS and
|
|
cuBLAS.
|
|
|
|
If you require row-major and 0-based indexing (used in C language arrays), download the file ``cblas.tgz`` from the `Netlib Repository <https://netlib.org/>`_.
|
|
Review the CBLAS functions that provide a thin interface to legacy BLAS. They convert from row-major and 0-based to column-major and
|
|
1-based. This is done by swapping the order of the function arguments. It is not necessary to transpose the matrices.
|
|
|
|
.. _pointer-mode:
|
|
|
|
Pointer mode
|
|
------------
|
|
|
|
The auxiliary functions ``rocblas_set_pointer`` and ``rocblas_get_pointer`` are
|
|
used to set and get the value of the state variable
|
|
``rocblas_pointer_mode``. This variable is stored in ``rocblas_handle``. If ``rocblas_pointer_mode ==
|
|
rocblas_pointer_mode_host``, then scalar parameters must be allocated on
|
|
the host. If ``rocblas_pointer_mode == rocblas_pointer_mode_device``, then
|
|
scalar parameters must be allocated on the device.
|
|
|
|
There are two types of scalar parameters:
|
|
|
|
* Scaling parameters like alpha and beta used in functions like ``axpy``, ``gemv``, and ``gemm``
|
|
* Scalar results from the functions ``amax``, ``amin``, ``asum``, ``dot``, and ``nrm2``
|
|
|
|
Scalar parameters like alpha and beta can be allocated on the host heap or
|
|
stack when ``rocblas_pointer_mode == rocblas_pointer_mode_host``.
|
|
The kernel launch is asynchronous, so if the parameters are on the heap,
|
|
they can be freed after the return from the kernel launch. When
|
|
``rocblas_pointer_mode == rocblas_pointer_mode_device``, the parameters must not be
|
|
changed until the kernel completes.
|
|
|
|
For scalar results when ``rocblas_pointer_mode ==
|
|
rocblas_pointer_mode_host``, the function blocks the CPU until the GPU
|
|
has copied the result back to the host. When ``rocblas_pointer_mode ==
|
|
rocblas_pointer_mode_device``, the function returns after the
|
|
asynchronous launch. Like the vector and matrix results, the scalar
|
|
result is only available when the kernel has completed execution.
|
|
|
|
Asynchronous API
|
|
----------------
|
|
|
|
rocBLAS functions are asynchronous unless:
|
|
|
|
* The function needs to allocate device memory
|
|
* The function returns a scalar result from GPU to CPU
|
|
|
|
The order of operations in the asynchronous functions is shown in the figure
|
|
below. The argument checking, calculation of the process grid, and kernel
|
|
launch take very little time. The asynchronous kernel running on the GPU
|
|
does not block the CPU. After the kernel launch, the CPU continues processing
|
|
the instructions.
|
|
|
|
.. asynch_blocks
|
|
.. figure:: ../data/asynch_function.PNG
|
|
:alt: code blocks in asynch function call
|
|
:align: center
|
|
|
|
Order of operations in asynchronous functions
|
|
|
|
|
|
The order of operations above will change if logging is enabled or the
|
|
function is synchronous. Logging requires system calls, so the program
|
|
must wait for them to complete before executing the next instruction.
|
|
For more information, see :doc:`Logging in rocBLAS <../how-to/logging-in-rocblas>`.
|
|
|
|
.. note::
|
|
|
|
The default setting has logging disabled.
|
|
|
|
If the CPU needs to allocate device memory, it must wait until memory allocation is complete before
|
|
executing the next instruction. For more detailed information, refer to the sections :ref:`Device Memory Allocation Usage` and :ref:`Device Memory allocation in detail`.
|
|
|
|
.. note::
|
|
|
|
Memory can be pre-allocated. This makes the function asynchronous because it removes the need for the function to allocate memory.
|
|
|
|
The following functions copy a scalar result from GPU to CPU if
|
|
``rocblas_pointer_mode == rocblas_pointer_mode_host``:
|
|
|
|
* ``asum``
|
|
* ``dot``
|
|
* ``max``
|
|
* ``min``
|
|
* ``nrm2``
|
|
|
|
This makes the function synchronous because the program must wait
|
|
for the copy before executing the next instruction. See :ref:`pointer-mode` for more information.
|
|
|
|
.. note::
|
|
|
|
You can make a function asynchronous by setting ``rocblas_pointer_mode == rocblas_pointer_mode_device``.
|
|
This keeps the result on the GPU.
|
|
|
|
The order of operations for logging, device memory allocation, and return of a scalar
|
|
result is shown in the figure below:
|
|
|
|
.. asynch_blocks
|
|
.. figure:: ../data/synchronous_function.PNG
|
|
:alt: code blocks in a synchronous function call
|
|
:align: center
|
|
|
|
Code blocks in a synchronous function call
|
|
|
|
Kernel launch status error checking
|
|
-----------------------------------
|
|
|
|
The function ``hipExtGetLastError()`` is called after a rocBLAS kernel launches.
|
|
This function detects if the launch parameters are incorrect, for example,
|
|
an invalid work group or thread block size. It also determines if the kernel code is unable to
|
|
run on the current GPU device. In that case, it returns a status of ``rocblas_status_arch_mismatch``.
|
|
Thus most rocblas API functions that launch kernels will flush a pre-existing error.
|
|
You can check for any previous HIP error before calling a rocBLAS API function
|
|
by calling ``hipGetLastError()``.
|
|
|
|
Complex number data types
|
|
-------------------------
|
|
|
|
The data types for rocBLAS complex numbers in the API are a special case.
|
|
For C compiler users, gcc, and other non-amdclang compiler users, these types
|
|
are exposed as a struct with x and y components and an identical memory layout
|
|
to ``std::complex`` for float and double precision. Internally, a templated
|
|
C++ class is defined, but it should be considered deprecated for external use.
|
|
For simplified usage with Hipified code, there is an option
|
|
to interpret the API as using the ``hipFloatComplex`` and ``hipDoubleComplex`` types
|
|
(for instance, ``typedef hipFloatComplex rocblas_float_complex``). This is made available
|
|
for users to avoid casting when using the HIP complex types in their code.
|
|
|
|
The memory layout is consistent across all three types, so
|
|
it is safe to cast arguments to API calls between the three types: ``hipFloatComplex``,
|
|
``std::complex<float>``, and ``rocblas_float_complex``, as well as for
|
|
the double-precision variants. To expose the API using the HIP-defined
|
|
complex types, use either a compiler define or an inlined
|
|
``#define ROCM_MATHLIBS_API_USE_HIP_COMPLEX`` before including the header file ``<rocblas.h>``.
|
|
The API is therefore compatible with both forms, but
|
|
recompilation is required to avoid casting if you are switching to pass in the HIP complex types.
|
|
Most device memory pointers are passed with ``void*``
|
|
types to the HIP utility functions (for example, ``hipMemcpy``), so uploading memory from ``std::complex`` arrays
|
|
or ``hipFloatComplex`` arrays doesn't require changes
|
|
regardless of the complex data type API choice.
|
|
|
|
.. _Atomic Operations:
|
|
|
|
Atomic operations
|
|
-----------------
|
|
|
|
Some functions within the rocBLAS library such as ``gemv``, ``symv``, ``trsv``, ``trsm``,
|
|
and ``gemm`` can use atomic operations to increase performance.
|
|
By using atomics, functions might not give bit-wise reproducible results.
|
|
Differences between multiple runs should not be significant and the results will
|
|
remain accurate. If you want to allow atomic operations, see :any:`rocblas_atomics_mode`,
|
|
:any:`rocblas_set_atomics_mode`, and :any:`rocblas_get_atomics_mode`.
|
|
|
|
In addition to the API above, rocBLAS also provides the environment variable ``ROCBLAS_DEFAULT_ATOMICS_MODE``,
|
|
which lets users set the default atomics mode during the creation of ``rocblas_handle``.
|
|
:any:`rocblas_set_atomics_mode` has higher precedence, so users can use
|
|
the API in an application to override the environment variable configuration setting.
|
|
|
|
The following settings apply to ``ROCBLAS_DEFAULT_ATOMICS_MODE``:
|
|
|
|
* ``ROCBLAS_DEFAULT_ATOMICS_MODE = 0`` : Sets the default to :any:`rocblas_atomics_not_allowed`
|
|
* ``ROCBLAS_DEFAULT_ATOMICS_MODE = 1`` : Sets the atomics to :any:`rocblas_atomics_allowed`
|
|
|
|
Bitwise reproducibility
|
|
-----------------------
|
|
|
|
In rocBLAS, bitwise-reproducible results can be obtained under the following conditions:
|
|
|
|
* Identical GFX target ISA
|
|
* Single HIP stream active per rocBLAS handle
|
|
* Identical ROCm versions
|
|
* Atomic operations are not allowed (for more information, see :ref:`Atomic Operations`)
|
|
|
|
By default, atomic operations are not allowed. All other functions are bitwise reproducible by default.
|
|
|
|
.. note::
|
|
|
|
Functions such as GEMV and TRSM use temporary device memory to allow optimized kernels to achieve higher performance.
|
|
If device memory is unavailable, these functions proceed to use an unoptimized kernel, which could also produce variable results.
|
|
To notify users that an unoptimized kernel is being used, the function returns the :any:`rocblas_status_perf_degraded` status.
|
|
|
|
======================================================
|
|
Functions that can be enabled to use atomic operations
|
|
======================================================
|
|
|
|
:any:`rocblas_sgemv`
|
|
:any:`rocblas_dgemv`
|
|
|
|
:any:`rocblas_ssymv`
|
|
:any:`rocblas_dsymv`
|
|
|
|
:any:`rocblas_strsv`
|
|
:any:`rocblas_dtrsv`
|
|
:any:`rocblas_ztrsv`
|
|
:any:`rocblas_ctrsv`
|
|
|
|
:any:`rocblas_strsm`
|
|
:any:`rocblas_dtrsm`
|
|
:any:`rocblas_ztrsm`
|
|
:any:`rocblas_ctrsm`
|
|
|
|
:any:`rocblas_sgemm`
|
|
:any:`rocblas_dgemm`
|
|
:any:`rocblas_hgemm`
|
|
:any:`rocblas_zgemm`
|
|
:any:`rocblas_cgemm`
|
|
|
|
=======================
|
|
|
|
.. note::
|
|
|
|
This list also includes all Level-3 functions.
|
|
|
|
Instinct MI100 (gfx908) considerations
|
|
---------------------------------------
|
|
|
|
On nodes using the MI100 (gfx908) GPU, Matrix-Fused-Multiply-Add (MFMA)
|
|
instructions are available to substantially speed up matrix operations.
|
|
This hardware feature is used in all GEMM and GEMM-based functions in
|
|
rocBLAS with 32-bit or shorter base data types with an associated 32-bit
|
|
``compute_type`` (``f32_r``, ``i32_r``, or ``f32_c`` as applicable).
|
|
|
|
Specifically, rocBLAS takes advantage of MI100's MFMA instructions for
|
|
three real base types ``f16_r``, ``bf16_r``, and ``f32_r`` with ``compute_type`` ``f32_r``,
|
|
one integral base type ``i8_r`` with ``compute_type`` ``i32_r``, and one complex
|
|
base type ``f32_c`` with ``compute_type`` ``f32_c``. In summary, all GEMM APIs and
|
|
APIs for GEMM-based functions using these five base types and their
|
|
associated ``compute_type`` (explicit or implicit) take advantage of MI100's
|
|
MFMA instructions.
|
|
|
|
.. note::
|
|
|
|
The MI100's MFMA instructions are used automatically. There is no user setting to turn this functionality on or off.
|
|
|
|
Not all problem sizes consistently select the MFMA-based kernels.
|
|
Additional tuning might be required to achieve good performance.
|
|
|
|
Instinct MI200 (gfx90a) Considerations
|
|
----------------------------------------
|
|
|
|
On nodes using the MI200 (gfx90a) GPU, MFMA_F64 instructions are available to
|
|
substantially speed up double-precision matrix operations. This
|
|
hardware feature is used in all GEMM and GEMM-based functions in
|
|
rocBLAS with 64-bit floating-point data types: ``DGEMM``, ``ZGEMM``,
|
|
``DTRSM``, ``ZTRSM``, ``DTRMM``, ``ZTRMM``, ``DSYRKX``, and ``ZSYRKX``.
|
|
|
|
The MI200 ``MFMA_F16``, ``MFMA_BF16``, and ``MFMA_BF16_1K`` instructions
|
|
flush subnormal input/output data ("denorms") to zero.
|
|
In some instances, use cases utilizing the HPA (High Precision Accumulate) HGEMM
|
|
kernels where ``a_type=b_type=c_type=d_type=f16_r`` and ``compute_type=f32_r``
|
|
do not work well with the MI200's flush-denorms-to-zero behavior.
|
|
The is due to the limited exponent range of the ``F16`` data types.
|
|
|
|
rocBLAS provides an alternate implementation of the
|
|
HPA HGEMM kernel that uses the ``MFMA_BF16_1K`` instruction. It
|
|
takes advantage of the much larger exponent range of ``BF16``, although with reduced
|
|
accuracy. To select the alternate implementation of HPA HGEMM with the
|
|
``gemm_ex`` or ``gemm_strided_batched_ex`` functions, use
|
|
the enum value of ``rocblas_gemm_flags_fp16_alt_impl`` for the ``flags`` argument.
|
|
|
|
.. note::
|
|
|
|
The MI200's MFMA instructions (including MFMA_F64) are used automatically. There is no user setting to turn this functionality on or off.
|
|
|
|
Not all problem sizes consistently select the MFMA-based kernels.
|
|
Additional tuning might be required to achieve good performance.
|