Skip to content

Deadlock in threaded dgemv #660

Closed

Description

@bkgood

I've compiled OpenBLAS dfe1eef and I'm linking to it from a JNI interface and calling it from the JVM. It was compiled using USE_THREAD=1 and NO_AFFINITY=0 using gcc 4.4.7. After approximately 5 days of processing between 5 and 10 dgemv calls per second, I saw a deadlock occurring with a thread consuming 100% usage of a CPU core.

I grabbed this backtrace; this was the only thread with symbols in libblas.so:
Thread 1 (process 60961):
#0 0x00007fde1dce2287 in sched_yield () from /lib64/libc.so.6
#1 0x00007fdcca2f5ba5 in exec_blas_async_wait () from ./libblas.so.3
#2 0x00007fdcca2f6272 in exec_blas () from ./libblas.so.3
#3 0x00007fdcca132a74 in dgemv_thread_n () from ./libblas.so.3
#4 0x00007fdcca0f4934 in cblas_dgemv () from ./libblas.so.3
#5 0x00007fdccb31dafb in Java_com_github_fommil_netlib_NativeSystemBLAS_dgemv_1offsets () from /tmp/jniloader5273540829126619406netlib-native_system-linux-x86_64.so
#6 0x00007fde094c04a9 in ?? ()
#7 0x0000000000000000 in ?? ()

./libblas.so.3 is
lrwxrwxrwx 1 wgood users 35 Sep 23 15:16 libblas.so.3 -> libopenblas_sandybridgep-r0.2.14.so

make output looks like this:
OpenBLAS build complete. (BLAS CBLAS LAPACK LAPACKE)

OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (command line : gcc)
Fortran compiler ... GFORTRAN (command line : gfortran)
Library Name ... libopenblas_sandybridgep-r0.2.14.a (Multi threaded; Max num-threads is 24)

The JVM is only calling dgemv from a single thread at any given point in time.

I will continue to watch for this; I suspect it will happen again in the next day or so although not all JVM processes failed after 5 days. My long term plan was to migrate to a single-threaded BLAS and do my own threading and that will fix this issue as well, but I'll try to see if I can learn anything more about this issue in the meanwhile.

Activity

  1. xianyi commented on Oct 5, 2015

    @xianyi
    Collaborator

    Do you know what is the input size for dgemv? On the machine, is there only one JVM process calling OpenBLAS?

  2. bkgood commented on Oct 5, 2015

    @bkgood
    Author

    The matrix is approx 50k rows x 10k cols (row count is ~49k and col count is precisely 10k) and there's a single thread in a single process calling OpenBLAS.

  3. brada4 commented on Dec 1, 2015

    @brada4
    Contributor

    If sched_yield uses 100% of CPU something is badly broken with your system's process scheduler and timers
    Can you post to gist
    gdb> attach
    gdb >thread apply all backtrace
    gdb> detach
    gdb> quit

  4. jbaiter commented on Oct 27, 2016

    @jbaiter

    I have the exact same problem with OpenBLAS called from numpy, same backtrace.

    Here's the full backtrace as suggested by @brada4: https://gist.github.com/jbaiter/8dd11939bedfa9d9bf7e417c86f02bd9

    The version is 0.2.18-1ubuntu1 running on Linux 4.4.0-38-generic.

  5. martin-frbg commented on Oct 27, 2016

    @martin-frbg
    Collaborator

    Could be related to races like
    ==7085== Possible data race during write of size 8 at 0x641C00 by thread #2
    ==7085== Locks held: none
    ==7085== at 0x432F91: blas_thread_server (blas_server.c:438)
    ==7085== by 0x4C2F736: mythread_wrapper (hg_intercepts.c:234)
    ==7085== by 0x54680A3: start_thread (pthread_create.c:309)
    ==7085==
    ==7085== This conflicts with a previous read of size 8 by thread #1
    ==7085== Locks held: none
    ==7085== at 0x4333F2: exec_blas_async_wait (blas_server.c:726)
    ==7085== by 0x4335A5: exec_blas (blas_server.c:795)
    ==7085== by 0x42C3DE: sgbmv_thread_n (gbmv_thread.c:260)
    ==7085== by 0x416480: sgbmv_ (gbmv.c:240)
    ==7085== by 0x40D3A1: schk1_ (sblat2.f:592)
    ==7085== by 0x413F6F: MAIN__ (sblat2.f:305)
    ==7085== by 0x4148FE: main (sblat2.f:390)
    ==7085== Address 0x641c00 is 0 bytes inside data symbol "thread_status"
    seen in #995 - I am a bit unsure how to (sanely) put a lock around or into the "while" loop at 726

    while(thread_status[queue -> assigned].queue) {
      YIELDING;
     };
    

    at the moment (and it may all be a red herring)

  6. berke commented on Oct 31, 2016

    @berke

    Had the same problem, via Lapack, using libopenblas 0.2.19-1 on Debian, on Intel(R) Xeon(R) CPU E5-2687W v3 @ 3.10GHz with 20 cores. The main thread got stuck after a few hours on exec_blas_async_wait called from dsytri from Lapack. Kernel was 4.5.0-2-amd64 #1 SMP Debian 4.5.3-2 (2016-05-08) x86_64 GNU/Linux. The other threads were all in pthread_cond_destroy.

    (gdb) bt
    #0 0x00007f2c9704b308 in exec_blas_async_wait () from /usr/lib/libopenblas.so.0
    #1 0x00007f2c9704b3a7 in exec_blas () from /usr/lib/libopenblas.so.0
    #2 0x00007f2c96e7a2ee in dsymv_thread_U () from /usr/lib/libopenblas.so.0
    #3 0x00007f2c9a6cb043 in dsymv_ () from /usr/lib/libblas.so.3
    #4 0x00007f2c9a12e3ff in dsytri_ () from /usr/lib/liblapack.so.3

  7. martin-frbg commented on Oct 31, 2016

    @martin-frbg
    Collaborator

    I am making extremely slow progress, if any, as thread programming is not exactly my forte. Part of the problem now seems to be that blas_thread_server appears to be "thinking" in terms of cpus while exec_blas_async_wait is iterating over threads so I have a hard time putting mutex locks in the latter on the right item to achieve anything.

  8. martin-frbg commented on Jan 4, 2017

    @martin-frbg
    Collaborator

    Would either of you be willing to retest with the changed blas_server.c and memory.c linked from #995 (or point me to some self-contained test to check this myself) please ?

  9. sparseinference commented on Feb 2, 2017

    @sparseinference

    I think I just ran into this problem too. I'd be very happy for a workaround ..

    I have a very simple test case with numpy 1.12.0 in Python 3.6.
    It hangs at the call to dot.

    from numpy import *
    from numpy.random import normal,uniform
    
    A = normal(size=(350,35))
    b = uniform(size=350)
    
    for i in range(1000000):
        for _ in range(1000):
            x = normal(size=35)
            y = dot(A,x) + b
        print(f"[{i:6d}] {y[0]:10.4f}")
    

    Here's the backtrace:

    GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu1) 7.11.90.20161005-git
    Copyright (C) 2016 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from python...done.
    (gdb) r testdot.py
    Starting program: /home/peter/python36/bin/python testdot.py
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    [New Thread 0x7ffff3c17700 (LWP 16527)]
    [New Thread 0x7ffff3416700 (LWP 16528)]
    [New Thread 0x7fffeec15700 (LWP 16529)]
    [New Thread 0x7fffee414700 (LWP 16530)]
    [New Thread 0x7fffe9c13700 (LWP 16531)]
    [New Thread 0x7fffe7412700 (LWP 16532)]
    [New Thread 0x7fffe4c11700 (LWP 16533)]
    [New Thread 0x7fffe2410700 (LWP 16534)]
    [New Thread 0x7fffdfc0f700 (LWP 16535)]
    [New Thread 0x7fffdd40e700 (LWP 16536)]
    [New Thread 0x7fffdac0d700 (LWP 16537)]
    [     0]     7.0992
    [     1]    10.2106
    [     2]   -14.5927
    [     3]    10.9267
    [     4]     0.8033
    [     5]     8.1307
    [     6]     9.4003
    [     7]    -2.9214
    [     8]     3.1963
    [     9]    -4.4260
    [    10]    -8.6859
    [    11]    -1.5888
    [    12]     2.4825
    [    13]    -3.8991
    [    14]     2.1277
    [    15]   -14.3231
    [    16]     6.9087
    [    17]     2.6755
    [    18]    -3.1991
    [    19]     7.4059
    ^C
    Thread 1 "python" received signal SIGINT, Interrupt.
    0x00007ffff71ce4e7 in sched_yield () at ../sysdeps/unix/syscall-template.S:84
    84      ../sysdeps/unix/syscall-template.S: No such file or directory.
    (gdb) bt
    #0  0x00007ffff71ce4e7 in sched_yield () at ../sysdeps/unix/syscall-template.S:84
    #1  0x00007ffff4249e75 in exec_blas_async_wait ()
       from /home/peter/python36/lib/python3.6/site-packages/numpy/core/../.libs/libopenblasp-r0-39a31c03.2.18.so
    #2  0x00007ffff4249f66 in exec_blas () from /home/peter/python36/lib/python3.6/site-packages/numpy/core/../.libs/libopenblasp-r0-39a31c03.2.18.so
    #3  0x00007ffff40789f5 in dgemv_thread_t () from /home/peter/python36/lib/python3.6/site-packages/numpy/core/../.libs/libopenblasp-r0-39a31c03.2.18.so
    #4  0x00007ffff4038d97 in cblas_dgemv () from /home/peter/python36/lib/python3.6/site-packages/numpy/core/../.libs/libopenblasp-r0-39a31c03.2.18.so
    #5  0x00007ffff66700a3 in gemv (typenum=typenum@entry=12, order=<optimized out>, trans=trans@entry=CblasNoTrans, A=A@entry=0x7ffff6df3350, 
        lda=<optimized out>, X=X@entry=0x7ffff7ed5bc0, incX=1, R=R@entry=0x7fffd5207c60) at numpy/core/src/multiarray/cblasfuncs.c:95
    #6  0x00007ffff6670e9c in cblas_matrixproduct (typenum=typenum@entry=12, ap1=ap1@entry=0x7ffff6df3350, ap2=ap2@entry=0x7ffff7ed5bc0, out=out@entry=0x0)
        at numpy/core/src/multiarray/cblasfuncs.c:623
    #7  0x00007ffff663ac5c in PyArray_MatrixProduct2 (op1=<optimized out>, op2=0x7ffff7ed5bc0, out=0x0) at numpy/core/src/multiarray/multiarraymodule.c:938
    #8  0x00007ffff663c08a in array_matrixproduct (__NPY_UNUSED_TAGGEDdummy=<optimized out>, args=0x7ffff7e0bec8, kwds=0x0)
        at numpy/core/src/multiarray/multiarraymodule.c:2180
    #9  0x0000555555685363 in _PyCFunction_FastCallDict (kwargs=<optimized out>, nargs=<optimized out>, args=<optimized out>, func_obj=0x7ffff6b30f78)
        at Objects/methodobject.c:231
    #10 _PyCFunction_FastCallKeywords () at Objects/methodobject.c:295
    #11 0x00005555556dea1d in call_function () at Python/ceval.c:4788
    #12 0x00005555556d702f in _PyEval_EvalFrameDefault () at Python/ceval.c:3275
    #13 0x00005555556d6187 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffff7f6ba20) at Python/ceval.c:718
    #14 _PyEval_EvalCodeWithName () at Python/ceval.c:4119
    #15 0x00005555556d5f03 in PyEval_EvalCodeEx (closure=0x0, kwdefs=0x0, defcount=0, defs=0x0, kwcount=0, kws=0x0, argcount=0, args=0x0, 
        locals=locals@entry=0x7ffff7f3d288, globals=globals@entry=0x7ffff7f3d288, _co=_co@entry=0x7ffff7ef7930) at Python/ceval.c:4140
    #16 PyEval_EvalCode (co=co@entry=0x7ffff7ef7930, globals=globals@entry=0x7ffff7f3d288, locals=locals@entry=0x7ffff7f3d288) at Python/ceval.c:695
    #17 0x0000555555727712 in run_mod () at Python/pythonrun.c:980
    #18 0x0000555555727b6d in PyRun_FileExFlags () at Python/pythonrun.c:933
    #19 0x000055555572794e in PyRun_SimpleFileExFlags () at Python/pythonrun.c:396
    #20 0x000055555572d631 in run_file (p_cf=0x7fffffffda30, filename=0x555555ab72c0 L"testdot.py", fp=0x555555b41f00) at Modules/main.c:320
    #21 Py_Main () at Modules/main.c:780
    #22 0x00005555556395ad in main () at ./Programs/python.c:69
    #23 0x00007ffff71033f1 in __libc_start_main (main=0x5555556394c0 <main>, argc=2, argv=0x7fffffffdc48, init=<optimized out>, fini=<optimized out>, 
        rtld_fini=<optimized out>, stack_end=0x7fffffffdc38) at ../csu/libc-start.c:291
    #24 0x0000555555724c8a in _start ()
    (gdb) 
    
  10. berke commented on Feb 2, 2017

    @berke

    @martin-frbg I don't have an easy-to-reproduce case as it happened after a very long computation launched by someone else, and the code has evolved since so that it doesn't make as many calls now. If the fix works on @sparseinference's case I would like to start using it on a development machine to catch some regressions, but there are no guarantees that I would run into the bug if it isn't fixed.

  11. sparseinference commented on Feb 2, 2017

    @sparseinference

    I can sacrifice some performance but still make stuff work with:

    export OPENBLAS_NUM_THREADS=1

  12. berke commented on Feb 2, 2017

    @berke

    Same here, we've been running with OPENBLAS_NUM_THREADS=1 since November and had no issues. I parallelize at the process level.

  13. martin-frbg commented on Feb 2, 2017

    @martin-frbg
    Collaborator

    @sparceinference which version of OpenBLAS do you see this with - one of the releases (including latest 0.2.19) or with current git develop tree ? The fix (if it is one) is only in the latter so far.

  14. sparseinference commented on Feb 3, 2017

    @sparseinference

    @martin-frbg - I think it's 2.18 . The library loaded is libopenblasp-r0.2.18.so .

  15. 21 remaining items

  16. martin-frbg commented on Mar 13, 2018

    @martin-frbg
    Collaborator

    Possibly the cpuid instruction used in the x86_64 "WhereAmI()" is unsuitable for "modern" big Intel systems. https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration
    discusses means to enumerate processor topology but I do not have time to look into this right now.

  17. dodomorandi commented on Mar 13, 2018

    @dodomorandi

    Can you provide more details about the platform you are using, and can you exclude any hardware/firmware/OS issues with that particular system ?

    I can show you as much information as possible, but I don't any idea of how I could find possible issue with OS (nevertheless, the machine works flawlessly, I just do not know what to search for to discover anomalous behaviours).
    This is from lscpu:

    Architecture:          x86_64                                                                                                                                                                                                                                                     
    CPU op-mode(s):        32-bit, 64-bit                                                                                                                                                                                                                                             
    Byte Order:            Little Endian                                                                                                                                                                                                                                              
    CPU(s):                64                                                                                                                                                                                                                                                         
    On-line CPU(s) list:   0-63                                                                                                                                                                                                                                                       
    Thread(s) per core:    2                                                                                                                                                                                                                                                          
    Core(s) per socket:    8                                                                                                                                                                                                                                                          
    Socket(s):             4                                                                                                                                                                                                                                                          
    NUMA node(s):          8                                                                                                                                                                                                                                                          
    Vendor ID:             AuthenticAMD                                                                                                                                                                                                                                               
    CPU family:            21                                                                                                                                                                                                                                                         
    Model:                 1                                                                                                                                                                                                                                                          
    Model name:            AMD Opteron(TM) Processor 6274                                                                                                                                                                                                                             
    Stepping:              2                                                                                                                                                                                                                                                          
    CPU MHz:               2200.052                                                                                                                                                                                                                                                   
    BogoMIPS:              4399.74                                                                                                                                                                                                                                                    
    Virtualization:        AMD-V                                                                                                                                                                                                                                                      
    L1d cache:             16K                                                                                                                                                                                                                                                        
    L1i cache:             64K                                                                                                                                                                                                                                                        
    L2 cache:              2048K                                                                                                                                                                                                                                                      
    L3 cache:              6144K                                                                                                                                                                                                                                                      
    NUMA node0 CPU(s):     0,4,8,12,16,20,24,28                                                                                                                                                                                                                                       
    NUMA node1 CPU(s):     32,36,40,44,48,52,56,60                                                                                                                                                                                                                                    
    NUMA node2 CPU(s):     2,6,10,14,18,22,26,30                                                                                                                                                                                                                                      
    NUMA node3 CPU(s):     34,38,42,46,50,54,58,62                                                                                                                                                                                                                                    
    NUMA node4 CPU(s):     3,7,11,15,19,23,27,31                                                                                                                                                                                                                                      
    NUMA node5 CPU(s):     35,39,43,47,51,55,59,63                                                                                                                                                                                                                                    
    NUMA node6 CPU(s):     1,5,9,13,17,21,25,29                                                                                                                                                                                                                                       
    NUMA node7 CPU(s):     33,37,41,45,49,53,57,61
    

    Feel free to ask me any specific information.
    However, to discover a bit the behaviour of my machine, I wrote a simple program in C++. It creates a pool of threads and every thread get the cpu index and the acpi id from sched_getcpu and the cpuid instruction and stores them. As soon I spawned the thread, I use the pthread_setaffinity_np to set the thread affinity. Then I join the threads and I check if the ids (both CPU and ACPI) are unique or not.
    What I found is that this was leading to spurious id collisions, for both types of ids. After a bit I understood the problem: the main thread was not set as affine. As soon as I set the main thread affine using the same procedure, I stopped having id collisions.

    The question is: could be exactly this the problem we are encountering?

  18. dodomorandi commented on Mar 13, 2018

    @dodomorandi

    Possibly the cpuid instruction used in the x86_64 "WhereAmI()" is unsuitable for "modern" big Intel systems. https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration
    discusses means to enumerate processor topology but I do not have time to look into this right now.

    Sorry, it took me some time to write down the previous reply. Maybe we don't need to touch the WhereAmI function, for now. But I will wait for your opinion to have a better idea.

  19. martin-frbg commented on Mar 15, 2018

    @martin-frbg
    Collaborator

    (Un?)fortunately it seems to me that you may well be more experienced with multithreading in general and NUMA architectures in particular than me. As far as I can tell, gotoblas_affinity_init() in init.c does a sched_setaffinity() for itself before enumerating the cores with whereAmI(), and I assume this should be equivalent to what your test code is doing with the non- (or less-)portable pthread_setaffinity_np() function that appears to be a GNU extension

  20. brada4 commented on Mar 15, 2018

    @brada4
    Contributor

    can you add "numactl -H" output? I have not seen out of order core numbering recently.
    Initial report is on small systems, nothing to do with NUMA.
    IMO trying to override OpenMP thread placement is wrong.

  21. dodomorandi commented on Mar 15, 2018

    @dodomorandi

    can you add "numactl -H" output?

    Sure!

    available: 8 nodes (0-7)
    node 0 cpus: 0 4 8 12 16 20 24 28
    node 0 size: 32166 MB
    node 0 free: 29854 MB
    node 1 cpus: 32 36 40 44 48 52 56 60
    node 1 size: 32254 MB
    node 1 free: 31911 MB
    node 2 cpus: 2 6 10 14 18 22 26 30
    node 2 size: 32254 MB
    node 2 free: 31786 MB
    node 3 cpus: 34 38 42 46 50 54 58 62
    node 3 size: 32254 MB
    node 3 free: 31936 MB
    node 4 cpus: 3 7 11 15 19 23 27 31
    node 4 size: 32254 MB
    node 4 free: 30836 MB
    node 5 cpus: 35 39 43 47 51 55 59 63
    node 5 size: 32254 MB
    node 5 free: 31727 MB
    node 6 cpus: 1 5 9 13 17 21 25 29
    node 6 size: 32254 MB
    node 6 free: 32004 MB
    node 7 cpus: 33 37 41 45 49 53 57 61
    node 7 size: 32237 MB
    node 7 free: 31628 MB
    node distances:
    node   0   1   2   3   4   5   6   7 
      0:  10  16  16  22  16  22  16  22 
      1:  16  10  22  16  16  22  22  16 
      2:  16  22  10  16  16  16  16  16 
      3:  22  16  16  10  16  16  22  22 
      4:  16  16  16  16  10  16  16  22 
      5:  22  22  16  16  16  10  22  16 
      6:  16  22  16  22  16  22  10  16 
      7:  22  16  16  22  22  16  16  10 
    

    I assume this should be equivalent to what your test code is doing with the non- (or less-)portable pthread_setaffinity_np() function that appears to be a GNU extension

    You are absolutely right, i just took the first one in my test... just because ;) I replaced it with the sched_setaffinity for coherence.

    Nevertheless, I want to update you on my tests: I started thinking that the problem was about thread switching in critical sections (not the one the could create a data race, but something like a couple of instruction one expects to be executed without an interruption), but now I am not sure. The test I have got now is much more similar to what is going on inside OpenBLAS -- a sched_setaffinity is called inside the thread. I tried to perform the following things inside the spawned thread, in order:

    • The ACPI ID is colllected
    • sched_setaffinity is called to make the thread affine to the CPU equal to the thread index
    • ACPI ID is collected again
    • The thread is explicitly yielded
    • Again, the ACPI ID is collected

    I see that it is always true that the first ID is (generally) different from the second, which in turn is always equal to the third. This means that, at least in this machine with this OS, the rescheduling happens as soon as the sched_setaffinity is called. I just wanted to be sure that something unexpected could happen in this context.
    Oh, the test written in this way never leads to ACPI ID collisions. Probably I am going toward the wrong direction 😞

  22. dodomorandi commented on Apr 4, 2018

    @dodomorandi

    I have been quite busy, but I took a bit of time to make a simple check. I initialized all the values of common->cpu_info inside drivers/other/init.c with ULONG_MAX. Then I tried to put around some assertions, just to check that the cpu_info parameter was written, and I see these throwing.

    I am not completely sure this could be the right way to perform this check, but surely @martin-frbg has a better knowledge of the code. Martin, if you have the possibility to give it a look, maybe we could be on the right direction. Thanks! 😄

  23. martin-frbg commented on Apr 5, 2018

    @martin-frbg
    Collaborator

    Not sure what you want me to do here, are you seeing active cpu nodes that never had their cpu_info set to a sensible value ? From the git history, the last person to do any serious work on the NUMA mapping seems to have been ashwinyes (remapping cpus to keep all tasks on a common node if possible). I do note there are a few printfs to dump the cpu_info already in the code that should become active when compiling with DEBUG=1.

  24. dodomorandi commented on Apr 5, 2018

    @dodomorandi

    I think I fixed the issue. As I said previously, I made a fork where you can go and perform some tests.

    Let's explain what I found. numa_mapping sets the common->cpu_info array using the counter count, incremented only when an assignment is performed. When hyperthreading is disabled, we are only assigning only common -> num_procs / 2.
    At the same time, inside local_cpu_map, mapping is used as a counter of mapped cores, while cpu is incremented in any case. This means that mapping can only reach common -> num_procs / 2 with disabled hyperthreading, but cpu can exceed this value. Therefore, here cpu_mapping[mapping] must be set related to common->cpu_info[mapping], not common->cpu_info[cpu].

    At the same time, cpu_sub_mapping maps to the complete sets of cores, therefore using it to take elements from common->cpu_info should only bring to use uninitialized values.

    The commit I pushed to my repo seems to fix the deadlock. I would really like to use the thread sanitizer to perform additional tests, but as suggested previously by @martin-frbg, this seems to introduce problems. This could also mean that there are still some issues, but it is difficult to say.

    If you have the possibility to perform some test, it would be really nice. In theory things should work flawlessly if previously were working, but at the same time who was experiencing the deadlock now should be able to run applications and tests without problems.

  25. martin-frbg commented on Apr 5, 2018

    @martin-frbg
    Collaborator

    Thanks for the detailed explanation - in retrospect it makes sense that a misbehaviour in the mapping would be related to the dubious nature of the hyperthreading semi-cores. (Which would also prevent
    its showing up on other big systems that use a different architecture)
    In my defense, I had looked at your fork but did not see a commit that contained the initializing of common->cpu_info that you had mentioned, then I had a look at the code paths that read or write this variable and became confused rather quickly... still after reading your patch I am unsure if dropping the cpu_sub_mapping would let the code still work as intended when hyperthreading is enabled (but I would take your word for it). Maybe I should just read what you wrote aloud three more times to get it.
    As an alternative to thread sanitizer, perhaps helgrind from the valgrind package can provide additional insight (but there too, the environmental changes necessary for observing may change the system under observation)

  26. dodomorandi commented on Apr 5, 2018

    @dodomorandi

    In my defense, I had looked at your fork but did not see a commit that contained the initializing of common->cpu_info that you had mentioned

    Actually, this is my fault: I did not include the initialization and the assertions in the commit of the patch, just to focus on the fix. But you are right, it is useful to have a commit with these, I will make one.

    As an alternative to thread sanitizer, perhaps helgrind from the valgrind package can provide additional insight (but there too, the environmental changes necessary for observing may change the system under observation)

    After I wrote the previous comment, I remembered I can use valgrind with helgrind. And the result is different from the thread sanitizer (which lead to a strange deadlock during the destruction phase), but it still involves issues. In details, the openblas_utest aborts on the check I put inside gotoblas_set_affinity to avoid node remapping. But I am not able to reproduce this situation without valgrind (until now).

    Even if changing the mapping behaviour seems to solve the deadlock problem, I want to be sure I did not introduce other issues, or, if there are other related bugs left, I would like to fix them. The problems with the thread sanitizer and valgrind leave me very suspicious.

  27. dodomorandi commented on Apr 6, 2018

    @dodomorandi

    I made some real case tests, and I find that the issues are still there 😢. I am going to continue searching for bugs.

  28. martin-frbg commented on Apr 6, 2018

    @martin-frbg
    Collaborator

    Ouch, too bad. Still the same symptoms though, and are you testing with dgemv (as was the original issue here) ? It is possible that the bug I tracked down in #1497 (using the return value from blas_quickdivide to calculate blocksizes without checking that it is non-zero ) may be present in some of the level3 BLAS files as well.

  29. martin-frbg commented on Dec 2, 2018

    @martin-frbg
    Collaborator

    Hopefilly this is now resolved with PR #1865, the fix for #1844 (where it was found that an old optimization (#532) for inputs with small M and large N had introduced local static storage that broke reentrancy)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions