BLIS:merge:

Merge conflicts araised has been fixed while downstreaming BLIS code from master to milan-3.1 branch

Implemented an automatic reduction in the number of threads when the user requests parallelism via a single number (ie: the automatic way) and (a) that number of threads is prime, and (b) that number exceeds a minimum threshold defined by the macro BLIS_NT_MAX_PRIME, which defaults to 11. If prime numbers are really desired, this feature may be suppressed by defining the macro BLIS_ENABLE_AUTO_PRIME_NUM_THREADS in the appropriate configuration family's bli_family_*.h. (Jeff Diamond)

Changed default value of BLIS_THREAD_RATIO_M from 2 to 1, which leads to slightly different automatic thread factorizations.

Enable the 1m method only if the real domain microkernel is not a reference kernel. BLIS now forgoes use of 1m if both the real and complex domain kernels are reference implementations.

Relocated the general stride handling for gemmsup. This fixed an issue whereby gemm would fail to trigger to conventional code path for cases that use general stride even after gemmsup rejected the problem. (RuQing Xu)

Fixed an incorrect function signature (and prototype) of bli_?gemmt(). (RuQing Xu)

Redefined BLIS_NUM_ARCHS to be part of the arch_t enum, which means it will be updated automatically when defining future subconfigs.

Minor code consolidation in all level-3 _front() functions.

Reorganized Windows cpp branch of bli_pthreads.c.

Implemented bli_pthread_self() and _equals(), but left them commented out (via cpp guards) due to issues with getting the Windows versions working. Thankfully, these functions aren't yet needed by BLIS.

Allow disabling of trsm diagonal pre-inversion at compile time via --disable-trsm-preinversion.

Fixed obscure testsuite bug for the gemmt test module that relates to its dependency on gemv.

AMD-internal-[CPUPL-1523]

Change-Id: I0d1df018e2df96a23dc4383d01d98b324d5ac5cd
This commit is contained in:
lcpu
2021-04-26 23:41:13 +05:30
320 changed files with 147817 additions and 4448 deletions

View File

@@ -1,6 +1,7 @@
# Contents
* **[Contents](BLISObjectAPI.md#contents)**
* **[Operation index](BLISObjectAPI.md#operation-index)**
* **[Introduction](BLISObjectAPI.md#introduction)**
* [BLIS types](BLISObjectAPI.md#blis-types)
* [Integer-based types](BLISObjectAPI.md#integer-based-types)
@@ -15,8 +16,9 @@
* **[Object management](BLISObjectAPI.md#object-management)**
* [Object creation function reference](BLISObjectAPI.md#object-creation-function-reference)
* [Object accessor function reference](BLISObjectAPI.md#object-accessor-function-reference)
* [Object mutator function reference](BLISObjectAPI.md#object-mutator-function-reference)
* [Other object function reference](BLISObjectAPI.md#other-object-function-reference)
* **[Computational function reference](BLISObjectAPI.md#computational-function-reference)**
* [Operation index](BLISObjectAPI.md#operation-index)
* [Level-1v operations](BLISObjectAPI.md#level-1v-operations)
* [Level-1d operations](BLISObjectAPI.md#level-1d-operations)
* [Level-1m operations](BLISObjectAPI.md#level-1m-operations)
@@ -24,14 +26,37 @@
* [Level-2 operations](BLISObjectAPI.md#level-2-operations)
* [Level-3 operations](BLISObjectAPI.md#level-3-operations)
* [Utility operations](BLISObjectAPI.md#utility-operations)
* [Level-3 microkernels](BLISObjectAPI.md#level-3-microkernels)
* **[Query function reference](BLISObjectAPI.md#query-function-reference)**
* [General library information](BLISObjectAPI.md#general-library-information)
* [Specific configuration](BLISObjectAPI.md#specific-configuration)
* [General configuration](BLISObjectAPI.md#general-configuration)
* [Kernel information](BLISObjectAPI.md#kernel-information)
* [Clock functions](BLISObjectAPI.md#clock-functions)
* **[Example code](BLISObjectAPI.md#example-code)**
# Operation index
This index provides a quick way to jump directly to the description for each operation discussed later in the [Computational function reference](BLISObjectAPI.md#computational-function-reference) section:
* **[Level-1v](BLISObjectAPI.md#level-1v-operations)**: Operations on vectors:
* [addv](BLISObjectAPI.md#addv), [amaxv](BLISObjectAPI.md#amaxv), [axpyv](BLISObjectAPI.md#axpyv), [axpbyv](BLISObjectAPI.md#axpbyv), [copyv](BLISObjectAPI.md#copyv), [dotv](BLISObjectAPI.md#dotv), [dotxv](BLISObjectAPI.md#dotxv), [invertv](BLISObjectAPI.md#invertv), [scal2v](BLISObjectAPI.md#scal2v), [scalv](BLISObjectAPI.md#scalv), [setv](BLISObjectAPI.md#setv), [setrv](BLISObjectAPI.md#setrv), [setiv](BLISObjectAPI.md#setiv), [subv](BLISObjectAPI.md#subv), [swapv](BLISObjectAPI.md#swapv), [xpbyv](BLISObjectAPI.md#xpbyv)
* **[Level-1d](BLISObjectAPI.md#level-1d-operations)**: Element-wise operations on matrix diagonals:
* [addd](BLISObjectAPI.md#addd), [axpyd](BLISObjectAPI.md#axpyd), [copyd](BLISObjectAPI.md#copyd), [invertd](BLISObjectAPI.md#invertd), [scald](BLISObjectAPI.md#scald), [scal2d](BLISObjectAPI.md#scal2d), [setd](BLISObjectAPI.md#setd), [setid](BLISObjectAPI.md#setid), [shiftd](BLISObjectAPI.md#shiftd), [subd](BLISObjectAPI.md#subd), [xpbyd](BLISObjectAPI.md#xpbyd)
* **[Level-1m](BLISObjectAPI.md#level-1m-operations)**: Element-wise operations on matrices:
* [addm](BLISObjectAPI.md#addm), [axpym](BLISObjectAPI.md#axpym), [copym](BLISObjectAPI.md#copym), [scalm](BLISObjectAPI.md#scalm), [scal2m](BLISObjectAPI.md#scal2m), [setm](BLISObjectAPI.md#setm), [setrm](BLISObjectAPI.md#setrm), [setim](BLISObjectAPI.md#setim), [subm](BLISObjectAPI.md#subm)
* **[Level-1f](BLISObjectAPI.md#level-1f-operations)**: Fused operations on multiple vectors:
* [axpy2v](BLISObjectAPI.md#axpy2v), [dotaxpyv](BLISObjectAPI.md#dotaxpyv), [axpyf](BLISObjectAPI.md#axpyf), [dotxf](BLISObjectAPI.md#dotxf), [dotxaxpyf](BLISObjectAPI.md#dotxaxpyf)
* **[Level-2](BLISObjectAPI.md#level-2-operations)**: Operations with one matrix and (at least) one vector operand:
* [gemv](BLISObjectAPI.md#gemv), [ger](BLISObjectAPI.md#ger), [hemv](BLISObjectAPI.md#hemv), [her](BLISObjectAPI.md#her), [her2](BLISObjectAPI.md#her2), [symv](BLISObjectAPI.md#symv), [syr](BLISObjectAPI.md#syr), [syr2](BLISObjectAPI.md#syr2), [trmv](BLISObjectAPI.md#trmv), [trsv](BLISObjectAPI.md#trsv)
* **[Level-3](BLISObjectAPI.md#level-3-operations)**: Operations with matrices that are multiplication-like:
* [gemm](BLISObjectAPI.md#gemm), [hemm](BLISObjectAPI.md#hemm), [herk](BLISObjectAPI.md#herk), [her2k](BLISObjectAPI.md#her2k), [symm](BLISObjectAPI.md#symm), [syrk](BLISObjectAPI.md#syrk), [syr2k](BLISObjectAPI.md#syr2k), [trmm](BLISObjectAPI.md#trmm), [trmm3](BLISObjectAPI.md#trmm3), [trsm](BLISObjectAPI.md#trsm)
* **[Utility](BLISObjectAPI.md#Utility-operations)**: Miscellaneous operations on matrices and vectors:
* [asumv](BLISObjectAPI.md#asumv), [norm1v](BLISObjectAPI.md#norm1v), [normfv](BLISObjectAPI.md#normfv), [normiv](BLISObjectAPI.md#normiv), [norm1m](BLISObjectAPI.md#norm1m), [normfm](BLISObjectAPI.md#normfm), [normim](BLISObjectAPI.md#normim), [mkherm](BLISObjectAPI.md#mkherm), [mksymm](BLISObjectAPI.md#mksymm), [mktrim](BLISObjectAPI.md#mktrim), [fprintv](BLISObjectAPI.md#fprintv), [fprintm](BLISObjectAPI.md#fprintm),[printv](BLISObjectAPI.md#printv), [printm](BLISObjectAPI.md#printm), [randv](BLISObjectAPI.md#randv), [randm](BLISObjectAPI.md#randm), [sumsqv](BLISObjectAPI.md#sumsqv), [getijm](BLISObjectAPI.md#getijm), [setijm](BLISObjectAPI.md#setijm)
# Introduction
This document summarizes one of the primary native APIs in BLIS--the object API. Here, we also discuss BLIS-specific type definitions, header files, and prototypes to auxiliary functions.
@@ -40,6 +65,9 @@ There are many functions that BLIS implements that are not listed here, either b
The object API was given its name (a) because it abstracts the floating-point types of its operands (along with many other properties) within a `typedef struct {...}` data structure, and (b) to contrast it with the other native API in BLIS, the typed API, which is [documented here](BLISTypedAPI.md). (The third API supported by BLIS is the BLAS compatibility layer, which mimics conventional Fortran-77 BLAS.)
In general, this document should be treated more as a reference than a place to learn how to use BLIS in your application. Thus, we highly encourage all readers to first study the [example code](BLISObjectAPI.md#example-code) provided within the BLIS source distribution.
## BLIS types
The following tables list various types used throughout the BLIS object API.
@@ -393,9 +421,7 @@ Objects initialized via this function should **never** be passed to `bli_obj_fre
Notes for interpreting function descriptions:
* Object accessor functions allow the caller to query certain properties of objects.
* These functions are only guaranteed to return meaningful values when called upon objects that have been fully initialized/created.
* Many specialized functions are omitted from this section for brevity. For a full list of accessor functions, please see [frame/include/bli_obj_macro_defs.h](https://github.com/flame/blis/tree/master/frame/include/bli_obj_macro_defs.h).
**Note**: For now, we mostly omit documentation for the corresponding functions used to modify object properties because those functions can easily invalidate the state of an `obj_t` and should be used only in specific instances. If you think you need to manually set the fields of an `obj_t`, please contact BLIS developers so we can give you personalized guidance.
* Many specialized functions are omitted from this section for brevity. For a full list of accessor functions, please see [frame/include/bli_obj_macro_defs.h](https://github.com/flame/blis/tree/master/frame/include/bli_obj_macro_defs.h), though most users will most likely not need methods beyond those documented below.
---
@@ -423,7 +449,7 @@ Return the precision component of the storage datatype property of `obj`.
```c
trans_t bli_obj_conjtrans_status( obj_t* obj );
```
Return the `trans_t` property of `obj`, which may indicate transposition, conjugation, both, or neither.
Return the `trans_t` property of `obj`, which may indicate transposition, conjugation, both, or neither. Thus, possible return values are `BLIS_NO_TRANSPOSE`, `BLIS_CONJ_NO_TRANSPOSE`, `BLIS_TRANSPOSE`, or `BLIS_CONJ_TRANSPOSE`.
---
@@ -444,23 +470,30 @@ Thus, possible return values are `BLIS_NO_CONJUGATE` or `BLIS_CONJUGATE`.
---
```c
uplo_t bli_obj_uplo( obj_t* obj );
struc_t bli_obj_struc( obj_t* obj );
```
Return the `uplo_t` property of `obj`.
Return the structure property of `obj`.
---
```c
struc_t bli_obj_struc( obj_t* obj );
uplo_t bli_obj_uplo( obj_t* obj );
```
Return the `struc_t` property of `obj`.
Return the uplo (i.e., storage) property of `obj`.
---
```c
diag_t bli_obj_diag( obj_t* obj );
```
Return the `diag_t` property of `obj`.
Return the diagonal property of `obj`.
---
```c
doff_t bli_obj_diag_offset( obj_t* obj );
```
Return the diagonal offset of `obj`. Note that the diagonal offset will be negative, `-i`, if the diagonal begins at element `(-i,0)` and positive `j` if the diagonal begins at element `(0,j)`.
---
@@ -492,13 +525,6 @@ Return the number of columns (or _n_ dimension) of `obj` after taking into accou
---
```c
doff_t bli_obj_diag_offset( obj_t* obj );
```
Return the diagonal offset of `obj`. Note that the diagonal offset will be negative, `-i`, if the diagonal begins at element `(-i,0)` and positive `j` if the diagonal begins at element `(0,j)`.
---
```c
inc_t bli_obj_row_stride( obj_t* obj );
```
@@ -542,6 +568,90 @@ siz_t bli_obj_elem_size( obj_t* obj );
```
Return the size, in bytes, of the storage datatype as indicated by `bli_obj_dt()`.
## Object mutator function reference
Notes for interpreting function descriptions:
* Object mutator functions allow the caller to modify certain properties of objects.
* The user should be extra careful about modifying properties after objects are created. For typical use of these functions, please study the example code provided in [examples/oapi](https://github.com/flame/blis/tree/master/examples/oapi).
* The list of mutators below is much shorter than the list of accessor functions provided in the previous section. Most mutator functions should *not* be called by users (unless you know what you are doing). For a full list of mutator functions, please see [frame/include/bli_obj_macro_defs.h](https://github.com/flame/blis/tree/master/frame/include/bli_obj_macro_defs.h), though most users will most likely not need methods beyond those documented below.
---
```c
void bli_obj_set_conjtrans( trans_t trans, obj_t* obj );
```
Set both conjugation and transposition properties of `obj` using the corresponding components of `trans`.
---
```c
void bli_obj_set_onlytrans( trans_t trans, obj_t* obj );
```
Set the transposition property of `obj` using the transposition component of `trans`. Leaves the conjugation property of `obj` unchanged.
---
```c
void bli_obj_set_conj( conj_t conj, obj_t* obj );
```
Set the conjugation property of `obj` using `conj`. Leaves the transposition property of `obj` unchanged.
---
```c
void bli_obj_apply_trans( trans_t trans, obj_t* obj );
```
Apply `trans` to the transposition property of `obj`. For example, applying `BLIS_TRANSPOSE` will toggle the transposition property of `obj` but leave the conjugation property unchanged; applying `BLIS_CONJ_TRANSPOSE` will toggle both the conjugation and transposition properties of `obj`.
---
```c
void bli_obj_apply_conj( conj_t conj, obj_t* obj );
```
Apply `conj` to the conjugation property of `obj`. Specifically, applying `BLIS_CONJUGATE` will toggle the conjugation property of `obj`; applying `BLIS_NO_CONJUGATE` will have no effect. Leaves the transposition property of `obj` unchanged.
---
```c
void bli_obj_set_struc( struc_t struc, obj_t* obj );
```
Set the structure property of `obj` to `struc`.
---
```c
void bli_obj_set_uplo( uplo_t uplo, obj_t* obj );
```
Set the uplo (i.e., storage) property of `obj` to `uplo`.
---
```c
void bli_obj_set_diag( diag_t diag, obj_t* obj );
```
Set the diagonal property of `obj` to `diag`.
---
```c
void bli_obj_set_diag_offset( doff_t doff, obj_t* obj );
```
Set the diagonal offset property of `obj` to `doff`. Note that `doff_t` may be typecast from any signed integer.
---
## Other object function reference
---
```c
void bli_obj_induce_trans( obj_t* obj );
```
Modify the properties of `obj` to induce a logical transposition. This function operates without regard to whether the transposition property is already set. Therefore, depending on the circumstance, the caller may or may not wish to clear the transposition property after calling this function.
---
```c
@@ -567,13 +677,6 @@ void bli_obj_imag_part( obj_t* c, obj_t* i );
```
Initialize `i` to be a modified shallow copy of `c` that refers only to the imaginary part of `c`.
---
```c
void bli_obj_induce_trans( obj_t* obj );
```
Modify the properties of `obj` to induce a logical transposition. This function operations without regard to whether the transposition property is already set. Therefore, depending on the circumstance, the caller may or may not wish to clear the transposition property after calling this function. (If needed, the user may call `bli_obj_toggle_trans( obj )` to toggle the transposition status.)
# Computational function reference
@@ -591,26 +694,6 @@ Notes for interpreting function descriptions:
---
## Operation index
* **[Level-1v](BLISObjectAPI.md#level-1v-operations)**: Operations on vectors:
* [addv](BLISObjectAPI.md#addv), [amaxv](BLISObjectAPI.md#amaxv), [axpyv](BLISObjectAPI.md#axpyv), [axpbyv](BLISObjectAPI.md#axpbyv), [copyv](BLISObjectAPI.md#copyv), [dotv](BLISObjectAPI.md#dotv), [dotxv](BLISObjectAPI.md#dotxv), [invertv](BLISObjectAPI.md#invertv), [scal2v](BLISObjectAPI.md#scal2v), [scalv](BLISObjectAPI.md#scalv), [setv](BLISObjectAPI.md#setv), [setrv](BLISObjectAPI.md#setrv), [setiv](BLISObjectAPI.md#setiv), [subv](BLISObjectAPI.md#subv), [swapv](BLISObjectAPI.md#swapv), [xpbyv](BLISObjectAPI.md#xpbyv)
* **[Level-1d](BLISObjectAPI.md#level-1d-operations)**: Element-wise operations on matrix diagonals:
* [addd](BLISObjectAPI.md#addd), [axpyd](BLISObjectAPI.md#axpyd), [copyd](BLISObjectAPI.md#copyd), [invertd](BLISObjectAPI.md#invertd), [scald](BLISObjectAPI.md#scald), [scal2d](BLISObjectAPI.md#scal2d), [setd](BLISObjectAPI.md#setd), [setid](BLISObjectAPI.md#setid), [shiftd](BLISObjectAPI.md#shiftd), [subd](BLISObjectAPI.md#subd), [xpbyd](BLISObjectAPI.md#xpbyd)
* **[Level-1m](BLISObjectAPI.md#level-1m-operations)**: Element-wise operations on matrices:
* [addm](BLISObjectAPI.md#addm), [axpym](BLISObjectAPI.md#axpym), [copym](BLISObjectAPI.md#copym), [scalm](BLISObjectAPI.md#scalm), [scal2m](BLISObjectAPI.md#scal2m), [setm](BLISObjectAPI.md#setm), [setrm](BLISObjectAPI.md#setrm), [setim](BLISObjectAPI.md#setim), [subm](BLISObjectAPI.md#subm)
* **[Level-1f](BLISObjectAPI.md#level-1f-operations)**: Fused operations on multiple vectors:
* [axpy2v](BLISObjectAPI.md#axpy2v), [dotaxpyv](BLISObjectAPI.md#dotaxpyv), [axpyf](BLISObjectAPI.md#axpyf), [dotxf](BLISObjectAPI.md#dotxf), [dotxaxpyf](BLISObjectAPI.md#dotxaxpyf)
* **[Level-2](BLISObjectAPI.md#level-2-operations)**: Operations with one matrix and (at least) one vector operand:
* [gemv](BLISObjectAPI.md#gemv), [ger](BLISObjectAPI.md#ger), [hemv](BLISObjectAPI.md#hemv), [her](BLISObjectAPI.md#her), [her2](BLISObjectAPI.md#her2), [symv](BLISObjectAPI.md#symv), [syr](BLISObjectAPI.md#syr), [syr2](BLISObjectAPI.md#syr2), [trmv](BLISObjectAPI.md#trmv), [trsv](BLISObjectAPI.md#trsv)
* **[Level-3](BLISObjectAPI.md#level-3-operations)**: Operations with matrices that are multiplication-like:
* [gemm](BLISObjectAPI.md#gemm), [hemm](BLISObjectAPI.md#hemm), [herk](BLISObjectAPI.md#herk), [her2k](BLISObjectAPI.md#her2k), [symm](BLISObjectAPI.md#symm), [syrk](BLISObjectAPI.md#syrk), [syr2k](BLISObjectAPI.md#syr2k), [trmm](BLISObjectAPI.md#trmm), [trmm3](BLISObjectAPI.md#trmm3), [trsm](BLISObjectAPI.md#trsm)
* **[Utility](BLISObjectAPI.md#Utility-operations)**: Miscellaneous operations on matrices and vectors:
* [asumv](BLISObjectAPI.md#asumv), [norm1v](BLISObjectAPI.md#norm1v), [normfv](BLISObjectAPI.md#normfv), [normiv](BLISObjectAPI.md#normiv), [norm1m](BLISObjectAPI.md#norm1m), [normfm](BLISObjectAPI.md#normfm), [normim](BLISObjectAPI.md#normim), [mkherm](BLISObjectAPI.md#mkherm), [mksymm](BLISObjectAPI.md#mksymm), [mktrim](BLISObjectAPI.md#mktrim), [fprintv](BLISObjectAPI.md#fprintv), [fprintm](BLISObjectAPI.md#fprintm),[printv](BLISObjectAPI.md#printv), [printm](BLISObjectAPI.md#printm), [randv](BLISObjectAPI.md#randv), [randm](BLISObjectAPI.md#randm), [sumsqv](BLISObjectAPI.md#sumsqv), [getijm](BLISObjectAPI.md#getijm), [setijm](BLISObjectAPI.md#setijm)
---
## Level-1v operations
Level-1v operations perform various level-1 BLAS-like operations on vectors (hence the _v_).
@@ -996,7 +1079,7 @@ void bli_setd
);
```
Observed object properties: `conj?(alpha)`, `diagoff(A)`, `diag(A)`.
Observed object properties: `conj?(alpha)`, `diagoff(A)`.
---
@@ -1599,6 +1682,27 @@ Observed object properties: `trans?(A)`, `trans?(B)`.
---
#### gemmt
```c
void bli_gemmt
(
obj_t* alpha,
obj_t* a,
obj_t* b,
obj_t* beta,
obj_t* c
);
```
Perform
```
C := beta * C + alpha * trans?(A) * trans?(B)
```
where `C` is an _m x m_ matrix, `trans?(A)` is an _m x k_ matrix, and `trans?(B)` is a _k x m_ matrix. This operation is similar to `bli_gemm()` except that it only updates the lower or upper triangle of `C` as specified by `uplo(C)`.
Observed object properties: `trans?(A)`, `trans?(B)`, `uplo(C)`.
---
#### hemm
```c
void bli_hemm
@@ -2132,7 +2236,55 @@ Possible microkernel types (ie: the return values for `bli_info_get_*_ukr_impl_s
* `BLIS_OPTIMIZED_UKERNEL` (`"optimzd"`): This value is returned when the queried microkernel is provided by an implementation that is neither reference nor virtual, and thus we assume the kernel author would deem it to be "optimized". Such a microkernel may not be optimal in the literal sense of the word, but nonetheless is _intended_ to be optimized, at least relative to the reference microkernels.
* `BLIS_NOTAPPLIC_UKERNEL` (`"notappl"`): This value is returned usually when performing a `gemmtrsm` or `trsm` microkernel type query for any `method` value that is not `BLIS_NAT` (ie: native). That is, induced methods cannot be (purely) used on `trsm`-based microkernels because these microkernels perform more a triangular inversion, which is not matrix multiplication.
## Clock functions
---
#### clock
```c
double bli_clock
(
void
);
```
Return the amount of time that has elapsed since some fixed time in the past. The return values of `bli_clock()` typically feature nanosecond precision, though this is not guaranteed.
**Note:** On Linux, `bli_clock()` is implemented in terms of `clock_gettime()` using the `clockid_t` value of `CLOCK_MONOTONIC`. On OS X, `bli_clock` is implemented in terms of `mach_absolute_time()`. And on Windows, `bli_clock` is implemented in terms of `QueryPerformanceFrequency()`. Please see [frame/base/bli_clock.c](https://github.com/flame/blis/blob/master/frame/base/bli_clock.c) for more details.
**Note:** This function is returns meaningless values when BLIS is configured with `--disable-system`.
---
#### clock_min_diff
```c
double bli_clock_min_diff
(
double time_prev_min,
double time_start
);
```
This function computes an intermediate value, `time_diff`, equal to `bli_clock() - time_start`, and then tentatively prepares to return the minimum value of `time_diff` and `time_min`. If that minimum value is extremely small (close to zero), the function returns `time_min` instead.
This function is meant to be used in conjuction with `bli_clock()` for
performance timing within applications--specifically in loops where only
the fastest timing is of interest. For example:
```c
double t_save = DBL_MAX;
for( i = 0; i < 3; ++i )
{
double t = bli_clock();
bli_gemm( ... );
t_save = bli_clock_min_diff( t_save, t );
}
double gflops = ( 2.0 * m * k * n ) / ( t_save * 1.0e9 );
```
This code calls `bli_gemm()` three times and computes the performance, in GFLOPS, of the fastest of the three executions.
---
# Example code
BLIS provides lots of example code in the [examples/oapi](https://github.com/flame/blis/tree/master/examples/oapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include creating and managing objects, printing vectors and matrices, setting and querying object properties, and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above.
BLIS provides lots of example code in the [examples/oapi](https://github.com/flame/blis/tree/master/examples/oapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include creating and managing objects, printing vectors and matrices, setting and querying object properties, and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above. Please read the `README` contained within the `examples/oapi` directory for further details.

View File

@@ -1,6 +1,7 @@
# Contents
* **[Contents](BLISTypedAPI.md#contents)**
* **[Operation index](BLISTypedAPI.md#operation-index)**
* **[Introduction](BLISTypedAPI.md#introduction)**
* [BLIS types](BLISTypedAPI.md#blis-types)
* [Integer-based types](BLISTypedAPI.md#integer-based-types)
@@ -12,7 +13,6 @@
* [BLIS header file](BLISTypedAPI.md#blis-header-file)
* [Initialization and cleanup](BLISTypedAPI.md#initialization-and-cleanup)
* **[Computational function reference](BLISTypedAPI.md#computational-function-reference)**
* [Operation index](BLISTypedAPI.md#operation-index)
* [Level-1v operations](BLISTypedAPI.md#level-1v-operations)
* [Level-1d operations](BLISTypedAPI.md#level-1d-operations)
* [Level-1m operations](BLISTypedAPI.md#level-1m-operations)
@@ -26,8 +26,32 @@
* [Specific configuration](BLISTypedAPI.md#specific-configuration)
* [General configuration](BLISTypedAPI.md#general-configuration)
* [Kernel information](BLISTypedAPI.md#kernel-information)
* [Clock functions](BLISTypedAPI.md#clock-functions)
* **[Example code](BLISTypedAPI.md#example-code)**
# Operation index
This index provides a quick way to jump directly to the description for each operation discussed later in the [Computational function reference](BLISTypedAPI.md#computational-function-reference) section:
* **[Level-1v](BLISTypedAPI.md#level-1v-operations)**: Operations on vectors:
* [addv](BLISTypedAPI.md#addv), [amaxv](BLISTypedAPI.md#amaxv), [axpyv](BLISTypedAPI.md#axpyv), [axpbyv](BLISTypedAPI.md#axpbyv), [copyv](BLISTypedAPI.md#copyv), [dotv](BLISTypedAPI.md#dotv), [dotxv](BLISTypedAPI.md#dotxv), [invertv](BLISTypedAPI.md#invertv), [scal2v](BLISTypedAPI.md#scal2v), [scalv](BLISTypedAPI.md#scalv), [setv](BLISTypedAPI.md#setv), [subv](BLISTypedAPI.md#subv), [swapv](BLISTypedAPI.md#swapv), [xpbyv](BLISTypedAPI.md#xpbyv)
* **[Level-1d](BLISTypedAPI.md#level-1d-operations)**: Element-wise operations on matrix diagonals:
* [addd](BLISTypedAPI.md#addd), [axpyd](BLISTypedAPI.md#axpyd), [copyd](BLISTypedAPI.md#copyd), [invertd](BLISTypedAPI.md#invertd), [scald](BLISTypedAPI.md#scald), [scal2d](BLISTypedAPI.md#scal2d), [setd](BLISTypedAPI.md#setd), [setid](BLISTypedAPI.md#setid), [shiftd](BLISTypedAPI.md#shiftd), [subd](BLISTypedAPI.md#subd), [xpbyd](BLISTypedAPI.md#xpbyd)
* **[Level-1m](BLISTypedAPI.md#level-1m-operations)**: Element-wise operations on matrices:
* [addm](BLISTypedAPI.md#addm), [axpym](BLISTypedAPI.md#axpym), [copym](BLISTypedAPI.md#copym), [scalm](BLISTypedAPI.md#scalm), [scal2m](BLISTypedAPI.md#scal2m), [setm](BLISTypedAPI.md#setm), [subm](BLISTypedAPI.md#subm)
* **[Level-1f](BLISTypedAPI.md#level-1f-operations)**: Fused operations on multiple vectors:
* [axpy2v](BLISTypedAPI.md#axpy2v), [dotaxpyv](BLISTypedAPI.md#dotaxpyv), [axpyf](BLISTypedAPI.md#axpyf), [dotxf](BLISTypedAPI.md#dotxf), [dotxaxpyf](BLISTypedAPI.md#dotxaxpyf)
* **[Level-2](BLISTypedAPI.md#level-2-operations)**: Operations with one matrix and (at least) one vector operand:
* [gemv](BLISTypedAPI.md#gemv), [ger](BLISTypedAPI.md#ger), [hemv](BLISTypedAPI.md#hemv), [her](BLISTypedAPI.md#her), [her2](BLISTypedAPI.md#her2), [symv](BLISTypedAPI.md#symv), [syr](BLISTypedAPI.md#syr), [syr2](BLISTypedAPI.md#syr2), [trmv](BLISTypedAPI.md#trmv), [trsv](BLISTypedAPI.md#trsv)
* **[Level-3](BLISTypedAPI.md#level-3-operations)**: Operations with matrices that are multiplication-like:
* [gemm](BLISTypedAPI.md#gemm), [hemm](BLISTypedAPI.md#hemm), [herk](BLISTypedAPI.md#herk), [her2k](BLISTypedAPI.md#her2k), [symm](BLISTypedAPI.md#symm), [syrk](BLISTypedAPI.md#syrk), [syr2k](BLISTypedAPI.md#syr2k), [trmm](BLISTypedAPI.md#trmm), [trmm3](BLISTypedAPI.md#trmm3), [trsm](BLISTypedAPI.md#trsm)
* **[Utility](BLISTypedAPI.md#Utility-operations)**: Miscellaneous operations on matrices and vectors:
* [asumv](BLISTypedAPI.md#asumv), [norm1v](BLISTypedAPI.md#norm1v), [normfv](BLISTypedAPI.md#normfv), [normiv](BLISTypedAPI.md#normiv), [norm1m](BLISTypedAPI.md#norm1m), [normfm](BLISTypedAPI.md#normfm), [normim](BLISTypedAPI.md#normim), [mkherm](BLISTypedAPI.md#mkherm), [mksymm](BLISTypedAPI.md#mksymm), [mktrim](BLISTypedAPI.md#mktrim), [fprintv](BLISTypedAPI.md#fprintv), [fprintm](BLISTypedAPI.md#fprintm),[printv](BLISTypedAPI.md#printv), [printm](BLISTypedAPI.md#printm), [randv](BLISTypedAPI.md#randv), [randm](BLISTypedAPI.md#randm), [sumsqv](BLISTypedAPI.md#sumsqv)
# Introduction
This document summarizes one of the primary native APIs in BLIS--the "typed" API. Here, we also discuss BLIS-specific type definitions, header files, and prototypes to auxiliary functions. This document also includes APIs to key kernels which are used to accelerate and optimize various level-2 and level-3 operations, though the [Kernels Guide](KernelsHowTo.md) goes into more detail, especially for level-3 microkernels.
@@ -36,6 +60,8 @@ There are many functions that BLIS implements that are not listed here, either b
For curious readers, the typed API was given its name (a) because it exposes the floating-point types in the names of its functions, and (b) to contrast it with the other native API in BLIS, the object API, which is [documented here](BLISObjectAPI.md). (The third API supported by BLIS is the BLAS compatibility layer, which mimics conventional Fortran-77 BLAS.)
In general, this document should be treated more as a reference than a place to learn how to use BLIS in your application. Thus, we highly encourage all readers to first study the [example code](BLISTypedAPI.md#example-code) provided within the BLIS source distribution.
## BLIS types
The following tables list various types used throughout the BLIS typed API.
@@ -190,26 +216,6 @@ Notes for interpreting function descriptions:
---
## Operation index
* **[Level-1v](BLISTypedAPI.md#level-1v-operations)**: Operations on vectors:
* [addv](BLISTypedAPI.md#addv), [amaxv](BLISTypedAPI.md#amaxv), [axpyv](BLISTypedAPI.md#axpyv), [axpbyv](BLISTypedAPI.md#axpbyv), [copyv](BLISTypedAPI.md#copyv), [dotv](BLISTypedAPI.md#dotv), [dotxv](BLISTypedAPI.md#dotxv), [invertv](BLISTypedAPI.md#invertv), [scal2v](BLISTypedAPI.md#scal2v), [scalv](BLISTypedAPI.md#scalv), [setv](BLISTypedAPI.md#setv), [subv](BLISTypedAPI.md#subv), [swapv](BLISTypedAPI.md#swapv), [xpbyv](BLISTypedAPI.md#xpbyv)
* **[Level-1d](BLISTypedAPI.md#level-1d-operations)**: Element-wise operations on matrix diagonals:
* [addd](BLISTypedAPI.md#addd), [axpyd](BLISTypedAPI.md#axpyd), [copyd](BLISTypedAPI.md#copyd), [invertd](BLISTypedAPI.md#invertd), [scald](BLISTypedAPI.md#scald), [scal2d](BLISTypedAPI.md#scal2d), [setd](BLISTypedAPI.md#setd), [setid](BLISTypedAPI.md#setid), [shiftd](BLISTypedAPI.md#shiftd), [subd](BLISTypedAPI.md#subd), [xpbyd](BLISTypedAPI.md#xpbyd)
* **[Level-1m](BLISTypedAPI.md#level-1m-operations)**: Element-wise operations on matrices:
* [addm](BLISTypedAPI.md#addm), [axpym](BLISTypedAPI.md#axpym), [copym](BLISTypedAPI.md#copym), [scalm](BLISTypedAPI.md#scalm), [scal2m](BLISTypedAPI.md#scal2m), [setm](BLISTypedAPI.md#setm), [subm](BLISTypedAPI.md#subm)
* **[Level-1f](BLISTypedAPI.md#level-1f-operations)**: Fused operations on multiple vectors:
* [axpy2v](BLISTypedAPI.md#axpy2v), [dotaxpyv](BLISTypedAPI.md#dotaxpyv), [axpyf](BLISTypedAPI.md#axpyf), [dotxf](BLISTypedAPI.md#dotxf), [dotxaxpyf](BLISTypedAPI.md#dotxaxpyf)
* **[Level-2](BLISTypedAPI.md#level-2-operations)**: Operations with one matrix and (at least) one vector operand:
* [gemv](BLISTypedAPI.md#gemv), [ger](BLISTypedAPI.md#ger), [hemv](BLISTypedAPI.md#hemv), [her](BLISTypedAPI.md#her), [her2](BLISTypedAPI.md#her2), [symv](BLISTypedAPI.md#symv), [syr](BLISTypedAPI.md#syr), [syr2](BLISTypedAPI.md#syr2), [trmv](BLISTypedAPI.md#trmv), [trsv](BLISTypedAPI.md#trsv)
* **[Level-3](BLISTypedAPI.md#level-3-operations)**: Operations with matrices that are multiplication-like:
* [gemm](BLISTypedAPI.md#gemm), [hemm](BLISTypedAPI.md#hemm), [herk](BLISTypedAPI.md#herk), [her2k](BLISTypedAPI.md#her2k), [symm](BLISTypedAPI.md#symm), [syrk](BLISTypedAPI.md#syrk), [syr2k](BLISTypedAPI.md#syr2k), [trmm](BLISTypedAPI.md#trmm), [trmm3](BLISTypedAPI.md#trmm3), [trsm](BLISTypedAPI.md#trsm)
* **[Utility](BLISTypedAPI.md#Utility-operations)**: Miscellaneous operations on matrices and vectors:
* [asumv](BLISTypedAPI.md#asumv), [norm1v](BLISTypedAPI.md#norm1v), [normfv](BLISTypedAPI.md#normfv), [normiv](BLISTypedAPI.md#normiv), [norm1m](BLISTypedAPI.md#norm1m), [normfm](BLISTypedAPI.md#normfm), [normim](BLISTypedAPI.md#normim), [mkherm](BLISTypedAPI.md#mkherm), [mksymm](BLISTypedAPI.md#mksymm), [mktrim](BLISTypedAPI.md#mktrim), [fprintv](BLISTypedAPI.md#fprintv), [fprintm](BLISTypedAPI.md#fprintm),[printv](BLISTypedAPI.md#printv), [printm](BLISTypedAPI.md#printm), [randv](BLISTypedAPI.md#randv), [randm](BLISTypedAPI.md#randm), [sumsqv](BLISTypedAPI.md#sumsqv)
---
## Level-1v operations
Level-1v operations perform various level-1 BLAS-like operations on vectors (hence the _v_).
@@ -1208,6 +1214,30 @@ where C is an _m x n_ matrix, `transa(A)` is an _m x k_ matrix, and `transb(B)`
---
#### gemmt
```c
void bli_?gemmt
(
uplo_t uploc,
trans_t transa,
trans_t transb,
dim_t m,
dim_t k,
ctype* alpha,
ctype* a, inc_t rsa, inc_t csa,
ctype* b, inc_t rsb, inc_t csb,
ctype* beta,
ctype* c, inc_t rsc, inc_t csc
);
```
Perform
```
C := beta * C + alpha * transa(A) * transb(B)
```
where C is an _m x m_ matrix, `transa(A)` is an _m x k_ matrix, and `transb(B)` is a _k x m_ matrix. This operation is similar to `bli_?gemm()` except that it only updates the lower or upper triangle of `C` as specified by `uploc`.
---
#### hemm
```c
void bli_?hemm
@@ -1266,7 +1296,8 @@ where C is an _m x m_ Hermitian matrix stored in the lower or upper triangle as
void bli_?her2k
(
uplo_t uploc,
trans_t transab,
trans_t transa,
trans_t transb,
dim_t m,
dim_t k,
ctype* alpha,
@@ -1278,9 +1309,9 @@ void bli_?her2k
```
Perform
```
C := beta * C + alpha * transab(A) * transab(B)^H + conj(alpha) * transab(B) * transab(A)^H
C := beta * C + alpha * transa(A) * transb(B)^H + conj(alpha) * transb(B) * transa(A)^H
```
where C is an _m x m_ Hermitian matrix stored in the lower or upper triangle as specified by `uploc` and `transab(A)` and `transab(B)` are _m x k_ matrices.
where C is an _m x m_ Hermitian matrix stored in the lower or upper triangle as specified by `uploc` and `transa(A)` and `transb(B)` are _m x k_ matrices.
**Note:** The floating-point type of `beta` is always the real projection of the floating-point types of `A` and `C`.
@@ -1342,7 +1373,8 @@ where C is an _m x m_ symmetric matrix stored in the lower or upper triangle as
void bli_?syr2k
(
uplo_t uploc,
trans_t transab,
trans_t transa,
trans_t transb,
dim_t m,
dim_t k,
ctype* alpha,
@@ -1354,9 +1386,9 @@ void bli_?syr2k
```
Perform
```
C := beta * C + alpha * transab(A) * transab(B)^T + alpha * transab(B) * transab(A)^T
C := beta * C + alpha * transa(A) * transb(B)^T + alpha * transb(B) * transa(A)^T
```
where C is an _m x m_ symmetric matrix stored in the lower or upper triangle as specified by `uploa` and `transab(A)` and `transab(B)` are _m x k_ matrices.
where C is an _m x m_ symmetric matrix stored in the lower or upper triangle as specified by `uploa` and `transa(A)` and `transb(B)` are _m x k_ matrices.
---
@@ -1873,7 +1905,55 @@ char* bli_info_get_trmm3_impl_string( num_t dt );
char* bli_info_get_trsm_impl_string( num_t dt );
```
## Clock functions
---
#### clock
```c
double bli_clock
(
void
);
```
Return the amount of time that has elapsed since some fixed time in the past. The return values of `bli_clock()` typically feature nanosecond precision, though this is not guaranteed.
**Note:** On Linux, `bli_clock()` is implemented in terms of `clock_gettime()` using the `clockid_t` value of `CLOCK_MONOTONIC`. On OS X, `bli_clock` is implemented in terms of `mach_absolute_time()`. And on Windows, `bli_clock` is implemented in terms of `QueryPerformanceFrequency()`. Please see [frame/base/bli_clock.c](https://github.com/flame/blis/blob/master/frame/base/bli_clock.c) for more details.
**Note:** This function is returns meaningless values when BLIS is configured with `--disable-system`.
---
#### clock_min_diff
```c
double bli_clock_min_diff
(
double time_prev_min,
double time_start
);
```
This function computes an intermediate value, `time_diff`, equal to `bli_clock() - time_start`, and then tentatively prepares to return the minimum value of `time_diff` and `time_min`. If that minimum value is extremely small (close to zero), the function returns `time_min` instead.
This function is meant to be used in conjuction with `bli_clock()` for
performance timing within applications--specifically in loops where only
the fastest timing is of interest. For example:
```c
double t_save = DBL_MAX;
for( i = 0; i < 3; ++i )
{
double t = bli_clock();
bli_gemm( ... );
t_save = bli_clock_min_diff( t_save, t );
}
double gflops = ( 2.0 * m * k * n ) / ( t_save * 1.0e9 );
```
This code calls `bli_gemm()` three times and computes the performance, in GFLOPS, of the fastest of the three executions.
---
# Example code
BLIS provides lots of example code in the [examples/tapi](https://github.com/flame/blis/tree/master/examples/tapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include printing vectors and matrices and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above.
BLIS provides lots of example code in the [examples/tapi](https://github.com/flame/blis/tree/master/examples/tapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include printing vectors and matrices and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above. Please read the `README` contained within the `examples/tapi` directory for further details.

View File

@@ -28,6 +28,7 @@ The BLIS build system was designed for use with GNU/Linux (or some other sane UN
* GNU `make` (3.81 or later)
* a working C99 compiler
* Perl (any version)
* `git` (1.8.5 or later, only required if cloning from Github)
BLIS also requires a POSIX threads library at link-time (`-lpthread` or `libpthread.so`). This requirement holds even when configuring BLIS with multithreading disabled (the default) or with multithreading via OpenMP (`--enable-multithreading=openmp`). (Note: BLIS implements basic pthreads functionality automatically for Windows builds via [AppVeyor](https://ci.appveyor.com/project/shpc/blis/).)

View File

@@ -677,14 +677,14 @@ Adding support for a new-subconfiguration to BLIS is similar to adding support f
BLIS_ARCH_POWER7,
BLIS_ARCH_BGQ,
BLIS_ARCH_GENERIC
BLIS_ARCH_GENERIC,
BLIS_NUM_ARCHS
} arch_t;
```
Additionally, you'll need to update the definition of `BLIS_NUM_ARCHS` to reflect the new total number of enumerated `arch_t` values:
```c
#define BLIS_NUM_ARCHS 16
```
Notice that the total number of `arch_t` values, `BLIS_NUM_ARCHS`, is updated automatically.
* **`frame/base/bli_gks.c`**. We must also update the global kernel structure, or gks, to register the new sub-configuration during library initialization. Sub-configuration registration occurs in `bli_gks_init()`. For `knl`, updating this function amounts to inserting the following lines

View File

@@ -8,6 +8,7 @@ project, as well as those we think a new user or developer might ask. If you do
* [Why did you create BLIS?](FAQ.md#why-did-you-create-blis)
* [Why should I use BLIS instead of GotoBLAS / OpenBLAS / ATLAS / MKL / ESSL / ACML / Accelerate?](FAQ.md#why-should-i-use-blis-instead-of-gotoblas--openblas--atlas--mkl--essl--acml--accelerate)
* [How is BLIS related to FLAME / libflame?](FAQ.md#how-is-blis-related-to-flame--libflame)
* [What is the difference between BLIS and the AMD fork of BLIS found in AOCL?](FAQ.md#what-is-the-difference-between-blis-and-the-amd-fork-of-blis-found-in-aocl)
* [Does BLIS automatically detect my hardware?](FAQ.md#does-blis-automatically-detect-my-hardware)
* [I understand that BLIS is mostly a tool for developers?](FAQ.md#i-understand-that-blis-is-mostly-a-tool-for-developers)
* [How do I link against BLIS?](FAQ.md#how-do-i-link-against-blis)
@@ -60,6 +61,12 @@ homepage](https://github.com/flame/blis#key-features). But here are a few reason
As explained [above](FAQ.md#why-did-you-create-blis?), BLIS was initially a layer within `libflame` that allowed more convenient interfacing to the BLAS. So in some ways, BLIS is a spin-off project. Prior to developing BLIS, [its author](http://www.cs.utexas.edu/users/field/) worked as the primary maintainer of `libflame`. If you look closely, you can also see that the design of BLIS was influenced by some of the more useful and innovative aspects of `libflame`, such as internal object abstractions and control trees. Also, various members of the [SHPC research group](http://shpc.ices.utexas.edu/people.html) and its [collaborators](http://shpc.ices.utexas.edu/collaborators.html) routinely provide insight, feedback, and also contribute code (especially kernels) to the BLIS project.
### What is the difference between BLIS and the AMD fork of BLIS found in AOCL?
BLIS, also known as "vanilla BLIS" or "upstream BLIS," is maintained by its [original developer](https://github.com/fgvanzee) (with the [support of others](http://shpc.ices.utexas.edu/collaborators.html)) in the [Science of High-Performance Computing](http://shpc.ices.utexas.edu/) (SHPC) group within the [The Oden Institute for Computational Engineering and Sciences](http://www.oden.utexas.edu/) at [The University of Texas at Austin](http://www.utexas.edu/). In 2015, [AMD](https://www.amd.com/) reorganized many of their software library efforts around existing open source projects. BLIS was chosen as the basis for their [CPU BLAS library](https://developer.amd.com/amd-aocl/blas-library/), and an AMD-maintained [fork of BLIS](https://github.com/amd/blis) was established.
AMD BLIS sometimes contains certain optimizations specific to AMD hardware. Many of these optimizations are (eventually) merged back into upstream BLIS. However, for various reasons, some changes may remain unique to AMD BLIS for quite some time. Thus, if you want the latest optimizations for AMD hardware, feel free to try AMD BLIS. However, please note that neither The University of Texas at Austin nor BLIS's developers can endorse or offer direct support for any outside fork of BLIS, including AMD BLIS.
### Does BLIS automatically detect my hardware?
On certain architectures (most notably x86_64), yes. In order to use auto-detection, you must specify `auto` as your configuration when running `configure` (Please see the BLIS [Build System](BuildSystem.md) guide for more info.) A runtime detection option is also available. (Please see the [Configuration Guide](ConfigurationHowTo.md) for a comprehensive walkthrough.)

View File

@@ -110,16 +110,19 @@ Regardless of which method is employed, and which specific way within each metho
**Note**: Please be aware of what happens if you try to specify both the automatic and manual ways, as it could otherwise confuse new users. Here are the important points:
* Regardless of which broad method is used, **if multithreading is specified via both the automatic and manual ways, the values set via the manual way will always take precedence.**
* Specifying parallelism for even *one* loop counts as specifying the manual way (in which case the ways of parallelism for the remaining loops will be assumed to be 1). And in the case of the environment variable method, setting the ways of parallelism for a loop to 1 counts as specifying parallelism! If you want to switch from using the manual way to automatic way, you must not only set (`export`) the `BLIS_NUM_THREADS` variable, but you must also `unset` all of the `BLIS_*_NT` variables.
* If you have specified multithreading via *both* the automatic and manual ways, BLIS will **not** complain if the values are inconsistent with one another. (For example, you may request 8 total threads be used while also specifying 4 ways of parallelism within each of two matrix multiplication loops, for a total of 16 ways.) Furthermore, you will be able to query these inconsistent values via the runtime API both before and after multithreading executes.
* If you have specified multithreading via *both* the automatic and manual ways, BLIS will **not** complain if the values are inconsistent with one another. (For example, you may request 12 total threads be used while also specifying 2 and 4 ways of parallelism within the JC and IC loops, respectively, for a total of 8 ways.) Furthermore, you will be able to query these inconsistent values via the runtime API both before and after multithreading executes.
* If multithreading is disabled, you **may still** specify multithreading values via either the manual or automatic ways. However, BLIS will silently ignore **all** of these values. A BLIS library that is built with multithreading disabled at configure-time will always run sequentially (from the perspective of a single application thread).
Furthermore:
* For small numbers of threads, the number requested will be honored faithfully. However, if you request a larger number of threads that happens to also be prime, BLIS will reduce the number by one in order to allow more more efficient thread factorizations. This behavior can be overridden by configuring BLIS with the `BLIS_ENABLE_AUTO_PRIME_NUM_THREADS` macro defined in the `bli_family_*.h` file of the relevant subconfiguration. Similarly, the threshold beyond which BLIS will reduce primes by one can be set via `BLIS_NT_MAX_PRIME`. (This latter value is ignored if the former macro is defined.)
## Globally via environment variables
The most common method of specifying multithreading in BLIS is globally via environment variables. With this method, the user sets one or more environment variables in the shell before launching the BLIS-linked executable.
Regardless of whether you end up using the automatic or manual way of expressing a request for multithreading, note that the environment variables are read (via `getenv()`) by BLIS **only once**, when the library is initialized. Subsequent to library initialization, the global settings for parallelization may only be changed via the [global runtime API](Multithreading.md#globally-at-runtime). If this constraint is not a problem, then environment variables may work fine for you. Otherwise, please consider [local settings](Multithreading.md#locally-at-runtime). (Local settings may used at any time, regardless of whether global settings were explicitly specified, and local settings always override global settings.)
**Note**: Regardless of which way ([automatic](Multithreading.md#environment-variables-the-automatic-way) or [manual](Multithreading.md#environment-variables-the-manual-way)) environment variables are used to specify multithreading, that specification will affect operation of BLIS through **both** the BLAS compatibility layer as well as the native [typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md) APIs that are unique to BLIS.
**Note**: Regardless of which way ([automatic](Multithreading.md#environment-variables-the-automatic-way) or [manual](Multithreading.md#environment-variables-the-manual-way)) environment variables are used to specify multithreading, that specification will affect operation of BLIS through **both** the BLAS compatibility layer as well as the native ([typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md)) APIs that are unique to BLIS.
### Environment variables: the automatic way
@@ -166,7 +169,7 @@ Next, which combinations of loops to parallelize depends on which caches are sha
If you still wish to set the parallelization scheme globally, but you want to do so at runtime, BLIS provides a thread-safe API for specifying multithreading. Think of these functions as a way to modify the same internal data structure into which the environment variables are read. (Recall that the environment variables are only read once, when BLIS is initialized).
**Note**: Regardless of which way ([automatic](Multithreading.md#globally-at-runtime-the-automatic-way) or [manual](Multithreading.md#globally-at-runtime-the-manual-way)) the global runtime API is used to specify multithreading, that specification will affect operation of BLIS through **both** the BLAS compatibility layer as well as the native [typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md) APIs that are unique to BLIS.
**Note**: Regardless of which way ([automatic](Multithreading.md#globally-at-runtime-the-automatic-way) or [manual](Multithreading.md#globally-at-runtime-the-manual-way)) the global runtime API is used to specify multithreading, that specification will affect operation of BLIS through **both** the BLAS compatibility layer as well as the native ([typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md)) APIs that are unique to BLIS.
### Globally at runtime: the automatic way
@@ -207,7 +210,7 @@ In addition to the global methods based on environment variables and runtime fun
As with environment variables and the global runtime API, there are two ways to specify parallelism: the automatic way and the manual way. Both ways involve allocating a BLIS-specific object, initializing the object and encoding the desired parallelization, and then passing a pointer to the object into one of the expert interfaces of either the [typed](docs/BLISTypedAPI.md) or [object](docs/BLISObjectAPI) APIs. We provide examples of utilizing this threading object below.
**Note**: Neither way ([automatic](Multithreading.md#locally-at-runtime-the-automatic-way) nor [manual](Multithreading.md#locally-at-runtime-the-manual-way)) of specifying multithreading via the local runtime API can be used via the BLAS interfaces. The local runtime API may *only* be used via the native [typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md) APIs, which are unique to BLIS. (Furthermore, the expert interfaces of each API must be used. This is demonstrated later on in this section.)
**Note**: Neither way ([automatic](Multithreading.md#locally-at-runtime-the-automatic-way) nor [manual](Multithreading.md#locally-at-runtime-the-manual-way)) of specifying multithreading via the local runtime API can be used via the BLAS interfaces. The local runtime API may *only* be used via the native ([typed](docs/BLISTypedAPI.md) and [object](docs/BLISObjectAPI.md)) APIs, which are unique to BLIS. (Furthermore, the expert interfaces of each API must be used. This is demonstrated later on in this section.)
### Initializing a rntm_t
@@ -289,6 +292,8 @@ Also, you may pass in `NULL` for the `rntm_t*` parameter of an expert interface.
This situation could lead to unexpectedly low multithreaded performance. Suppose the user calls `gemm` on a problem with a large m dimension and small k and n dimensions, and explicitly requests parallelism only in the IC loop, but also suppose that the storage of C does not match that of the microkernel's preference. After BLIS transposes the operation internally, the *effective* m dimension will no longer be large; instead, it will be small (because the original m and n dimension will have been swapped). The multithreaded implementation will then proceed to parallelize this small m dimension.
There are currently no good *and* easy solutions to this problem. Eventually, though, we plan to add support for two microkernels per datatype per configuration--one for use with matrices C that are row-stored, and one for those that are column-stored. This will obviate the logic within BLIS that sometimes induces the operation transposition, and the problem will go away.
* **Thread affinity when BLIS and MKL are used together.** Some users have reported that when running a program that links both BLIS (configured with OpenMP) and MKL, **and** when OpenMP thread affinity has been specified (e.g. via `OMP_PROC_BIND` and `OMP_PLACES`), that very poor performance is observed. This may be due to incorrect thread masking in this case, causing all threads to run on one physical core. The exact circumstances leading to this behavior have not been identified, but unsetting the OpenMP thread affinity variables appears to be a solution.
# Conclusion

View File

@@ -15,9 +15,15 @@
* **[Haswell](Performance.md#haswell)**
* **[Experiment details](Performance.md#haswell-experiment-details)**
* **[Results](Performance.md#haswell-results)**
* **[Epyc](Performance.md#epyc)**
* **[Experiment details](Performance.md#epyc-experiment-details)**
* **[Results](Performance.md#epyc-results)**
* **[Zen](Performance.md#zen)**
* **[Experiment details](Performance.md#zen-experiment-details)**
* **[Results](Performance.md#zen-results)**
* **[Zen2](Performance.md#zen2)**
* **[Experiment details](Performance.md#zen2-experiment-details)**
* **[Results](Performance.md#zen2-results)**
* **[A64fx](Performance.md#a64fx)**
* **[Experiment details](Performance.md#a64fx-experiment-details)**
* **[Results](Performance.md#a64fx-results)**
* **[Feedback](Performance.md#feedback)**
# Introduction
@@ -240,6 +246,7 @@ The `runthese.m` file will contain example invocations of the function.
endif()
```
* configured and built BLAS library via `mkdir build; cd build; cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (26 core) execution requested via `export OMP_NUM_THREADS=26`
@@ -320,6 +327,7 @@ The `runthese.m` file will contain example invocations of the function.
endif()
```
* configured and built BLAS library via `mkdir build; cd build; cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (12 core) execution requested via `export OMP_NUM_THREADS=12`
@@ -355,12 +363,12 @@ The `runthese.m` file will contain example invocations of the function.
---
## Epyc
## Zen
### Epyc experiment details
### Zen experiment details
* Location: Oracle cloud
* Processor model: AMD Epyc 7551 (Zen1)
* Processor model: AMD Epyc 7551 (Zen1 "Naples")
* Core topology: two sockets, 4 dies per socket, 2 core complexes (CCX) per die, 4 cores per CCX, 64 cores total
* SMT status: enabled, but not utilized
* Max clock rate: 3.0GHz (single-core), 2.55GHz (multicore)
@@ -398,6 +406,7 @@ The `runthese.m` file will contain example invocations of the function.
endif()
```
* configured and built BLAS library via `mkdir build; cd build; cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (32 core) execution requested via `export OMP_NUM_THREADS=32`
@@ -417,22 +426,184 @@ The `runthese.m` file will contain example invocations of the function.
* Comments:
* MKL performance is dismal, despite being linked in the same manner as on the Xeon Platinum. It's not clear what is causing the slowdown. It could be that MKL's runtime kernel/blocksize selection logic is falling back to some older, more basic implementation because CPUID is not returning Intel as the hardware vendor. Alternatively, it's possible that MKL is trying to use kernels for the closest Intel architectures--say, Haswell/Broadwell--but its implementations use Haswell-specific optimizations that, due to microarchitectural differences, degrade performance on Zen.
### Epyc results
### Zen results
#### pdf
* [Epyc single-threaded](graphs/large/l3_perf_epyc_nt1.pdf)
* [Epyc multithreaded (32 cores)](graphs/large/l3_perf_epyc_jc1ic8jr4_nt32.pdf)
* [Epyc multithreaded (64 cores)](graphs/large/l3_perf_epyc_jc2ic8jr4_nt64.pdf)
* [Zen single-threaded](graphs/large/l3_perf_zen_nt1.pdf)
* [Zen multithreaded (32 cores)](graphs/large/l3_perf_zen_jc1ic8jr4_nt32.pdf)
* [Zen multithreaded (64 cores)](graphs/large/l3_perf_zen_jc2ic8jr4_nt64.pdf)
#### png (inline)
* **Epyc single-threaded**
![single-threaded](graphs/large/l3_perf_epyc_nt1.png)
* **Epyc multithreaded (32 cores)**
![multithreaded (32 cores)](graphs/large/l3_perf_epyc_jc1ic8jr4_nt32.png)
* **Epyc multithreaded (64 cores)**
![multithreaded (64 cores)](graphs/large/l3_perf_epyc_jc2ic8jr4_nt64.png)
* **Zen single-threaded**
![single-threaded](graphs/large/l3_perf_zen_nt1.png)
* **Zen multithreaded (32 cores)**
![multithreaded (32 cores)](graphs/large/l3_perf_zen_jc1ic8jr4_nt32.png)
* **Zen multithreaded (64 cores)**
![multithreaded (64 cores)](graphs/large/l3_perf_zen_jc2ic8jr4_nt64.png)
---
## Zen2
### Zen2 experiment details
* Location: Oracle cloud
* Processor model: AMD Epyc 7742 (Zen2 "Rome")
* Core topology: two sockets, 8 Core Complex Dies (CCDs) per socket, 2 Core Complexes (CCX) per CCD, 4 cores per CCX, 128 cores total
* SMT status: enabled, but not utilized
* Max clock rate: 2.25GHz (base, documented); 3.4GHz boost (single-core, documented); 2.6GHz boost (multicore, estimated)
* Max vector register length: 256 bits (AVX2)
* Max FMA vector IPC: 2
* Alternatively, FMA vector IPC is 4 when vectors are limited to 128 bits each.
* Peak performance:
* single-core: 54.4 GFLOPS (double-precision), 108.8 GFLOPS (single-precision)
* multicore (estimated): 41.6 GFLOPS/core (double-precision), 83.2 GFLOPS/core (single-precision)
* Operating system: Ubuntu 18.04 (Linux kernel 4.15.0)
* Page size: 4096 bytes
* Compiler: gcc 9.3.0
* Results gathered: 24 September 2020, 29 September 2020
* Implementations tested:
* BLIS 4fd8d9f (0.7.0-55)
* configured with `./configure -t openmp auto` (single- and multithreaded)
* sub-configuration exercised: `zen2`
* Single-threaded (1 core) execution requested via no change in environment variables
* Multithreaded (64 core) execution requested via `export BLIS_JC_NT=4 BLIS_IC_NT=4 BLIS_JR_NT=4`
* Multithreaded (128 core) execution requested via `export BLIS_JC_NT=8 BLIS_IC_NT=4 BLIS_JR_NT=4`
* OpenBLAS 0.3.10
* configured `Makefile.rule` with `BINARY=64 NO_CBLAS=1 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=0` (single-threaded)
* configured `Makefile.rule` with `BINARY=64 NO_CBLAS=1 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=1 NUM_THREADS=64` (multithreaded, 64 cores)
* configured `Makefile.rule` with `BINARY=64 NO_CBLAS=1 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=1 NUM_THREADS=128` (multithreaded, 128 cores)
* Single-threaded (1 core) execution requested via `export OPENBLAS_NUM_THREADS=1`
* Multithreaded (64 core) execution requested via `export OPENBLAS_NUM_THREADS=64`
* Multithreaded (128 core) execution requested via `export OPENBLAS_NUM_THREADS=128`
* Eigen 3.3.90
* Obtained via the [Eigen GitLab homepage](https://gitlab.com/libeigen/eigen) (24 September 2020)
* Prior to compilation, modified top-level `CMakeLists.txt` to ensure that `-march=native` was added to `CXX_FLAGS` variable (h/t Sameer Agarwal):
```
# These lines added after line 60.
check_cxx_compiler_flag("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
```
* configured and built BLAS library via `mkdir build; cd build; cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (64 core) execution requested via `export OMP_NUM_THREADS=64`
* Multithreaded (128 core) execution requested via `export OMP_NUM_THREADS=128`
* **NOTE**: This version of Eigen does not provide multithreaded implementations of `symm`/`hemm`, `syrk`/`herk`, `trmm`, or `trsm`, and therefore those curves are omitted from the multithreaded graphs.
* MKL 2020 update 3
* Single-threaded (1 core) execution requested via `export MKL_NUM_THREADS=1`
* Multithreaded (64 core) execution requested via `export MKL_NUM_THREADS=64`
* Multithreaded (128 core) execution requested via `export MKL_NUM_THREADS=128`
* Affinity:
* Thread affinity for BLIS was specified manually via `GOMP_CPU_AFFINITY="0-127"`. However, multithreaded OpenBLAS appears to revert to single-threaded execution if `GOMP_CPU_AFFINITY` is set. Therefore, when measuring OpenBLAS performance, the `GOMP_CPU_AFFINITY` environment variable was unset.
* All executables were run through `numactl --interleave=all`.
* Frequency throttling (via `cpupower`):
* Driver: acpi-cpufreq
* Governor: performance
* Hardware limits (steps): 1.5GHz, 2.0GHz, 2.25GHz
* Adjusted minimum: 2.25GHz
* Comments:
* MKL performance is once again underwhelming. This is likely because Intel has decided that it does not want to give users of MKL a reason to purchase AMD hardware.
### Zen2 results
#### pdf
* [Zen2 single-threaded](graphs/large/l3_perf_zen2_nt1.pdf)
* [Zen2 multithreaded (64 cores)](graphs/large/l3_perf_zen2_jc4ic4jr4_nt64.pdf)
* [Zen2 multithreaded (128 cores)](graphs/large/l3_perf_zen2_jc8ic4jr4_nt128.pdf)
#### png (inline)
* **Zen2 single-threaded**
![single-threaded](graphs/large/l3_perf_zen2_nt1.png)
* **Zen2 multithreaded (64 cores)**
![multithreaded (64 cores)](graphs/large/l3_perf_zen2_jc4ic4jr4_nt64.png)
* **Zen2 multithreaded (128 cores)**
![multithreaded (128 cores)](graphs/large/l3_perf_zen2_jc8ic4jr4_nt128.png)
---
## A64fx
### A64fx experiment details
* Location: RIKEN Center of Computational Science in Kobe, Japan
* These test results were gathered on the Fugaku supercomputer under project "量子物質の創発と機能のための基礎科学 ―「富岳」と最先端実験の密連携による革新的強相関電子科学" (hp200132)
* Processor model: Fujitsu A64fx
* Core topology: one socket, 4 NUMA groups per socket, 13 cores per group (one reserved for the OS), 48 cores total
* SMT status: Unknown
* Max clock rate: 2.2GHz (single- and multicore, observed)
* Max vector register length: 512 bits (SVE)
* Max FMA vector IPC: 2
* Peak performance:
* single-core: 70.4 GFLOPS (double-precision), 140.8 GFLOPS (single-precision)
* multicore: 70.4 GFLOPS/core (double-precision), 140.8 GFLOPS/core (single-precision)
* Operating system: RHEL 8.3
* Page size: 256 bytes
* Compiler: gcc 9.3.0
* Results gathered: 2 April 2021
* Implementations tested:
* BLIS 757cb1c (post-0.8.1)
* configured with `./configure -t openmp --sve-vector-size=vla CFLAGS="-D_A64FX -DPREFETCH256 -DSVE_NO_NAT_COMPLEX_KERNELS" arm64_sve` (single- and multithreaded)
* sub-configuration exercised: `arm64_sve`
* Single-threaded (1 core) execution requested via:
* `export BLIS_SVE_KC_D=2048 BLIS_SVE_MC_D=128 BLIS_SVE_NC_D=26880 BLIS_SVE_KERNEL_IDX_D=14` (double precision)
* `export BLIS_SVE_KC_S=2048 BLIS_SVE_MC_S=256 BLIS_SVE_NC_S=23040 BLIS_SVE_KERNEL_IDX_S=2` (single precision)
* Multithreaded (12 core) execution requested via:
* `export BLIS_JC_NT=1 BLIS_IC_NT=2 BLIS_JR_NT=6`
* `export BLIS_SVE_KC_D=2400 BLIS_SVE_MC_D=64 BLIS_SVE_NC_D=26880 BLIS_SVE_KERNEL_IDX_D=14` (double precision)
* `export BLIS_SVE_KC_S=2400 BLIS_SVE_MC_S=128 BLIS_SVE_NC_S=23040 BLIS_SVE_KERNEL_IDX_S=2` (single precision)
* Multithreaded (48 core) execution requested via:
* `export BLIS_JC_NT=1 BLIS_IC_NT=4 BLIS_JR_NT=12`
* `export BLIS_SVE_KC_D=2048 BLIS_SVE_MC_D=128 BLIS_SVE_NC_D=26880 BLIS_SVE_KERNEL_IDX_D=14` (double precision)
* `export BLIS_SVE_KC_S=2048 BLIS_SVE_MC_S=256 BLIS_SVE_NC_S=23040 BLIS_SVE_KERNEL_IDX_S=2` (single precision)
* Eigen 3.3.9
* Obtained via the [Eigen GitLab homepage](https://gitlab.com/libeigen/eigen)
* configured and built BLAS library via `mkdir build; cd build; cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (12 core) execution requested via `export OMP_NUM_THREADS=12`
* Multithreaded (48 core) execution requested via `export OMP_NUM_THREADS=48`
* **NOTE**: This version of Eigen does not provide multithreaded implementations of `symm`/`hemm`, `syrk`/`herk`, `trmm`, or `trsm`, and therefore those curves are omitted from the multithreaded graphs.
* ARMPL (20.1.0 for A64fx)
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (12 core) execution requested via `export OMP_NUM_THREADS=12`
* Multithreaded (48 core) execution requested via `export OMP_NUM_THREADS=48`
* **NOTE**: While this version of ARMPL does provide multithreaded implementations of `symm`/`hemm`, `syrk`/`herk`, `trmm`, or `trsm` (with the exception `dtrsm`), but these implementations yield very low performance, and their long run times led us to skip collecting these data altogether.
* Fujitsu SSL2 (Fujitsu toolchain 1.2.31)
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1 NPARALLEL=1`
* Multithreaded (12 core) execution requested via `export OMP_NUM_THREADS=12 NPARALLEL=12`
* Multithreaded (48 core) execution requested via `export OMP_NUM_THREADS=48 NPARALLEL=48`
* Affinity:
* Thread affinity for BLIS was specified manually via `GOMP_CPU_AFFINITY="12-23 24-35 36-47 48-59"`.
* All executables were run through `numactl --interleave=all` (multithreaded only).
* Frequency throttling: No change made. No frequency lowering observed.
* Comments:
* Special thanks to Stepan Nassyr and RuQing G. Xu for their work in developing and optimizing A64fx support. Also, thanks to RuQing G. Xu for collecting the data that appear in these graphs.
### A64fx results
#### pdf
* [A64fx single-threaded](graphs/large/l3_perf_a64fx_nt1.pdf)
* [A64fx multithreaded (12 cores)](graphs/large/l3_perf_a64fx_jc1ic2jr6_nt12.pdf)
* [A64fx multithreaded (48 cores)](graphs/large/l3_perf_a64fx_jc1ic4jr12_nt48.pdf)
#### png (inline)
* **A64fx single-threaded**
![single-threaded](graphs/large/l3_perf_a64fx_nt1.png)
* **A64fx multithreaded (12 cores)**
![multithreaded (12 cores)](graphs/large/l3_perf_a64fx_jc1ic2jr6_nt12.png)
* **A64fx multithreaded (48 cores)**
![multithreaded (48 cores)](graphs/large/l3_perf_a64fx_jc1ic4jr12_nt48.png)
---

View File

@@ -12,9 +12,12 @@
* **[Haswell](PerformanceSmall.md#haswell)**
* **[Experiment details](PerformanceSmall.md#haswell-experiment-details)**
* **[Results](PerformanceSmall.md#haswell-results)**
* **[Epyc](PerformanceSmall.md#epyc)**
* **[Experiment details](PerformanceSmall.md#epyc-experiment-details)**
* **[Results](PerformanceSmall.md#epyc-results)**
* **[Zen](PerformanceSmall.md#zen)**
* **[Experiment details](PerformanceSmall.md#zen-experiment-details)**
* **[Results](PerformanceSmall.md#zen-results)**
* **[Zen2](PerformanceSmall.md#zen2)**
* **[Experiment details](PerformanceSmall.md#zen2-experiment-details)**
* **[Results](PerformanceSmall.md#zen2-results)**
* **[Feedback](PerformanceSmall.md#feedback)**
# Introduction
@@ -295,9 +298,9 @@ The `runthese.m` file will contain example invocations of the function.
---
## Epyc
## Zen
### Epyc experiment details
### Zen experiment details
* Location: Oracle cloud
* Processor model: AMD Epyc 7551 (Zen1)
@@ -318,7 +321,7 @@ The `runthese.m` file will contain example invocations of the function.
* BLIS 90db88e (0.6.1-8)
* configured with `./configure --enable-cblas auto` (single-threaded)
* configured with `./configure --enable-cblas -t openmp auto` (multithreaded)
* sub-configuration exercised: `haswell`
* sub-configuration exercised: `zen`
* Multithreaded (32 cores) execution requested via `export BLIS_NUM_THREADS=32`
* OpenBLAS 0.3.8
* configured `Makefile.rule` with `BINARY=64 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=0 USE_LOCKING=1` (single-threaded)
@@ -357,25 +360,122 @@ The `runthese.m` file will contain example invocations of the function.
* Comments:
* libxsmm is highly competitive for very small problems, but quickly gives up once the "large" dimension exceeds about 180-240 (or 64 in the case where all operands are square). Also, libxsmm's `gemm` cannot handle a transposition on matrix A and similarly dispatches the fallback implementation for those cases. libxsmm also does not export CBLAS interfaces, and therefore only appears on the graphs for column-stored matrices.
### Epyc results
### Zen results
#### pdf
* [Epyc single-threaded row-stored](graphs/sup/dgemm_rrr_epyc_nt1.pdf)
* [Epyc single-threaded column-stored](graphs/sup/dgemm_ccc_epyc_nt1.pdf)
* [Epyc multithreaded (32 cores) row-stored](graphs/sup/dgemm_rrr_epyc_nt32.pdf)
* [Epyc multithreaded (32 cores) column-stored](graphs/sup/dgemm_ccc_epyc_nt32.pdf)
* [Zen single-threaded row-stored](graphs/sup/dgemm_rrr_zen_nt1.pdf)
* [Zen single-threaded column-stored](graphs/sup/dgemm_ccc_zen_nt1.pdf)
* [Zen multithreaded (32 cores) row-stored](graphs/sup/dgemm_rrr_zen_nt32.pdf)
* [Zen multithreaded (32 cores) column-stored](graphs/sup/dgemm_ccc_zen_nt32.pdf)
#### png (inline)
* **Epyc single-threaded row-stored**
![single-threaded row-stored](graphs/sup/dgemm_rrr_epyc_nt1.png)
* **Epyc single-threaded column-stored**
![single-threaded column-stored](graphs/sup/dgemm_ccc_epyc_nt1.png)
* **Epyc multithreaded (32 cores) row-stored**
![multithreaded row-stored](graphs/sup/dgemm_rrr_epyc_nt32.png)
* **Epyc multithreaded (32 cores) column-stored**
![multithreaded column-stored](graphs/sup/dgemm_ccc_epyc_nt32.png)
* **Zen single-threaded row-stored**
![single-threaded row-stored](graphs/sup/dgemm_rrr_zen_nt1.png)
* **Zen single-threaded column-stored**
![single-threaded column-stored](graphs/sup/dgemm_ccc_zen_nt1.png)
* **Zen multithreaded (32 cores) row-stored**
![multithreaded row-stored](graphs/sup/dgemm_rrr_zen_nt32.png)
* **Zen multithreaded (32 cores) column-stored**
![multithreaded column-stored](graphs/sup/dgemm_ccc_zen_nt32.png)
---
## Zen2
### Zen2 experiment details
* Location: Oracle cloud
* Processor model: AMD Epyc 7742 (Zen2 "Rome")
* Core topology: two sockets, 8 Core Complex Dies (CCDs) per socket, 2 Core Complexes (CCX) per CCD, 4 cores per CCX, 128 cores total
* SMT status: enabled, but not utilized
* Max clock rate: 2.25GHz (base, documented); 3.4GHz boost (single-core, documented); 2.6GHz boost (multicore, estimated)
* Max vector register length: 256 bits (AVX2)
* Max FMA vector IPC: 2
* Alternatively, FMA vector IPC is 4 when vectors are limited to 128 bits each.
* Peak performance:
* single-core: 54.4 GFLOPS (double-precision), 108.8 GFLOPS (single-precision)
* multicore (estimated): 41.6 GFLOPS/core (double-precision), 83.2 GFLOPS/core (single-precision)
* Operating system: Ubuntu 18.04 (Linux kernel 4.15.0)
* Page size: 4096 bytes
* Compiler: gcc 9.3.0
* Results gathered: 8 October 2020
* Implementations tested:
* BLIS a0849d3 (0.7.0-67)
* configured with `./configure --enable-cblas auto` (single-threaded)
* configured with `./configure --enable-cblas -t openmp auto` (multithreaded)
* sub-configuration exercised: `zen2`
* Multithreaded (32 cores) execution requested via `export BLIS_NUM_THREADS=32`
* OpenBLAS 0.3.10
* configured `Makefile.rule` with `BINARY=64 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=0 USE_LOCKING=1` (single-threaded)
* configured `Makefile.rule` with `BINARY=64 NO_LAPACK=1 NO_LAPACKE=1 USE_THREAD=1 NUM_THREADS=32` (multithreaded)
* Multithreaded (32 cores) execution requested via `export OPENBLAS_NUM_THREADS=32`
* BLASFEO 5b26d40
* configured `Makefile.rule` with: `BLAS_API=1 FORTRAN_BLAS_API=1 CBLAS_API=1`.
* built BLAS library via `make CC=gcc`
* Eigen 3.3.90
* Obtained via the [Eigen GitLab homepage](https://gitlab.com/libeigen/eigen) (24 September 2020)
* Prior to compilation, modified top-level `CMakeLists.txt` to ensure that `-march=native` was added to `CXX_FLAGS` variable (h/t Sameer Agarwal):
```
# These lines added after line 60.
check_cxx_compiler_flag("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
```
* configured and built BLAS library via `mkdir build; cd build; CC=gcc cmake ..; make blas`
* installed headers via `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/flame/eigen; make install`
* The `gemm` implementation was pulled in at compile-time via Eigen headers; other operations were linked to Eigen's BLAS library.
* Single-threaded (1 core) execution requested via `export OMP_NUM_THREADS=1`
* Multithreaded (32 cores) execution requested via `export OMP_NUM_THREADS=32`
* MKL 2020 update 3
* Single-threaded (1 core) execution requested via `export MKL_NUM_THREADS=1`
* Multithreaded (32 cores) execution requested via `export MKL_NUM_THREADS=32`
* libxsmm f0ab9cb (post-1.16.1)
* compiled with `make AVX=2`; linked with [netlib BLAS](http://www.netlib.org/blas/) 3.6.0 as the fallback library to better show where libxsmm stops handling the computation internally.
* Affinity:
* Thread affinity for BLIS was specified manually via `GOMP_CPU_AFFINITY="0-31"`. However, multithreaded OpenBLAS appears to revert to single-threaded execution if `GOMP_CPU_AFFINITY` is set. Therefore, when measuring OpenBLAS performance, the `GOMP_CPU_AFFINITY` environment variable was unset.
* All executables were run through `numactl --interleave=all`.
* Frequency throttling (via `cpupower`):
* Driver: acpi-cpufreq
* Governor: performance
* Hardware limits (steps): 1.5GHz, 2.0GHz, 2.25GHz
* Adjusted minimum: 2.25GHz
* Comments:
* None.
### Zen2 results
#### pdf
* [Zen2 sgemm single-threaded row-stored](graphs/sup/sgemm_rrr_zen2_nt1.pdf)
* [Zen2 sgemm single-threaded column-stored](graphs/sup/sgemm_ccc_zen2_nt1.pdf)
* [Zen2 dgemm single-threaded row-stored](graphs/sup/dgemm_rrr_zen2_nt1.pdf)
* [Zen2 dgemm single-threaded column-stored](graphs/sup/dgemm_ccc_zen2_nt1.pdf)
* [Zen2 sgemm multithreaded (32 cores) row-stored](graphs/sup/sgemm_rrr_zen2_nt32.pdf)
* [Zen2 sgemm multithreaded (32 cores) column-stored](graphs/sup/sgemm_ccc_zen2_nt32.pdf)
* [Zen2 dgemm multithreaded (32 cores) row-stored](graphs/sup/dgemm_rrr_zen2_nt32.pdf)
* [Zen2 dgemm multithreaded (32 cores) column-stored](graphs/sup/dgemm_ccc_zen2_nt32.pdf)
#### png (inline)
* **Zen2 sgemm single-threaded row-stored**
![sgemm single-threaded row-stored](graphs/sup/sgemm_rrr_zen2_nt1.png)
* **Zen2 sgemm single-threaded column-stored**
![sgemm single-threaded column-stored](graphs/sup/sgemm_ccc_zen2_nt1.png)
* **Zen2 dgemm single-threaded row-stored**
![dgemm single-threaded row-stored](graphs/sup/dgemm_rrr_zen2_nt1.png)
* **Zen2 dgemm single-threaded column-stored**
![dgemm single-threaded column-stored](graphs/sup/dgemm_ccc_zen2_nt1.png)
* **Zen2 sgemm multithreaded (32 cores) row-stored**
![sgemm multithreaded row-stored](graphs/sup/sgemm_rrr_zen2_nt32.png)
* **Zen2 sgemm multithreaded (32 cores) column-stored**
![sgemm multithreaded column-stored](graphs/sup/sgemm_ccc_zen2_nt32.png)
* **Zen2 dgemm multithreaded (32 cores) row-stored**
![dgemm multithreaded row-stored](graphs/sup/dgemm_rrr_zen2_nt32.png)
* **Zen2 dgemm multithreaded (32 cores) column-stored**
![dgemm multithreaded column-stored](graphs/sup/dgemm_ccc_zen2_nt32.png)
---

View File

@@ -4,6 +4,8 @@
## Contents
* [Changes in 0.8.1](ReleaseNotes.md#changes-in-081)
* [Changes in 0.8.0](ReleaseNotes.md#changes-in-080)
* [Changes in 0.7.0](ReleaseNotes.md#changes-in-070)
* [Changes in 0.6.1](ReleaseNotes.md#changes-in-061)
* [Changes in 0.6.0](ReleaseNotes.md#changes-in-060)
@@ -37,6 +39,104 @@
* [Changes in 0.0.2](ReleaseNotes.md#changes-in-002)
* [Changes in 0.0.1](ReleaseNotes.md#changes-in-001)
## Changes in 0.8.1
March 22, 2021
Improvements present in 0.8.1:
Framework:
- Implemented an automatic reduction in the number of threads when the user requests parallelism via a single number (ie: the automatic way) and (a) that number of threads is prime, and (b) that number exceeds a minimum threshold defined by the macro `BLIS_NT_MAX_PRIME`, which defaults to 11. If prime numbers are really desired, this feature may be suppressed by defining the macro `BLIS_ENABLE_AUTO_PRIME_NUM_THREADS` in the appropriate configuration family's `bli_family_*.h`. (Jeff Diamond)
- Changed default value of `BLIS_THREAD_RATIO_M` from 2 to 1, which leads to slightly different automatic thread factorizations.
- Enable the 1m method only if the real domain microkernel is not a reference kernel. BLIS now forgoes use of 1m if both the real and complex domain kernels are reference implementations.
- Relocated the general stride handling for `gemmsup`. This fixed an issue whereby `gemm` would fail to trigger to conventional code path for cases that use general stride even after `gemmsup` rejected the problem. (RuQing Xu)
- Fixed an incorrect function signature (and prototype) of `bli_?gemmt()`. (RuQing Xu)
- Redefined `BLIS_NUM_ARCHS` to be part of the `arch_t` enum, which means it will be updated automatically when defining future subconfigs.
- Minor code consolidation in all level-3 `_front()` functions.
- Reorganized Windows cpp branch of `bli_pthreads.c`.
- Implemented `bli_pthread_self()` and `_equals()`, but left them commented out (via cpp guards) due to issues with getting the Windows versions working. Thankfully, these functions aren't yet needed by BLIS.
Kernels:
- Added low-precision POWER10 `gemm` kernels via a `power10` sandbox. This sandbox also provides an API for implementations that use these kernels. See the `sandbox/power10/POWER10.md` document for more info. (Nicholai Tukanov)
- Added assembly `packm` kernels for the `haswell` kernel set and registered to `haswell`, `zen`, and `zen2` subconfigs accordingly. The `s`, `c`, and `z` kernels were modeled on the `d` kernel, which was contributed by AMD.
- Reduced KC in the `skx` subconfig from 384 to 256. (Tze Meng Low)
- Fixed bugs in two `haswell` dgemmsup kernels, which involved extraneous assembly instructions left over from when the kernels were first written. (Kiran Varaganti, Bhaskar Nallani)
- Minor updates to all of the `gemmtrsm` kernels to allow division by diagonal elements rather that scaling by pre-inverted elements. This change was applied to `haswell` and `penryn` kernel sets as well as reference kernels, 1m kernels, and the pre-broadcast B (bb) format kernels used by the `power9` subconfig. (Bhaskar Nallani)
- Fixed incorrect return type on `bli_diag_offset_with_trans()`. (Devin Matthews)
Build system:
- Output a pkgconfig file so that CMake users that use BLIS can find and incorporate BLIS build products. (Ajay Panyala)
- Fixed an issue in the the configure script's kernel-to-config map that caused `skx` kernel flags to be used when compiling kernels from the `zen` kernel set. This issue wasn't really fixed, but rather tweaked in such a way that it happens to now work. A more proper fix would require a serious rethinking of the configuration system. (Devin Matthews)
- Fixed the shared library build rule in top-level Makefile. The previous rule was incorrectly only linking prerequisites that were newer than the target (`$?`) rather than correctly linking all prerequisites (`$^`). (Devin Matthews)
- Fixed `cc_vendor` for crosstool-ng toolchains. (Isuru Fernando)
- Allow disabling of `trsm` diagonal pre-inversion at compile time via `--disable-trsm-preinversion`.
Testing:
- Fixed obscure testsuite bug for the `gemmt` test module that relates to its dependency on `gemv`.
- Allow the `amaxv` testsuite module to run with a dimension of 0. (Meghana Vankadari)
Documentation:
- Documented auto-reduction for prime numbers of threads in `docs/Multithreading.md`.
- Fixed a missing `trans_t` argument in the API documentation for `her2k`/`syr2k` in `docs/BLISTypedAPI.md`. (RuQing Xu)
- Removed an extra call to `free()` in the level-1v typed API example code. (Ilknur Mustafazade)
## Changes in 0.8.0
November 19, 2020
Improvements present in 0.8.0:
Framework:
- Implemented support for the level-3 operation `gemmt`, which performs a `gemm` on only the lower or only the upper triangle of a square matrix C. For now, only the conventional/large code path (and not the sup code path) is provided. This support also includes `gemmt` APIs in the BLAS and CBLAS compatibility layers. (AMD)
- Added a C++ template header, `blis.hh`, containing a BLAS-inspired wrapper to a set of polymorphic CBLAS-like function wrappers defined in another header, `cblas.hh`. These headers are installed only when running the `install` target with `INSTALL_HH` set to `yes`. (AMD)
- Disallow `randv`, `randm`, `randnv`, and `randnm` from producing vectors and matrices with 1-norms of zero.
- Changed the behavior of user-initialized `rntm_t` objects so that packing of A and B is disabled by default. (Kiran Varaganti)
- Transitioned to using `bool` keyword instead of the previous integer-based `bool_t` typedef. (RuQing Xu)
- Updated all inline function definitions to use the cpp macro `BLIS_INLINE` instead of the `static` keyword. (Giorgos Margaritis, Devin Matthews)
- Relocated `#include "cpuid.h"` directive from `bli_cpuid.h` to `bli_cpuid.c` so that applications can `#include` both `blis.h` and `cpuid.h`. (Bhaskar Nallani, Devin Matthews)
- Defined `xerbla_array_()` to complement the netlib routine `xerbla_array()`. (Isuru Fernando)
- Replaced the previously broken `ref99` sandbox with a simpler, functioning alternative. (Francisco Igual)
- Fixed a harmless bug whereby `herk` was calling `trmm`-related code for determining the blocksize of KC in the 4th loop.
Kernels:
- Implemented a full set of `sgemmsup` assembly millikernels and microkernels for `haswell` kernel set.
- Implemented POWER10 `sgemm` and `dgemm` microkernels. (Nicholai Tukanov)
- Added two kernels (`dgemm` and `dpackm`) that employ ARM SVE vector extensions. (Guodong Xu)
- Implemented explicit beta = 0 handling in the `sgemm` microkernel in `bli_gemm_armv7a_int_d4x4.c`. This omission was causing testsuite failures in the new `gemmt` testsuite module for `cortexa15` builds given that the `gemmt` correctness check relies on `gemm` with beta = 0.
- Updated `void*` function arguments in reference `packm` kernels to use the native pointer type, and fixed a related dormant type bug in `bli_kernels_knl.h`.
- Fixed missing `restrict` qualifier in `sgemm` microkernel prototype for `knl` kernel set header.
- Added some missing n = 6 edge cases to `dgemmsup` kernels.
- Fixed an erroneously disabled edge case optimization in `gemmsup` variant code.
- Various bugfixes and cleanups to `dgemmsup` kernels.
Build system:
- Implemented runtime subconfiguration selection override via `BLIS_ARCH_TYPE`. (decandia50)
- Output the python found during `configure` into the `PYTHON` variable set in `build/config.mk`. (AMD)
- Added configure support for Intel oneAPI via the `CC` environment variable. (Ajay Panyala, Devin Matthews)
- Use `-O2` for all framework code, potentially avoiding intermitten issues with `f2c`'ed packed and banded code. (Devin Matthews)
- Tweaked `zen2` subconfiguration's cache blocksizes and registered full suite of `sgemm` and `dgemm` millikernels.
- Use the `-fomit-frame-pointer` compiler optimization option in the `haswell` and `skx` subconfigurations. (Jeff Diamond, Devin Matthews)
- Tweaked Makefiles in `test`, `test/3`, and `test/sup` so that running any of the usual targets without having first built BLIS results in a helpful error message.
- Add support for `--complex-return=[gnu|intel]` to `configure`, which allows the user to toggle between the GNU and Intel return value conventions for functions such as `cdotc`, `cdotu`, `zdotc`, and `zdotu`.
- Updates to `cortexa9`, `cortexa53` compilation flags. (Dave Love)
Testing:
- Added a `gemmt` module to the testsuite and a standalone test driver to the `test` directory, both of which exercise the new `gemmt` functionality. (AMD)
- Support creating matrices with small or large leading dimensions in `test/sup` test drivers.
- Support executing `test/sup` drivers with unpacked or packed matrices.
- Added optional `numactl` usage to `test/3/runme.sh`.
- Updated and/or consolidated octave scripts in `test/3` and `test/sup`.
- Increased `dotxaxpyf` testsuite thresholds to avoid false `MARGINAL` results during normal execution. (nagsingh)
Documentation:
- Added Epyc 7742 Zen2 ("Rome") performance results (single- and multithreaded) to `Performance.md` and `PerformanceSmall.md`. (Jeff Diamond)
- Documented `gemmt` APIs in `BLISObjectAPI.md` and `BLISTypedAPI.md`. (AMD)
- Documented commonly-used object mutator functions in `BLISObjectAPI.md`. (Jeff Diamond)
- Relocated the operation indices of `BLISObjectAPI.md` and `BLISTypedAPI.md` to appear immediately after their respective tables of contents. (Jeff Diamond)
- Added missing perl prerequisite to `BuildSystem.md`. (pkubaj, Dilyn Corner)
- Fixed missing `conjy` parameter in `BLISTypedAPI.md` documentation for `her2` and `syr2`. (Robert van de Geijn)
- Fixed incorrect link to `shiftd` in `BLISTypedAPI.md`. (Jeff Diamond)
- Mention example code at the top of `BLISObjectAPI.md` and `BLISTypedAPI.md`.
- Minor updates to `README.md`, `FAQ.md`, `Multithreading.md`, and `Sandboxes.md` documents.
## Changes in 0.7.0
April 7, 2020

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

View File

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

View File

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB