]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - dense-linear-algebra-libraries/linalg.git/blob - blis/frame/base/bli_init.c
Consolidate all git repos of linalg into one.
[dense-linear-algebra-libraries/linalg.git] / blis / frame / base / bli_init.c
1 /*
3    BLIS    
4    An object-based framework for developing high-performance BLAS-like
5    libraries.
7    Copyright (C) 2014, The University of Texas at Austin
9    Redistribution and use in source and binary forms, with or without
10    modification, are permitted provided that the following conditions are
11    met:
12     - Redistributions of source code must retain the above copyright
13       notice, this list of conditions and the following disclaimer.
14     - Redistributions in binary form must reproduce the above copyright
15       notice, this list of conditions and the following disclaimer in the
16       documentation and/or other materials provided with the distribution.
17     - Neither the name of The University of Texas at Austin nor the names
18       of its contributors may be used to endorse or promote products
19       derived from this software without specific prior written permission.
21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
35 #include "blis.h"
37 // -- Global variables --
39 static bool_t bli_initialized = FALSE;
41 obj_t BLIS_TWO;
42 obj_t BLIS_ONE;
43 obj_t BLIS_ONE_HALF;
44 obj_t BLIS_ZERO;
45 obj_t BLIS_MINUS_ONE_HALF;
46 obj_t BLIS_MINUS_ONE;
47 obj_t BLIS_MINUS_TWO;
49 packm_thrinfo_t BLIS_PACKM_SINGLE_THREADED;
50 gemm_thrinfo_t BLIS_GEMM_SINGLE_THREADED;
51 herk_thrinfo_t BLIS_HERK_SINGLE_THREADED;
52 thread_comm_t BLIS_SINGLE_COMM;
54 err_t bli_init( void )
55 {
56         err_t r_val = BLIS_FAILURE;
58         // If bli_initialized is TRUE, then we know without a doubt that
59         // BLIS is presently initialized, and thus we can return early.
60         if ( bli_initialized == TRUE ) return r_val;
62         // NOTE: if bli_initialized is FALSE, we cannot be certain that BLIS
63         // is ready to be initialized; it may be the case that a thread is
64         // inside the critical section below and is already in the process
65         // of initializing BLIS, but has not yet finished and updated
66         // bli_initialized accordingly. This boolean asymmetry is important!
68         // We enclose the bodies of bli_init() and bli_finalize() in a
69         // critical section (both with the same name) so that they can be
70         // safely called from multiple external (application) threads.
71         // Note that while the conditional test for early return may reside
72         // outside the critical section (as it should, for efficiency
73         // reasons), the conditional test below MUST be within the critical
74         // section to prevent a race condition of the type described above.
76         // BEGIN CRITICAL SECTION
78 #ifdef BLIS_ENABLE_OPENMP
79 /*#ifdef BLIS_ENABLE_C66X_BUILD
80         _Pragma( "omp critical" )
81 #else*/
82         _Pragma( "omp critical (init)" )
83 /*#endif*/
84 #endif
85         {
87         // Proceed with initialization only if BLIS is presently uninitialized.
88         // Since we bli_init() and bli_finalize() use the same named critical
89         // section, we can be sure that no other thread is either (a) updating
90         // bli_initialized, or (b) testing bli_initialized within the critical
91         // section (for the purposes of deciding whether to perform the
92         // necessary initialization subtasks).
93         if ( bli_initialized == FALSE )
94         {
95                 bli_init_const();
97                 bli_cntl_init();
99                 bli_error_msgs_init();
101                 bli_mem_init();
103 #ifdef BLIS_ENABLE_C66X_EDMA
104         // Initializing the DMA channels
105             bli_dma_init();
106 #endif
107     
108                 bli_setup_communicator( &BLIS_SINGLE_COMM, 1 );
109                 bli_setup_packm_single_threaded_info( &BLIS_PACKM_SINGLE_THREADED );
110                 bli_setup_gemm_single_threaded_info( &BLIS_GEMM_SINGLE_THREADED );
111                 bli_setup_herk_single_threaded_info( &BLIS_HERK_SINGLE_THREADED );
113                 // After initialization is complete, mark BLIS as initialized.
114                 bli_initialized = TRUE;
116                 // Only the thread that actually performs the initialization will
117                 // return "success".
118                 r_val = BLIS_SUCCESS;
119         }
121         // END CRITICAL SECTION
122         }
124         return r_val;
127 err_t bli_finalize( void )
129         err_t r_val = BLIS_FAILURE;
131         // If bli_initialized is FALSE, then we know without a doubt that
132         // BLIS is presently uninitialized, and thus we can return early.
133         if ( bli_initialized == FALSE ) return r_val;
135         // NOTE: if bli_initialized is TRUE, we cannot be certain that BLIS
136         // is ready to be finalized; it may be the case that a thread is
137         // inside the critical section below and is already in the process
138         // of finalizing BLIS, but has not yet finished and updated
139         // bli_initialized accordingly. This boolean asymmetry is important!
141         // We enclose the bodies of bli_init() and bli_finalize() in a
142         // critical section (both with the same name) so that they can be
143         // safely called from multiple external (application) threads.
144         // Note that while the conditional test for early return may reside
145         // outside the critical section (as it should, for efficiency
146         // reasons), the conditional test below MUST be within the critical
147         // section to prevent a race condition of the type described above.
149         // BEGIN CRITICAL SECTION
150 #ifdef BLIS_ENABLE_OPENMP
151 /*#ifdef BLIS_ENABLE_C66X_BUILD
152         _Pragma( "omp critical" )
153 #else*/
154         _Pragma( "omp critical (init)" )
155 /*#endif*/
156 #endif
157         {
159         // Proceed with finalization only if BLIS is presently initialized.
160         // Since we bli_init() and bli_finalize() use the same named critical
161         // section, we can be sure that no other thread is either (a) updating
162         // bli_initialized, or (b) testing bli_initialized within the critical
163         // section (for the purposes of deciding whether to perform the
164         // necessary finalization subtasks).
165         if ( bli_initialized == TRUE )
166         {
167                 bli_finalize_const();
169                 bli_cntl_finalize();
171                 // Don't need to do anything to finalize error messages.
173                 bli_mem_finalize();
175 #ifdef BLIS_ENABLE_C66X_EDMA
176                 bli_dma_finalize();
177 #endif
179                 // After finalization is complete, mark BLIS as uninitialized.
180                 bli_initialized = FALSE;
182                 // Only the thread that actually performs the finalization will
183                 // return "success".
184                 r_val = BLIS_SUCCESS;
185         }
187         // END CRITICAL SECTION
188         }
190         return r_val;
193 void bli_init_const( void )
195         bli_obj_create_const(  2.0, &BLIS_TWO );
196         bli_obj_create_const(  1.0, &BLIS_ONE );
197         bli_obj_create_const(  0.5, &BLIS_ONE_HALF );
198         bli_obj_create_const(  0.0, &BLIS_ZERO );
199         bli_obj_create_const( -0.5, &BLIS_MINUS_ONE_HALF );
200         bli_obj_create_const( -1.0, &BLIS_MINUS_ONE );
201         bli_obj_create_const( -2.0, &BLIS_MINUS_TWO );
204 void bli_finalize_const( void )
206         bli_obj_free( &BLIS_TWO );
207         bli_obj_free( &BLIS_ONE );
208         bli_obj_free( &BLIS_ONE_HALF );
209         bli_obj_free( &BLIS_ZERO );
210         bli_obj_free( &BLIS_MINUS_ONE_HALF );
211         bli_obj_free( &BLIS_MINUS_ONE );
212         bli_obj_free( &BLIS_MINUS_TWO );
215 void bli_init_auto( err_t* init_result )
217         *init_result = bli_init();
220 void bli_finalize_auto( err_t init_result )
222 #ifdef BLIS_ENABLE_STAY_AUTO_INITIALIZED
224         // If BLIS was configured to stay initialized after being automatically
225         // initialized, we honor the configuration request and do nothing.
226         // BLIS will remain initialized unless and until the user explicitly
227         // calls bli_finalize().
229 #else
231         // If BLIS was NOT configured to stay initialized after being automatically
232         // initialized, we call bli_finalize() only if the corresponding call to
233         // bli_init_auto() actually resulted in BLIS being initialized (indicated
234         // by it returning BLIS_SUCCESS); if it did nothing, we similarly do
235         // nothing here.
236         if ( init_result == BLIS_SUCCESS )
237                 bli_finalize();
239 #endif