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 #ifndef BLIS_OBJ_MACRO_DEFS_H
36 #define BLIS_OBJ_MACRO_DEFS_H
39 // -- Object query/modification macros --
41 // Info query
43 #define bli_obj_is_float( obj ) \
44 \
45 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_FLOAT_TYPE )
47 #define bli_obj_is_double( obj ) \
48 \
49 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_DOUBLE_TYPE )
51 #define bli_obj_is_scomplex( obj ) \
52 \
53 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_SCOMPLEX_TYPE )
55 #define bli_obj_is_dcomplex( obj ) \
56 \
57 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_DCOMPLEX_TYPE )
59 #define bli_obj_is_int( obj ) \
60 \
61 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_INT_TYPE )
63 #define bli_obj_is_const( obj ) \
64 \
65 ( ( (obj).info & BLIS_DATATYPE_BITS ) == BLIS_BITVAL_CONST_TYPE )
67 #define bli_obj_domain( obj ) \
68 \
69 ( (obj).info & BLIS_DOMAIN_BIT )
71 #define bli_obj_is_real( obj ) \
72 \
73 ( ( (obj).info & BLIS_DOMAIN_BIT ) == BLIS_BITVAL_REAL )
75 #define bli_obj_is_complex( obj ) \
76 \
77 ( ( (obj).info & BLIS_DOMAIN_BIT ) == BLIS_BITVAL_COMPLEX )
79 #define bli_obj_precision( obj ) \
80 \
81 ( (obj).info & BLIS_PRECISION_BIT )
83 #define bli_obj_is_double_precision( obj ) \
84 \
85 ( ( (obj).info & BLIS_PRECISION_BIT ) == BLIS_BITVAL_DOUBLE_PREC )
87 #define bli_obj_datatype( obj ) \
88 \
89 ( (num_t) ((obj).info & BLIS_DATATYPE_BITS ))
91 #define bli_obj_datatype_proj_to_real( obj ) \
92 \
93 ( (num_t) ( ( (obj).info & BLIS_DATATYPE_BITS ) & ~BLIS_BITVAL_COMPLEX ))
95 #define bli_obj_datatype_proj_to_complex( obj ) \
96 \
97 ( (num_t) ( ( (obj).info & BLIS_DATATYPE_BITS ) & BLIS_BITVAL_COMPLEX ))
99 #define bli_obj_target_datatype( obj ) \
100 \
101 ( (num_t) ( ( (obj).info & BLIS_TARGET_DT_BITS ) >> BLIS_TARGET_DT_SHIFT ))
103 #define bli_obj_execution_datatype( obj ) \
104 \
105 ( (num_t) ( ( (obj).info & BLIS_EXECUTION_DT_BITS ) >> BLIS_EXECUTION_DT_SHIFT ) )
107 #define bli_obj_conjtrans_status( obj ) \
108 \
109 ( (trans_t) ((obj).info & BLIS_CONJTRANS_BITS ) )
111 #define bli_obj_onlytrans_status( obj ) \
112 \
113 ( (trans_t) ( (obj).info & BLIS_TRANS_BIT ))
115 #define bli_obj_has_trans( obj ) \
116 \
117 ( ( (obj).info & BLIS_TRANS_BIT ) == BLIS_BITVAL_TRANS ) \
119 #define bli_obj_has_notrans( obj ) \
120 \
121 ( ( (obj).info & BLIS_TRANS_BIT ) == BLIS_BITVAL_NO_TRANS ) \
123 #define bli_obj_conj_status( obj ) \
124 \
125 ( (conj_t) ( (obj).info & BLIS_CONJ_BIT ))
127 #define bli_obj_has_conj( obj ) \
128 \
129 ( ( (obj).info & BLIS_CONJ_BIT ) == BLIS_BITVAL_CONJ ) \
131 #define bli_obj_has_noconj( obj ) \
132 \
133 ( ( (obj).info & BLIS_CONJ_BIT ) == BLIS_BITVAL_NO_CONJ ) \
135 #define bli_obj_uplo( obj ) \
136 \
137 ( (uplo_t) ((obj).info & BLIS_UPLO_BITS )) \
139 #define bli_obj_is_upper( obj ) \
140 \
141 ( ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_UPPER )
143 #define bli_obj_is_lower( obj ) \
144 \
145 ( ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_LOWER )
147 #define bli_obj_is_upper_after_trans( obj ) \
148 \
149 ( bli_obj_has_trans( (obj) ) ? bli_obj_is_lower( (obj) ) \
150 : bli_obj_is_upper( (obj) ) )
152 #define bli_obj_is_lower_after_trans( obj ) \
153 \
154 ( bli_obj_has_trans( (obj) ) ? bli_obj_is_upper( (obj) ) \
155 : bli_obj_is_lower( (obj) ) )
157 #define bli_obj_is_upper_or_lower( obj ) \
158 \
159 ( ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_UPPER || \
160 ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_LOWER )
162 #define bli_obj_is_dense( obj ) \
163 \
164 ( ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_DENSE )
166 #define bli_obj_is_zeros( obj ) \
167 \
168 ( ( (obj).info & BLIS_UPLO_BITS ) == BLIS_BITVAL_ZEROS )
170 #define bli_obj_diag( obj ) \
171 \
172 ( (diag_t) ( (obj).info & BLIS_UNIT_DIAG_BIT ))
174 #define bli_obj_has_nonunit_diag( obj ) \
175 \
176 ( ( (obj).info & BLIS_UNIT_DIAG_BIT ) == BLIS_BITVAL_NONUNIT_DIAG )
178 #define bli_obj_has_unit_diag( obj ) \
179 \
180 ( ( (obj).info & BLIS_UNIT_DIAG_BIT ) == BLIS_BITVAL_UNIT_DIAG )
182 #define bli_obj_has_inverted_diag( obj ) \
183 \
184 ( ( (obj).info & BLIS_INVERT_DIAG_BIT ) == BLIS_BITVAL_INVERT_DIAG )
186 #define bli_obj_is_pack_rev_if_upper( obj ) \
187 \
188 ( ( (obj).info & BLIS_PACK_REV_IF_UPPER_BIT ) == BLIS_BITVAL_PACK_REV_IF_UPPER )
190 #define bli_obj_is_pack_rev_if_lower( obj ) \
191 \
192 ( ( (obj).info & BLIS_PACK_REV_IF_LOWER_BIT ) == BLIS_BITVAL_PACK_REV_IF_LOWER )
194 #define bli_obj_pack_schema( obj ) \
195 \
196 ( (pack_t) ( (obj).info & BLIS_PACK_SCHEMA_BITS ))
198 #define bli_obj_is_packed( obj ) \
199 \
200 ( ( (obj).info & BLIS_PACK_BIT ) )
202 #define bli_obj_is_row_packed( obj ) \
203 \
204 ( ( (obj).info & BLIS_PACK_RC_BIT ) == ( BLIS_BITVAL_PACKED_UNSPEC ^ \
205 BLIS_BITVAL_PACKED_ROWS ) )
207 #define bli_obj_is_col_packed( obj ) \
208 \
209 ( ( (obj).info & BLIS_PACK_RC_BIT ) == ( BLIS_BITVAL_PACKED_UNSPEC ^ \
210 BLIS_BITVAL_PACKED_COLUMNS ) )
212 #define bli_obj_is_panel_packed( obj ) \
213 \
214 ( ( (obj).info & BLIS_PACK_PANEL_BIT ) )
216 #define bli_obj_is_4m_packed( obj ) \
217 \
218 ( ( (obj).info & BLIS_PACK_FORMAT_BITS ) == BLIS_BITVAL_4M )
220 #define bli_obj_is_3m_packed( obj ) \
221 \
222 ( ( (obj).info & BLIS_PACK_FORMAT_BITS ) == BLIS_BITVAL_3M )
224 #define bli_obj_is_ro_packed( obj ) \
225 \
226 ( ( (obj).info & BLIS_PACK_FORMAT_BITS ) == BLIS_BITVAL_RO )
228 #define bli_obj_is_io_packed( obj ) \
229 \
230 ( ( (obj).info & BLIS_PACK_FORMAT_BITS ) == BLIS_BITVAL_IO )
232 #define bli_obj_is_rpi_packed( obj ) \
233 \
234 ( ( (obj).info & BLIS_PACK_FORMAT_BITS ) == BLIS_BITVAL_RPI )
236 #define bli_obj_is_rih_packed( obj ) \
237 \
238 ( bli_obj_is_ro_packed( obj ) || \
239 bli_obj_is_io_packed( obj ) || \
240 bli_obj_is_rpi_packed( obj ) )
242 #define bli_obj_pack_buffer_type( obj ) \
243 \
244 ( (obj).info & BLIS_PACK_BUFFER_BITS )
246 #define bli_obj_struc( obj ) \
247 \
248 ( (struc_t) ( (obj).info & BLIS_STRUC_BITS ))
250 #define bli_obj_is_general( obj ) \
251 \
252 ( ( (obj).info & BLIS_STRUC_BITS ) == BLIS_BITVAL_GENERAL )
254 #define bli_obj_is_hermitian( obj ) \
255 \
256 ( ( (obj).info & BLIS_STRUC_BITS ) == BLIS_BITVAL_HERMITIAN )
258 #define bli_obj_is_symmetric( obj ) \
259 \
260 ( ( (obj).info & BLIS_STRUC_BITS ) == BLIS_BITVAL_SYMMETRIC )
262 #define bli_obj_is_triangular( obj ) \
263 \
264 ( ( (obj).info & BLIS_STRUC_BITS ) == BLIS_BITVAL_TRIANGULAR )
266 #define bli_obj_is_herm_or_symm( obj ) \
267 \
268 ( bli_obj_is_hermitian( obj ) || \
269 bli_obj_is_symmetric( obj ) )
273 // Info modification
275 #define bli_obj_set_conjtrans( conjtrans, obj ) \
276 { \
277 (obj).info = ( (obj).info & ~BLIS_CONJTRANS_BITS ) | (conjtrans); \
278 }
280 #define bli_obj_set_onlytrans( trans, obj ) \
281 { \
282 (obj).info = ( (obj).info & ~BLIS_TRANS_BIT ) | (trans); \
283 }
285 #define bli_obj_set_conj( conjval, obj ) \
286 { \
287 (obj).info = ( (obj).info & ~BLIS_CONJ_BIT ) | (conjval); \
288 }
290 #define bli_obj_set_uplo( uplo, obj ) \
291 { \
292 (obj).info = ( (obj).info & ~BLIS_UPLO_BITS ) | (uplo); \
293 }
295 #define bli_obj_set_diag( diag, obj ) \
296 { \
297 (obj).info = ( (obj).info & ~BLIS_UNIT_DIAG_BIT ) | (diag); \
298 }
300 #define bli_obj_set_invert_diag( inv_diag, obj ) \
301 { \
302 (obj).info = ( (obj).info & ~BLIS_INVERT_DIAG_BIT ) | (inv_diag); \
303 }
305 #define bli_obj_set_datatype( dt, obj ) \
306 { \
307 (obj).info = ( (obj).info & ~BLIS_DATATYPE_BITS ) | (dt); \
308 }
310 #define bli_obj_set_target_datatype( dt, obj ) \
311 { \
312 (obj).info = ( (obj).info & ~BLIS_TARGET_DT_BITS ) | ( dt << BLIS_TARGET_DT_SHIFT ); \
313 }
315 #define bli_obj_set_execution_datatype( dt, obj ) \
316 { \
317 (obj).info = ( (obj).info & ~BLIS_EXECUTION_DT_BITS ) | ( dt << BLIS_EXECUTION_DT_SHIFT ); \
318 }
320 #define bli_obj_set_pack_schema( pack, obj ) \
321 { \
322 (obj).info = ( (obj).info & ~BLIS_PACK_SCHEMA_BITS ) | (pack); \
323 }
325 #define bli_obj_set_pack_order_if_upper( packordifup, obj ) \
326 { \
327 (obj).info = ( (obj).info & ~BLIS_PACK_REV_IF_UPPER_BIT ) | (packordifup); \
328 }
330 #define bli_obj_set_pack_order_if_lower( packordiflo, obj ) \
331 { \
332 (obj).info = ( (obj).info & ~BLIS_PACK_REV_IF_LOWER_BIT ) | (packordiflo); \
333 }
335 #define bli_obj_set_pack_buffer_type( packbuf, obj ) \
336 { \
337 (obj).info = ( (obj).info & ~BLIS_PACK_BUFFER_BITS ) | (packbuf); \
338 }
340 #define bli_obj_set_struc( struc, obj ) \
341 { \
342 (obj).info = ( (obj).info & ~BLIS_STRUC_BITS ) | (struc); \
343 }
345 #define bli_obj_toggle_trans( obj )\
346 { \
347 (obj).info = ( (obj).info ^ BLIS_TRANS_BIT ); \
348 }
350 #define bli_obj_toggle_conj( obj )\
351 { \
352 (obj).info = ( (obj).info ^ BLIS_CONJ_BIT ); \
353 }
355 #define bli_obj_toggle_uplo( obj ) \
356 { \
357 (obj).info = ( (obj).info ^ BLIS_LOWER_BIT ) ^ BLIS_UPPER_BIT; \
358 }
360 #define bli_obj_toggle_region_ref( obj ) \
361 { \
362 if ( bli_obj_is_upper( obj ) ) bli_obj_inc_diag_off( -1, obj ); \
363 else if ( bli_obj_is_lower( obj ) ) bli_obj_inc_diag_off( 1, obj ); \
364 \
365 bli_obj_toggle_uplo( obj ); \
366 }
368 #define bli_obj_toggle_uplo_if_trans( trans, obj ) \
369 { \
370 if ( bli_does_trans( trans ) && ( bli_obj_is_upper_or_lower( obj ) ) ) \
371 { \
372 bli_obj_toggle_uplo( obj ); \
373 bli_obj_negate_diag_offset( obj ); \
374 } \
375 }
377 #define bli_obj_apply_trans( trans, obj )\
378 { \
379 (obj).info = ( (obj).info ^ (trans) ); \
380 }
382 #define bli_obj_apply_conj( conjval, obj )\
383 { \
384 (obj).info = ( (obj).info ^ (conjval) ); \
385 }
388 // Root matrix query
390 #define bli_obj_root( obj ) \
391 \
392 ((obj).root)
394 #define bli_obj_root_is_general( obj ) \
395 \
396 bli_obj_is_general( *bli_obj_root( obj ) ) \
398 #define bli_obj_root_is_hermitian( obj ) \
399 \
400 bli_obj_is_hermitian( *bli_obj_root( obj ) ) \
402 #define bli_obj_root_is_symmetric( obj ) \
403 \
404 bli_obj_is_symmetric( *bli_obj_root( obj ) ) \
406 #define bli_obj_root_is_triangular( obj ) \
407 \
408 bli_obj_is_triangular( *bli_obj_root( obj ) ) \
410 #define bli_obj_root_is_herm_or_symm( obj ) \
411 \
412 ( bli_obj_is_hermitian( *bli_obj_root( obj ) ) || \
413 bli_obj_is_symmetric( *bli_obj_root( obj ) ) )
415 #define bli_obj_root_is_upper( obj ) \
416 \
417 bli_obj_is_upper( *bli_obj_root( obj ) ) \
419 #define bli_obj_root_is_lower( obj ) \
420 \
421 bli_obj_is_lower( *bli_obj_root( obj ) ) \
424 // Root matrix modification
426 #define bli_obj_set_as_root( obj )\
427 { \
428 (obj).root = &(obj); \
429 }
432 // Dimension query
434 #define bli_obj_length( obj ) \
435 \
436 ((obj).m)
438 #define bli_obj_width( obj ) \
439 \
440 ((obj).n)
442 #define bli_obj_min_dim( obj ) \
443 \
444 ( bli_min( bli_obj_length( obj ), \
445 bli_obj_width( obj ) ) )
447 #define bli_obj_max_dim( obj ) \
448 \
449 ( bli_max( bli_obj_length( obj ), \
450 bli_obj_width( obj ) ) )
452 #define bli_obj_length_after_trans( obj ) \
453 \
454 ( bli_obj_has_trans( (obj) ) ? bli_obj_width( (obj) ) \
455 : bli_obj_length( (obj) ) )
457 #define bli_obj_width_after_trans( obj ) \
458 \
459 ( bli_obj_has_trans( (obj) ) ? bli_obj_length( (obj) ) \
460 : bli_obj_width( (obj) ) )
462 #define bli_obj_get_dims_after_trans( obj, dim_m, dim_n ) \
463 { \
464 if ( bli_obj_has_notrans( trans ) ) \
465 { \
466 dim_m = bli_obj_length( obj ); \
467 dim_n = bli_obj_width( obj ); \
468 } \
469 else \
470 { \
471 dim_m = bli_obj_width( obj ); \
472 dim_n = bli_obj_length( obj ); \
473 } \
474 }
476 /*
477 bli_obj_length_stored( obj )
478 {
479 if ( lower )
480 {
481 if ( diagoff < 0 ) m_stored = m + diagoff;
482 else m_stored = m
483 }
484 else if ( upper )
485 {
486 if ( diagoff < 0 ) m_stored = min( m, n - diagoff );
487 else m_stored = min( m, n - diagoff );
488 }
489 }
490 bli_obj_width_stored( obj )
491 {
492 if ( lower )
493 {
494 if ( diagoff < 0 ) n_stored = min( n, m + diagoff );
495 else n_stored = min( n, m + diagoff );
496 }
497 else if ( upper )
498 {
499 if ( diagoff < 0 ) n_stored = n;
500 else n_stored = n - diagoff;
501 }
502 }
503 */
504 // Note: The purpose of these macros is to obtain the length and width
505 // of the smallest submatrices of an object that could still encompass
506 // the stored data above (if obj is upper) or below (if obj is lower)
507 // the diagonal.
508 #define bli_obj_length_stored( obj ) \
509 \
510 ( bli_obj_is_upper( obj ) \
511 ? bli_min( bli_obj_length( obj ), \
512 bli_obj_width( obj ) - bli_obj_diag_offset( obj ) ) \
513 : bli_min( bli_obj_length( obj ), \
514 bli_obj_length( obj ) + bli_obj_diag_offset( obj ) ) \
515 )
517 #define bli_obj_width_stored( obj ) \
518 \
519 ( bli_obj_is_lower( obj ) \
520 ? bli_min( bli_obj_width( obj ), \
521 bli_obj_length( obj ) + bli_obj_diag_offset( obj ) ) \
522 : bli_min( bli_obj_width( obj ), \
523 bli_obj_width( obj ) - bli_obj_diag_offset( obj ) ) \
524 )
526 #define bli_obj_length_stored_after_trans( obj ) \
527 \
528 ( bli_obj_has_trans( obj ) ? bli_obj_width_stored( obj ) \
529 : bli_obj_length_stored( obj ) )
531 #define bli_obj_width_stored_after_trans( obj ) \
532 \
533 ( bli_obj_has_trans( obj ) ? bli_obj_length_stored( obj ) \
534 : bli_obj_width_stored( obj ) )
536 #define bli_obj_vector_dim( x ) \
537 \
538 ( bli_obj_length( x ) == 1 ? bli_obj_width( x ) \
539 : bli_obj_length( x ) )
541 #define bli_obj_vector_inc( x ) \
542 \
543 ( bli_obj_is_1x1( x ) ? 1 : \
544 ( bli_obj_length( x ) == 1 ? bli_obj_col_stride( x ) \
545 : bli_obj_row_stride( x ) ) \
546 )
548 #define bli_obj_is_vector( x ) \
549 \
550 ( bli_obj_length( x ) == 1 || \
551 bli_obj_width( x ) == 1 )
553 #define bli_obj_is_row_vector( x ) \
554 \
555 ( bli_obj_length( x ) == 1 )
557 #define bli_obj_is_col_vector( x ) \
558 \
559 ( bli_obj_width( x ) == 1 )
561 #define bli_obj_has_zero_dim( obj ) \
562 \
563 ( bli_obj_length( obj ) == 0 || \
564 bli_obj_width( obj ) == 0 )
566 #define bli_obj_is_1x1( x ) \
567 \
568 ( bli_obj_length( x ) == 1 && \
569 bli_obj_width( x ) == 1 )
572 // Dimension modification
574 #define bli_obj_set_dims( dim_m, dim_n, obj ) \
575 { \
576 (obj).m = dim_m; \
577 (obj).n = dim_n; \
578 }
580 #define bli_obj_set_dims_with_trans( trans, dim_m, dim_n, obj ) \
581 { \
582 if ( bli_does_notrans( trans ) ) \
583 { \
584 (obj).m = dim_m; \
585 (obj).n = dim_n; \
586 } \
587 else \
588 { \
589 (obj).m = dim_n; \
590 (obj).n = dim_m; \
591 } \
592 }
595 // Stride/increment query
597 #define bli_obj_row_stride( obj ) \
598 \
599 ((obj).rs)
601 #define bli_obj_col_stride( obj ) \
602 \
603 ((obj).cs)
605 #define bli_obj_row_stride_mag( obj ) \
606 \
607 ( bli_abs( bli_obj_row_stride( obj ) ) )
609 #define bli_obj_col_stride_mag( obj ) \
610 \
611 ( bli_abs( bli_obj_col_stride( obj ) ) )
613 //
614 // NOTE: The following two macros differ from their non-obj counterparts
615 // in that they do not identify m x 1 and 1 x n objects as row-stored and
616 // column-stored, respectively, which is needed when considering packed
617 // objects. But this is okay, since none of the invocations of these
618 // "obj" macros are used on packed matrices.
619 //
620 #define bli_obj_is_row_stored( obj ) \
621 \
622 ( bli_obj_col_stride_mag( obj ) == 1 )
624 #define bli_obj_is_col_stored( obj ) \
625 \
626 ( bli_obj_row_stride_mag( obj ) == 1 )
628 #define bli_obj_is_gen_stored( obj ) \
629 \
630 ( bli_obj_row_stride_mag( obj ) != 1 && \
631 bli_obj_col_stride_mag( obj ) != 1 )
633 #define bli_obj_is_row_tilted( obj ) \
634 \
635 ( bli_obj_col_stride_mag( obj ) < bli_obj_row_stride_mag( obj ) )
637 #define bli_obj_is_col_tilted( obj ) \
638 \
639 ( bli_obj_row_stride_mag( obj ) < bli_obj_col_stride_mag( obj ) )
642 // Stride/increment modification
644 #define bli_obj_set_incs( row_stride, col_stride, obj ) \
645 { \
646 (obj).rs = row_stride; \
647 (obj).cs = col_stride; \
648 }
651 // Offset query
653 #define bli_obj_row_offset( obj ) \
654 \
655 ( (obj).offm )
657 #define bli_obj_col_offset( obj ) \
658 \
659 ( (obj).offn )
662 // Offset modification
664 #define bli_obj_set_offs( offset_m, offset_n, obj ) \
665 { \
666 (obj).offm = offset_m; \
667 (obj).offn = offset_n; \
668 }
670 #define bli_obj_inc_offs( offset_m, offset_n, obj ) \
671 { \
672 (obj).offm += offset_m; \
673 (obj).offn += offset_n; \
674 }
676 #define bli_obj_dec_offs( offset_m, offset_n, obj ) \
677 { \
678 (obj).offm -= offset_m; \
679 (obj).offn -= offset_n; \
680 }
683 // Diagonal offset query
685 #define bli_obj_diag_offset( obj ) \
686 \
687 ((obj).diag_off)
689 #define bli_obj_diag_offset_after_trans( obj ) \
690 \
691 ( bli_obj_has_trans( obj ) ? -bli_obj_diag_offset( obj ) \
692 : bli_obj_diag_offset( obj ) )
694 #define bli_obj_has_main_diag( obj ) \
695 \
696 ( bli_obj_diag_offset( obj ) == 0 )
698 #define bli_obj_is_strictly_above_diag( obj ) \
699 \
700 ( ( doff_t )bli_obj_length( obj ) <= -bli_obj_diag_offset( obj ) )
702 #define bli_obj_is_strictly_below_diag( obj ) \
703 \
704 ( ( doff_t )bli_obj_width( obj ) <= bli_obj_diag_offset( obj ) )
706 #define bli_obj_is_outside_diag( obj ) \
707 \
708 ( bli_obj_is_strictly_above_diag( obj ) || \
709 bli_obj_is_strictly_below_diag( obj ) )
711 #define bli_obj_intersects_diag( obj ) \
712 \
713 ( !bli_obj_is_strictly_above_diag( obj ) && \
714 !bli_obj_is_strictly_below_diag( obj ) )
716 #define bli_obj_is_unstored_subpart( obj ) \
717 \
718 ( ( bli_obj_root_is_lower( obj ) && bli_obj_is_strictly_above_diag( obj ) ) || \
719 ( bli_obj_root_is_upper( obj ) && bli_obj_is_strictly_below_diag( obj ) ) )
722 // Diagonal offset modification
724 #define bli_obj_set_diag_offset( offset, obj ) \
725 { \
726 (obj).diag_off = ( doff_t )(offset); \
727 }
729 #define bli_obj_negate_diag_offset( obj ) \
730 { \
731 (obj).diag_off = -(obj).diag_off; \
732 }
734 #define bli_obj_inc_diag_off( offset, obj ) \
735 { \
736 (obj).diag_off += ( doff_t )(offset); \
737 }
740 // Buffer address query
742 #define bli_obj_buffer( obj ) \
743 \
744 (obj).buffer
746 // Buffer address modification
748 #define bli_obj_set_buffer( buf, obj ) \
749 { \
750 (obj).buffer = buf; \
751 }
754 // Bufferless scalar field query
756 #define bli_obj_internal_scalar_buffer( obj ) \
757 \
758 &((obj).scalar)
760 // Bufferless scalar field modification
762 #define bli_obj_set_internal_scalar( val, obj ) \
763 { \
764 (obj).scalar = val; \
765 }
767 #define bli_obj_copy_internal_scalar( a, b ) \
768 { \
769 (b).scalar = (a).scalar; \
770 }
772 // Element size query
774 #define bli_obj_elem_size( obj ) \
775 \
776 (obj).elem_size \
778 // Element size modification
780 #define bli_obj_set_elem_size( size, obj ) \
781 { \
782 (obj).elem_size = size; \
783 }
786 // Pack mem_t entry query
788 #define bli_obj_pack_mem( obj ) \
789 \
790 ( &((obj).pack_mem) )
792 // Pack mem_t entry modification
794 #define bli_obj_set_pack_mem( mem_p, obj ) \
795 { \
796 (obj).pack_mem = *mem_p; \
797 }
800 // Packed matrix info query
802 #define bli_obj_padded_length( obj ) \
803 \
804 ( (obj).m_padded )
806 #define bli_obj_padded_width( obj ) \
807 \
808 ( (obj).n_padded )
810 // Packed matrix info modification
812 #define bli_obj_set_padded_length( m0, obj ) \
813 { \
814 (obj).m_padded = m0; \
815 }
817 #define bli_obj_set_padded_width( n0, obj ) \
818 { \
819 (obj).n_padded = n0; \
820 }
822 #define bli_obj_set_padded_dims( m0, n0, obj ) \
823 { \
824 bli_obj_set_padded_length( m0, obj ); \
825 bli_obj_set_padded_width( n0, obj ); \
826 }
829 // Packed panel info query
831 #define bli_obj_panel_length( obj ) \
832 \
833 ((obj).m_panel)
835 #define bli_obj_panel_width( obj ) \
836 \
837 ((obj).n_panel)
839 #define bli_obj_panel_dim( obj ) \
840 \
841 ((obj).pd)
843 #define bli_obj_panel_stride( obj ) \
844 \
845 ((obj).ps)
847 // Packed panel info modification
849 #define bli_obj_set_panel_length( m0, obj ) \
850 { \
851 (obj).m_panel = m0; \
852 }
854 #define bli_obj_set_panel_width( n0, obj ) \
855 { \
856 (obj).n_panel = n0; \
857 }
859 #define bli_obj_set_panel_dim( panel_dim, obj ) \
860 { \
861 (obj).pd = panel_dim; \
862 }
864 #define bli_obj_set_panel_stride( panel_stride, obj ) \
865 { \
866 (obj).ps = panel_stride; \
867 }
871 // -- Miscellaneous object macros --
873 // Make a special alias (shallow copy) that does not overwrite pack_mem
874 // entry.
876 #define bli_obj_alias_for_packing( a, b ) \
877 { \
878 bli_obj_init_basic_shallow_copy_of( a, b ); \
879 }
881 // Make a full alias (shallow copy), including pack_mem and friends
883 #define bli_obj_alias_to( a, b ) \
884 { \
885 bli_obj_init_full_shallow_copy_of( a, b ); \
886 }
888 // Check if two objects are aliases of one another
890 #define bli_obj_is_alias_of( a, b ) \
891 \
892 ( (b).buffer == (a).buffer )
894 // Create an alias with a trans value applied.
895 // (Note: trans may include a conj component.)
897 #define bli_obj_alias_with_trans( trans, a, b ) \
898 { \
899 bli_obj_alias_to( a, b ); \
900 bli_obj_apply_trans( trans, b ); \
901 }
903 // Create an alias with a conj value applied.
905 #define bli_obj_alias_with_conj( conja, a, b ) \
906 { \
907 bli_obj_alias_to( a, b ); \
908 bli_obj_apply_conj( conja, b ); \
909 }
912 // Initialize object with default properties (info field)
914 #define bli_obj_set_defaults( obj ) \
915 { \
916 (obj).info = 0x0; \
917 (obj).info = (obj).info | BLIS_BITVAL_DENSE | BLIS_BITVAL_GENERAL; \
918 }
921 // Initialize object for packing purposes
922 #ifdef BLIS_ENABLE_C66X_EDMA
923 #define bli_obj_init_pack( obj_p ) \
924 { \
925 mem_t* pack_mem = bli_obj_pack_mem( *obj_p ); \
926 mem_t* dma_mem = bli_obj_dma_mem( *obj_p ); \
927 \
928 bli_mem_set_buffer( NULL, pack_mem ); \
929 bli_mem_set_buffer( NULL, dma_mem ); \
930 bli_edma_handle_set_NULL( *obj_p ); \
931 }
933 #else
934 #define bli_obj_init_pack( obj_p ) \
935 { \
936 mem_t* pack_mem = bli_obj_pack_mem( *obj_p ); \
937 \
938 bli_mem_set_buffer( NULL, pack_mem ); \
939 }
940 #endif
943 // Release object's pack (and cast) memory entries back to memory manager
945 #define bli_obj_release_pack( obj_p , cntl) \
946 { \
947 mem_t* pack_mem = bli_obj_pack_mem( *(obj_p) ); \
948 if ( bli_mem_is_alloc( pack_mem ) && cntl != NULL) \
949 bli_mem_release( pack_mem ); \
950 }
954 // Submatrix/scalar buffer acquisition
956 #define BLIS_CONSTANT_SLOT_SIZE BLIS_MAX_TYPE_SIZE
957 #define BLIS_CONSTANT_SIZE ( 5 * BLIS_CONSTANT_SLOT_SIZE )
959 #define bli_obj_buffer_for_const( dt, obj ) \
960 \
961 ( void* )( \
962 ( ( char* )( (obj).buffer ) ) + dt * BLIS_CONSTANT_SLOT_SIZE \
963 )
965 #define bli_obj_buffer_at_off( obj ) \
966 \
967 ( void* )( \
968 ( ( char* )( (obj).buffer ) ) + ( dim_t )(obj).elem_size * \
969 ( (obj).offn * (obj).cs + \
970 (obj).offm * (obj).rs ) \
971 )
973 #define bli_obj_buffer_for_1x1( dt, obj ) \
974 \
975 ( void* )( bli_obj_is_const( obj ) ? ( bli_obj_buffer_for_const( dt, obj ) ) \
976 : ( bli_obj_buffer_at_off( obj ) ) \
977 )
980 // Swap objects
982 #define bli_obj_swap( a, b ) \
983 { \
984 obj_t t; \
985 t = b; b = a; a = t; \
986 }
989 // Swap object pointers
991 #define bli_obj_swap_pointers( a, b ) \
992 { \
993 obj_t* t; \
994 t = b; b = a; a = t; \
995 }
998 // If a transposition is needed, induce one: swap dimensions, increments
999 // and offsets, and then clear the trans bit.
1001 #define bli_obj_induce_trans( obj ) \
1002 { \
1003 { \
1004 dim_t m = bli_obj_length( obj ); \
1005 dim_t n = bli_obj_width( obj ); \
1006 inc_t rs = bli_obj_row_stride( obj ); \
1007 inc_t cs = bli_obj_col_stride( obj ); \
1008 dim_t offm = bli_obj_row_offset( obj ); \
1009 dim_t offn = bli_obj_col_offset( obj ); \
1010 doff_t diag_off = bli_obj_diag_offset( obj ); \
1011 \
1012 bli_obj_set_dims( n, m, obj ); \
1013 bli_obj_set_incs( cs, rs, obj ); \
1014 bli_obj_set_offs( offn, offm, obj ); \
1015 bli_obj_set_diag_offset( -diag_off, obj ); \
1016 \
1017 if ( bli_obj_is_upper_or_lower( obj ) ) \
1018 bli_obj_toggle_uplo( obj ); \
1019 \
1020 /* Note that this macro DOES NOT touch the transposition bit! If
1021 the calling code is using this macro to handle an object whose
1022 transposition bit is set prior to computation, that code needs
1023 to manually clear or toggle the bit, via
1024 bli_obj_set_onlytrans() or bli_obj_toggle_trans(),
1025 respectively. */ \
1026 } \
1027 }
1029 // Sometimes we need to "reflect" a partition because the data we want is
1030 // actually stored on the other side of the diagonal. The nuts and bolts of
1031 // this macro look a lot like an induced transposition, except that the row
1032 // and column strides are left unchanged (which, of course, drastically
1033 // changes the effect of the macro).
1035 #define bli_obj_reflect_about_diag( obj ) \
1036 { \
1037 { \
1038 dim_t m = bli_obj_length( obj ); \
1039 dim_t n = bli_obj_width( obj ); \
1040 dim_t offm = bli_obj_row_offset( obj ); \
1041 dim_t offn = bli_obj_col_offset( obj ); \
1042 doff_t diag_off = bli_obj_diag_offset( obj ); \
1043 \
1044 bli_obj_set_dims( n, m, obj ); \
1045 bli_obj_set_offs( offn, offm, obj ); \
1046 bli_obj_set_diag_offset( -diag_off, obj ); \
1047 \
1048 bli_obj_toggle_trans( obj ); \
1049 } \
1050 }
1052 #endif