1 //------------------------------------------------------------------------------ 2 // GB_AxB_saxpy3_fineGus_notM_phase2: C<!M>=A*B, fine Gustavson, phase2 3 //------------------------------------------------------------------------------ 4 5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 6 // SPDX-License-Identifier: Apache-2.0 7 8 //------------------------------------------------------------------------------ 9 10 { 11 12 //-------------------------------------------------------------------------- 13 // phase2: fine Gustavson task, C(:,j)<!M(:,j)>=A*B(:,j) 14 //-------------------------------------------------------------------------- 15 16 // Hf [i] is 0 if M(i,j) not present or M(i,j)=0. 17 // 0 -> 1 : has already been done in phase0 if M(i,j)=1 18 19 // 1 -> 1 : to ignore, if M(i,j)=1 20 // 0 -> 3 : to lock, if i seen for first time 21 // 2 -> 3 : to lock, if i seen already 22 // 3 -> 2 : to unlock; now i has been seen 23 24 for ( ; pB < pB_end ; pB++) // scan B(:,j) 25 { 26 GB_GET_B_kj_INDEX ; // get index k of B(k,j) 27 GB_GET_A_k ; // get A(:,k) 28 if (aknz == 0) continue ; 29 GB_GET_B_kj ; // bkj = B(k,j) 30 // scan A(:,k) 31 for (int64_t pA = pA_start ; pA < pA_end ; pA++) 32 { 33 GB_GET_A_ik_INDEX ; // get index i of A(i,k) 34 GB_MULT_A_ik_B_kj ; // t = A(i,k) * B(k,j) 35 int8_t f ; 36 37 #if GB_IS_ANY_MONOID 38 39 //-------------------------------------------------------------- 40 // ANY monoid 41 //-------------------------------------------------------------- 42 43 // lock state (3) not needed 44 // 0: not seen: update with new value, f becomes 2 45 // 1: masked, do nothing, f stays 1 46 // 2: already updated, do nothing, f stays 2 47 // 3: state not used, f can be 2 48 GB_ATOMIC_READ 49 f = Hf [i] ; 50 if (!f) 51 { 52 GB_ATOMIC_WRITE 53 Hf [i] = 2 ; 54 GB_ATOMIC_WRITE_HX (i, t) ; // Hx [i] = t 55 } 56 57 58 #else 59 60 //-------------------------------------------------------------- 61 // all other monoids 62 //-------------------------------------------------------------- 63 64 GB_ATOMIC_READ 65 f = Hf [i] ; // grab the entry 66 67 #if GB_HAS_ATOMIC 68 { 69 // the monoid can be done with a single atomic update 70 if (f == 2) // if true, update C(i,j) 71 { 72 GB_ATOMIC_UPDATE_HX (i, t) ; // Hx [i] += t 73 continue ; // C(i,j) has been updated 74 } 75 } 76 #endif 77 78 if (f == 1) continue ; // M(i,j)=1; ignore C(i,j) 79 do // lock the entry 80 { 81 // do this atomically: 82 // { f = Hf [i] ; Hf [i] = 3 ; } 83 GB_ATOMIC_CAPTURE_INT8 (f, Hf [i], 3) ; 84 } while (f == 3) ; // lock owner of gets f=0 or 2 85 if (f == 0) 86 { 87 // C(i,j) is a new entry 88 GB_ATOMIC_WRITE_HX (i, t) ; // Hx [i] = t 89 } 90 else // f == 2 91 { 92 // C(i,j) already seen 93 GB_ATOMIC_UPDATE_HX (i, t) ; // Hx [i] += t 94 } 95 GB_ATOMIC_WRITE 96 Hf [i] = 2 ; // unlock the entry 97 98 #endif 99 } 100 } 101 } 102 103