1function test21(fulltest)
2%TEST21 test GxB_subassign
3
4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
5% SPDX-License-Identifier: Apache-2.0
6
7if (nargin < 1)
8    % do a short test, by default
9    fulltest = 0 ;
10end
11
12[binops, ~, ~, types, ~, ~] = GB_spec_opsall ;
13accum_ops = binops.all ;
14types = types.real ;
15
16dn = struct ;
17dt = struct ( 'inp0', 'tran' ) ;
18
19if (fulltest)
20    fprintf ('\ntest21 --------------exhaustive test of GB_mex_subassign\n') ;
21    k1test = 0:length(accum_ops) ;
22else
23    fprintf ('\ntest21 --------------quick test of GB_mex_subassign\n') ;
24    k1test = [ 4 0] ; % Was [4 0 2 7] ;
25end
26
27% try all accum
28for k1 = k1test
29    if (k1 == 0)
30        accum_op = ''  ;
31        ntypes = 1 ;
32    else
33        accum_op = accum_ops {k1}  ;
34        ntypes = length (types) ;
35    end
36    fprintf ('\naccum: [%s]', accum_op) ;
37
38    if (fulltest)
39        k2test = 1:ntypes ;
40    else
41        k2test = 11 ; % Was [1 2 11] ;
42    end
43
44    % try all types
45    for k2 = k2test % 1:ntypes
46    clear accum
47    if (~isempty (accum_op))
48        accum_type = types {k2}  ;
49        accum.opname = accum_op ;
50        accum.optype = accum_type ;
51    else
52        accum = '' ;
53        accum_type = '' ;
54    end
55
56    if (GB_spec_is_positional (accum))
57        continue ;
58    end
59
60    try
61        GB_spec_operator (accum) ;
62    catch
63        continue ;
64    end
65    fprintf (' %s', accum_type) ;
66
67    rng (k1 * 100 + k2, 'v4') ;
68
69    for Mask_complement = [false true]
70
71    if (Mask_complement)
72        dn.mask = 'complement' ;
73        dt.mask = 'complement' ;
74    else
75        dn.mask = 'default' ;
76        dt.mask = 'default' ;
77    end
78
79    for C_replace = [false true]
80
81    if (C_replace)
82        dn.outp = 'replace' ;
83        dt.outp = 'replace' ;
84    else
85        dn.outp = 'default' ;
86        dt.outp = 'default' ;
87    end
88
89    kk3 = randperm (length (types), 1) ;
90
91    % try all matrix types, to test casting
92    for k3 = kk3 % 1:length (types)
93    atype = types {k3}  ;
94
95    % try some matrices
96    for m = [1 10] % Was [1 5 10 ]
97    for n = [1 10] % Was [ 1 5 10 ]
98    for sm = [0 1 5] % Was [ 0 1 5 10 ]
99    if (sm > m)
100        continue
101    end
102    for sn = [0 1 5] % Was [ 0 1 5 10 ]
103    if (sn > n)
104        continue
105    end
106    for scalar = [false true]
107
108    %---------------------------------------
109
110
111    if (sm == 0)
112        I = [ ] ;
113        am = m ;
114    else
115        I = randperm (m,sm) ; % I = I(1:sm);
116        am = sm ;
117    end
118    I0 = uint64 (I-1) ;
119    if (sn == 0)
120        J = [ ] ;
121        an = n ;
122    else
123        J = randperm (n,sn) ; % J = J(1:sn);
124        an = sn ;
125    end
126    J0 = uint64 (J-1) ;
127
128    fprintf ('.') ;
129
130    for A_is_hyper = 0:1
131    for A_is_csc   = 0:1
132    for C_is_hyper = 0:1
133    for C_is_csc   = 0:1
134    for M_is_hyper = 0:1
135    for M_is_csc   = 0:1
136
137    if (scalar)
138        % test scalar expansion
139        % fprintf ('test expansion\n') ;
140        A.matrix = sparse (rand (1)) * 100 ;
141        A.pattern = sparse (logical (true));
142        A.class = atype ;
143        if (A_is_hyper || ~A_is_csc)
144            continue
145        end
146    else
147        A = GB_spec_random (am,an,0.2,100,atype, A_is_csc, A_is_hyper) ;
148    end
149
150    C = GB_spec_random (m,n,0.2,100,atype, C_is_csc, C_is_hyper) ;
151    Mask = GB_random_mask (am,an,0.2, M_is_csc, M_is_hyper) ;
152
153    % C(I,J) = accum (C (I,J),A)
154    % Mask = [ ] ;
155
156    C0 = GB_spec_subassign (C, [ ], accum, A, I, J, dn, scalar);
157    C1 = GB_mex_subassign  (C, [ ], accum, A, I0, J0, dn);
158    GB_spec_compare (C0, C1) ;
159
160    % C(I,J)<Mask> = accum (C (I,J),A)
161    C0 = GB_spec_subassign (C, Mask, accum, A, I, J, dn, scalar);
162    C1 = GB_mex_subassign  (C, Mask, accum, A, I0, J0, dn);
163    GB_spec_compare (C0, C1) ;
164
165    %---------------------------------------
166
167    % C(I,J)<Mask> = accum (C(I,J), A');
168    % note transposing twice
169    clear AT
170    AT.matrix  = A.matrix' ;
171    AT.pattern = A.pattern' ;
172    AT.class = A.class ;
173
174    C0 = GB_spec_subassign (C, [ ], accum, AT, I, J, dt, scalar);
175    C1 = GB_mex_subassign  (C, [ ], accum, AT, I0, J0, dt);
176    GB_spec_compare (C0, C1) ;
177
178    C0 = GB_spec_subassign (C, Mask, accum, AT, I, J, dt, scalar);
179    C1 = GB_mex_subassign  (C, Mask, accum, AT, I0, J0, dt);
180    GB_spec_compare (C0, C1) ;
181
182    %---------------------------------------
183end
184end
185end
186end
187end
188end
189end
190end
191end
192end
193end
194end
195end
196end
197end
198end
199
200fprintf ('\ntest21: all tests passed\n') ;
201
202