Scippy

SCIP

Solving Constraint Integer Programs

clock.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file clock.c
26  * @ingroup OTHER_CFILES
27  * @brief methods for clocks and timing issues
28  * @author Tobias Achterberg
29  */
30 
31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32 
33 #include <assert.h>
34 #if defined(_WIN32) || defined(_WIN64)
35 #include <windows.h>
36 #else
37 #include <sys/times.h>
38 #include <sys/time.h>
39 #include <unistd.h>
40 #endif
41 #include <time.h>
42 
43 #include "scip/def.h"
44 #include "scip/pub_message.h"
45 #include "blockmemshell/memory.h"
46 #include "scip/set.h"
47 #include "scip/clock.h"
48 
49 #include "scip/struct_clock.h"
50 
51 /** converts CPU clock ticks into seconds */
52 static
54  clock_t cputime /**< clock ticks for CPU time */
55  )
56 {
57  clock_t clocks_per_second;
58 
59 #if defined(_WIN32) || defined(_WIN64)
60  clocks_per_second = 100;
61 #else
62 #ifndef CLK_TCK
63  clocks_per_second = sysconf(_SC_CLK_TCK);
64 #else
65  clocks_per_second = CLK_TCK;
66 #endif
67 #endif
68 
69  return (SCIP_Real)cputime / (SCIP_Real)clocks_per_second;
70 }
71 
72 /*lint -esym(*,timeval)*/
73 /*lint -esym(*,gettimeofday)*/
74 
75 /** converts wall clock time into seconds */
76 static
78  long sec, /**< seconds counter */
79  long usec /**< microseconds counter */
80  )
81 {
82  return (SCIP_Real)sec + 0.000001 * (SCIP_Real)usec;
83 }
84 
85 /** converts seconds into CPU clock ticks */
86 static
88  SCIP_Real sec, /**< seconds */
89  clock_t* cputime /**< pointer to store clock ticks for CPU time */
90  )
91 {
92  clock_t clocks_per_second;
93 
94  assert(cputime != NULL);
95 
96 #if defined(_WIN32) || defined(_WIN64)
97  clocks_per_second = 100;
98 #else
99 #ifndef CLK_TCK
100  clocks_per_second = sysconf(_SC_CLK_TCK);
101 #else
102  clocks_per_second = CLK_TCK;
103 #endif
104 #endif
105  *cputime = (clock_t)(sec * clocks_per_second);
106 }
107 
108 /** converts wall clock time into seconds */
109 static
111  SCIP_Real sec, /**< seconds */
112  long* wallsec, /**< pointer to store seconds counter */
113  long* wallusec /**< pointer to store microseconds counter */
114  )
115 {
116  assert(wallsec != NULL);
117  assert(wallusec != NULL);
118 
119  *wallsec = (long)sec;
120  *wallusec = (long)((sec - *wallsec) * 1000000.0);
121 }
122 
123 
124 /** sets the clock's type and converts the clock timer accordingly */
125 static
127  SCIP_CLOCK* clck, /**< clock timer */
128  SCIP_CLOCKTYPE newtype /**< new clock type */
129  )
130 {
131  assert(clck != NULL);
132  assert(newtype != SCIP_CLOCKTYPE_DEFAULT);
133 
134  if( clck->clocktype != newtype )
135  {
136  if( clck->clocktype == SCIP_CLOCKTYPE_DEFAULT )
137  {
138  assert(clck->nruns == 0);
139  clck->clocktype = newtype;
140  SCIPclockReset(clck);
141  SCIPdebugMessage("switched clock type to %d\n", newtype);
142  }
143  else
144  {
145  SCIP_Real sec;
146 
147  sec = SCIPclockGetTime(clck);
148  clck->clocktype = newtype;
149  SCIPclockSetTime(clck, sec);
150  SCIPdebugMessage("switched clock type to %d (%g seconds -> %g seconds)\n", newtype, sec, SCIPclockGetTime(clck));
151  }
152  }
153 }
154 
155 /** if the clock uses the default clock type and the default changed, converts the clock timer to the new type */
156 static
158  SCIP_CLOCK* clck, /**< clock timer */
159  SCIP_CLOCKTYPE defaultclocktype /**< default type of clock to use */
160  )
161 {
162  assert(clck != NULL);
163  assert(defaultclocktype != SCIP_CLOCKTYPE_DEFAULT);
164 
165  if( clck->usedefault && clck->clocktype != defaultclocktype )
166  clockSetType(clck, defaultclocktype);
167 }
168 
169 /** creates a clock and initializes it */
171  SCIP_CLOCK** clck, /**< pointer to clock timer */
172  SCIP_CLOCKTYPE clocktype /**< type of clock */
173  )
174 {
175  assert(clck != NULL);
176 
177  SCIP_ALLOC( BMSallocMemory(clck) );
178 
179  SCIPclockInit(*clck, clocktype);
180 
181  return SCIP_OKAY;
182 }
183 
184 /** frees a clock */
186  SCIP_CLOCK** clck /**< pointer to clock timer */
187  )
188 {
189  assert(clck != NULL);
190 
191  BMSfreeMemory(clck);
192 }
193 
194 /** initializes and resets a clock */
196  SCIP_CLOCK* clck, /**< clock timer */
197  SCIP_CLOCKTYPE clocktype /**< type of clock */
198  )
199 {
200  assert(clck != NULL);
201 
202  SCIPdebugMessage("initializing clock %p of type %d\n", (void*)clck, clocktype);
203  clck->enabled = TRUE;
204  clck->lasttime = 0.0;
205  SCIPclockSetType(clck, clocktype);
206 }
207 
208 /** completely stop the clock and reset the clock's counter to zero */
210  SCIP_CLOCK* clck /**< clock timer */
211  )
212 {
213  assert(clck != NULL);
214 
215  SCIPdebugMessage("resetting clock %p of type %d (usedefault=%u)\n", (void*)clck, clck->clocktype, clck->usedefault);
216  switch( clck->clocktype )
217  {
219  break;
220  case SCIP_CLOCKTYPE_CPU:
221  clck->data.cpuclock.user = 0;
222  break;
223  case SCIP_CLOCKTYPE_WALL:
224  clck->data.wallclock.sec = 0;
225  clck->data.wallclock.usec = 0;
226  break;
227  default:
228  SCIPerrorMessage("invalid clock type\n");
229  SCIPABORT();
230  }
231  clck->nruns = 0;
232 }
233 
234 /** enables the clock */
236  SCIP_CLOCK* clck /**< clock timer */
237  )
238 {
239  assert(clck != NULL);
240 
241  SCIPdebugMessage("enabling clock %p of type %d (usedefault=%u)\n", (void*)clck, clck->clocktype, clck->usedefault);
242 
243  clck->enabled = TRUE;
244 }
245 
246 /** disables and resets the clock */
248  SCIP_CLOCK* clck /**< clock timer */
249  )
250 {
251  assert(clck != NULL);
252 
253  SCIPdebugMessage("disabling clock %p of type %d (usedefault=%u)\n", (void*)clck, clck->clocktype, clck->usedefault);
254 
255  clck->enabled = FALSE;
256  SCIPclockReset(clck);
257 }
258 
259 /** enables or disables \p clck, depending on the value of the flag */
261  SCIP_CLOCK* clck, /**< the clock to be disabled/enabled */
262  SCIP_Bool enable /**< should the clock be enabled? */
263  )
264 {
265  assert(clck != NULL);
266 
267  if( enable )
268  SCIPclockEnable(clck);
269  else
270  SCIPclockDisable(clck);
271 }
272 
273 /** sets the type of the clock, overriding the default clock type, and resets the clock */
275  SCIP_CLOCK* clck, /**< clock timer */
276  SCIP_CLOCKTYPE clocktype /**< type of clock */
277  )
278 {
279  assert(clck != NULL);
280 
281  SCIPdebugMessage("setting type of clock %p (type %d, usedefault=%u) to %d\n",
282  (void*)clck, clck->clocktype, clck->usedefault, clocktype);
283 
284  clck->clocktype = clocktype;
285  clck->usedefault = (clocktype == SCIP_CLOCKTYPE_DEFAULT);
286  SCIPclockReset(clck);
287 }
288 
289 /** starts measurement of time in the given clock */
291  SCIP_CLOCK* clck, /**< clock timer */
292  SCIP_SET* set /**< global SCIP settings */
293  )
294 {
295  assert(clck != NULL);
296  assert(set != NULL);
297 
298  if( set->time_enabled && clck->enabled )
299  {
300  clockUpdateDefaultType(clck, set->time_clocktype);
301 
302  if( clck->nruns == 0 )
303  {
304 #if defined(_WIN32) || defined(_WIN64)
305  FILETIME creationtime;
306  FILETIME exittime;
307  FILETIME kerneltime;
308  FILETIME usertime;
309 #else
310  struct timeval tp; /*lint !e86*/
311  struct tms now;
312 #endif
313 
314  SCIPdebugMessage("starting clock %p (type %d, usedefault=%u)\n", (void*)clck, clck->clocktype, clck->usedefault);
315 
316  switch( clck->clocktype )
317  {
318  case SCIP_CLOCKTYPE_CPU:
319 #if defined(_WIN32) || defined(_WIN64)
320  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
321  clck->data.cpuclock.user -= usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L;
322 #else
323  (void)times(&now);
324  clck->data.cpuclock.user -= now.tms_utime;
325 #endif
326  clck->lasttime = cputime2sec(clck->data.cpuclock.user);
327  break;
328 
329  case SCIP_CLOCKTYPE_WALL:
330 #if defined(_WIN32) || defined(_WIN64)
331  clck->data.wallclock.sec -= time(NULL);
332 #else
333  gettimeofday(&tp, NULL);
334  if( tp.tv_usec > clck->data.wallclock.usec ) /*lint !e115 !e40*/
335  {
336  clck->data.wallclock.sec -= (tp.tv_sec + 1); /*lint !e115 !e40*/
337  clck->data.wallclock.usec += (1000000 - tp.tv_usec); /*lint !e115 !e40*/
338  }
339  else
340  {
341  clck->data.wallclock.sec -= tp.tv_sec; /*lint !e115 !e40*/
342  clck->data.wallclock.usec -= tp.tv_usec; /*lint !e115 !e40*/
343  }
344 #endif
345  clck->lasttime = walltime2sec(clck->data.wallclock.sec, clck->data.wallclock.usec);
346  break;
347 
349  default:
350  SCIPerrorMessage("invalid clock type\n");
351  SCIPABORT();
352  }
353  }
354 
355  clck->nruns++;
356  }
357 }
358 
359 /** stops measurement of time in the given clock */
361  SCIP_CLOCK* clck, /**< clock timer */
362  SCIP_SET* set /**< global SCIP settings */
363  )
364 {
365  assert(clck != NULL);
366  assert(set != NULL);
367 
368  if( set->time_enabled && clck->enabled )
369  {
370  assert(clck->nruns >= 1);
371 
372  clck->nruns--;
373  if( clck->nruns == 0 )
374  {
375 #if defined(_WIN32) || defined(_WIN64)
376  FILETIME creationtime;
377  FILETIME exittime;
378  FILETIME kerneltime;
379  FILETIME usertime;
380 #else
381  struct timeval tp; /*lint !e86*/
382  struct tms now;
383 #endif
384 
385  SCIPdebugMessage("stopping clock %p (type %d, usedefault=%u)\n", (void*)clck, clck->clocktype, clck->usedefault);
386 
387  switch( clck->clocktype )
388  {
389  case SCIP_CLOCKTYPE_CPU:
390 #if defined(_WIN32) || defined(_WIN64)
391  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
392  clck->data.cpuclock.user += usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L;
393 #else
394  (void)times(&now);
395  clck->data.cpuclock.user += now.tms_utime;
396 #endif
397  break;
398 
399  case SCIP_CLOCKTYPE_WALL:
400 #if defined(_WIN32) || defined(_WIN64)
401  clck->data.wallclock.sec += time(NULL);
402 #else
403  gettimeofday(&tp, NULL);
404  if( tp.tv_usec + clck->data.wallclock.usec > 1000000 ) /*lint !e115 !e40*/
405  {
406  clck->data.wallclock.sec += (tp.tv_sec + 1); /*lint !e115 !e40*/
407  clck->data.wallclock.usec -= (1000000 - tp.tv_usec); /*lint !e115 !e40*/
408  }
409  else
410  {
411  clck->data.wallclock.sec += tp.tv_sec; /*lint !e115 !e40*/
412  clck->data.wallclock.usec += tp.tv_usec; /*lint !e115 !e40*/
413  }
414 #endif
415  break;
416 
418  default:
419  SCIPerrorMessage("invalid clock type\n");
420  SCIPABORT();
421  }
422  }
423  }
424 }
425 
426 /** returns whether the clock is currently running */
428  SCIP_CLOCK* clck /**< clock timer */
429  )
430 {
431  assert(clck != NULL);
432 
433  return (clck->nruns > 0);
434 }
435 
436 
437 /** gets the used time of this clock in seconds */
439  SCIP_CLOCK* clck /**< clock timer */
440  )
441 {
442  SCIP_Real result;
443  assert(clck != NULL);
444  result = 0.0;
445 
446  SCIPdebugMessage("getting time of clock %p (type %d, usedefault=%u, nruns=%d)\n",
447  (void*)clck, clck->clocktype, clck->usedefault, clck->nruns);
448 
449  if( !clck->enabled )
450  {
451  result = 0.0;
452  }
453  else if( clck->nruns == 0 )
454  {
455  /* the clock is not running: convert the clocks timer into seconds */
456  switch( clck->clocktype )
457  {
459  break;
460  case SCIP_CLOCKTYPE_CPU:
461  result = cputime2sec(clck->data.cpuclock.user);
462  break;
463  case SCIP_CLOCKTYPE_WALL:
464  result = walltime2sec(clck->data.wallclock.sec, clck->data.wallclock.usec);
465  break;
466  default:
467  SCIPerrorMessage("invalid clock type\n");
468  SCIPABORT();
469  result = 0.0; /*lint !e527*/
470  }
471  }
472  else
473  {
474 #if defined(_WIN32) || defined(_WIN64)
475  FILETIME creationtime;
476  FILETIME exittime;
477  FILETIME kerneltime;
478  FILETIME usertime;
479 #else
480  struct timeval tp; /*lint !e86*/
481  struct tms now;
482 #endif
483 
484  /* the clock is currently running: we have to add the current time to the clocks timer */
485  switch( clck->clocktype )
486  {
487  case SCIP_CLOCKTYPE_CPU:
488 #if defined(_WIN32) || defined(_WIN64)
489  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
490  result = cputime2sec(clck->data.cpuclock.user + usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L);
491 #else
492  (void)times(&now);
493  result = cputime2sec(clck->data.cpuclock.user + now.tms_utime);
494 #endif
495  break;
496  case SCIP_CLOCKTYPE_WALL:
497 #if defined(_WIN32) || defined(_WIN64)
498  result = walltime2sec(clck->data.wallclock.sec + time(NULL), 0);
499 #else
500  gettimeofday(&tp, NULL);
501  if( tp.tv_usec + clck->data.wallclock.usec > 1000000 ) /*lint !e115 !e40*/
502  result = walltime2sec(clck->data.wallclock.sec + tp.tv_sec + 1, /*lint !e115 !e40*/
503  (clck->data.wallclock.usec - 1000000) + tp.tv_usec); /*lint !e115 !e40*/
504  else
505  result = walltime2sec(clck->data.wallclock.sec + tp.tv_sec, /*lint !e115 !e40*/
506  clck->data.wallclock.usec + tp.tv_usec); /*lint !e115 !e40*/
507 #endif
508  break;
510  default:
511  SCIPerrorMessage("invalid clock type\n");
512  SCIPABORT();
513  result = 0.0; /*lint !e527*/
514  }
515  }
516 
517  clck->lasttime = result;
518  return result;
519 }
520 
521 /** gets the last validated time of this clock in seconds */
523  SCIP_CLOCK* clck /**< clock timer */
524  )
525 {
526  assert(clck != NULL);
527 
528  return clck->lasttime;
529 }
530 
531 /** sets the used time of this clock in seconds */
533  SCIP_CLOCK* clck, /**< clock timer */
534  SCIP_Real sec /**< time in seconds to set the clock's timer to */
535  )
536 {
537  assert(clck != NULL);
538 
539  SCIPdebugMessage("setting time of clock %p (type %d, usedefault=%u, nruns=%d) to %g\n",
540  (void*)clck, clck->clocktype, clck->usedefault, clck->nruns, sec);
541 
542  /* if the clock type is not yet set, set it to an arbitrary value to be able to store the number */
543  if( clck->clocktype == SCIP_CLOCKTYPE_DEFAULT )
545 
546  switch( clck->clocktype )
547  {
548  case SCIP_CLOCKTYPE_CPU:
549  sec2cputime(sec, &clck->data.cpuclock.user);
550  break;
551 
552  case SCIP_CLOCKTYPE_WALL:
553  sec2walltime(sec, &clck->data.wallclock.sec, &clck->data.wallclock.usec);
554  break;
555 
557  default:
558  SCIPerrorMessage("invalid clock type\n");
559  SCIPABORT();
560  }
561 
562  if( clck->nruns >= 1 )
563  {
564 #if defined(_WIN32) || defined(_WIN64)
565  FILETIME creationtime;
566  FILETIME exittime;
567  FILETIME kerneltime;
568  FILETIME usertime;
569 #else
570  struct timeval tp; /*lint !e86*/
571  struct tms now;
572 #endif
573 
574  /* the clock is currently running: we have to subtract the current time from the new timer value */
575  switch( clck->clocktype )
576  {
577  case SCIP_CLOCKTYPE_CPU:
578 #if defined(_WIN32) || defined(_WIN64)
579  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
580  clck->data.cpuclock.user -= usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L;
581 #else
582  (void)times(&now);
583  clck->data.cpuclock.user -= now.tms_utime;
584 #endif
585  break;
586 
587  case SCIP_CLOCKTYPE_WALL:
588 #if defined(_WIN32) || defined(_WIN64)
589  clck->data.wallclock.sec -= time(NULL);
590 #else
591  gettimeofday(&tp, NULL);
592  if( tp.tv_usec > clck->data.wallclock.usec ) /*lint !e115 !e40*/
593  {
594  clck->data.wallclock.sec -= (tp.tv_sec + 1); /*lint !e115 !e40*/
595  clck->data.wallclock.usec += (1000000 - tp.tv_usec); /*lint !e115 !e40*/
596  }
597  else
598  {
599  clck->data.wallclock.sec -= tp.tv_sec; /*lint !e115 !e40*/
600  clck->data.wallclock.usec -= tp.tv_usec; /*lint !e115 !e40*/
601  }
602 #endif
603  break;
604 
606  default:
607  SCIPerrorMessage("invalid clock type\n");
608  SCIPABORT();
609  }
610  }
611 }
612 
613 /** gets current time of day in seconds (standard time zone) */
615  void
616  )
617 {
618 #if defined(_WIN32) || defined(_WIN64)
619  time_t now;
620  now = time(NULL);
621  return (SCIP_Real)(now % (24*3600));
622 #else
623  struct timeval tp; /*lint !e86*/
624 
625  gettimeofday(&tp, NULL);
626 
627  return (SCIP_Real)(tp.tv_sec % (24*3600)) + (SCIP_Real)tp.tv_usec / 1e+6; /*lint !e40 !e115*/
628 #endif
629 }
void SCIPclockEnable(SCIP_CLOCK *clck)
Definition: clock.c:235
void SCIPclockSetType(SCIP_CLOCK *clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:274
SCIP_Bool usedefault
Definition: struct_clock.h:74
static SCIP_Real walltime2sec(long sec, long usec)
Definition: clock.c:77
SCIP_CLOCKTYPE clocktype
Definition: struct_clock.h:73
internal methods for clocks and timing issues
void SCIPclockDisable(SCIP_CLOCK *clck)
Definition: clock.c:247
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:47
#define FALSE
Definition: def.h:96
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
#define TRUE
Definition: def.h:95
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
static void clockSetType(SCIP_CLOCK *clck, SCIP_CLOCKTYPE newtype)
Definition: clock.c:126
void SCIPclockInit(SCIP_CLOCK *clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:195
SCIP_Bool enabled
Definition: struct_clock.h:75
#define SCIPdebugMessage
Definition: pub_message.h:96
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:260
#define BMSfreeMemory(ptr)
Definition: memory.h:147
Definition: heur_padm.c:132
SCIP_Bool SCIPclockIsRunning(SCIP_CLOCK *clck)
Definition: clock.c:427
void SCIPclockSetTime(SCIP_CLOCK *clck, SCIP_Real sec)
Definition: clock.c:532
SCIP_Real lasttime
Definition: struct_clock.h:71
SCIP_Real SCIPclockGetLastTime(SCIP_CLOCK *clck)
Definition: clock.c:522
static void sec2walltime(SCIP_Real sec, long *wallsec, long *wallusec)
Definition: clock.c:110
#define SCIPerrorMessage
Definition: pub_message.h:64
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:209
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:438
#define NULL
Definition: lpi_spx1.cpp:164
internal methods for global SCIP settings
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:170
#define SCIP_Bool
Definition: def.h:93
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:185
SCIP_Real SCIPclockGetTimeOfDay(void)
Definition: clock.c:614
static SCIP_Real cputime2sec(clock_t cputime)
Definition: clock.c:53
static void sec2cputime(SCIP_Real sec, clock_t *cputime)
Definition: clock.c:87
static void clockUpdateDefaultType(SCIP_CLOCK *clck, SCIP_CLOCKTYPE defaultclocktype)
Definition: clock.c:157
datastructures for clocks and timing issues
public methods for message output
#define SCIP_Real
Definition: def.h:186
#define BMSallocMemory(ptr)
Definition: memory.h:120
common defines and data types used in all packages of SCIP
#define SCIP_ALLOC(x)
Definition: def.h:405
#define SCIPABORT()
Definition: def.h:366
memory allocation routines