Re: [fricas-devel] )fin, restart, (|spad|) with Clozure CL based FriCAS

2024-05-22 Thread Grégory Vanuxem
CTRL-C is not affected in fact. This is the usual behavior of FriCAS
with Clozure CL.
Sorry for the noise.

Le mer. 22 mai 2024 à 22:08, Grégory Vanuxem  a écrit :
>
> Oh, zut! (responding to myself)
>
> > (there are several use of 'CATCH' and there is 'handler-bind').
>
> Badly handled. CTRL-C for example.
>
> More work needed in this regard.
>
> Le mer. 22 mai 2024 à 22:03, Grégory Vanuxem  a écrit :
> >
> > Hello Waldek, hello all,
> >
> > First, thanks for your response, it was very instructive it leads me
> > to solve this long outstanding issue with my FriCAS copy.
> >
> > Le mar. 21 mai 2024 à 20:32, Waldek Hebisch  a écrit :
> > >
> > > On Tue, May 21, 2024 at 01:57:45PM +0200, Grégory Vanuxem wrote:
> > > > Hello,
> > > >
> > > > I try to understand why a Clozure CL 'terminate' method is not called
> > > > from the interpreter. I have a CL class jlref, when a jlref object is
> > > > no longer referenced the CL garbage collector reclaims it. It is
> > > > possible in different CL implementations to add a 'hook' to do some
> > > > job at that time. Personally I then unreference the real Julia object
> > > > in such a way it can be GC reclaimed in Julia, jlref is just a class
> > > > that holds information about it.
> > > >
> > > > For SBCL I have no problem, but 'ccl:terminate' which should be
> > > > automatically called is never called. But, and this is the main point,
> > > > following an advice in a Clozure mailing list, I tried to use/define
> > > > this method directly at execution time using ')fin', and surprisingly,
> > > > using ')fin' automatically triggers 'terminate' on every objects that
> > > > are/(were ?) reclaimed.
> > > >
> > > > So my question, what does ')fin' do? And do you happen to know where I
> > > > need to look in the FriCAS source code to better understand its
> > > > effect?
> > >
> > > AFAIK ')fin' is doing "nothing", is just returns back to whatever Lisp
> > > was doing befor calling FriCAS.  To understand relation with Lisp,
> > > look at 'src/lisp/fricas-lisp.lisp', in particular 'save-core-restart'.
> >
> > Yes!!! This is what helped me. I looked more carefully at this function 
> > and..
> >
> > >
> > > > Furthermore, in src/interp/int-top.boot, the documentation says that
> > > > to return to the interpreterafer after ')fin'  '(restart)' should be
> > > > used. In fact, before some change in the FriCAS source I think, so I
> > > > used (|spad|). Again following an advice. And, again, with Clozure CL,
> > > > contrary to SBCL, that leads to strange things after returning to the
> > > > interpreter and executing foreign code (principally bad addresses and
> > > > therefore segfault).
> > >
> > > The function to start FriCAS is 'fricas_restart'.  'fricas_restart'
> > > is doing some initialization which may be unnecessary when executed
> > > second time.  OTOH re-doing initalization should be harmless and
> > > some probably is needed.
> >
> > I see that, and in fact only propog CL use (|spad|) directly in other
> > piece(s ?) of code. Using it is handy though, not everything is
> > reinitialized.
> >
> > > Note that ')fin' is really unsuppored by FriCAS, basically
> > > it is "pray that Lisp will do what you want".  In particular IIRC
> > > it simply quits FriCAS when using ECL and I think it never fully
> > > worked with Clozure CL.
> > >
> > > > So maybe I first need to know a better CL command, to return to the
> > > > interpreter? But also, of course, to know why the ccl:terminate is not
> > > > called in the interpreter. R. Munyer in the CCL mailing list found a
> > > > way, see the attached transcript file, but he uses ')fin' and no
> > > > Clozure CL FFI. I tried to use different (eva-when) to define the
> > > > ccl:terminate method without success since the code is build/compiled
> > > > (src/lisp).
> > >
> > > I think that ')fin' is irrelevant, you should get the same effect
> > > using ')lisp' or if that is inconvenient you can put code in the
> > > file and use ')read'.  The main difference is that FriCAS needs
> > > specific settings of several global variables and FriCAS catches
> > > errors (there are several use of 'CATCH' and there is 'handler-bind').
> > > This _should_ make no difference.  What _may_ matter is order of
> > > initialization.  In particular FriCAS performs some initializations
> > > before dumping image.  But several thing do not survive to
> > > restarted image, so need to be done later, after start of new image.
> >
> > I guessed after your email that the behavior of ')fin' is somewhat 
> > undefined.
> >
> > So now, my solution to my problem. A proposed diff is attached, it
> > uniformizes/simplifies the Clozure CL boot I think.
> >
> > Looking at the attached transcript in my previous email I was
> > surprised to see that the banner was displayed at that time, and
> > experimenting more with the pure CL interpreter after ')fin' I first
> > saw that calling Julia was not possible. When you embed Julia using
> > libjulia, Julia doe

Re: [fricas-devel] )fin, restart, (|spad|) with Clozure CL based FriCAS

2024-05-22 Thread Grégory Vanuxem
Oh, zut! (responding to myself)

> (there are several use of 'CATCH' and there is 'handler-bind').

Badly handled. CTRL-C for example.

More work needed in this regard.

Le mer. 22 mai 2024 à 22:03, Grégory Vanuxem  a écrit :
>
> Hello Waldek, hello all,
>
> First, thanks for your response, it was very instructive it leads me
> to solve this long outstanding issue with my FriCAS copy.
>
> Le mar. 21 mai 2024 à 20:32, Waldek Hebisch  a écrit :
> >
> > On Tue, May 21, 2024 at 01:57:45PM +0200, Grégory Vanuxem wrote:
> > > Hello,
> > >
> > > I try to understand why a Clozure CL 'terminate' method is not called
> > > from the interpreter. I have a CL class jlref, when a jlref object is
> > > no longer referenced the CL garbage collector reclaims it. It is
> > > possible in different CL implementations to add a 'hook' to do some
> > > job at that time. Personally I then unreference the real Julia object
> > > in such a way it can be GC reclaimed in Julia, jlref is just a class
> > > that holds information about it.
> > >
> > > For SBCL I have no problem, but 'ccl:terminate' which should be
> > > automatically called is never called. But, and this is the main point,
> > > following an advice in a Clozure mailing list, I tried to use/define
> > > this method directly at execution time using ')fin', and surprisingly,
> > > using ')fin' automatically triggers 'terminate' on every objects that
> > > are/(were ?) reclaimed.
> > >
> > > So my question, what does ')fin' do? And do you happen to know where I
> > > need to look in the FriCAS source code to better understand its
> > > effect?
> >
> > AFAIK ')fin' is doing "nothing", is just returns back to whatever Lisp
> > was doing befor calling FriCAS.  To understand relation with Lisp,
> > look at 'src/lisp/fricas-lisp.lisp', in particular 'save-core-restart'.
>
> Yes!!! This is what helped me. I looked more carefully at this function and..
>
> >
> > > Furthermore, in src/interp/int-top.boot, the documentation says that
> > > to return to the interpreterafer after ')fin'  '(restart)' should be
> > > used. In fact, before some change in the FriCAS source I think, so I
> > > used (|spad|). Again following an advice. And, again, with Clozure CL,
> > > contrary to SBCL, that leads to strange things after returning to the
> > > interpreter and executing foreign code (principally bad addresses and
> > > therefore segfault).
> >
> > The function to start FriCAS is 'fricas_restart'.  'fricas_restart'
> > is doing some initialization which may be unnecessary when executed
> > second time.  OTOH re-doing initalization should be harmless and
> > some probably is needed.
>
> I see that, and in fact only propog CL use (|spad|) directly in other
> piece(s ?) of code. Using it is handy though, not everything is
> reinitialized.
>
> > Note that ')fin' is really unsuppored by FriCAS, basically
> > it is "pray that Lisp will do what you want".  In particular IIRC
> > it simply quits FriCAS when using ECL and I think it never fully
> > worked with Clozure CL.
> >
> > > So maybe I first need to know a better CL command, to return to the
> > > interpreter? But also, of course, to know why the ccl:terminate is not
> > > called in the interpreter. R. Munyer in the CCL mailing list found a
> > > way, see the attached transcript file, but he uses ')fin' and no
> > > Clozure CL FFI. I tried to use different (eva-when) to define the
> > > ccl:terminate method without success since the code is build/compiled
> > > (src/lisp).
> >
> > I think that ')fin' is irrelevant, you should get the same effect
> > using ')lisp' or if that is inconvenient you can put code in the
> > file and use ')read'.  The main difference is that FriCAS needs
> > specific settings of several global variables and FriCAS catches
> > errors (there are several use of 'CATCH' and there is 'handler-bind').
> > This _should_ make no difference.  What _may_ matter is order of
> > initialization.  In particular FriCAS performs some initializations
> > before dumping image.  But several thing do not survive to
> > restarted image, so need to be done later, after start of new image.
>
> I guessed after your email that the behavior of ')fin' is somewhat undefined.
>
> So now, my solution to my problem. A proposed diff is attached, it
> uniformizes/simplifies the Clozure CL boot I think.
>
> Looking at the attached transcript in my previous email I was
> surprised to see that the banner was displayed at that time, and
> experimenting more with the pure CL interpreter after ')fin' I first
> saw that calling Julia was not possible. When you embed Julia using
> libjulia, Julia does not support multithreaded code from the host
> process, I encountered this with SBCL, and it leads to segfault, bad
> stack etc. Only the thread that initialized Julia is able to use
> commands using the C interface. Experimenting some interruptions and
> backtraces I saw a thread started after ')fin'. Apparently the "main"
> process (not exactly in fact, the 

Re: [fricas-devel] )fin, restart, (|spad|) with Clozure CL based FriCAS

2024-05-22 Thread Grégory Vanuxem
Hello Waldek, hello all,

First, thanks for your response, it was very instructive it leads me
to solve this long outstanding issue with my FriCAS copy.

Le mar. 21 mai 2024 à 20:32, Waldek Hebisch  a écrit :
>
> On Tue, May 21, 2024 at 01:57:45PM +0200, Grégory Vanuxem wrote:
> > Hello,
> >
> > I try to understand why a Clozure CL 'terminate' method is not called
> > from the interpreter. I have a CL class jlref, when a jlref object is
> > no longer referenced the CL garbage collector reclaims it. It is
> > possible in different CL implementations to add a 'hook' to do some
> > job at that time. Personally I then unreference the real Julia object
> > in such a way it can be GC reclaimed in Julia, jlref is just a class
> > that holds information about it.
> >
> > For SBCL I have no problem, but 'ccl:terminate' which should be
> > automatically called is never called. But, and this is the main point,
> > following an advice in a Clozure mailing list, I tried to use/define
> > this method directly at execution time using ')fin', and surprisingly,
> > using ')fin' automatically triggers 'terminate' on every objects that
> > are/(were ?) reclaimed.
> >
> > So my question, what does ')fin' do? And do you happen to know where I
> > need to look in the FriCAS source code to better understand its
> > effect?
>
> AFAIK ')fin' is doing "nothing", is just returns back to whatever Lisp
> was doing befor calling FriCAS.  To understand relation with Lisp,
> look at 'src/lisp/fricas-lisp.lisp', in particular 'save-core-restart'.

Yes!!! This is what helped me. I looked more carefully at this function and..

>
> > Furthermore, in src/interp/int-top.boot, the documentation says that
> > to return to the interpreterafer after ')fin'  '(restart)' should be
> > used. In fact, before some change in the FriCAS source I think, so I
> > used (|spad|). Again following an advice. And, again, with Clozure CL,
> > contrary to SBCL, that leads to strange things after returning to the
> > interpreter and executing foreign code (principally bad addresses and
> > therefore segfault).
>
> The function to start FriCAS is 'fricas_restart'.  'fricas_restart'
> is doing some initialization which may be unnecessary when executed
> second time.  OTOH re-doing initalization should be harmless and
> some probably is needed.

I see that, and in fact only propog CL use (|spad|) directly in other
piece(s ?) of code. Using it is handy though, not everything is
reinitialized.

> Note that ')fin' is really unsuppored by FriCAS, basically
> it is "pray that Lisp will do what you want".  In particular IIRC
> it simply quits FriCAS when using ECL and I think it never fully
> worked with Clozure CL.
>
> > So maybe I first need to know a better CL command, to return to the
> > interpreter? But also, of course, to know why the ccl:terminate is not
> > called in the interpreter. R. Munyer in the CCL mailing list found a
> > way, see the attached transcript file, but he uses ')fin' and no
> > Clozure CL FFI. I tried to use different (eva-when) to define the
> > ccl:terminate method without success since the code is build/compiled
> > (src/lisp).
>
> I think that ')fin' is irrelevant, you should get the same effect
> using ')lisp' or if that is inconvenient you can put code in the
> file and use ')read'.  The main difference is that FriCAS needs
> specific settings of several global variables and FriCAS catches
> errors (there are several use of 'CATCH' and there is 'handler-bind').
> This _should_ make no difference.  What _may_ matter is order of
> initialization.  In particular FriCAS performs some initializations
> before dumping image.  But several thing do not survive to
> restarted image, so need to be done later, after start of new image.

I guessed after your email that the behavior of ')fin' is somewhat undefined.

So now, my solution to my problem. A proposed diff is attached, it
uniformizes/simplifies the Clozure CL boot I think.

Looking at the attached transcript in my previous email I was
surprised to see that the banner was displayed at that time, and
experimenting more with the pure CL interpreter after ')fin' I first
saw that calling Julia was not possible. When you embed Julia using
libjulia, Julia does not support multithreaded code from the host
process, I encountered this with SBCL, and it leads to segfault, bad
stack etc. Only the thread that initialized Julia is able to use
commands using the C interface. Experimenting some interruptions and
backtraces I saw a thread started after ')fin'. Apparently the "main"
process (not exactly in fact, the actual boot process of FriCAS bypass
the CCL read-eval-print loop main thread) was at that time in a idle
state or not started or sleeping, I don't really know, and the
ccl::terminate method is then called on reclaimed CL objects. It's
another thread in fact. FriCAS on CCL is then a multithreaded app :-)

Diggering more in 'save-core-restart' I saw that only FriCAS on top of
CCL is using a fricas-a

[fricas-devel] Serial part of build

2024-05-22 Thread Waldek Hebisch
I looked a what takes time during serial part of build.  More
precisly, during database bootstrap step (that is 'boo_db.input').
>From top-level point of view most time goes into compilation
of Spad files (about 90%) and about 10% of time is spent in
'make-databases'.  At lower level time usage of mostly spread
out into many small contibutions.  Biggest single item is
'COMPILE-FILE' (23.3%), next is pretty printer (about 15%) and
EVAl.  Also, significant time goes into parsing and scanning of
Spad sources (2.9% + 8.5%).  Surprisingly expensive is clearing
of category caches (7%).  What could be improved?  We probably
could save part of time spent in 'COMPILE-FILE', say by tweaking
optimization setting or (as Qian did) loading files in interpret
mode.  But trying

)lisp (proclaim '(optimize (speed 0) (safety 1) (compilation-speed 3)))

before database bootstrap made no differece.

I am affraid that bigger gain is possible only as sum of several
small improvements.  For example both Lisp pretty
printing and Spad syntactic processing take much more time than
they should (on my machine pretty printer spends about 880 clocks
per output charater), but speeding them up really means new
faster implementation, so nontrivial work.  Some gains may be
easy, but probably would produce only small effect, so we would
need many such improvements to have visible speedup.


Top positions (slightly abbreviated to make it clear) in profile are:


  2750  23.3   |compDefineLisplib| [986]
 1   0.0   2750  23.3   COMPILE-FILE [991]

 2   0.0   (LABELS #:BODY-NAME-2161 :IN PPRINT-FILL) [108]
  1405  11.9   (LABELS SB-IMPL::HANDLE-IT :IN SB-KERNEL:OUTPUT-O
BJECT) [142]
14   0.1   1852  15.7   SB-PRETTY:OUTPUT-PRETTY-OBJECT [157]

 1   0.0   |DomainSubstitutionFunction| [2232]
 1   0.0   |get_database2| [134]
 1   0.0   |compSPADSLAM| [1703]
  1104   9.3   |eval| [96]
21   0.2   PRINT-AND-EVAL-DEFUN [1702]
  1176   9.9   |npboot| [1629]
19   0.2   2322  19.6   EVAL [124]
 2   0.0   SB-INT:EVAL-IN-LEXENV [881]
28   0.2   SB-KERNEL:MAKE-NULL-LEXENV [61]
  2266  19.2   SB-EVAL:EVAL-IN-NATIVE-ENVIRONMENT [38]

  1176   9.9   SB-EVAL::EVAL-TAGBODY [1665]
 0   0.0   1176   9.9   SB-EVAL::EVAL-RETURN-FROM [1664]
  1098   9.3   |make_databases| [2968]
78   0.7   |processGlobals| [1663]

   164   1.4   |merge_info_from_nrlib1| [1769]
   665   5.6   |compDefineLisplib| [986]
 0   0.0830   7.0   |clearConstructorCaches| [1885]
 1   0.0   PNAME [238]
 1   0.0   |clearConstructorCaches| [1885]
 1   0.0   SB-IMPL::GETHASH3 [45]
   828   7.0   |clearCategoryCaches| [115]

 10484  88.7   |compilerDoit| [1540]
 0   0.0  10484  88.7   |spadCompile1| [1539]
 2   0.0   |ncloopIncFileName| [1622]
 10482  88.7   |handle_input_file| [1538]

   662   5.6   |merge_info_from_objects| [1770]
 11727  99.2   |intloopInclude| [1548]
 10482  88.7   |spadCompile1| [1539]
 0   0.0  11727  99.2   |handle_input_file| [1538]
 5   0.0   (FLET #:CLEANUP-FUN-610 :IN |handle_input_file|) 
[2199]
23   0.2   |sayKeyedMsg| [893]
   614   5.2   |merge_info_from_nrlib1| [1769]
23   0.2   OPEN [627]
 9   0.1   SB-SYS:MAKE-FD-STREAM [490]
  1117   9.4   |intloopInclude0| [1547]
  9937  84.0   |fakeloopInclude0| [1537]

 10470  88.5   |fakeloopInclude0| [1537]
 4   0.0  10470  88.5   |fakeloopProcess| [411]
 1   0.0   |incAppend| [630]
 2   0.0   SB-IMPL::LIST-NREVERSE* [87]
48   0.4   |InterpExecuteSpadSystemCommand| [1545]
  9402  79.5   |fakeloopProcess1| [607]
26   0.2   |processSymbol| [90]
   985   8.3   |StreamNull| [139]

  9402  79.5   |fakeloopProcess| [411]
  

[fricas-devel] [PATCH] fix title related memory issues

2024-05-22 Thread Qian Yun

This patch fixes many memory issues related with title --
especially with long titles in graphs.

The fix includes:

1. memory overwrite in 'spadAction'

(1) -> vp := draw(x,x=1..2); title(vp, new(100, "a".1)$String)
   Compiling function %C with type DoubleFloat -> DoubleFloat
   Graph data being transmitted to the viewport manager...
   FriCAS2D data being transmitted to the viewport manager...
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  3 (X_GetWindowAttributes)
  Resource id in failed request:  0x61616161
  Serial number of failed request:  777
  Current serial number in output stream:  778

2. buffer overflow in 'makeViewport'

3. memory leakage in 'funView2D'/'funView3D'

(if you run "title" in a loop)

- Qian

--
You received this message because you are subscribed to the Google Groups "FriCAS - 
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to fricas-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/8c7e41a7-de44-4daf-9bd6-68ebf9943aa1%40gmail.com.
diff --git a/src/graph/include/spadAction2d.H1 b/src/graph/include/spadAction2d.H1
index 455fef4a..fd4457ad 100644
--- a/src/graph/include/spadAction2d.H1
+++ b/src/graph/include/spadAction2d.H1
@@ -1,2 +1 @@
-extern int readViewman(void *, int);
 extern int spadAction(void);
diff --git a/src/graph/include/spadAction3d.H1 b/src/graph/include/spadAction3d.H1
index cc2cc432..753346ae 100644
--- a/src/graph/include/spadAction3d.H1
+++ b/src/graph/include/spadAction3d.H1
@@ -1,3 +1,2 @@
-extern int readViewman(void *, int);
 extern void scalePoint(viewTriple *);
 extern int spadAction(void);
diff --git a/src/graph/view2D/spadAction2d.c b/src/graph/view2D/spadAction2d.c
index a923ad88..8440b639 100644
--- a/src/graph/view2D/spadAction2d.c
+++ b/src/graph/view2D/spadAction2d.c
@@ -44,22 +44,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "util.H1"
 #include "strutil.h"
 
-/**
- * int readViewman(info,size) *
- **/
-
-int
-readViewman(void * info,int size)
-{
-  int mold = 0;
-
-  fricas_sprintf_to_buf3(errorStr, "%s %d %s", "read of ", size,
-  " bytes from viewport manager\n");
-  mold = check(read(0,info,size));
-  return(mold);
-
-}
-
 /
  * int spadAction() *
  /
@@ -95,8 +79,7 @@ spadAction(void)
 
   case changeTitle:
 readViewman(&i1,intSize);
-readViewman(viewport->title,i1);
-viewport->title[i1] = '\0';
+readViewmanStr(viewport->title, i1, sizeof(viewport->title));
 writeTitle();
 writeControlTitle();
 XFlush(dsply);
@@ -105,8 +88,7 @@ spadAction(void)
 
   case writeView:
 readViewman(&i1,intSize);
-readViewman(filename,i1);
-filename[i1] = '\0';
+readViewmanStr(filename, i1, sizeof(filename));
 fricas_sprintf_to_buf1(errorStr, "%s", "writing of viewport data");
 i3 = 0;
 readViewman(&i2,intSize);
diff --git a/src/graph/view2D/viewport2D.c b/src/graph/view2D/viewport2D.c
index 95b15f21..bc428ce5 100644
--- a/src/graph/view2D/viewport2D.c
+++ b/src/graph/view2D/viewport2D.c
@@ -514,7 +514,7 @@ makeViewport(char *title,int vX,int vY,int vW,int vH,int showCP)
   fprintf(stderr,"view2D: Made a viewport\n");
 #endif
 
-  strcpy(viewport->title,title);
+  strncpy(viewport->title, title, sizeof(viewport->title) - 1);
 
   viewport->closing  = no;
   viewport->allowDraw= yes;   /* just draw axes the first time around */
diff --git a/src/graph/view3D/header.h b/src/graph/view3D/header.h
index 21009335..622b744e 100644
--- a/src/graph/view3D/header.h
+++ b/src/graph/view3D/header.h
@@ -269,7 +269,7 @@ typedef struct _buttonStruct {
 
 typedef struct _controlPanelStruct {
   WindowcontrolWindow, messageWindow, colormapWindow;
-  char  message[40];
+  char  message[80];
   buttonStruct  buttonQueue[maxButtons3D];
 } controlPanelStruct;
 
diff --git a/src/graph/view3D/spadAction3d.c b/src/graph/view3D/spadAction3d.c
index 1cf79001..23260f05 100644
--- a/src/graph/view3D/spadAction3d.c
+++ b/src/graph/view3D/spadAction3d.c
@@ -46,17 +46,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "all_3d.H1"
 #include "strutil.h"
 
-int
-readViewman (void *info,int size)
-{
-  int m = 0;
-
-  fricas_sprintf_to_buf1(errorStr, "%s", "read from viewport manager\n");
-  m = check(read( 0, info, size));
-
-  return(m);
-
-}
 void
 scalePoint (viewTriple *p)
 {
@@ -398,8 +387,7 @@ spadAction (void)
 
   case changeTitle:
 readViewman(&i1,intSize);
-readViewman(viewport->title,i1);
-viewport->title[i1] = '\0';
+readViewmanStr(viewport->title, i1, sizeof(viewport->title));
 writeTitle();
 switch (doingPanel) {
 case CONTROLpanel:
@@ -418,8 +406,7 @@ spadAction (void)
 
   case writeView:
 readViewman(&i1,intSize);