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