source: CIVL/examples/focus/development/csr_add_driver_focus.c

main
Last change on this file was 6d5b8a3, checked in by Alex Wilton <awilton@…>, 8 months ago

Cleaned up focus examples. Enhanced focus window performance. Fixed a pretty print bug

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5993 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[5f01b84]1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <civlc.cvh>
5#include <pointer.cvh>
6
7#pragma CIVL ACSL
8
9typedef struct
10{
11 int* i;
12 int* j;
13 int num_rows;
14 int num_cols;
15 int num_nonzeros;
16 float* data;
17} hypre_CSRMatrix;
18
19$input int M;
20$assume(1 <= M);
21$input int N = 1;
22
23$input float A[M][N], B[M][N];
24
25int main(int argc, char* argv[])
26{
27 /* Initialize csr_A.i.
28 */
29 hypre_CSRMatrix csr_A;
30 csr_A.num_rows = M;
31 csr_A.num_cols = N;
32 csr_A.i = (int*) malloc(sizeof(int) * (csr_A.num_rows + 1));
33 /* Fill out the data of csr_A.i
34 */
35 csr_A.i[0] = 0;
36 //@ focus R;
37 /*@ loop invariant csr_A.i[0] == 0;
38 @ loop invariant \forall int x; \forall int y; 0 <= x && x < y && y <= i ==> csr_A.i[x] <= csr_A.i[y] && csr_A.i[y] <= csr_A.i[x] + ((y-x)*N);
39 @*/
40 for (int i = 0; i < M; i++) {
41 csr_A.i[i+1] = csr_A.i[i];
42 for (int j = 0; j < N; j++) {
43 if (A[i][j] != 0.0) {
44 csr_A.i[i+1]++;
45 }
46 }
47 }
48
49 csr_A.num_nonzeros = csr_A.i[M];
50 csr_A.data = NULL;
51 csr_A.j = NULL;
52 if (csr_A.num_nonzeros)
53 {
54 csr_A.data = (float*) malloc(sizeof(float) * csr_A.num_nonzeros);
55 memset(csr_A.data, 0, sizeof(float) * csr_A.num_nonzeros);
56 csr_A.j = (int*) malloc(sizeof(int) * csr_A.num_nonzeros);
57 memset(csr_A.j, 0, sizeof(int) * csr_A.num_nonzeros);
58 }
59
60
61 /* Setup data of csr_A
62 */
63 int k = 0;
64 //@ focus R;
65 //@ loop invariant k == csr_A.i[i];
66 for (int i = 0; i < M; ++i)
67 {
68 for (int j = 0; j < N; ++j)
69 {
70 if (A[i][j] != 0.0)
71 {
72 csr_A.data[k] = A[i][j];
73 csr_A.j[k] = j;
74 ++k;
75 }
76 }
77 }
78
79
80 /* Initialize csr_B
81 */
82 hypre_CSRMatrix csr_B;
83 csr_B.num_rows = M;
84 csr_B.num_cols = N;
85 csr_B.i = (int*) malloc(sizeof(int) * (csr_B.num_rows + 1));
86 /* Fill out the data of csr_B.i
87 */
88 csr_B.i[0] = 0;
89 //@ focus R;
90 /*@ loop invariant csr_B.i[0] == 0;
91 @ loop invariant \forall int x; \forall int y; 0 <= x && x < y && y <= i ==> csr_B.i[x] <= csr_B.i[y] && csr_B.i[y] <= csr_B.i[x] + ((y-x)*N);
92 @*/
93 for (int i = 0; i < M; i++) {
94 csr_B.i[i+1] = csr_B.i[i];
95 for (int j = 0; j < N; j++) {
96 if (B[i][j] != 0.0) {
97 csr_B.i[i+1]++;
98 }
99 }
100 }
101
102 csr_B.num_nonzeros = csr_B.i[M];
103 csr_B.data = NULL;
104 csr_B.j = NULL;
105 if (csr_B.num_nonzeros)
106 {
107 csr_B.data = (float*) malloc(sizeof(float) * csr_B.num_nonzeros);
108 memset(csr_B.data, 0, sizeof(float) * csr_B.num_nonzeros);
109 csr_B.j = (int*) malloc(sizeof(int) * csr_B.num_nonzeros);
110 memset(csr_B.j, 0, sizeof(int) * csr_B.num_nonzeros);
111 }
112
113
114 /* Setup data of csr_B.
115 */
116 k = 0;
117 //@ focus R;
118 /*@ loop invariant k == csr_B.i[i];
119 @*/
120 for (int i = 0; i < M; ++i)
121 {
122 for (int j = 0; j < N; ++j)
123 {
124 if (B[i][j] != 0.0)
125 {
126 csr_B.data[k] = B[i][j];
127 csr_B.j[k] = j;
128 ++k;
129 }
130 }
131 }
132
133
134 /** Alg start **/
135 hypre_CSRMatrix csr_C;
136 int* marker;
137
138 marker = (int*) malloc(sizeof(int) * N);
139 memset(marker, 0, sizeof(int) * N);
140
141 csr_C.i = (int*) malloc(sizeof(int) * (M+1));
142 memset(csr_C.i, 0, sizeof(int) * (M+1));
143
144 /* Initialize elems of marker to -1.
145 */
146 for (int ia = 0; ia < N; ia++)
147 {
148 marker[ia] = -1;
149 }
150
151
152 /* Count number of nonzeros of C
153 */
154 int num_nonzeros = 0;
155 csr_C.i[0] = 0;
156 //@ focus R;
157 /*@ loop invariant num_nonzeros == csr_C.i[ic];
158 @ loop invariant csr_C.i[0] == 0;
159 @ loop invariant \forall int x; \forall int y; 0 <= x && x < y && y <= ic ==>
160 @ csr_C.i[x] <= csr_C.i[y] &&
161 @ csr_C.i[y] <= csr_C.i[x] + ((y-x)*N);
162 @ loop invariant \forall int t; 0 <= t && t < N ==> marker[t] < ic;
163 @*/
164 for (int ic = 0; ic < M; ic++)
165 {
166 for (int ia = csr_A.i[ic]; ia < csr_A.i[ic+1]; ia++)
167 {
168 int jcol = csr_A.j[ia];
169 marker[jcol] = ic;
170 num_nonzeros++;
171 }
172 for (int ib = csr_B.i[ic]; ib < csr_B.i[ic+1]; ib++)
173 {
174 int jcol = csr_B.j[ib];
175 if (marker[jcol] != ic)
176 {
177 marker[jcol] = ic;
178 num_nonzeros++;
179 }
180 }
181 csr_C.i[ic+1] = num_nonzeros;
182 }
183
184
185 /* Initialize csr_C.
186 */
187 csr_C.num_rows = M;
188 csr_C.num_cols = N;
189 csr_C.num_nonzeros = num_nonzeros;
190 csr_C.data = NULL;
191 csr_C.j = NULL;
192 if (csr_C.num_nonzeros)
193 {
194 csr_C.data = (float*) malloc(sizeof(float) * csr_C.num_nonzeros);
195 memset(csr_C.data, 0, sizeof(float) * csr_C.num_nonzeros);
196 csr_C.j = (int*) malloc(sizeof(int) * csr_C.num_nonzeros);
197 memset(csr_C.j, 0, sizeof(int) * csr_C.num_nonzeros);
198 }
199
200
201 /* Initialize elements of marker to -1.
202 */
203 for (int ia = 0; ia < N; ia++)
204 {
205 marker[ia] = -1;
206 }
207
208
209 int pos = 0;
210 //@ focus R;
211 /*@ loop invariant pos == csr_C.i[ic];
212 @ loop invariant \forall int t; 0 <= t && t < N ==> marker[t] < pos;
213 @*/
214 for (int ic = 0; ic < M; ic++)
215 {
216 for (int ia = csr_A.i[ic]; ia < csr_A.i[ic+1]; ia++)
217 {
218 int jcol = csr_A.j[ia];
219 csr_C.j[pos] = jcol;
220 csr_C.data[pos] = csr_A.data[ia];
221 marker[jcol] = pos;
222 pos++;
223 }
224 for (int ib = csr_B.i[ic]; ib < csr_B.i[ic+1]; ib++)
225 {
226 int jcol = csr_B.j[ib];
227 if (marker[jcol] < csr_C.i[ic])
228 {
229 csr_C.j[pos] = jcol;
230 csr_C.data[pos] = csr_B.data[ib];
231 marker[jcol] = pos;
232 pos++;
233 }
234 else
235 {
236 csr_C.data[marker[jcol]] += csr_B.data[ib];
237 }
238 }
239 }
240 free(marker);
241 marker = NULL;
242 /** Alg end **/
243
244
245 /* Initialize elements of impl_C to 0.
246 */
247 float impl_C[M][N];
248 //@ focus R;
249 for (int i = 0; i < M; ++i)
250 {
251 for (int j = 0; j < N; ++j)
252 {
253 impl_C[i][j] = 0.0;
254 }
255 }
256
257
258 /* Merge in nonzero elements of csr_C into impl_C.
259 */
260 //@ focus R;
261 for (int i = 0; i < M; ++i)
262 {
263 int start = csr_C.i[i], end = csr_C.i[i+1];
264 for (int k = start; k < end; ++k)
265 {
266 impl_C[i][csr_C.j[k]] = csr_C.data[k];
267 }
268 }
269
270 /* Set up spec_C to be A + B.
271 */
272 float spec_C[M][N];
273 //@ focus R;
274 for (int i = 0; i < M; ++i)
275 {
276 for (int j = 0; j < N; ++j)
277 {
278 spec_C[i][j] = A[i][j] + B[i][j];
279 }
280 }
281
282 //@ focus R;
283 $assert($forall(int i:0..M-1;int j:0..N-1) spec_C[i][j] == impl_C[i][j]);
284}
Note: See TracBrowser for help on using the repository browser.