1 /*
2 
3     Copyright (C) 2014, The University of Texas at Austin
4 
5     This file is part of libflame and is available under the 3-Clause
6     BSD license, which can be found in the LICENSE file at the top-level
7     directory, or at http://opensource.org/licenses/BSD-3-Clause
8 
9 */
10 
11 #include "FLAME.h"
12 
13 
14 static FLA_Bool FLA_initialized = FALSE;
15 
16 FLA_Obj FLA_THREE = {};
17 FLA_Obj FLA_TWO = {};
18 FLA_Obj FLA_ONE = {};
19 FLA_Obj FLA_ONE_HALF = {};
20 FLA_Obj FLA_ZERO = {};
21 FLA_Obj FLA_MINUS_ONE_HALF = {};
22 FLA_Obj FLA_MINUS_ONE = {};
23 FLA_Obj FLA_MINUS_TWO = {};
24 FLA_Obj FLA_MINUS_THREE = {};
25 
26 FLA_Obj FLA_EPSILON = {};
27 FLA_Obj FLA_SAFE_MIN = {};
28 FLA_Obj FLA_SAFE_MIN_SQUARE = {};
29 FLA_Obj FLA_SAFE_INV_MIN = {};
30 FLA_Obj FLA_SAFE_INV_MIN_SQUARE = {};
31 FLA_Obj FLA_UNDERFLOW_THRES = {};
32 FLA_Obj FLA_OVERFLOW_THRES = {};
33 FLA_Obj FLA_UNDERFLOW_SQUARE_THRES = {};
34 FLA_Obj FLA_OVERFLOW_SQUARE_THRES = {};
35 
36 const float    fzero = 0.0f;
37 const double   dzero = 0.0;
38 const scomplex czero = { 0.0f, 0.0f };
39 const dcomplex zzero = { 0.0 , 0.0  };
40 
41 /* *************************************************************************
42 
43    FLA_Init()
44 
45  *************************************************************************** */
46 
FLA_Init()47 void FLA_Init()
48 {
49   if ( FLA_initialized == TRUE ) return;
50 
51   FLA_initialized = TRUE;
52 
53   FLA_Error_messages_init();
54 
55   FLA_Memory_leak_counter_init();
56 
57   FLA_Init_constants();
58 
59   FLA_Cntl_init();
60 
61 #if FLA_VECTOR_INTRINSIC_TYPE == FLA_SSE_INTRINSICS
62   _MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
63 #endif
64 
65 #ifdef FLA_ENABLE_SUPERMATRIX
66   FLASH_Queue_init();
67 #endif
68 }
69 
70 /* *************************************************************************
71 
72   FLA_Finalize()
73 
74  *************************************************************************** */
75 
FLA_Finalize()76 void FLA_Finalize()
77 {
78   if ( FLA_initialized == FALSE ) return;
79 
80   FLA_initialized = FALSE;
81 
82   FLA_Finalize_constants();
83 
84   FLA_Cntl_finalize();
85 
86 #ifdef FLA_ENABLE_SUPERMATRIX
87   FLASH_Queue_finalize();
88 #endif
89 
90   FLA_Memory_leak_counter_finalize();
91 }
92 
93 /* *************************************************************************
94 
95   FLA_Init_safe()
96 
97  *************************************************************************** */
98 
FLA_Init_safe(FLA_Error * init_result)99 void FLA_Init_safe( FLA_Error* init_result )
100 {
101   if ( FLA_Initialized() )
102   {
103     *init_result = FLA_FAILURE;
104   }
105   else
106   {
107     FLA_Init();
108     *init_result = FLA_SUCCESS;
109   }
110 }
111 
112 /* *************************************************************************
113 
114   FLA_Finalize_safe()
115 
116  *************************************************************************** */
117 
FLA_Finalize_safe(FLA_Error init_result)118 void FLA_Finalize_safe( FLA_Error init_result )
119 {
120   if ( init_result == FLA_SUCCESS )
121     FLA_Finalize();
122 }
123 
124 /* *************************************************************************
125 
126    FLA_Initialized()
127 
128  *************************************************************************** */
129 
FLA_Initialized(void)130 FLA_Bool FLA_Initialized( void )
131 {
132   return FLA_initialized;
133 }
134 
135 /* *************************************************************************
136 
137    FLA_Init_constants()
138 
139  *************************************************************************** */
140 
FLA_Init_constants()141 void FLA_Init_constants()
142 {
143   FLA_Obj_create_constant(  3.0, &FLA_THREE );
144   FLA_Obj_create_constant(  2.0, &FLA_TWO );
145   FLA_Obj_create_constant(  1.0, &FLA_ONE );
146   FLA_Obj_create_constant(  0.5, &FLA_ONE_HALF );
147   FLA_Obj_create_constant(  0.0, &FLA_ZERO );
148   FLA_Obj_create_constant( -0.5, &FLA_MINUS_ONE_HALF );
149   FLA_Obj_create_constant( -1.0, &FLA_MINUS_ONE );
150   FLA_Obj_create_constant( -2.0, &FLA_MINUS_TWO );
151   FLA_Obj_create_constant( -3.0, &FLA_MINUS_THREE );
152 
153 
154   {
155     float
156       eps_f,
157       sfmin_f = FLT_MIN, sfmin_f2,
158       small_f = ( 1.0F / FLT_MAX ),
159       under_f = FLT_MIN,
160       over_f  = FLT_MAX;
161 
162     double
163       eps_d,
164       sfmin_d = DBL_MIN, sfmin_d2,
165       small_d = ( 1.0  / DBL_MAX ),
166       under_d = DBL_MIN,
167       over_d  = DBL_MAX;
168 
169     if ( FLT_ROUNDS == 1 )
170     {
171       eps_f = FLT_EPSILON*0.5F;
172       eps_d = DBL_EPSILON*0.5;
173     }
174     else
175     {
176       eps_f = FLT_EPSILON;
177       eps_d = DBL_EPSILON;
178     }
179 
180     if ( small_f >= sfmin_f ) sfmin_f = small_f * ( 1.0F + eps_f );
181     if ( small_d >= sfmin_d ) sfmin_d = small_d * ( 1.0  + eps_d );
182 
183     sfmin_f  = sfmin_f/eps_f;
184     sfmin_d  = sfmin_d/eps_d;
185 
186     sfmin_f2 = sqrt( sfmin_f );
187     sfmin_d2 = sqrt( sfmin_d );
188 
189     FLA_Obj_create_constant_ext( eps_f,           eps_d,           &FLA_EPSILON );
190 
191     FLA_Obj_create_constant_ext( sfmin_f,         sfmin_d,         &FLA_SAFE_MIN );
192     FLA_Obj_create_constant_ext( 1.0F/sfmin_f,    1.0/sfmin_d,     &FLA_SAFE_INV_MIN );
193 
194     FLA_Obj_create_constant_ext( sfmin_f2,        sfmin_d2,        &FLA_SAFE_MIN_SQUARE );
195     FLA_Obj_create_constant_ext( 1.0F/sfmin_f2,   1.0/sfmin_d2,    &FLA_SAFE_INV_MIN_SQUARE );
196 
197     FLA_Obj_create_constant_ext( under_f,         under_d,         &FLA_UNDERFLOW_THRES );
198     FLA_Obj_create_constant_ext( over_f,          over_d,          &FLA_OVERFLOW_THRES );
199 
200     FLA_Obj_create_constant_ext( sqrt( under_f ), sqrt( under_d ), &FLA_UNDERFLOW_SQUARE_THRES );
201     FLA_Obj_create_constant_ext( sqrt( over_f ),  sqrt( over_d ),  &FLA_OVERFLOW_SQUARE_THRES );
202   }
203 }
204 
205 /* *************************************************************************
206 
207    FLA_Finalize_constants()
208 
209  *************************************************************************** */
210 
FLA_Finalize_constants()211 void FLA_Finalize_constants()
212 {
213   FLA_Obj_free( &FLA_THREE );
214   FLA_Obj_free( &FLA_TWO );
215   FLA_Obj_free( &FLA_ONE );
216   FLA_Obj_free( &FLA_ONE_HALF );
217   FLA_Obj_free( &FLA_ZERO );
218   FLA_Obj_free( &FLA_MINUS_ONE_HALF );
219   FLA_Obj_free( &FLA_MINUS_ONE );
220   FLA_Obj_free( &FLA_MINUS_TWO );
221   FLA_Obj_free( &FLA_MINUS_THREE );
222 
223   FLA_Obj_free( &FLA_EPSILON );
224   FLA_Obj_free( &FLA_SAFE_MIN );
225   FLA_Obj_free( &FLA_SAFE_MIN_SQUARE );
226   FLA_Obj_free( &FLA_SAFE_INV_MIN );
227   FLA_Obj_free( &FLA_SAFE_INV_MIN_SQUARE );
228   FLA_Obj_free( &FLA_UNDERFLOW_THRES );
229   FLA_Obj_free( &FLA_OVERFLOW_THRES );
230   FLA_Obj_free( &FLA_UNDERFLOW_SQUARE_THRES );
231   FLA_Obj_free( &FLA_OVERFLOW_SQUARE_THRES );
232 }
233 
234