> On 23 Nov 2015, at 11:49, Stephen Linton <s...@st-andrews.ac.uk> wrote:
> 
> Dear Andrew,
> 
> I think what you need is to set BreakOnError to false, as well as possibly 
> setting OnBreak to what you want.
> The messages may still be a bit ugly, but it should do what you need.

Hmm, I would expect that some more work is needed -- for similar problems, I 
have made extensive use of the undocumented (bug highly useful) function 
"CALL_WITH_CATCH", combined with setting BreakOnError to false (and resetting 
it to its previous value afterwards). 

Before I give some example code, let me point out another caveat that was not 
mentioned so far: You were talking about out of memory errors. For these, the 
strategy suggested by other (and which the example below also uses) is NOT a 
particular good one. The reason is that when you encounter an out-of-memory 
error, GAP increases its heap space (I think for now it doubles it). It always 
does that, before the error handling (it has to -- otherwise, the error handler 
cannot run, as it also needs memory).

Thus, GAP will eat more and more memory, with each out-of-memory error. If you 
need to handle dozens or more of this, this quickly gets impractical. Hence, 
for my own large-scale computations of this kind, I deal with this in a 
different way. There, I need to compute results for millions (billions?) of 
inputs, and a couple thousand of them will lead to OOM errors initially). What 
I am doing is this: The computations are distributed over multiple machines. On 
each, a shell script runs a GAP instance. The instances are set up to quit when 
there is an error (instead of the break loop); when that happens, the shell 
script just restarts GAP -- thanks to suitable bookkeeping, the computations 
resumes at the next group, and the logs contain a marker telling me whether / 
which cases failed. The bookkeeping in my context is actually a bit complicated 
(GAP communicates with a central server via SCSP), but for a single machine 
setup, one can simply use a text file, with one line for each task -
 - when a task starts, its id is added to the file, when it is finished, the 
the result is stored in another file. This way, I can see which tasks started, 
and which actually finished. When the GAP script starts, it reads in the first 
file, to find out which problems already are "done".

This approach deals with memory issues, and also makes sure that I never 
continue computations with inconsistent internal state.


Anyway, if you only expect a small number of these error, or if you mainly need 
to deal with other kinds of errors, you could use (a variation of) the 
following snippet, using the UNDOCUMENTED function CALL_WITH_CATCH


CallWithErrorHandling := function(f, args)
  local old, result;
  old := BreakOnError;
  BreakOnError := false;
  result := CALL_WITH_CATCH(f, args);
  BreakOnError := old;
  if result[1] = false then
    return fail; # an error occurred
  fi;
  return result[2];  # return actual result
end;


Then, replace e.g.
  x := f(a,b,c)
by
  x := CallWithErrorHandling(f,[a,b,c]);

Of course the above code makes various assumptions, e.g. it assumes the
function being called returns something, etc. -- but you should be able to 
modify
it to do what you need.

But remember: This is using an UNDOCUMENTED GAP function, so it may
break in the future -- though right now that seems unlikely.


Cheers,
Max
_______________________________________________
Forum mailing list
Forum@mail.gap-system.org
http://mail.gap-system.org/mailman/listinfo/forum

Reply via email to