1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7 /*                            fuer Informationstechnik Berlin                */
8 /*                                                                           */
9 /*  SCIP is distributed under the terms of the ZIB Academic License.         */
10 /*                                                                           */
11 /*  You should have received a copy of the ZIB Academic License              */
12 /*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13 /*                                                                           */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file   scip_mem.c
17  * @ingroup OTHER_CFILES
18  * @brief  public methods for memory management
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Gerald Gamrath
22  * @author Leona Gottwald
23  * @author Stefan Heinz
24  * @author Gregor Hendel
25  * @author Thorsten Koch
26  * @author Alexander Martin
27  * @author Marc Pfetsch
28  * @author Michael Winkler
29  * @author Kati Wolter
30  *
31  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "scip/mem.h"
37 #include "scip/pub_message.h"
38 #include "scip/scip_mem.h"
39 #include "scip/set.h"
40 #include "scip/stat.h"
41 #include "scip/struct_mem.h"
42 #include "scip/struct_scip.h"
43 
44 /** returns block memory to use at the current time
45  *
46  *  @return the block memory to use at the current time.
47  */
SCIPblkmem(SCIP * scip)48 BMS_BLKMEM* SCIPblkmem(
49    SCIP*                 scip                /**< SCIP data structure */
50    )
51 {
52    assert(scip != NULL);
53    assert(scip->set != NULL);
54    assert(scip->mem != NULL);
55 
56    return scip->mem->probmem;
57 }
58 
59 /** returns buffer memory for short living temporary objects
60  *
61  *  @return the buffer memory for short living temporary objects
62  */
SCIPbuffer(SCIP * scip)63 BMS_BUFMEM* SCIPbuffer(
64    SCIP*                 scip                /**< SCIP data structure */
65    )
66 {
67    assert(scip != NULL);
68    assert(scip->mem != NULL);
69 
70    return scip->mem->buffer;
71 }
72 
73 /** returns clean buffer memory for short living temporary objects initialized to all zero
74  *
75  *  @return the buffer memory for short living temporary objects initialized to all zero
76  */
SCIPcleanbuffer(SCIP * scip)77 BMS_BUFMEM* SCIPcleanbuffer(
78    SCIP*                 scip                /**< SCIP data structure */
79    )
80 {
81    assert(scip != NULL);
82    assert(scip->mem != NULL);
83 
84    return scip->mem->cleanbuffer;
85 }
86 
87 /** returns the total number of bytes used in block and buffer memory
88  *
89  *  @return the total number of bytes used in block and buffer memory.
90  */
SCIPgetMemUsed(SCIP * scip)91 SCIP_Longint SCIPgetMemUsed(
92    SCIP*                 scip                /**< SCIP data structure */
93    )
94 {
95    assert(scip != NULL);
96 
97    return SCIPmemGetUsed(scip->mem);
98 }
99 
100 /** returns the total number of bytes in block and buffer memory
101  *
102  *  @return the total number of bytes in block and buffer memory.
103  */
SCIPgetMemTotal(SCIP * scip)104 SCIP_Longint SCIPgetMemTotal(
105    SCIP*                 scip                /**< SCIP data structure */
106    )
107 {
108    assert(scip != NULL);
109 
110    return SCIPmemGetTotal(scip->mem);
111 }
112 
113 /** returns the estimated number of bytes used by external software, e.g., the LP solver
114  *
115  *  @return the estimated number of bytes used by external software, e.g., the LP solver.
116  */
SCIPgetMemExternEstim(SCIP * scip)117 SCIP_Longint SCIPgetMemExternEstim(
118    SCIP*                 scip                /**< SCIP data structure */
119    )
120 {
121    assert(scip != NULL);
122 
123    return SCIPstatGetMemExternEstim(scip->stat);
124 }
125 
126 /** calculate memory size for dynamically allocated arrays
127  *
128  *  @return the memory size for dynamically allocated arrays.
129  */
SCIPcalcMemGrowSize(SCIP * scip,int num)130 int SCIPcalcMemGrowSize(
131    SCIP*                 scip,               /**< SCIP data structure */
132    int                   num                 /**< minimum number of entries to store */
133    )
134 {
135    assert(scip != NULL);
136 
137    return SCIPsetCalcMemGrowSize(scip->set, num);
138 }
139 
140 /** extends a dynamically allocated block memory array to be able to store at least the given number of elements;
141  *  use SCIPensureBlockMemoryArray() define to call this method!
142  *
143  *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
144  *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
145  */
SCIPensureBlockMemoryArray_call(SCIP * scip,void ** arrayptr,size_t elemsize,int * arraysize,int minsize)146 SCIP_RETCODE SCIPensureBlockMemoryArray_call(
147    SCIP*                 scip,               /**< SCIP data structure */
148    void**                arrayptr,           /**< pointer to dynamically sized array */
149    size_t                elemsize,           /**< size in bytes of each element in array */
150    int*                  arraysize,          /**< pointer to current array size */
151    int                   minsize             /**< required minimal array size */
152    )
153 {
154    assert(scip != NULL);
155    assert(arrayptr != NULL);
156    assert(elemsize > 0);
157    assert(arraysize != NULL);
158 
159    if( minsize > *arraysize )
160    {
161       int newsize;
162 
163       newsize = SCIPsetCalcMemGrowSize(scip->set, minsize);
164       SCIP_ALLOC( BMSreallocBlockMemorySize(SCIPblkmem(scip), arrayptr, *arraysize * elemsize, newsize * elemsize) );
165       *arraysize = newsize;
166    }
167 
168    return SCIP_OKAY;
169 }
170 
171 /** prints output about used memory */
SCIPprintMemoryDiagnostic(SCIP * scip)172 void SCIPprintMemoryDiagnostic(
173    SCIP*                 scip                /**< SCIP data structure */
174    )
175 {
176    assert(scip != NULL);
177    assert(scip->mem != NULL);
178    assert(scip->set != NULL);
179 
180    BMSdisplayMemory();
181 
182    SCIPmessagePrintInfo(scip->messagehdlr, "\nParameter Block Memory (%p):\n", (void*)scip->mem->setmem);
183    BMSdisplayBlockMemory(scip->mem->setmem);
184 
185    SCIPmessagePrintInfo(scip->messagehdlr, "\nSolution Block Memory (%p):\n", (void*)scip->mem->probmem);
186    BMSdisplayBlockMemory(scip->mem->probmem);
187 
188    SCIPmessagePrintInfo(scip->messagehdlr, "\nMemory Buffers:\n");
189    BMSprintBufferMemory(SCIPbuffer(scip));
190 
191    SCIPmessagePrintInfo(scip->messagehdlr, "\nClean Memory Buffers:\n");
192    BMSprintBufferMemory(SCIPcleanbuffer(scip));
193 }
194