1function gbtest74 2%GBTEST74 test bitwise operators 3 4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 5% SPDX-License-Identifier: GPL-3.0-or-later 6 7int_types = { 8'int8' 9'int16' 10'int32' 11'int64' 12'uint8' 13'uint16' 14'uint32' 15'uint64' } ; 16 17int_nbits = [ 8, 16, 32, 64, 8, 16, 32, 64 ] ; 18 19rng ('default') ; 20 21for k = 1:8 22 23 type = int_types {k} ; 24 nbits = int_nbits (k) ; 25 fprintf ('\n%s', type) ; 26 27 for trial = 1:40 28 fprintf ('.') ; 29 30 % dense case 31 32 imax = double (intmax (type) / 4) ; 33 A = cast (imax * rand (4), type) ; 34 B = cast ((nbits-1) * rand (4), type) + 1 ; 35 A2 = GrB (A) ; 36 B2 = GrB (B) ; 37 V = rand (4) > 0.5 ; 38 39 C1 = bitget (A, B) ; 40 C2 = bitget (A2, B2) ; 41 assert (isequal (C1, C2)) ; 42 43 C1 = bitset (A, B) ; 44 C2 = bitset (A2, B2) ; 45 assert (isequal (C1, C2)) ; 46 47 C1 = bitset (A, B, 1) ; 48 C2 = bitset (A2, B2, 1) ; 49 assert (isequal (C1, C2)) ; 50 51 C1 = bitset (A, B, 0) ; 52 C2 = bitset (A2, B2, 0) ; 53 assert (isequal (C1, C2)) ; 54 55 C1 = bitset (A, B, V) ; 56 C2 = bitset (A2, B2, V) ; 57 assert (isequal (C1, C2)) ; 58 59 for a = 0:3 60 for b = 1:4 61 C1 = bitset (a, b, 1) ; 62 C2 = bitset (a, b, GrB (1)) ; 63 assert (isequal (C1, C2)) ; 64 end 65 end 66 67 C1 = bitset (a, B, 1) ; 68 C2 = bitset (a, B, GrB (1)) ; 69 assert (isequal (C1, C2)) ; 70 71 C1 = bitand (A, B) ; 72 C2 = bitand (A2, B2) ; 73 assert (isequal (C1, C2)) ; 74 75 C1 = bitor (A, B) ; 76 C2 = bitor (A2, B2) ; 77 assert (isequal (C1, C2)) ; 78 79 C1 = bitxor (A, B) ; 80 C2 = bitxor (A2, B2) ; 81 assert (isequal (C1, C2)) ; 82 83 C1 = bitcmp (A) ; 84 C2 = bitcmp (A2) ; 85 assert (isequal (C1, C2)) ; 86 87 % dense double case, with assumedtype 88 A = double (A) ; 89 B = double (B) ; 90 A2 = GrB (A) ; 91 B2 = GrB (B) ; 92 93 C1 = bitget (A, B, type) ; 94 C2 = bitget (A2, B2, type) ; 95 assert (isequal (C1, C2)) ; 96 97 C1 = bitset (A, B, type) ; 98 C2 = bitset (A2, B2, type) ; 99 assert (isequal (C1, C2)) ; 100 101 C1 = bitset (A, B, 1, type) ; 102 C2 = bitset (A2, B2, 1, type) ; 103 assert (isequal (C1, C2)) ; 104 105 C1 = bitset (A, B, 0, type) ; 106 C2 = bitset (A2, B2, 0, type) ; 107 assert (isequal (C1, C2)) ; 108 109 C1 = bitset (A, B, V, type) ; 110 C2 = bitset (A2, B2, V, type) ; 111 assert (isequal (C1, C2)) ; 112 113 C1 = bitand (A, B, type) ; 114 C2 = bitand (A2, B2, type) ; 115 assert (isequal (C1, C2)) ; 116 117 C1 = bitor (A, B, type) ; 118 C2 = bitor (A2, B2, type) ; 119 assert (isequal (C1, C2)) ; 120 121 C1 = bitxor (A, B, type) ; 122 C2 = bitxor (A2, B2, type) ; 123 assert (isequal (C1, C2)) ; 124 125 if (~ispc) 126 % MATLAB R2019b on Windows has a bug here, so this 127 % test is skipped. Here is the pure MATLAB test: 128 % 129 % ver 130 % A = 1287128410976072704 131 % fprintf ('A: %30o\n', A) ; 132 % C = bitcmp (A, 'uint64') 133 % fprintf ('bitcmp(A): %30o\n', C) ; 134 % 135 % printing input and output in octal, with spaces 136 % added for readability: 137 % 138 % A: 0 107 346 307 414 442 532 000 139 % 140 % Linux bitcmp(A): 1 670 431 470 363 335 244 000 141 % Win. bitcmp(A): 1 670 431 470 363 335 250 000 142 % 143 % GraphBLAS obtains the Linux result on all 144 % platforms, including Windows. 145 % 146 % Expanding the last 5 octal digits into binary, 147 % with a space where I think the double mantissa 148 % runs about of bits when converted to uint64. 149 % 150 % A: 32000 = 011.01 0.000.000.000 151 % 152 % Linux bitcmp(A): 44000 = 100.10 0.000.000.000 153 % Win. bitcmp(A): 50000 = 101.00 0.000.000.000 154 % 155 % Note that A starts out as double, so it only 156 % has about 53 bits of mantissa. I would expect 157 % the result to have 10 or 11 trailing zeros, as a 158 % result. On Linux (and also GraphBLAS on Windows), 159 % bitcmp(A) has 10 trailing zero bits, and the 160 % remaining bits are properly complemented. 161 % 162 % On MATLAB in Windows, the result is not comprehensible. 163 164 C1 = bitcmp (A, type) ; 165 C2 = bitcmp (A2, type) ; 166 assert (isequal (C1, C2)) ; 167 end 168 169 C1 = bitshift (A, B, type) ; 170 C2 = bitshift (A2, B2, type) ; 171 assert (isequal (C1, C2)) ; 172 173 % sparse case 174 175 A = sprand (10, 10, 0.5) * imax ; 176 Afull = cast (full (A), type) ; 177 % B ranges in value from 0 to 8 178 B = round (sprand (10, 10, 0.5) * nbits) ; 179 Bfull = cast (full (B), type) ; 180 A2 = GrB.prune (GrB (Afull)) ; 181 B2 = GrB.prune (GrB (Bfull)) ; 182 183 C1 = bitxor (Afull, Bfull) ; 184 C2 = bitxor (A2, B2) ; 185 assert (isequal (C1, full (C2))) ; 186 187 C1 = bitand (Afull, Bfull) ; 188 C2 = bitand (A2, B2) ; 189 assert (isequal (C1, full (C2))) ; 190 191 C1 = bitor (Afull, Bfull) ; 192 C2 = bitor (A2, B2) ; 193 assert (isequal (C1, full (C2))) ; 194 195 C1 = bitshift (Afull, Bfull) ; 196 C2 = bitshift (A2, B2) ; 197 assert (isequal (C1, full (C2))) ; 198 199 C1 = bitcmp (Afull) ; 200 C2 = bitcmp (A2) ; 201 assert (isequal (C1, full (C2))) ; 202 203 % the MATLAB bitget and bitset cannot be used for B == 0, 204 % so find where Bfull is explicitly zero. 205 B_is_nonzero = (B ~= 0) ; 206 A_ok = Afull (B_is_nonzero) ; 207 B_ok = Bfull (B_is_nonzero) ; 208 X1 = bitget (A_ok, B_ok) ; 209 210 % the GraphBLAS bitget and bitset can tolerate B == 0 211 C2 = full (bitget (A2, B2)) ; 212 X2 = C2 (B_is_nonzero) ; 213 assert (isequal (X1, X2)) 214 215 X1 = bitset (A_ok, B_ok) ; 216 C2 = full (bitset (A2, B2)) ; 217 X2 = C2 (B_is_nonzero) ; 218 assert (isequal (X1, X2)) 219 220 X1 = bitset (A_ok, B_ok, 0) ; 221 C2 = full (bitset (A2, B2, 0)) ; 222 X2 = C2 (B_is_nonzero) ; 223 assert (isequal (X1, X2)) 224 225 % dense case with any A and B 226 227 imax = double (intmax (type)) ; 228 imin = double (intmin (type)) ; 229 A1 = GrB ((imax-imin) * rand (4) - imin, type) ; 230 B1 = GrB ((imax-imin) * rand (4) - imin, type) ; 231 A = cast (A1, type) ; 232 B = cast (B1, type) ; 233 A2 = GrB.prune (GrB (A1)) ; 234 B2 = GrB.prune (GrB (B1)) ; 235 236 C1 = bitxor (A, B) ; 237 C2 = bitxor (A1, B1) ; 238 assert (isequal (C1, full (C2))) ; 239 240 C1 = bitand (A, B) ; 241 C2 = bitand (A2, B2) ; 242 assert (isequal (C1, full (C2))) ; 243 244 C1 = bitor (A, B) ; 245 C2 = bitor (A2, B2) ; 246 assert (isequal (C1, full (C2))) ; 247 248 if (verLessThan ('matlab', '9.7') && isequal (type, 'int64')) 249 % skip this test (older MATLAB versions have a bug in bitshift) 250 else 251 C1 = bitshift (A, B) ; 252 C2 = bitshift (A2, B2) ; 253 assert (isequal (C1, full (C2))) ; 254 end 255 256 C1 = bitcmp (A) ; 257 C2 = bitcmp (A2) ; 258 assert (isequal (C1, full (C2))) ; 259 260 end 261end 262 263fprintf ('\ngbtest74: all tests passed\n') ; 264 265