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 #ifdef FLA_ENABLE_SCC
15 typedef volatile unsigned char* t_vcharp;
16 t_vcharp RCCE_shmalloc(size_t);
17 void RCCE_shfree(t_vcharp);
18 int RCCE_ue(void);
19
20
FLA_shmalloc(size_t size)21 void* FLA_shmalloc( size_t size )
22 {
23 return ( void * ) RCCE_shmalloc( size );
24 }
25
26
FLA_shfree(void * ptr)27 void FLA_shfree( void* ptr )
28 {
29 RCCE_shfree( ( t_vcharp ) ptr );
30 }
31
32
FLA_is_owner(void)33 FLA_Bool FLA_is_owner( void )
34 {
35 if ( RCCE_ue() == 0 )
36 return TRUE;
37 return FALSE;
38 }
39 #endif
40
FLA_Obj_nullify(FLA_Obj * obj)41 FLA_Error FLA_Obj_nullify( FLA_Obj *obj )
42 {
43 // Nullify the fields in the view object.
44 obj->m = 0;
45 obj->n = 0;
46 obj->offm = 0;
47 obj->offn = 0;
48 obj->m_inner = 0;
49 obj->n_inner = 0;
50 obj->base = NULL;
51
52 return FLA_SUCCESS;
53 }
54
FLA_Obj_create(FLA_Datatype datatype,dim_t m,dim_t n,dim_t rs,dim_t cs,FLA_Obj * obj)55 FLA_Error FLA_Obj_create( FLA_Datatype datatype, dim_t m, dim_t n, dim_t rs, dim_t cs, FLA_Obj *obj )
56 {
57 FLA_Obj_create_ext( datatype, FLA_SCALAR, m, n, m, n, rs, cs, obj );
58
59 return FLA_SUCCESS;
60 }
61
62
63
FLA_Obj_create_ext(FLA_Datatype datatype,FLA_Elemtype elemtype,dim_t m,dim_t n,dim_t m_inner,dim_t n_inner,dim_t rs,dim_t cs,FLA_Obj * obj)64 FLA_Error FLA_Obj_create_ext( FLA_Datatype datatype, FLA_Elemtype elemtype, dim_t m, dim_t n, dim_t m_inner, dim_t n_inner, dim_t rs, dim_t cs, FLA_Obj *obj )
65 {
66 size_t buffer_size;
67 size_t n_elem;
68
69 // Adjust the strides, if necessary.
70 FLA_adjust_strides( m, n, &rs, &cs );
71
72 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
73 FLA_Obj_create_ext_check( datatype, elemtype, m, n, m_inner, n_inner, rs, cs, obj );
74
75 // Populate the fields in the view object.
76 obj->m = m;
77 obj->n = n;
78 obj->offm = 0;
79 obj->offn = 0;
80 obj->m_inner = m_inner;
81 obj->n_inner = n_inner;
82
83 // Allocate the base object field.
84 obj->base = ( FLA_Base_obj * ) FLA_malloc( sizeof( FLA_Base_obj ) );
85
86 // Populate the fields in the base object.
87 obj->base->datatype = datatype;
88 obj->base->elemtype = elemtype;
89 obj->base->m = m;
90 obj->base->n = n;
91 obj->base->m_inner = m_inner;
92 obj->base->n_inner = n_inner;
93 obj->base->id = ( unsigned long ) obj->base;
94 obj->base->m_index = 0;
95 obj->base->n_index = 0;
96
97 // Compute the number of elements needed for the buffer, adjusting
98 // the strides for alignment if needed.
99 n_elem = FLA_compute_num_elem( FLA_Obj_elem_size( *obj ),
100 m, n, &rs, &cs );
101
102 // Compute the buffer size in bytes.
103 buffer_size = ( size_t ) n_elem *
104 ( size_t ) FLA_Obj_elem_size( *obj );
105
106 // Allocate the base object's element buffer.
107 #ifdef FLA_ENABLE_SCC
108 obj->base->buffer = ( FLA_Obj_elemtype( *obj ) == FLA_MATRIX ? FLA_malloc( buffer_size ) : FLA_shmalloc( buffer_size ) );
109 #else
110 obj->base->buffer = FLA_malloc( buffer_size );
111 #endif
112 obj->base->buffer_info = 0;
113
114 // Just in case this is a FLASH object, save the number of elements
115 // allocated so that we can more easily free the elements later on.
116 obj->base->n_elem_alloc = n_elem;
117
118 // Save the row and column strides used in the memory allocation.
119 obj->base->rs = rs;
120 obj->base->cs = cs;
121
122 #ifdef FLA_ENABLE_SUPERMATRIX
123 // Initialize SuperMatrix fields.
124 obj->base->n_read_tasks = 0;
125 obj->base->read_task_head = NULL;
126 obj->base->read_task_tail = NULL;
127 obj->base->write_task = NULL;
128 #endif
129
130 return FLA_SUCCESS;
131 }
132
133
FLA_compute_num_elem(dim_t elem_size,dim_t m,dim_t n,dim_t * rs,dim_t * cs)134 dim_t FLA_compute_num_elem( dim_t elem_size, dim_t m, dim_t n, dim_t* rs, dim_t* cs )
135 {
136 dim_t n_elem;
137
138 // Determine the amount of space we need to allocate based on the values of
139 // the row and column strides.
140 if ( m == 0 || n == 0 )
141 {
142 // For empty objects, set the length of the buffer to 0. Row and column
143 // strides should remain unchanged (because alignment is not needed).
144 n_elem = 0;
145 }
146 else if ( *rs == 1 )
147 {
148 // For column-major storage, use cs for computing the length of the buffer
149 // to allocate.
150
151 // Align the leading dimension to some user-defined address multiple,
152 // if requested at configure-time.
153 *cs = FLA_align_ldim( *cs, elem_size );
154
155 // Compute the length of the buffer needed for the object we're creating.
156 n_elem = ( size_t ) *cs *
157 ( size_t ) n;
158 }
159 else if ( *cs == 1 )
160 {
161 // For row-major storage, use rs for computing the length of the buffer
162 // to allocate.
163
164 // Align the leading dimension to some user-defined address multiple,
165 // if requested at configure-time.
166 *rs = FLA_align_ldim( *rs, elem_size );
167
168 // Compute the length of the buffer needed for the object we're creating.
169 n_elem = ( size_t ) m *
170 ( size_t ) *rs;
171 }
172 else
173 {
174 // For general storage, use rs and cs to compute the length of the buffer
175 // to allocate.
176
177 // Compute the size of the buffer needed for the object we're creating.
178 if ( *rs < *cs )
179 {
180 *cs = FLA_align_ldim( *cs, elem_size );
181
182 n_elem = ( size_t ) *cs *
183 ( size_t ) n;
184 }
185 else if ( *rs > *cs )
186 {
187 *rs = FLA_align_ldim( *rs, elem_size );
188
189 n_elem = ( size_t ) m *
190 ( size_t ) *rs;
191 }
192 else // if ( rs == cs )
193 {
194 //rs = FLA_align_ldim( rs, FLA_Obj_elem_size( *obj ) );
195 *cs = FLA_align_ldim( *cs, elem_size );
196
197 // Note that if rs == cs, then we must be creating either a 1-by-n matrix
198 // or a m-by-1 matrix. This constraint is enforced in
199 // FLA_Check_matrix_strides(). Thus, we can compute the buffer length:
200 // m * n * (rs|cs).
201 n_elem = ( size_t ) m *
202 ( size_t ) n *
203 ( size_t ) *cs;
204 }
205 }
206
207 return n_elem;
208 }
209
210
FLA_align_ldim(dim_t ldim,dim_t elem_size)211 dim_t FLA_align_ldim( dim_t ldim, dim_t elem_size )
212 {
213 #ifdef FLA_ENABLE_MEMORY_ALIGNMENT
214 #ifdef FLA_ENABLE_LDIM_ALIGNMENT
215 // Increase ldim so that ( ldim * elem_size ) is a multiple of the desired
216 // alignment.
217 ldim = ( ( ldim * elem_size + FLA_MEMORY_ALIGNMENT_BOUNDARY - 1 ) /
218 FLA_MEMORY_ALIGNMENT_BOUNDARY ) *
219 FLA_MEMORY_ALIGNMENT_BOUNDARY /
220 elem_size;
221 #endif
222 #endif
223
224 return ldim;
225 }
226
227
FLA_adjust_strides(dim_t m,dim_t n,dim_t * rs,dim_t * cs)228 void FLA_adjust_strides( dim_t m, dim_t n, dim_t* rs, dim_t* cs )
229 {
230 // Check the strides, and modify them if needed.
231 if ( *rs == 0 && *cs == 0 )
232 {
233 // Default values induce column-major storage, except when m == 1,
234 // because we dont want both strides to be unit.
235 if ( m == 1 && n > 1 )
236 {
237 *rs = n;
238 *cs = 1;
239 }
240 else
241 {
242 *rs = 1;
243 *cs = m;
244 }
245 }
246 else if ( *rs == 1 && *cs == 1 )
247 {
248 // If both strides are unit, this is probably a "lazy" request for a
249 // single vector (but could also be a request for a 1xn matrix in column-
250 // major order or an mx1 matrix in row-major order). In libflame, we have
251 // decided to "reserve" the case where rs == cs == 1 for scalars only, as
252 // having unit strides can upset the BLAS error checking when attempting
253 // to induce a row-major operation. Also, there is another special case
254 // where rs == cs == 1 and one or both of m and n equal zero. This last
255 // case is supported to allow creating "empty" objects.
256
257 if ( m == 0 || n == 0 )
258 {
259 // Nothing needs to be done for the "empty" case where m and/or n
260 // equal zero.
261 }
262 else if ( m == 1 && n == 1 )
263 {
264 // Nothing needs to be done for the scalar case where m == n == 1.
265 }
266 else if ( m > 1 && n == 1 )
267 {
268 // Set the column stride to indicate that this is a column vector stored
269 // in column-major order. This is necessary because, in some cases, we
270 // have to satisify the error checking in the underlying BLAS library,
271 // which expects the leading dimension to be set to at least m, even if
272 // it will never be used for indexing since it is a vector and thus only
273 // has one column of data.
274 *cs = m;
275 }
276 else if ( m == 1 && n > 1 )
277 {
278 // Set the row stride to indicate that this is a row vector stored
279 // in row-major order.
280 *rs = n;
281 }
282 }
283 }
284
285
FLA_Obj_create_conf_to(FLA_Trans trans,FLA_Obj obj_cur,FLA_Obj * obj_new)286 FLA_Error FLA_Obj_create_conf_to( FLA_Trans trans, FLA_Obj obj_cur, FLA_Obj *obj_new )
287 {
288 FLA_Datatype datatype;
289 FLA_Elemtype elemtype;
290 dim_t m, n;
291 dim_t rs, cs;
292
293 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
294 FLA_Obj_create_conf_to_check( trans, obj_cur, obj_new );
295
296 datatype = FLA_Obj_datatype( obj_cur );
297 elemtype = FLA_Obj_elemtype( obj_cur );
298
299 // Query the dimensions of the existing object.
300 if ( trans == FLA_NO_TRANSPOSE || trans == FLA_CONJ_NO_TRANSPOSE )
301 {
302 m = FLA_Obj_length( obj_cur );
303 n = FLA_Obj_width( obj_cur );
304 }
305 else // if ( trans == FLA_TRANSPOSE || trans == FLA_CONJ_TRANSPOSE )
306 {
307 m = FLA_Obj_width( obj_cur );
308 n = FLA_Obj_length( obj_cur );
309 }
310
311 // Query the row and column strides of the existing object. We don't care
312 // about the actual leading dimension of the existing object, only whether
313 // it is in row- or column-major format.
314 rs = FLA_Obj_row_stride( obj_cur );
315 cs = FLA_Obj_col_stride( obj_cur );
316
317 if ( ( rs == 1 && cs == 1 ) )
318 {
319 // Do nothing. This special case will be handled by FLA_adjust_strides().
320 ;
321 }
322 else if ( rs == 1 )
323 {
324 // For column-major storage, use the m dimension as the column stride.
325 // Row stride is already set to 1.
326 cs = m;
327 }
328 else if ( cs == 1 )
329 {
330 // For row-major storage, use the n dimension as the row stride.
331 // Column stride is already set to 1.
332 rs = n;
333 }
334
335 // Handle empty views.
336 if ( m == 0 ) cs = 1;
337 if ( n == 0 ) rs = 1;
338
339 FLA_Obj_create_ext( datatype, elemtype, m, n, m, n, rs, cs, obj_new );
340
341 return FLA_SUCCESS;
342 }
343
344
FLA_Obj_create_copy_of(FLA_Trans trans,FLA_Obj obj_cur,FLA_Obj * obj_new)345 FLA_Error FLA_Obj_create_copy_of( FLA_Trans trans, FLA_Obj obj_cur, FLA_Obj *obj_new )
346 {
347 // Create a new object conformal to the current object.
348 FLA_Obj_create_conf_to( trans, obj_cur, obj_new );
349
350 #ifdef FLA_ENABLE_SCC
351 if ( !FLA_is_owner() )
352 return FLA_SUCCESS;
353 #endif
354
355 // Copy the contents of the current object to the new object.
356 FLA_Copyt_external( trans, obj_cur, *obj_new );
357
358 return FLA_SUCCESS;
359 }
360
361
FLA_Obj_create_without_buffer(FLA_Datatype datatype,dim_t m,dim_t n,FLA_Obj * obj)362 FLA_Error FLA_Obj_create_without_buffer( FLA_Datatype datatype, dim_t m, dim_t n, FLA_Obj *obj )
363 {
364 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
365 FLA_Obj_create_without_buffer_check( datatype, m, n, obj );
366
367 // Populate the fields in the view object.
368 obj->m = m;
369 obj->n = n;
370 obj->offm = 0;
371 obj->offn = 0;
372 obj->m_inner = m;
373 obj->n_inner = n;
374
375 // Allocate the base object field.
376 obj->base = ( FLA_Base_obj * ) FLA_malloc( sizeof( FLA_Base_obj ) );
377
378 // Populate the fields in the base object.
379 obj->base->datatype = datatype;
380 obj->base->elemtype = FLA_SCALAR;
381 obj->base->m = m;
382 obj->base->n = n;
383 obj->base->m_inner = m;
384 obj->base->n_inner = n;
385 obj->base->id = ( unsigned long ) obj->base;
386 obj->base->m_index = 0;
387 obj->base->n_index = 0;
388
389 // Set the row and column strides to invalid values.
390 obj->base->rs = 0;
391 obj->base->cs = 0;
392
393 // Initialize the base object's element buffer to NULL.
394 obj->base->buffer = NULL;
395 obj->base->buffer_info = 0;
396 obj->base->n_elem_alloc = 0;
397
398 #ifdef FLA_ENABLE_SUPERMATRIX
399 // Initialize SuperMatrix fields.
400 obj->base->n_read_tasks = 0;
401 obj->base->read_task_head = NULL;
402 obj->base->read_task_tail = NULL;
403 obj->base->write_task = NULL;
404 #endif
405
406 return FLA_SUCCESS;
407 }
408
409
410
FLA_Obj_create_constant(double const_real,FLA_Obj * obj)411 FLA_Error FLA_Obj_create_constant( double const_real, FLA_Obj *obj )
412 {
413 int* temp_i;
414 float* temp_s;
415 double* temp_d;
416 scomplex* temp_c;
417 dcomplex* temp_z;
418
419 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
420 FLA_Obj_create_constant_check( const_real, obj );
421
422 FLA_Obj_create( FLA_CONSTANT, 1, 1, 0, 0, obj );
423
424 #ifdef FLA_ENABLE_SCC
425 if ( !FLA_is_owner() )
426 return FLA_SUCCESS;
427 #endif
428
429 temp_i = FLA_INT_PTR( *obj );
430 temp_s = FLA_FLOAT_PTR( *obj );
431 temp_d = FLA_DOUBLE_PTR( *obj );
432 temp_c = FLA_COMPLEX_PTR( *obj );
433 temp_z = FLA_DOUBLE_COMPLEX_PTR( *obj );
434
435 *temp_i = ( int ) const_real;
436 *temp_s = ( float ) const_real;
437 *temp_d = const_real;
438 temp_c->real = ( float ) const_real;
439 temp_c->imag = ( float ) 0.0;
440 temp_z->real = const_real;
441 temp_z->imag = 0.0;
442
443 return FLA_SUCCESS;
444 }
445
446
447
FLA_Obj_create_constant_ext(float const_s,double const_d,FLA_Obj * obj)448 FLA_Error FLA_Obj_create_constant_ext( float const_s, double const_d, FLA_Obj *obj )
449 {
450 int* temp_i;
451 float* temp_s;
452 double* temp_d;
453 scomplex* temp_c;
454 dcomplex* temp_z;
455
456 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
457 FLA_Obj_create_constant_ext_check( const_s, const_d, obj );
458
459 FLA_Obj_create( FLA_CONSTANT, 1, 1, 0, 0, obj );
460
461 #ifdef FLA_ENABLE_SCC
462 if ( !FLA_is_owner() )
463 return FLA_SUCCESS;
464 #endif
465
466 temp_i = FLA_INT_PTR( *obj );
467 temp_s = FLA_FLOAT_PTR( *obj );
468 temp_d = FLA_DOUBLE_PTR( *obj );
469 temp_c = FLA_COMPLEX_PTR( *obj );
470 temp_z = FLA_DOUBLE_COMPLEX_PTR( *obj );
471
472 *temp_i = ( int ) const_s;
473 *temp_s = const_s;
474 *temp_d = const_d;
475 temp_c->real = const_s;
476 temp_c->imag = 0.0F;
477 temp_z->real = const_d;
478 temp_z->imag = 0.0;
479
480 return FLA_SUCCESS;
481 }
482
483
484
FLA_Obj_create_complex_constant(double const_real,double const_imag,FLA_Obj * obj)485 FLA_Error FLA_Obj_create_complex_constant( double const_real, double const_imag, FLA_Obj *obj )
486 {
487 int* temp_i;
488 float* temp_s;
489 double* temp_d;
490 scomplex* temp_c;
491 dcomplex* temp_z;
492
493 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
494 FLA_Obj_create_complex_constant_check( const_real, const_imag, obj );
495
496 FLA_Obj_create( FLA_CONSTANT, 1, 1, 0, 0, obj );
497
498 #ifdef FLA_ENABLE_SCC
499 if ( !FLA_is_owner() )
500 return FLA_SUCCESS;
501 #endif
502
503 temp_i = FLA_INT_PTR( *obj );
504 temp_s = FLA_FLOAT_PTR( *obj );
505 temp_d = FLA_DOUBLE_PTR( *obj );
506 temp_c = FLA_COMPLEX_PTR( *obj );
507 temp_z = FLA_DOUBLE_COMPLEX_PTR( *obj );
508
509 *temp_i = ( int ) const_real;
510 *temp_s = ( float ) const_real;
511 *temp_d = const_real;
512 temp_c->real = ( float ) const_real;
513 temp_c->imag = ( float ) const_imag;
514 temp_z->real = const_real;
515 temp_z->imag = const_imag;
516
517 return FLA_SUCCESS;
518 }
519
520
521
FLA_Obj_attach_buffer(void * buffer,dim_t rs,dim_t cs,FLA_Obj * obj)522 FLA_Error FLA_Obj_attach_buffer( void *buffer, dim_t rs, dim_t cs, FLA_Obj *obj )
523 {
524 dim_t m, n;
525
526 m = FLA_Obj_length( *obj );
527 n = FLA_Obj_width( *obj );
528
529 // Adjust the strides, if necessary.
530 FLA_adjust_strides( m, n, &rs, &cs );
531
532 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
533 FLA_Obj_attach_buffer_check( buffer, rs, cs, obj );
534
535 obj->base->buffer = buffer;
536 obj->base->rs = rs;
537 obj->base->cs = cs;
538
539 return FLA_SUCCESS;
540 }
541
542
543
FLA_Obj_create_buffer(dim_t rs,dim_t cs,FLA_Obj * obj)544 FLA_Error FLA_Obj_create_buffer( dim_t rs, dim_t cs, FLA_Obj *obj )
545 {
546 size_t buffer_size;
547 size_t n_elem;
548 dim_t m, n;
549
550 m = FLA_Obj_length( *obj );
551 n = FLA_Obj_width( *obj );
552
553 // Adjust the strides, if necessary.
554 FLA_adjust_strides( m, n, &rs, &cs );
555
556 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
557 FLA_Obj_create_buffer_check( rs, cs, obj );
558
559 // Compute the number of elements needed for the buffer, adjusting
560 // the strides for alignment if needed.
561 n_elem = FLA_compute_num_elem( FLA_Obj_elem_size( *obj ),
562 m, n, &rs, &cs );
563
564 // Compute the buffer size in bytes.
565 buffer_size = ( size_t ) n_elem *
566 ( size_t ) FLA_Obj_elem_size( *obj );
567
568 // Allocate the base object's element buffer.
569 #ifdef FLA_ENABLE_SCC
570 obj->base->buffer = ( FLA_Obj_elemtype( *obj ) == FLA_MATRIX ? FLA_malloc( buffer_size ) : FLA_shmalloc( buffer_size ) );
571 #else
572 obj->base->buffer = FLA_malloc( buffer_size );
573 #endif
574 obj->base->buffer_info = 0;
575
576 // Save the number of elements allocated (for use with FLASH).
577 obj->base->n_elem_alloc = n_elem;
578
579 // Save the row and column strides used in the memory allocation.
580 obj->base->rs = rs;
581 obj->base->cs = cs;
582
583 return FLA_SUCCESS;
584 }
585
586
587
FLA_Obj_free(FLA_Obj * obj)588 FLA_Error FLA_Obj_free( FLA_Obj *obj )
589 {
590 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
591 FLA_Obj_free_check( obj );
592
593 if ( obj->base != NULL )
594 {
595 #ifdef FLA_ENABLE_SCC
596 ( FLA_Obj_elemtype( *obj ) == FLA_MATRIX ? FLA_free( obj->base->buffer ) : FLA_shfree( obj->base->buffer ) );
597 #else
598 //printf( "freeing buff %p\n", obj->base->buffer ); fflush( stdout );
599 FLA_free( obj->base->buffer );
600 #endif
601 //printf( "freeing base %p\n", obj->base ); fflush( stdout );
602 FLA_free( ( void * ) obj->base );
603 }
604
605 obj->offm = 0;
606 obj->offn = 0;
607 obj->m = 0;
608 obj->n = 0;
609
610 return FLA_SUCCESS;
611 }
612
613
614
FLA_Obj_free_without_buffer(FLA_Obj * obj)615 FLA_Error FLA_Obj_free_without_buffer( FLA_Obj *obj )
616 {
617 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
618 FLA_Obj_free_without_buffer_check( obj );
619
620 FLA_free( ( void * ) obj->base );
621
622 obj->offm = 0;
623 obj->offn = 0;
624 obj->m = 0;
625 obj->n = 0;
626
627 return FLA_SUCCESS;
628 }
629
630
631
FLA_Obj_free_buffer(FLA_Obj * obj)632 FLA_Error FLA_Obj_free_buffer( FLA_Obj *obj )
633 {
634 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
635 FLA_Obj_free_buffer_check( obj );
636
637 #ifdef FLA_ENABLE_SCC
638 ( FLA_Obj_elemtype( *obj ) == FLA_MATRIX ? FLA_free( obj->base->buffer ) : FLA_shfree( obj->base->buffer ) );
639 #else
640 FLA_free( obj->base->buffer );
641 #endif
642 obj->base->buffer = NULL;
643
644 return FLA_SUCCESS;
645 }
646
FLA_Obj_flip_base(FLA_Obj * obj)647 FLA_Error FLA_Obj_flip_base( FLA_Obj *obj )
648 {
649 FLA_Error e_val;
650 dim_t temp;
651
652 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
653 {
654 e_val = FLA_Check_null_pointer( obj );
655 FLA_Check_error_code( e_val );
656
657 e_val = FLA_Check_null_pointer( obj->base );
658 FLA_Check_error_code( e_val );
659 }
660
661 exchange( obj->base->m, obj->base->n, temp );
662 exchange( obj->base->cs, obj->base->rs, temp );
663 exchange( obj->base->m_inner, obj->base->n_inner, temp );
664 exchange( obj->base->m_index, obj->base->n_index, temp );
665
666 return FLA_SUCCESS;
667 }
668
FLA_Obj_flip_view(FLA_Obj * obj)669 FLA_Error FLA_Obj_flip_view( FLA_Obj *obj )
670 {
671 FLA_Error e_val;
672 dim_t temp;
673
674 if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
675 {
676 e_val = FLA_Check_null_pointer( obj );
677 FLA_Check_error_code( e_val );
678 }
679
680 exchange( obj->offm, obj->offn, temp );
681 exchange( obj->m, obj->n, temp );
682 exchange( obj->m_inner, obj->n_inner, temp );
683
684 return FLA_SUCCESS;
685 }
686