Closed yantosca closed 2 years ago
Looks good.
Thanks for given the CI tests a nice structure!
Still debugging a seg fault when I try to build a larger mechanism than small_strato. It seems to be in C_InitDeclare when we pass it the EQN_NAMES. Will dig into this a bit.
gdb output says:
Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaaf60f76 in __mempcpy_sse2 () from /lib64/libc.so.6
(gdb) where
#0 0x00002aaaaaf60f76 in __mempcpy_sse2 () from /lib64/libc.so.6
#1 0x00002aaaaaf4e06c in _IO_default_xsputn () from /lib64/libc.so.6
#2 0x00002aaaaaf1e033 in vfprintf () from /lib64/libc.so.6
#3 0x00002aaaaaf424cb in vsprintf () from /lib64/libc.so.6
#4 0x0000000000401b55 in bprintf (fmt=0x425ce4 "\"%s\"") at code.c:202
#5 0x0000000000404878 in C_InitDeclare (v=90, n=235, values=0x7ffffffda350)
at code_c.c:333
#6 0x000000000040dd4d in GenerateMonitorData () at gen.c:525
#7 0x000000000041998c in Generate () at gen.c:3629
#8 0x000000000041c66e in main (argc=2, argv=0x7fffffffb938) at kpp.c:640
@RolfSander, I think I see what is going on. In routine C_InitDeclare
I put in a debug statement that only executes when the variable EQN_NAMES is passed:
// debug
if ( v==90 ) {
printf("\n");
for (i=0; i<n; i++) printf( "\n%d, %s\n", i, cval[i] );
exit(1);
}
which gives this output:
0, NO2 --> O3P + NO O3P + AIR + O2 --> O3 O3P + O3 --> 2 O2 O3P + NO + AIR --> NO2 O3P + NO2 --> NO O3P + NO2 --> NO3 O3 + NO --> NO2
so for each index i
, the cval[i]
contains the list of equations from i
to the end of the file. This is causing the seg fault as we eventually run out of memory.
This is called from GenerateMonitorData
in gen.c
here:
p = bufeqn;
for (i = 0; i < EqnNr; i++) {
EqnString(i, p);
seqn[i] = p;
p += MAX_EQNLEN;
}
InitDeclare( EQN_NAMES, EqnNr, (void*)seqn );
If you have any ideas then let me know. Thanks!
I'm sorry but I don't know how to solve this problem.
Maybe the easiest quick&dirty fix is to deactive EQN_NAMES for the C language? I think that would be okay because I don't even know a single KPP user who creates output in C.
Found a solution!
switch( var->type ) {
case VELM: bprintf( " %s %s[] = {\n%5s", C_types[var->baseType], var->name, " " );
for( i = 0; i < n; i++ ) {
switch( var->baseType ) {
case INT:
bprintf( "%3d", ival[i] );
maxCols=12;
break;
case DOUBLE:
case REAL:
bprintf( "%5lg", dval[i] );
maxCols=8;
break;
case STRING:
bprintf( "\"%s\"", cval[i] );
maxCols=8;
break;
case DOUBLESTRING:
// Bug fix: To avoid a segmentation fault, copy the
// string from cval[i] to string variable thisEqn
// before passing it to bprintf.
// -- Bob Yantosca (28 Jun 2022)
strncpy( thisEqn, cval[i], MAX_EQNLEN+1 );
bprintf( "\"%s\"", thisEqn );
maxCols=1;
break;
}
I've since fixed the issue above. For now I only use the small_strato
mechanism for all the C-language integration tests. KPP will now generate code with the other mechanisms (e.g. saprcnov.eqn) though. Good enough for the sake of continuity and for the KPP 3.0.0 version.
This PR fixes several issues that were preventing KPP from generating C-language output code. Namely:
Change
/* */
comment headers to//
, which reads much more clearlyRestored and updated the
drv/general.c
anddrv/general_adj.c
driver programsAdded updates to
gen.c
:_Function
file is generated, we now wrap Fortran90 optional arguments with anif ( useLang == F90_LANG )
. This prevents a compiler error when the target language is C.Vdot
is added to_Function
, we need to loop over elements of the Vdot array if the target language is C. We can only use array notation for Fortran90.Added updates to
code_c.c
:fncPrototipe=0
. This will declare each C-language function so that arrays will have dimensions included in the function interface. This will avoid a compilation error.I have also reorganized the
./ci_tests
subfolders.C_
orF90_
, to denote the target language. (The minimum version test folder has been renamed toX_minver
so that it will come last.NOTE: At present, the C-language code fails when trying to use a mechanism other than
small_strato
. I think this is due to a Makefile issue that happens when e.g. Hessian is turned off but the Makefile looks for the Hessian files. I can implement a similar fix as was done for Fortran90.