1function test19b(fulltest)
2%TEST19B test GrB_assign and GrB_*_setElement with many pending operations
3
4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
5% SPDX-License-Identifier: Apache-2.0
6
7fprintf ('\ntest19b: GrB_assign and setElement, many pending computations\n') ;
8
9debug_status = stat ;
10if (debug_status)
11    % turn off malloc debugging for this test
12    debug_off
13end
14
15if (nargin < 1)
16    fulltest = 0 ;
17end
18if (fulltest)
19    nt = 3000 ;
20else
21    nt = 2000 ;
22end
23
24for problem = 0:2
25
26    clear Work Work2
27    switch (problem)
28        case 0
29            Corig = sparse (5,5) ;
30            d = 1 ;
31            ntrials = 100 ;
32        case 1
33            Corig = sprandn (10,20,0.1) ;
34            d = 0.3 ;
35            ntrials = nt ;
36        case 2
37            Corig = sparse (rand (10, 20)) ;
38            d = 0.3 ;
39            ntrials = nt ;
40    end
41
42    rng ('default') ;
43    [m n] = size (Corig) ;
44    fprintf ('problem %d: C is %d-by-%d, # assign/setElement to do: %d\n', ...
45        problem, m, n, ntrials) ;
46
47    if (problem > 0)
48        fprintf ('... please wait\n') ;
49    end
50
51    for k = 1:ntrials
52
53        c = randi (10,1) ;
54        if (c == 10)
55            d = struct ('outp', 'replace') ;
56        elseif (c == 9)
57            d = struct ('outp', 'replace', 'mask', 'complement') ;
58        elseif (c == 8)
59            d = struct ('mask', 'complement') ;
60        else
61            d = [ ] ;
62        end
63
64        c = randi (3,1) ;
65        switch (c)
66            case 1
67                accum = '' ;
68            case 2
69                accum = 'plus' ;
70            case 3
71                accum = 'second' ;
72        end
73
74        kind = 0 ;
75        c = randi (12,1) ;
76        if (c < 8)
77            ni = randi (3,1) ;
78            nj = randi (3,1) ;
79            J = randperm (n, nj) ;
80            I = randperm (m, ni) ;
81            A = sprand (ni, nj, 0.3) ;
82            scalar = 0 ;
83        elseif (c == 8)
84            % scalar expansion
85            ni = 2 ;
86            nj = 2 ;
87            J = randperm (n, nj) ;
88            I = randperm (m, ni) ;
89            A = sparse (rand (1)) ;
90            scalar = 1 ;
91        elseif (c == 9)
92            ni = 1 ;
93            nj = 1 ;
94            I = randperm (m,1) ;
95            J = randperm (n,1) ;
96            A = sparse (rand (1)) ;
97            scalar = 0 ;
98        elseif (c == 10)
99            ni = 2 ;
100            nj = 2 ;
101            I = randperm (m,2) ;
102            J = randperm (n,2) ;
103            A = sparse (rand (2)) ;
104            scalar = 0 ;
105        elseif (c == 11)
106            % column assign
107            ni = randi (3,1) ;
108            nj = 1 ;
109            kind = 1 ;
110            J = randperm (n, 1) ;
111            I = randperm (m, ni) ;
112            A = sprand (ni, 1, 0.3) ;
113            scalar = 0 ;
114        else % (c == 12)
115            % row assign: A is a single *column* vector
116            ni = 1 ;
117            nj = randi (3,1) ;
118            kind = 2 ;
119            J = randperm (n, nj) ;
120            I = randperm (m, 1) ;
121            A = sprand (nj, 1, 0.3) ;
122            scalar = 0 ;
123        end
124
125        c = randi (2,1) ;
126        switch (c)
127            case 1
128                % no mask
129                Mask = [ ] ;
130            case 2
131                density = rand (1) ;
132                if (density < 0.8)
133                    if (kind == 0)
134                        % mask same size as C: Matrix or Vector assign
135                        Mask = (sprand (m, n, 0.3) ~= 0) ;
136                    elseif (kind == 1)
137                        % mask same size as C(:,j): column assign
138                        Mask = (sprand (m, 1, 0.3) ~= 0) ;
139                    else % (kind == 2)
140                        % mask same size as C(i,:)': row assign
141                        Mask = (sprand (n, 1, 0.3) ~= 0) ;
142                    end
143                else
144                    if (kind == 0)
145                        % mask same size as C: Matrix or Vector assign
146                        Mask = sparse (true (m, n)) ;
147                    elseif (kind == 1)
148                        % mask same size as C(:,j): column assign
149                        Mask = sparse (true (m, 1)) ;
150                    else % (kind == 2)
151                        % mask same size as C(i,:)': row assign
152                        Mask = sparse (true (n, 1)) ;
153                    end
154
155                end
156        end
157
158        Work (k).A = A ;
159        Work (k).I = I ;
160        Work (k).J = J ;
161        Work (k).Mask = Mask ;
162        Work (k).accum = accum ;
163        Work (k).desc = d ;
164        Work (k).scalar = scalar ;
165        Work (k).kind = kind ;
166
167        Work2 (k).A = A ;
168        Work2 (k).I = uint64 (I-1) ;
169        Work2 (k).J = uint64 (J-1) ;
170        Work2 (k).Mask = Mask ;
171        Work2 (k).accum = accum ;
172        Work2 (k).desc = d ;
173        Work2 (k).kind = kind ;
174
175    end
176
177    C3 = Corig ;
178
179    for k = 1:ntrials
180        J = Work (k).J ;
181        I = Work (k).I ;
182        A = Work (k).A ;
183        M = Work (k).Mask ;
184        accum = Work (k).accum ;
185        d = Work (k).desc ;
186        scalar = Work (k).scalar ;
187        kind = Work (k).kind ;
188        if (kind == 0)
189            % matrix/vector assign
190            C3 = GB_spec_assign (C3, M, accum, A, I, J, d, scalar) ;
191        elseif (kind == 1)
192            % col assign
193            C3 = GB_spec_Col_assign (C3, M, accum, A, I, J, d) ;
194        else % (kind == 2)
195            % row assign
196            C3 = GB_spec_Row_assign (C3, M, accum, A, I, J, d) ;
197        end
198    end
199
200    % default sparsity
201    C2 = GB_mex_assign (Corig, Work2) ;
202    GB_spec_compare (C2, C3) ;
203
204    % with sparsity control
205    for s = 0:15
206        C2 = GB_mex_assign (Corig, Work2, [s s]) ;
207        GB_spec_compare (C2, C3) ;
208    end
209
210    % default sparsity but both C and M sparse
211    C2 = GB_mex_assign (Corig, Work2, [2 2]) ;
212    GB_spec_compare (C2, C3) ;
213
214    % default sparsity but C sparse and M bitmap/full
215    C2 = GB_mex_assign (Corig, Work2, [2 8]) ;
216    GB_spec_compare (C2, C3) ;
217
218end
219
220if (debug_status)
221    debug_on
222end
223fprintf ('\ntest19b: all tests passed\n') ;
224
225