OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
stacksize.cpp
Go to the documentation of this file.
1//Copyright> OpenRadioss
2//Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3//Copyright>
4//Copyright> This program is free software: you can redistribute it and/or modify
5//Copyright> it under the terms of the GNU Affero General Public License as published by
6//Copyright> the Free Software Foundation, either version 3 of the License, or
7//Copyright> (at your option) any later version.
8//Copyright>
9//Copyright> This program is distributed in the hope that it will be useful,
10//Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11//Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12//Copyright> GNU Affero General Public License for more details.
13//Copyright>
14//Copyright> You should have received a copy of the GNU Affero General Public License
15//Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16//Copyright>
17//Copyright>
18//Copyright> Commercial Alternative: Altair Radioss Software
19//Copyright>
20//Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21//Copyright> software under a commercial license. Contact Altair to discuss further if the
22//Copyright> commercial version may interest you: https://www.altair.com/radioss/.
23#include <cstdlib>
24#include <iostream>
25#include <string>
26#include <cstring>
27
28#ifdef _WIN64
29// Windows only
30#include <Windows.h>
31#include <processthreadsapi.h>
32#else
33// Linux only
34#include <stdio.h>
35#include <sys/resource.h>
36#endif
37
38#ifdef _OPENMP
39#include <omp.h>
40#endif
41
42#define _FCALL
43
44char omp_stacksize[128];
45char stacksize[128];
46
47void solver_stacksize();
48
49
50// -------------------------------------------------------------------------------------------------------
51// Solver_Stacksize
52// -------------------------------------------------------------------------------------------------------
53// Gets the defined OMP_STACKSIZE or KMP_STACKSIZE for the solver
54// For intel Compilers : if less than 250MB, set to 250MB
55// For other compilers (gfortran / armflang): get the value from the environment variable OMP_STACKSIZE
56// check it it makes sense. store the value in the global variable omp_stacksize
57//
58// Get the stacksize of the solver
59// -------------------------------------------------------------------------------------------------------
61
62 // -------------------------------------------------------------------------------------------------------
63 // Thread Stacksize : OMP_STACKSIZE or KMP_STACKSIZE
64 // -------------------------------------------------------------------------------------------------------
65 std::string str_stack;
66
67#ifdef _OPENMP
68
69#if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
70
71 // Intel Compilers use kmp_get_stacksize / kmp_set_stacksize API
72 size_t stack_size = kmp_get_stacksize();
73 if (stack_size < 262144000){ // < 250 MB, set to 250 MB
74 stack_size = 262144000;
75 kmp_set_stacksize(stack_size);
76 }
77 size_t stack_mb = stack_size /1048576;
78 str_stack = std::to_string(stack_mb)+" MB";
79
80#else
81
82 // No API on gfortran or ArmFlang
83 // Grab the value from the environment variable OMP_STACKSIZE and postrpocess it
84 // tp have a value in MB or K,M,G if expressed like this
85 const char* env_stack_size = std::getenv("OMP_STACKSIZE");
86
87 if ( env_stack_size == NULL) {
88 str_stack = "0 MB";
89
90 }else{
91 char last_char = env_stack_size[strlen(env_stack_size)-1];
92
93 if (last_char == 'G' || last_char == 'g' || last_char == 'M' || last_char == 'm' || last_char == 'K' || last_char == 'k'){ // Value is set in KB or MB or GB
94 char *stack_size = strdup(env_stack_size);
95 stack_size[strlen(stack_size)-1] = '\0';
96 try{ // Try to convert value in Integer - if Rubish print 0 as OMP_STACKSIZE
97 int stack_size_int = std::stoi(stack_size);
98 str_stack = std::to_string(stack_size_int)+" "+last_char+"B";
99 }
100 catch (...){ // Cannot convert
101 str_stack = "0 MB";
102 }
103 }else{ // Value is set in KBytes / Read & try to convert in MB
104 try{
105 int stack_size_int = std::stoi(env_stack_size)/1024;
106 str_stack = std::to_string(stack_size_int)+" MB";
107 }
108 catch (...){
109 str_stack = "0 MB";
110 }
111 }
112 }
113
114#endif
115
116#else
117 str_stack = std::string("0");
118#endif
119
120 // -------------------------------------------------------------------------------------------------------
121 // Stacksize on Windows or Linux
122 // -------------------------------------------------------------------------------------------------------
123#ifdef _WIN64
124 // Stacksize on Windows with Handle
125 // -------------------------------------------------------------------------------------------------------
126 std::string stsize;
127
128 // Method : Get the stacksize from the PE Header
129 // Grab in the Header from Module Handle
130 HMODULE Program= GetModuleHandle(NULL);
131 if(Program != NULL) {
132 IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)Program;
133 IMAGE_NT_HEADERS* pNTHeaders =(IMAGE_NT_HEADERS*)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
134 PIMAGE_OPTIONAL_HEADER pOptionalHeader = &pNTHeaders->OptionalHeader;
135 DWORD stack=pOptionalHeader->SizeOfStackReserve /(1024*1024);
136 stsize = std::to_string(stack) + " MB";
137 }else{
138 stsize = "-1 MB";
139 }
140 strcpy_s(stacksize, 128, stsize.c_str());
141#else
142 // Stacksize on Linux getrlimit call
143 // -------------------------------------------------------------------------------------------------------
144 struct rlimit rl;
145 int result = getrlimit(RLIMIT_STACK, &rl);
146 if (result == 0){
147 if (rl.rlim_cur == -1){
148 strcpy(stacksize, "Unlimited");
149 }else{
150 long int StMB = rl.rlim_cur / (1024*1024);
151 sprintf(stacksize, "%ld MB", StMB);
152 // Try to increase Stacksize
153 rl.rlim_cur = rl.rlim_max;
154 setrlimit(RLIMIT_STACK, &rl);
155 }
156 }else{
157 strcpy(stacksize, "-1 MB");
158 }
159#endif
160
161#ifdef _WIN64
162 strcpy_s(omp_stacksize, 128, str_stack.c_str());
163#else
164 strcpy(omp_stacksize, str_stack.c_str());
165#endif
166}
167
168extern "C" {
169 // get solver stacksize : return the stacksize stored in the global variable omp_stacksize
170 // stacksize : output string must be allocated
171 // len : length of the output string : must be at least 128
172 void get_solver_stacksize(char* stsize, int* stsize_len, char *omp_stsize,int * omp_stsize_len){
173#ifdef _WIN64
174 strcpy_s(stsize, *stsize_len, stacksize);
175 strcpy_s(omp_stsize, *omp_stsize_len, omp_stacksize);
176
177#else
178 strcpy(stsize, stacksize);
179 strcpy(omp_stsize, omp_stacksize);
180#endif
181 *stsize_len = strlen(stacksize);
182 *omp_stsize_len = strlen(omp_stacksize);
183 }
184
185
186 void get_solver_stacksize_(char* stsize, int* stsize_len, char *omp_stsize,int * omp_stsize_len){
187#ifdef _WIN64
188 strcpy_s(stsize, *stsize_len, stacksize);
189 strcpy_s(omp_stsize, *omp_stsize_len, omp_stacksize);
190
191#else
192 strcpy(stsize, stacksize);
193 strcpy(omp_stsize, omp_stacksize);
194#endif
195 *stsize_len = strlen(stacksize);
196 *omp_stsize_len = strlen(omp_stacksize);
197 }
198
199 void get_solver_stacksize__(char* stsize, int* stsize_len, char *omp_stsize,int * omp_stsize_len){
200#ifdef _WIN64
201 strcpy_s(stsize, *stsize_len, stacksize);
202 strcpy_s(omp_stsize, *omp_stsize_len, omp_stacksize);
203
204#else
205 strcpy(stsize, stacksize);
206 strcpy(omp_stsize, omp_stacksize);
207#endif
208 *stsize_len = strlen(stacksize);
209 *omp_stsize_len = strlen(omp_stacksize);
210 }
211
212 void _FCALL GET_SOLVER_STACKSIZE(char* stsize, int* stsize_len, char *omp_stsize,int * omp_stsize_len){
213#ifdef _WIN64
214 strcpy_s(stsize, *stsize_len, stacksize);
215 strcpy_s(omp_stsize, *omp_stsize_len, omp_stacksize);
216
217#else
218 strcpy(stsize, stacksize);
219 strcpy(omp_stsize, omp_stacksize);
220#endif
221 *stsize_len = strlen(stacksize);
222 *omp_stsize_len = strlen(omp_stacksize);
223 }
224
225
229
233
237
238}
239
240#ifdef USE_MAIN
241
242int main(){
244 int stsize_len;
245 char stsize[128];
246 int omp_stsize_len;
247 char omp_stsize[128];
248
249 stsize_len=128;
250 omp_stsize_len=128;
251 get_solver_stacksize(stsize, &stsize_len, omp_stsize, &omp_stsize_len);
252
253 std::cout << "Stacksize: " << stsize << std::endl;
254 std::cout << "OMP_STACKSIZE: " << omp_stsize << std::endl;
255
256 HMODULE Program= GetModuleHandle(NULL);
257 if(Program == NULL) return 0;
258 IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)Program;
259 IMAGE_NT_HEADERS* pNTHeaders =(IMAGE_NT_HEADERS*)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
260 PIMAGE_OPTIONAL_HEADER pOptionalHeader = &pNTHeaders->OptionalHeader;
261
262 std::cout << "yeah!!!" << pNTHeaders->OptionalHeader.SizeOfImage << std::endl;
263 std::cout << "SizeOfStackReserve: " << std::hex << pOptionalHeader->SizeOfStackReserve << std::endl;
264 std::cout << "SizeOfStackReserve: " << std::dec << pOptionalHeader->SizeOfStackReserve << std::endl;
265
266 exit(0);
267}
268
269#endif
270
int main()
#define _FCALL
void solver_stacksize__()
char omp_stacksize[128]
Definition stacksize.cpp:44
char stacksize[128]
Definition stacksize.cpp:45
void get_solver_stacksize__(char *stsize, int *stsize_len, char *omp_stsize, int *omp_stsize_len)
void get_solver_stacksize(char *stsize, int *stsize_len, char *omp_stsize, int *omp_stsize_len)
void get_solver_stacksize_(char *stsize, int *stsize_len, char *omp_stsize, int *omp_stsize_len)
void _FCALL GET_SOLVER_STACKSIZE(char *stsize, int *stsize_len, char *omp_stsize, int *omp_stsize_len)
void solver_stacksize_()
void solver_stacksize()
Definition stacksize.cpp:60
void _FCALL SOLVER_STACKSIZE()