1 //------------------------------------------------------------------------------ 2 // GB_AxB_saxpy3_fineGus_phase2: C=A*B, saxpy3 method, 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)=A*B(:,j) 14 //-------------------------------------------------------------------------- 15 16 // Hf [i] is initially 0. 17 // 0 -> 3 : to lock, if i seen for first time 18 // 2 -> 3 : to lock, if i seen already 19 // 3 -> 2 : to unlock; now i has been seen 20 21 for ( ; pB < pB_end ; pB++) // scan B(:,j) 22 { 23 GB_GET_B_kj_INDEX ; // get index k of B(k,j) 24 GB_GET_A_k ; // get A(:,k) 25 if (aknz == 0) continue ; 26 GB_GET_B_kj ; // bkj = B(k,j) 27 // scan A(:,k) 28 for (int64_t pA = pA_start ; pA < pA_end ; pA++) 29 { 30 GB_GET_A_ik_INDEX ; // get index i of A(i,k) 31 GB_MULT_A_ik_B_kj ; // t = A(i,k) * B(k,j) 32 int8_t f ; 33 34 #if GB_IS_ANY_MONOID 35 36 //-------------------------------------------------------------- 37 // C(i,j) += t ; with the ANY monoid 38 //-------------------------------------------------------------- 39 40 GB_ATOMIC_READ 41 f = Hf [i] ; // grab the entry 42 if (f == 2) continue ; // check if already updated 43 GB_ATOMIC_WRITE_HX (i, t) ; // Hx [i] = t 44 45 #else 46 47 //-------------------------------------------------------------- 48 // C(i,j) += t ; with all other monoids 49 //-------------------------------------------------------------- 50 51 #if GB_HAS_ATOMIC 52 53 // if C(i,j) is already present (f==2), and the monoid can 54 // be done atomically, then do the atomic update. No need 55 // to modify Hf [i]. 56 GB_ATOMIC_READ 57 f = Hf [i] ; // grab the entry 58 if (f == 2) // if true, update C(i,j) 59 { 60 GB_ATOMIC_UPDATE_HX (i, t) ; // Hx [i] += t 61 continue ; // C(i,j) has been updated 62 } 63 64 #endif 65 66 do // lock the entry 67 { 68 // do this atomically: 69 // { f = Hf [i] ; Hf [i] = 3 ; } 70 GB_ATOMIC_CAPTURE_INT8 (f, Hf [i], 3) ; 71 } while (f == 3) ; // lock owner gets f=0 or 2 72 if (f == 0) 73 { 74 // C(i,j) is a new entry 75 GB_ATOMIC_WRITE_HX (i, t) ; // Hx [i] = t 76 } 77 else // f == 2 78 { 79 // C(i,j) already appears in C(:,j) 80 GB_ATOMIC_UPDATE_HX (i, t) ; // Hx [i] += t 81 } 82 83 #endif 84 85 GB_ATOMIC_WRITE 86 Hf [i] = 2 ; // flag/unlock the entry 87 } 88 } 89 } 90 91