52
$\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$
7
  • 1
    $\begingroup$ Depending on what you're running, it can sometimes take a while in between pressing Alt+. and the execution being aborted. $\endgroup$ Jul 14, 2016 at 16:00
  • 1
    $\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$ Jul 14, 2016 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, 2016 at 16:07
  • 8
    $\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, 2016 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$ Oct 8, 2018 at 7:58

5 Answers 5

36
$\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$
13
  • 8
    $\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$ Jul 14, 2016 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$ Jul 19, 2016 at 22:35
  • 2
    $\begingroup$ @EricTowers it's weird because OS can kill any processes very fast but kernel somehow lacks this opportunity. $\endgroup$ Mar 24, 2018 at 22:47
  • 3
    $\begingroup$ @EricTowers but it could make new processes and control them, right? $\endgroup$ Mar 24, 2018 at 22:56
  • 2
    $\begingroup$ @EricTowers I was wondering if anything is preventing this to be implemented. $\endgroup$ Mar 24, 2018 at 23:45
8
$\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$
7
$\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$
5
$\begingroup$

The lack of ability to abort a running computation is Mma's greatest aggravation. After reading everyone's comments here, I still can't see why the kernel does not have a hardware watchdog timer that interrupts once/second to check for an Abort signal. It would slow everything down by 0.00001%; so what?

Anyway, here is my workaround: inside your deepest undebugged loop, put a "Pause[0.0001]" statement. This greatly facilitates detection of the Abort signal.

$\endgroup$
2
$\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$
1
  • $\begingroup$ That solved the problem for me, thanks. $\endgroup$
    – Luca
    Mar 29 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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