Why does a call to torch.tensor inside of apply_async fail to complete (seems to block execution)?
I'm trying to understand why the following simple example doesn't successfully complete execution and seems to get stuck on the first line of really_simple_func (on Ubuntu machines, but not Windows). The code is:
import torch as t
import numpy as np
import multiprocessing as mp          # I've tried both multiprocessing
# import torch.multiprocessing as mp  # and torch.multiprocessing

def really_simple_func():
    temp_val_2 = t.tensor(np.zeros(425447)[0:400000])  # this is the line that blocks.
    return 4.3

if __name__ == &quot;__main__&quot;:
    print(&quot;Run brief starting&quot;)
    some_zeros = np.zeros(425447)
    temp_val = t.tensor(some_zeros[0:400000]) # DELETE THIS LINE TO MAKE IT WORK

    pool = mp.Pool(processes=1)
    job = pool.apply_async(really_simple_func)
    print(&quot;just before job.get()&quot;)
    result = job.get()
    print(&quot;Run brief completed. Reward = {}&quot;.format(result))

I have torch 1.11.0 installed, numpy 1.22.3 and have tried both CPU and GPU versions of Torch. When I run this code on two different Ubuntu machines, I get the following output:
Run brief starting
just before job.get()

However, the code never successfully completes (doesn't print the &quot;Run brief completed&quot; line). (It does complete on a third Windows box).
On the Ubuntu machines, if I delete the line with the comment &quot;#DELETE THIS LINE TO MAKE IT WORK&quot; the execution DOES complete, printing the final line as expected. Similarly, if I leave the line defining temp_val in but delete the line with the comment &quot;This is the line that blocks&quot; it will also complete. Moreover, if I reduce the size of the temp_val tensor (say from 400000 to 4000) it will also complete successfully. Finally, it is worth noting that while I can reproduce this behaviour on two different Ubuntu machines, this code does actually complete on my Windows machine - though, as far as I can tell, the versions of key packages, such as torch, are the same.
I don't understand this behaviour. I suspect it is something to do with the way torch allocates memory or stores information. I've tried calling del temp_val to free up memory, but that doesn't seem to fix things. It seems to me that the async call to t.tensor within really_simple_func is stopped from completing if there has already been a call to t.tensor in the main code block, creating a sufficiently large tensor.
I don't understand why this is happening, or even if that is the correct explanation. In any case, what would be best practice if I do need to do some tensor processing within apply_async as well as in the main thread? More generally, what is Torch waiting on when I make a call to t.tensor?
(Obviously, this is just the simplest version of the real code I'm trying to get to work that reproduced this issue. I realise that calling mp.Pool with only one process doesn't really make sense...nor, indeed, does using apply_async to call a function that returns a constant!)

Unfortunately, I cannot provide any answers to your questions.
I can, however, share experiences with seemingly the same issue. I use a Linux machine with torch 1.8.1 and numpy 1.19.2.
When I run the following code on my machine:
with Pool(max_pool) as p:
    pool_outputs = list(
        tqdm(
            p.imap(lambda f: get_model_results_per_query_file(get_preds, tokenizer, f), query_files),
            total=len(query_files)
        )
    )   

For which the function get_model_results_per_query_file contains operations similar to the following:
feats = features.unsqueeze(0).repeat(batch_size, 1, 1).to(device)

(features is a torch tensor)
The first round of jobs automatically fail, and new ones are immediately started (that do not fail for some reason). The whole process never completes though, since the main process still seems to be waiting for the first failed jobs.
If I remove the lines in my code involving the repeat function, no jobs fail.
I managed to solve my issue and preserve the same results by adapting a similar solution to yours:
feats = torch.as_tensor(np.tile(features, (batch_size, 1, 1))).to(device)

I believe as_tensor works in a similar fashion to from_numpy in this case.
I only managed to find this solution thanks to your post and your proposed workaround, so thank you!
