mirror of
https://github.com/amd/blis.git
synced 2026-05-11 17:50:00 +00:00
1. Check OpenMP active level against max active levels when setting
number of threads for starting a new parallel region in
./frame/thread/bli_thread.c to ensure the correct number of threads
is used when BLIS is called within nested OpenMP parallelism.
2. In subsequent BLIS calls, threading choices could be incorrectly
set based on values used and stored in global_rntm by a previous
call. This could apply when the OpenMP number of threads differ from
call to call, different nested parallelism is used in different
parts of a user's code, or different threads at the user level
request different numbers of OpenMP threads for BLIS calls.
Keep threading information in both global_rntm and a new Thread
Local Storage copy tl_rntm. Update tl_rntm from OpenMP runtime
environment (as appropriate) during bli_init_auto() calls in each
BLIS routine. The details are:
* global_rntm is initialized on first BLIS call based on OpenMP and
BLIS threading environment variables.
* global_rntm is updated by any BLIS threading function calls.
* In bli_thread_update_tl(), called by bli_init_auto(), sync with
any BLIS values set or updated in global_rntm. Then, if BLIS
threading control is not used, check OpenMP ICVs and set thread
count and auto_factor appropriately.
* Setting BLIS threading locally (using expert interfaces to pass
a user defined rntm data structure) should work as before.
3. bli_thread_get_is_parallel can now only be called outside of
parallelism within BLIS routines. Change calls in trsm to reflect
this.
4. Ensure blis_mt is set to TRUE in bli_thread_init_rntm_from_env()
if any BLIS_*_NT environment variables are set.
5. Set auto_factor = FALSE when the number of threads is 1.
6. bli_rntm_set_num_threads() and bli_rntm_set_ways() set blis_mt=TRUE.
7. Set blis_mt=FALSE in BLIS_RNTM_INITIALIZER and bli_rntm_init().
8. For debugging, internal information on the rntm threading data can
be printed by defining "PRINT_THREADING" at the top of bli_rntm.h
9. bli_rntm_print() now also prints the value of blis_mt.
10. Function prototypes in bli_rntm.h moved to top of file, so that
bli_rntm_print() can be used within inline functions defined in
this header file.
11. Comment out bli_init_auto() and bli_finalize_auto() calls in
Fortran interfaces in frame/compat/blis/thread/b77_thread.c
12. In frame/3/bli_l3_sup_int_amd.c move two calls to set_pack_a and
set_pack_b functions outside of the auto_factor if statements.
13. Misc code tidying.
AMD-Internal: [CPUPL-2433]
Change-Id: I8342c37fb4e280118e5e55164fbd6ea636f858ee
313 lines
8.5 KiB
C
313 lines
8.5 KiB
C
/*
|
|
|
|
BLIS
|
|
An object-based framework for developing high-performance BLAS-like
|
|
libraries.
|
|
|
|
Copyright (C) 2014, The University of Texas at Austin
|
|
Copyright (C) 2016, Hewlett Packard Enterprise Development LP
|
|
Copyright (C) 2018 - 21, Advanced Micro Devices, Inc. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
- Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
- Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
- Neither the name(s) of the copyright holder(s) nor the names of its
|
|
contributors may be used to endorse or promote products derived
|
|
from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#ifndef BLIS_THREAD_H
|
|
#define BLIS_THREAD_H
|
|
|
|
// Include thread communicator (thrcomm_t) object definitions and prototypes.
|
|
#include "bli_thrcomm.h"
|
|
|
|
// Include thread info (thrinfo_t) object definitions and prototypes.
|
|
#include "bli_thrinfo.h"
|
|
#include "bli_thrinfo_sup.h"
|
|
|
|
// Include some operation-specific thrinfo_t prototypes.
|
|
// Note that the bli_packm_thrinfo.h must be included before the others!
|
|
#include "bli_packm_thrinfo.h"
|
|
#include "bli_l3_thrinfo.h"
|
|
|
|
// Include the level-3 thread decorator and related definitions and prototypes
|
|
// for the conventional code path.
|
|
#include "bli_l3_decor.h"
|
|
|
|
// Include the level-3 thread decorator and related definitions and prototypes
|
|
// for the sup code path.
|
|
#include "bli_l3_sup_decor.h"
|
|
|
|
// Initialization-related prototypes.
|
|
void bli_thread_init( void );
|
|
void bli_thread_update_tl( void );
|
|
void bli_thread_finalize( void );
|
|
void bli_thread_finalize_tl( void );
|
|
|
|
// Thread range-related prototypes.
|
|
|
|
BLIS_EXPORT_BLIS
|
|
void bli_thread_range_sub
|
|
(
|
|
thrinfo_t* thread,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* start,
|
|
dim_t* end
|
|
);
|
|
|
|
#undef GENPROT
|
|
#define GENPROT( opname ) \
|
|
\
|
|
siz_t PASTEMAC0( opname ) \
|
|
( \
|
|
dir_t direct, \
|
|
thrinfo_t* thr, \
|
|
obj_t* a, \
|
|
obj_t* b, \
|
|
obj_t* c, \
|
|
cntl_t* cntl, \
|
|
cntx_t* cntx, \
|
|
dim_t* start, \
|
|
dim_t* end \
|
|
);
|
|
|
|
GENPROT( thread_range_mdim )
|
|
GENPROT( thread_range_ndim )
|
|
|
|
#undef GENPROT
|
|
#define GENPROT( opname ) \
|
|
\
|
|
siz_t PASTEMAC0( opname ) \
|
|
( \
|
|
thrinfo_t* thr, \
|
|
obj_t* a, \
|
|
blksz_t* bmult, \
|
|
dim_t* start, \
|
|
dim_t* end \
|
|
);
|
|
|
|
GENPROT( thread_range_l2r )
|
|
GENPROT( thread_range_r2l )
|
|
GENPROT( thread_range_t2b )
|
|
GENPROT( thread_range_b2t )
|
|
|
|
GENPROT( thread_range_weighted_l2r )
|
|
GENPROT( thread_range_weighted_r2l )
|
|
GENPROT( thread_range_weighted_t2b )
|
|
GENPROT( thread_range_weighted_b2t )
|
|
|
|
|
|
dim_t bli_thread_range_width_l
|
|
(
|
|
doff_t diagoff_j,
|
|
dim_t m,
|
|
dim_t n_j,
|
|
dim_t j,
|
|
dim_t n_way,
|
|
dim_t bf,
|
|
dim_t bf_left,
|
|
double area_per_thr,
|
|
bool handle_edge_low
|
|
);
|
|
siz_t bli_find_area_trap_l
|
|
(
|
|
dim_t m,
|
|
dim_t n,
|
|
doff_t diagoff
|
|
);
|
|
siz_t bli_thread_range_weighted_sub
|
|
(
|
|
thrinfo_t* restrict thread,
|
|
doff_t diagoff,
|
|
uplo_t uplo,
|
|
dim_t m,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* restrict j_start_thr,
|
|
dim_t* restrict j_end_thr
|
|
);
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Factorization and partitioning prototypes
|
|
typedef struct
|
|
{
|
|
dim_t n;
|
|
dim_t sqrt_n;
|
|
dim_t f;
|
|
} bli_prime_factors_t;
|
|
|
|
void bli_prime_factorization(dim_t n, bli_prime_factors_t* factors);
|
|
|
|
dim_t bli_next_prime_factor(bli_prime_factors_t* factors);
|
|
bool bli_is_prime( dim_t n );
|
|
|
|
void bli_thread_partition_2x2
|
|
(
|
|
dim_t n_thread,
|
|
dim_t work1,
|
|
dim_t work2,
|
|
dim_t* restrict nt1,
|
|
dim_t* restrict nt2
|
|
);
|
|
|
|
void bli_thread_partition_2x2_slow
|
|
(
|
|
dim_t n_thread,
|
|
dim_t work1,
|
|
dim_t work2,
|
|
dim_t* restrict nt1,
|
|
dim_t* restrict nt2
|
|
);
|
|
void bli_thread_partition_2x2_fast
|
|
(
|
|
dim_t n_thread,
|
|
dim_t work1,
|
|
dim_t work2,
|
|
dim_t* restrict nt1,
|
|
dim_t* restrict nt2
|
|
);
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
dim_t bli_gcd( dim_t x, dim_t y );
|
|
dim_t bli_lcm( dim_t x, dim_t y );
|
|
dim_t bli_ipow( dim_t base, dim_t power );
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_jc_nt( void );
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_pc_nt( void );
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_ic_nt( void );
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_jr_nt( void );
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_ir_nt( void );
|
|
BLIS_EXPORT_BLIS dim_t bli_thread_get_num_threads( void );
|
|
|
|
BLIS_EXPORT_BLIS bool bli_thread_get_is_parallel( void );
|
|
|
|
BLIS_EXPORT_BLIS void bli_thread_set_ways( dim_t jc, dim_t pc, dim_t ic, dim_t jr, dim_t ir );
|
|
BLIS_EXPORT_BLIS void bli_thread_set_num_threads( dim_t value );
|
|
|
|
BLIS_EXPORT_BLIS void bli_thread_init_rntm_from_env( rntm_t* rntm );
|
|
|
|
BLIS_EXPORT_BLIS void bli_thread_update_rntm_from_env( rntm_t* rntm );
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
BLIS_INLINE void bli_thread_range_jrir_rr
|
|
(
|
|
thrinfo_t* thread,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* start,
|
|
dim_t* end,
|
|
dim_t* inc
|
|
)
|
|
{
|
|
// Use interleaved partitioning of jr/ir loops.
|
|
*start = bli_thread_work_id( thread );
|
|
*inc = bli_thread_n_way( thread );
|
|
*end = n;
|
|
}
|
|
|
|
BLIS_INLINE void bli_thread_range_jrir_sl
|
|
(
|
|
thrinfo_t* thread,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* start,
|
|
dim_t* end,
|
|
dim_t* inc
|
|
)
|
|
{
|
|
// Use contiguous slab partitioning of jr/ir loops.
|
|
bli_thread_range_sub( thread, n, bf, handle_edge_low, start, end );
|
|
*inc = 1;
|
|
}
|
|
|
|
BLIS_INLINE void bli_thread_range_jrir
|
|
(
|
|
thrinfo_t* thread,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* start,
|
|
dim_t* end,
|
|
dim_t* inc
|
|
)
|
|
{
|
|
// Define a general-purpose version of bli_thread_range_jrir() whose
|
|
// definition depends on whether slab or round-robin partitioning was
|
|
// requested at configure-time.
|
|
#ifdef BLIS_ENABLE_JRIR_SLAB
|
|
bli_thread_range_jrir_sl( thread, n, bf, handle_edge_low, start, end, inc );
|
|
#else
|
|
bli_thread_range_jrir_rr( thread, n, bf, handle_edge_low, start, end, inc );
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
BLIS_INLINE void bli_thread_range_weighted_jrir
|
|
(
|
|
thrinfo_t* thread,
|
|
doff_t diagoff,
|
|
uplo_t uplo,
|
|
dim_t m,
|
|
dim_t n,
|
|
dim_t bf,
|
|
bool handle_edge_low,
|
|
dim_t* start,
|
|
dim_t* end,
|
|
dim_t* inc
|
|
)
|
|
{
|
|
#ifdef BLIS_ENABLE_JRIR_SLAB
|
|
|
|
// Use contiguous slab partitioning for jr/ir loops.
|
|
bli_thread_range_weighted_sub( thread, diagoff, uplo, m, n, bf,
|
|
handle_edge_low, start, end );
|
|
|
|
*start = *start / bf; *inc = 1;
|
|
|
|
if ( *end % bf ) *end = *end / bf + 1;
|
|
else *end = *end / bf;
|
|
|
|
#else
|
|
|
|
// Use interleaved partitioning of jr/ir loops.
|
|
*start = bli_thread_work_id( thread );
|
|
*inc = bli_thread_n_way( thread );
|
|
*end = n;
|
|
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|