Bug Summary

File:gromacs/gmxlib/splitter.c
Location:line 417, column 5
Description:Value stored to 'nsid' is never read

Annotated Source Code

1/*
2 * This file is part of the GROMACS molecular simulation package.
3 *
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
10 *
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
15 *
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 *
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
33 *
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
36 */
37#include "splitter.h"
38
39#ifdef HAVE_CONFIG_H1
40#include <config.h>
41#endif
42
43#include <assert.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include "macros.h"
48#include "mshift.h"
49
50#include "gromacs/utility/fatalerror.h"
51#include "gromacs/utility/smalloc.h"
52
53typedef struct {
54 int atom, sid;
55} t_sid;
56
57static int sid_comp(const void *a, const void *b)
58{
59 t_sid *sa, *sb;
60 int dd;
61
62 sa = (t_sid *)a;
63 sb = (t_sid *)b;
64
65 dd = sa->sid-sb->sid;
66 if (dd == 0)
67 {
68 return (sa->atom-sb->atom);
69 }
70 else
71 {
72 return dd;
73 }
74}
75
76static int mk_grey(egCol egc[], t_graph *g, int *AtomI,
77 int maxsid, t_sid sid[])
78{
79 int j, ng, ai, aj, g0;
80
81 ng = 0;
82 ai = *AtomI;
83
84 g0 = g->at_start;
85 /* Loop over all the bonds */
86 for (j = 0; (j < g->nedge[ai]); j++)
87 {
88 aj = g->edge[ai][j]-g0;
89 /* If there is a white one, make it gray and set pbc */
90 if (egc[aj] == egcolWhite)
91 {
92 if (aj < *AtomI)
93 {
94 *AtomI = aj;
95 }
96 egc[aj] = egcolGrey;
97
98 /* Check whether this one has been set before... */
99 range_check(aj+g0, 0, maxsid)_range_check(aj+g0, 0, maxsid, ((void*)0),"aj+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 99)
;
100 range_check(ai+g0, 0, maxsid)_range_check(ai+g0, 0, maxsid, ((void*)0),"ai+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 100)
;
101 if (sid[aj+g0].sid != -1)
102 {
103 gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 103
, "sid[%d]=%d, sid[%d]=%d, file %s, line %d",
104 ai, sid[ai+g0].sid, aj, sid[aj+g0].sid, __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c", __LINE__104);
105 }
106 else
107 {
108 sid[aj+g0].sid = sid[ai+g0].sid;
109 sid[aj+g0].atom = aj+g0;
110 }
111 ng++;
112 }
113 }
114 return ng;
115}
116
117static int first_colour(int fC, egCol Col, t_graph *g, egCol egc[])
118/* Return the first node with colour Col starting at fC.
119 * return -1 if none found.
120 */
121{
122 int i;
123
124 for (i = fC; (i < g->nnodes); i++)
125 {
126 if ((g->nedge[i] > 0) && (egc[i] == Col))
127 {
128 return i;
129 }
130 }
131
132 return -1;
133}
134
135static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[])
136{
137 int ng, nnodes;
138 int nW, nG, nB; /* Number of Grey, Black, White */
139 int fW, fG; /* First of each category */
140 egCol *egc = NULL((void*)0); /* The colour of each node */
141 int g0, nblock;
142
143 if (!g->nbound)
144 {
145 return 0;
146 }
147
148 nblock = 0;
149
150 nnodes = g->nnodes;
151 snew(egc, nnodes)(egc) = save_calloc("egc", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 151, (nnodes), sizeof(*(egc)))
;
152
153 g0 = g->at_start;
154 nW = g->nbound;
155 nG = 0;
156 nB = 0;
157
158 fW = 0;
159
160 /* We even have a loop invariant:
161 * nW+nG+nB == g->nbound
162 */
163
164 if (fp)
165 {
166 fprintf(fp, "Walking down the molecule graph to make constraint-blocks\n");
167 }
168
169 while (nW > 0)
170 {
171 /* Find the first white, this will allways be a larger
172 * number than before, because no nodes are made white
173 * in the loop
174 */
175 if ((fW = first_colour(fW, egcolWhite, g, egc)) == -1)
176 {
177 gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 177
, "No WHITE nodes found while nW=%d\n", nW);
178 }
179
180 /* Make the first white node grey, and set the block number */
181 egc[fW] = egcolGrey;
182 range_check(fW+g0, 0, maxsid)_range_check(fW+g0, 0, maxsid, ((void*)0),"fW+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 182)
;
183 sid[fW+g0].sid = nblock++;
184 nG++;
185 nW--;
186
187 /* Initial value for the first grey */
188 fG = fW;
189
190 if (debug)
191 {
192 fprintf(debug, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n",
193 nW, nG, nB, nW+nG+nB);
194 }
195
196 while (nG > 0)
197 {
198 if ((fG = first_colour(fG, egcolGrey, g, egc)) == -1)
199 {
200 gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 200
, "No GREY nodes found while nG=%d\n", nG);
201 }
202
203 /* Make the first grey node black */
204 egc[fG] = egcolBlack;
205 nB++;
206 nG--;
207
208 /* Make all the neighbours of this black node grey
209 * and set their block number
210 */
211 ng = mk_grey(egc, g, &fG, maxsid, sid);
212 /* ng is the number of white nodes made grey */
213 nG += ng;
214 nW -= ng;
215 }
216 }
217 sfree(egc)save_free("egc", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 217, (egc))
;
218
219 if (debug)
220 {
221 fprintf(debug, "Found %d shake blocks\n", nblock);
222 }
223
224 return nblock;
225}
226
227
228typedef struct {
229 int first, last, sid;
230} t_merge_sid;
231
232static int ms_comp(const void *a, const void *b)
233{
234 t_merge_sid *ma = (t_merge_sid *)a;
235 t_merge_sid *mb = (t_merge_sid *)b;
236 int d;
237
238 d = ma->first-mb->first;
239 if (d == 0)
240 {
241 return ma->last-mb->last;
242 }
243 else
244 {
245 return d;
246 }
247}
248
249static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[],
250 t_blocka *sblock)
251{
252 int i, j, k, n, isid, ndel;
253 t_merge_sid *ms;
254 int nChanged;
255
256 /* We try to remdy the following problem:
257 * Atom: 1 2 3 4 5 6 7 8 9 10
258 * Sid: 0 -1 1 0 -1 1 1 1 1 1
259 */
260
261 /* Determine first and last atom in each shake ID */
262 snew(ms, nsid)(ms) = save_calloc("ms", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 262, (nsid), sizeof(*(ms)))
;
263
264 for (k = 0; (k < nsid); k++)
265 {
266 ms[k].first = at_end+1;
267 ms[k].last = -1;
268 ms[k].sid = k;
269 }
270 for (i = at_start; (i < at_end); i++)
271 {
272 isid = sid[i].sid;
273 range_check(isid, -1, nsid)_range_check(isid, -1, nsid, ((void*)0),"isid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 273)
;
274 if (isid >= 0)
275 {
276 ms[isid].first = min(ms[isid].first, sid[i].atom)(((ms[isid].first) < (sid[i].atom)) ? (ms[isid].first) : (
sid[i].atom) )
;
277 ms[isid].last = max(ms[isid].last, sid[i].atom)(((ms[isid].last) > (sid[i].atom)) ? (ms[isid].last) : (sid
[i].atom) )
;
278 }
279 }
280 qsort(ms, nsid, sizeof(ms[0]), ms_comp);
281
282 /* Now merge the overlapping ones */
283 ndel = 0;
284 for (k = 0; (k < nsid); )
285 {
286 for (j = k+1; (j < nsid); )
287 {
288 if (ms[j].first <= ms[k].last)
289 {
290 ms[k].last = max(ms[k].last, ms[j].last)(((ms[k].last) > (ms[j].last)) ? (ms[k].last) : (ms[j].last
) )
;
291 ms[k].first = min(ms[k].first, ms[j].first)(((ms[k].first) < (ms[j].first)) ? (ms[k].first) : (ms[j].
first) )
;
292 ms[j].sid = -1;
293 ndel++;
294 j++;
295 }
296 else
297 {
298 k = j;
299 j = k+1;
300 }
301 }
302 if (j == nsid)
303 {
304 k++;
305 }
306 }
307 for (k = 0; (k < nsid); k++)
308 {
309 while ((k < nsid-1) && (ms[k].sid == -1))
310 {
311 for (j = k+1; (j < nsid); j++)
312 {
313 memcpy(&(ms[j-1]), &(ms[j]), sizeof(ms[0]));
314 }
315 nsid--;
316 }
317 }
318
319 for (k = at_start; (k < at_end); k++)
320 {
321 sid[k].atom = k;
322 sid[k].sid = -1;
323 }
324 sblock->nr = nsid;
325 sblock->nalloc_index = sblock->nr+1;
326 snew(sblock->index, sblock->nalloc_index)(sblock->index) = save_calloc("sblock->index", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 326, (sblock->nalloc_index), sizeof(*(sblock->index))
)
;
327 sblock->nra = at_end - at_start;
328 sblock->nalloc_a = sblock->nra;
329 snew(sblock->a, sblock->nalloc_a)(sblock->a) = save_calloc("sblock->a", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 329, (sblock->nalloc_a), sizeof(*(sblock->a)))
;
330 sblock->index[0] = 0;
331 for (k = n = 0; (k < nsid); k++)
332 {
333 sblock->index[k+1] = sblock->index[k] + ms[k].last - ms[k].first+1;
334 for (j = ms[k].first; (j <= ms[k].last); j++)
335 {
336 range_check(n, 0, sblock->nra)_range_check(n, 0, sblock->nra, ((void*)0),"n", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 336)
;
337 sblock->a[n++] = j;
338 range_check(j, 0, at_end)_range_check(j, 0, at_end, ((void*)0),"j", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 338)
;
339 if (sid[j].sid == -1)
340 {
341 sid[j].sid = k;
342 }
343 else
344 {
345 fprintf(stderrstderr, "Double sids (%d, %d) for atom %d\n", sid[j].sid, k, j);
346 }
347 }
348 }
349 assert(k == nsid)((void) (0));
350 /* Removed 2007-09-04
351 sblock->index[k+1] = natoms;
352 for(k=0; (k<natoms); k++)
353 if (sid[k].sid == -1)
354 sblock->a[n++] = k;
355 assert(n == natoms);
356 */
357 sblock->nra = n;
358 assert(sblock->index[k] == sblock->nra)((void) (0));
359 sfree(ms)save_free("ms", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 359, (ms))
;
360
361 return nsid;
362}
363
364void gen_sblocks(FILE *fp, int at_start, int at_end,
365 t_idef *idef, t_blocka *sblock,
366 gmx_bool bSettle)
367{
368 t_graph *g;
369 int i, i0, j, k, istart, n;
370 t_sid *sid;
371 int isid, nsid;
372
373 g = mk_graph(NULL((void*)0), idef, at_start, at_end, TRUE1, bSettle);
374 if (debug)
375 {
376 p_graph(debug, "Graaf Dracula", g);
377 }
378 snew(sid, at_end)(sid) = save_calloc("sid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 378, (at_end), sizeof(*(sid)))
;
379 for (i = at_start; (i < at_end); i++)
380 {
381 sid[i].atom = i;
382 sid[i].sid = -1;
383 }
384 nsid = mk_sblocks(fp, g, at_end, sid);
385
386 if (!nsid)
387 {
388 return;
389 }
390
391 /* Now sort the shake blocks... */
392 qsort(sid+at_start, at_end-at_start, (size_t)sizeof(sid[0]), sid_comp);
393
394 if (debug)
395 {
396 fprintf(debug, "Sorted shake block\n");
397 for (i = at_start; (i < at_end); i++)
398 {
399 fprintf(debug, "sid[%5d] = atom:%5d sid:%5d\n", i, sid[i].atom, sid[i].sid);
400 }
401 }
402 /* Now check how many are NOT -1, i.e. how many have to be shaken */
403 for (i0 = at_start; (i0 < at_end); i0++)
404 {
405 if (sid[i0].sid > -1)
406 {
407 break;
408 }
409 }
410
411 /* Now we have the sids that have to be shaken. We'll check the min and
412 * max atom numbers and this determines the shake block. DvdS 2007-07-19.
413 * For the purpose of making boundaries all atoms in between need to be
414 * part of the shake block too. There may be cases where blocks overlap
415 * and they will have to be merged.
416 */
417 nsid = merge_sid(at_start, at_end, nsid, sid, sblock);
Value stored to 'nsid' is never read
418 /* Now sort the shake blocks again... */
419 /*qsort(sid,natoms,(size_t)sizeof(sid[0]),sid_comp);*/
420
421 /* Fill the sblock struct */
422 /* sblock->nr = nsid;
423 sblock->nra = natoms;
424 srenew(sblock->a,sblock->nra);
425 srenew(sblock->index,sblock->nr+1);
426
427 i = i0;
428 isid = sid[i].sid;
429 n = k = 0;
430 sblock->index[n++]=k;
431 while (i < natoms) {
432 istart = sid[i].atom;
433 while ((i<natoms-1) && (sid[i+1].sid == isid))
434 i++;*/
435 /* After while: we found a new block, or are thru with the atoms */
436 /* for(j=istart; (j<=sid[i].atom); j++,k++)
437 sblock->a[k]=j;
438 sblock->index[n] = k;
439 if (i < natoms-1)
440 n++;
441 if (n > nsid)
442 gmx_fatal(FARGS,"Death Horror: nsid = %d, n= %d",nsid,n);
443 i++;
444 isid = sid[i].sid;
445 }
446 */
447 sfree(sid)save_free("sid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 447, (sid))
;
448 /* Due to unknown reason this free generates a problem sometimes */
449 done_graph(g);
450 sfree(g)save_free("g", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c"
, 450, (g))
;
451 if (debug)
452 {
453 fprintf(debug, "Done gen_sblocks\n");
454 }
455}