35
$\begingroup$

This frequently happens to me. I'll have some code, execute it, and realize it's taking a long time. My PC isn't frozen, and Mathematica itself isn't even frozen: I can select stuff in the notebook, type new stuff, open and close sections, etc. But when I click "abort evaluation", it will just ignore it. I'll repeatedly do it, and it will ignore it for several minutes.

What's going on here? How can the notebook be responding to everything else, but just ignore my request to stop evaluating? It makes me furious when this happens.

$\endgroup$
  • 1
    $\begingroup$ Depending on what you're running, it can sometimes take a while in between pressing Alt+. and the execution being aborted. $\endgroup$ – J. M. is away Jul 14 '16 at 16:00
  • $\begingroup$ @J.M. Well, that's what I'm curious about. Why? In Windows or Linux, if I kill a process, it almost always immediately closes, especially if I use a hard kill. $\endgroup$ – YungHummmma Jul 14 '16 at 16:01
  • 9
    $\begingroup$ Killing a process is different from asking Mathematica to abort an evaluation because in the latter case it has to return with the Kernel in a state that permits you to continue working with the previously generated results and definitions. You can of course kill the Mathematica process immediately, too. But that means it quits and you lose your work. Although I wish abort were more responsive, too, one has to keep in mind that checking for aborts more frequently would also slow down normal computations. $\endgroup$ – Jens Jul 14 '16 at 16:07
  • 7
    $\begingroup$ Some interfaces to external libraries that Mathematica uses (for example TriangleLink and TetGenLink) do not handle aborts. It's only when this 'external' process has come to a halt that the abort goes through. $\endgroup$ – user21 Jul 14 '16 at 16:42
  • $\begingroup$ there is also CheckAbort and AbortProtect which allow top level Mathematica code to handle/ignore aborts, so it not necessarily needs external libraries to see the situation you are reporting... $\endgroup$ – Albert Retey Oct 8 '18 at 7:58
26
$\begingroup$

There are two processes running. The first process is the FrontEnd. The FrontEnd receives your keypresses and renders text and plots. The second process is the Kernel. The Kernel receives commands to perform calculations, stores the states of variables, and does pretty much all the calculating.

When you press Alt-., the FrontEnd immediately receives your abort command. It immediately passes it to the Kernel. In the Kernel, the abort command is queued until the Kernel actually checks its queue of things to do. If the Kernel is busily executing a calculation, it may only check the queue infrequently. There is a tradeoff here -- if the kernel frequently interrupts calculations to check the queue, the calculations take noticeably longer to run; if it checks infrequently, abort commands take a long time to have effect.

After the Kernel checks the queue, it will terminate the current calculation. This termination can also take a while. (If your calculation produces checkpointing output, it is easy to see that the checkpointing output stops.) It was much worse in earlier versions of Mathematica. For instance, I have had calculations that ran for a day, were aborted, then spent another day meticulously freeing memory for bazillions of temporary results, one at a time. (Kernel: "I'm done with these four bytes." OS: "OK." Kernel: "I'm done with these four bytes". OS: "OK." ...) (This was far more likely if the computation had intermediate expression swell sufficient to significantly spill into swap.)

When the cleanup is complete, the Kernel is ready to continue calculating.

In the context of your Question and comments to it, it is important to note that no process is terminated by an abort. If you really want to abort a calculation and you are willing to re-evaluate all the context you had before the computation, you can "Quit Kernel", which does result in killing the Kernel process. If the system is excessively busy (say swapping a working set that is about twice as large as memory), even this can take a long time because even the FrontEnd will become nonresponsive. (First I have to get the OS to reload the code for what to do when someone clicks on a menu item. ... Okay. Now I have to get the OS to reload the code for the callback for that particular menu item. ... Okay. Now I have to ...) It is interesting/frustrating to watch the FrontEnd have to swap in code to figure out how to draw the menus and deal with overlaps. My fingers still have Alt-k-q (menu:Kernel: Quit) in muscle memory as a way to minimize the amount of swap-in required to kill a kernel. (Note that this key sequence hasn't worked for several versions of Mathematica.)

$\endgroup$
  • 3
    $\begingroup$ In regards to your mention of the tradeoff: I totally understand the tradeoff idea, but to me it's always seemed obvious: if I can give up 1% of my computation time to have the kernel check if I want to end evaluation, I'd do that in a heartbeat. $\endgroup$ – YungHummmma Jul 14 '16 at 19:19
  • 2
    $\begingroup$ It's not always that simple. The kernel may have to pass control to another process (see MathLink example). The kernel may be using a library function incorporated from elsewhere (see BLAS: relavant question/answer). Consequently, the kernel's thread of execution may spend arbitrarily large amounts of time in code not written by Wolfram, Inc. $\endgroup$ – Eric Towers Jul 19 '16 at 22:35
  • 1
    $\begingroup$ @EricTowers it's weird because OS can kill any processes very fast but kernel somehow lacks this opportunity. $\endgroup$ – Vsevolod A. Mar 24 '18 at 22:47
  • 1
    $\begingroup$ @VsevolodA. : The OS gets control every process switch, every IO call from a process, every interrupt, and in several other circumstances. It is constantly receiving control. The Mathematica kernel is a user space process that passes control to other user space processes. When it has passed control, it is not running and can take no actions. $\endgroup$ – Eric Towers Mar 24 '18 at 22:49
  • 1
    $\begingroup$ @EricTowers but it could make new processes and control them, right? $\endgroup$ – Vsevolod A. Mar 24 '18 at 22:56
7
$\begingroup$

The situation has already been explained by Eric Towers in more detail and clarity than I would have been capable of, but as far as a solution goes I think I have a slightly better one:

This gives me a keyboard shortcut Ctrl+Q to kill the kernel, and it is now a reflex action if I realize that I just asked Mathematica to do something that is going to hang the system. Naturally you will lose all of the in-memory definitions, but with a well structured Notebook restoring them is usually much faster than dealing with a hung system.

This keyboard shortcut seems to act faster and more reliably than walking the menus by key command as Eric advised.

Recommended reading:

$\endgroup$
6
$\begingroup$

If you ever develop a library for LibraryLink, be sure to include calls to AbortQ to support aborting lengthy computations.

Code that runs for a long time should call AbortQ to see if the user has aborted the computation.

Otherwise, your library will be one of the causes of long-ignored aborts.

$\endgroup$
1
$\begingroup$

This happens to me if I use the NotebookEvaluate[] function as described here: Why doesn't 'Abort evaluation' properly work when NotebookEvaluate is executed?

Avoiding that function and rewriting the other notebooks as packages has fixed this issue for me.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.