JuliaInterop / Cxx.jl

The Julia C++ Interface
Other
757 stars 108 forks source link

Added x86_64-generic-linux tripple, used by Clear Linux. #415

Closed chriselrod closed 5 years ago

chriselrod commented 5 years ago

Adding an additional triple. The path on Clear Linux version 29310 to the gcc libraries is /usr/lib64/gcc/x86_64-generic-linux/9/.

Note that while I can build Cxx, I don't have it working yet locally. However, I imagine this PR should be fine.

julia> using Cxx
[ Info: Recompiling stale cache file /home/chriselrod/.julia/compiled/v1.2/Cxx/ESGkI.ji for Cxx [a0b5b9ef-44b7-5148-a2d1-f6db19f3c3d2]

signal (11): Segmentation fault
in expression starting at REPL[2]:1
_ZN4llvm11InstructionC2EPNS_4TypeEjPNS_3UseEjPS0_ at /home/chriselrod/Documents/languages/julia6/usr/bin/../lib/libLLVM-6.0.so (unknown line)
_ZN4llvm10AllocaInstC1EPNS_4TypeEjPNS_5ValueERKNS_5TwineEPNS_11InstructionE at /home/chriselrod/Documents/languages/julia6/usr/bin/../lib/libLLVM-6.0.so (unknown line)
_ZN5clang7CodeGen15CodeGenFunction16CreateTempAllocaEPN4llvm4TypeERKNS2_5TwineEPNS2_5ValueE at /home/chriselrod/.julia/dev/Cxx/src/../deps/usr/lib/libcxxffi.so (unknown line)
_ZN5clang7CodeGen15CodeGenFunction16CreateTempAllocaEPN4llvm4TypeENS_9CharUnitsERKNS2_5TwineEPNS2_5ValueEb at /home/chriselrod/.julia/dev/Cxx/src/../deps/usr/lib/libcxxffi.so (unknown line)
_ZN5clang7CodeGen15CodeGenFunction12EmitParmDeclERKNS_7VarDeclENS1_10ParamValueEj at /home/chriselrod/.julia/dev/Cxx/src/../deps/usr/lib/libcxxffi.so (unknown line)
AssociateValue at /home/chriselrod/.julia/dev/Cxx/deps/../src/bootstrap.cpp:1773
AssociateValue at /home/chriselrod/.julia/dev/Cxx/src/clangwrapper.jl:317 [inlined]
associateargs at /home/chriselrod/.julia/dev/Cxx/src/codegen.jl:407
unknown function (ip: 0x7ff275726cc9)
#EmitExpr#33 at /home/chriselrod/.julia/dev/Cxx/src/codegen.jl:671
unknown function (ip: 0x7ff275720062)
#EmitExpr at ./none:0 [inlined]
#EmitExpr at ./none:0 [inlined]
#CallDNE#54 at /home/chriselrod/.julia/dev/Cxx/src/cxxstr.jl:371
#CallDNE at ./none:0
unknown function (ip: 0x7ff27571db15)
#s37#70 at /home/chriselrod/.julia/dev/Cxx/src/cxxstr.jl:718 [inlined]
#s37#70 at ./none:0
jl_apply_2va at /home/chriselrod/Documents/languages/julia6/src/rtutils.c:353
GeneratedFunctionStub at ./boot.jl:524
jl_apply at /home/chriselrod/Documents/languages/julia6/src/julia.h:1604 [inlined]
jl_call_staged at /home/chriselrod/Documents/languages/julia6/src/method.c:373
jl_code_for_staged at /home/chriselrod/Documents/languages/julia6/src/method.c:403
get_staged at ./compiler/utilities.jl:92
retrieve_code_info at ./compiler/utilities.jl:103 [inlined]
Type at ./compiler/inferencestate.jl:112
typeinf_edge at ./compiler/typeinfer.jl:473
abstract_call_method at ./compiler/abstractinterpretation.jl:369
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:92
abstract_call at ./compiler/abstractinterpretation.jl:808
abstract_call at ./compiler/abstractinterpretation.jl:598
abstract_eval_call at ./compiler/abstractinterpretation.jl:837
abstract_eval at ./compiler/abstractinterpretation.jl:907
typeinf_local at ./compiler/abstractinterpretation.jl:1164
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1220
typeinf at ./compiler/typeinfer.jl:12
typeinf_edge at ./compiler/typeinfer.jl:482
abstract_call_method at ./compiler/abstractinterpretation.jl:369
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:92
abstract_call at ./compiler/abstractinterpretation.jl:808
abstract_call at ./compiler/abstractinterpretation.jl:598
abstract_eval_call at ./compiler/abstractinterpretation.jl:837
abstract_eval_cfunction at ./compiler/abstractinterpretation.jl:886
abstract_eval at ./compiler/abstractinterpretation.jl:961
typeinf_local at ./compiler/abstractinterpretation.jl:1164
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1220
typeinf at ./compiler/typeinfer.jl:12
typeinf_ext at ./compiler/typeinfer.jl:568
typeinf_ext at ./compiler/typeinfer.jl:599
jfptr_typeinf_ext_1 at /home/chriselrod/Documents/languages/julia6/usr/lib/julia/sys.so (unknown line)
jl_apply at /home/chriselrod/Documents/languages/julia6/src/julia.h:1604 [inlined]
jl_type_infer at /home/chriselrod/Documents/languages/julia6/src/gf.c:207
jl_compile_method_internal at /home/chriselrod/Documents/languages/julia6/src/gf.c:1773
jl_apply_generic at /home/chriselrod/Documents/languages/julia6/src/gf.c:2196
do_call at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:323
eval_value at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:411
eval_stmt_value at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:362 [inlined]
eval_body at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:754
jl_interpret_toplevel_thunk_callback at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:884
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7ff2852bad0f)
unknown function (ip: (nil))
jl_interpret_toplevel_thunk at /home/chriselrod/Documents/languages/julia6/src/interpreter.c:893
jl_toplevel_eval_flex at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:797
jl_toplevel_eval at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:806 [inlined]
jl_toplevel_eval_in at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:826
eval at ./boot.jl:330 [inlined]
eval at /home/chriselrod/.julia/dev/Cxx/src/Cxx.jl:228 [inlined]
__init__ at /home/chriselrod/.julia/dev/Cxx/src/Cxx.jl:230
jl_apply at /home/chriselrod/Documents/languages/julia6/src/julia.h:1604 [inlined]
jl_module_run_initializer at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:73
jl_init_restored_modules at /home/chriselrod/Documents/languages/julia6/src/dump.c:2426
_include_from_serialized at ./loading.jl:685
_require_from_serialized at ./loading.jl:736
_require at ./loading.jl:1023
require at ./loading.jl:911
require at ./loading.jl:906
jl_apply at /home/chriselrod/Documents/languages/julia6/src/julia.h:1604 [inlined]
call_require at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:398 [inlined]
eval_import_path at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:435
jl_toplevel_eval_flex at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:639
jl_toplevel_eval_flex at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:746
jl_toplevel_eval at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:806 [inlined]
jl_toplevel_eval_in at /home/chriselrod/Documents/languages/julia6/src/toplevel.c:826
eval at ./boot.jl:330
eval_user_input at /home/chriselrod/Documents/languages/julia6/usr/share/julia/stdlib/v1.2/REPL/src/REPL.jl:86
macro expansion at /home/chriselrod/Documents/languages/julia6/usr/share/julia/stdlib/v1.2/REPL/src/REPL.jl:118 [inlined]
#26 at ./task.jl:268
jl_apply at /home/chriselrod/Documents/languages/julia6/src/julia.h:1604 [inlined]
start_task at /home/chriselrod/Documents/languages/julia6/src/task.c:583
unknown function (ip: 0xffffffffffffffff)
Allocations: 19150589 (Pool: 19147076; Big: 3513); GC: 43
Segmentation fault (core dumped)

My experience with gdb is extremely limited:

GNU gdb (GDB) 8.2.1
Copyright (C) 2018 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-generic-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 /home/chriselrod/Documents/languages/julia6/usr/bin/julia...done.
(gdb) run
Starting program: /home/chriselrod/Documents/languages/julia6/usr/bin/julia 
warning: the debug information found in "/usr/lib/debug//usr/lib64/libdl-2.29.so.debug" does not match "/usr/lib64/libdl.so.2" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/libdl-2.29.so.debug" does not match "/usr/lib64/libdl.so.2" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/librt-2.29.so.debug" does not match "/usr/lib64/librt.so.1" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/librt-2.29.so.debug" does not match "/usr/lib64/librt.so.1" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/libpthread-2.29.so.debug" does not match "/usr/lib64/libpthread.so.0" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/libpthread-2.29.so.debug" does not match "/usr/lib64/libpthread.so.0" (CRC mismatch).

warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
    add-auto-load-safe-path /usr/lib64/libthread_db-1.0.so
line to your configuration file "/home/chriselrod/.gdbinit".
To completely disable this security protection add
    set auto-load safe-path /
line to your configuration file "/home/chriselrod/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
    info "(gdb)Auto-loading safe path"
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: the debug information found in "/usr/lib/debug//usr/lib64/haswell/libc-2.29.so.debug" does not match "/usr/lib64/haswell/libc.so.6" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/haswell/libc-2.29.so.debug" does not match "/usr/lib64/haswell/libc.so.6" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/haswell/avx512_1/libm-2.29.so.debug" does not match "/usr/lib64/haswell/avx512_1/libm.so.6" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/haswell/avx512_1/libm-2.29.so.debug" does not match "/usr/lib64/haswell/avx512_1/libm.so.6" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug//usr/lib64/libgcc_s.so.1.debug" does not match "/usr/lib64/libgcc_s.so.1" (CRC mismatch).

[New LWP 16076]
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.2.0-pre.0 (2019-04-11)
 _/ |\__'_|_|_|\__'_|  |  release-1.2/8a84ba5018* (fork: 1 commits, 28 days)
|__/                   |

julia> using Cxx

Thread 1 "julia" received signal SIGSEGV, Segmentation fault.
0x00007ffff51940b7 in llvm::Instruction::Instruction(llvm::Type*, unsigned int, llvm::Use*, unsigned int, llvm::Instruction*) () from /home/chriselrod/Documents/languages/julia6/usr/bin/../lib/libLLVM-6.0.so
(gdb) 
Gnimuc commented 5 years ago

I haven't tried the source build on Julia v1.2 yet, so have no idea about the segment fault. Cxx.jl may need to be patched for Julia v1.2 compatibility. Also, it might be caused by certain mistakes committed when I was merging bootstrap.cpp's code from the BB2 version. Could you revert bootstrap.cpp to this commit and apply #407 and then try it again?

chriselrod commented 5 years ago

That works, although there's still some old pre-Julia 1.0 in there:

julia> cxx"""
           #include <iostream>
           class Hello {
               public:
                   void hello_world(const char *now) {
                       std::string snow = now;
                       std::cout << "Hello, World! Now is " << snow << std::endl;
                   }
           };
       """
true

julia> hello_class = @cxxnew Hello()
Error showing value of type Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{:Hello},(false, false, false)},N} where N,(false, false, false)}:
ERROR: UndefVarError: Void not defined

The show method has been fixed on master.

Also, as aside, what's the easiest way to map simple C++ structs to Julia, eg __m256d from immintrin.h <=> NTuple{4,Core.VecElement{Float64}}? Ie, these are bitcastable, and equivalent across a ccall. But here I get:

ERROR: Got bad type information while compiling Cxx.CxxCore.CppNNS{Tuple{:xserf_512d}} (got NTuple{8,VecElement{Float64}} for argument 1)
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] check_args at /home/chriselrod/.julia/dev/Cxx/src/codegen.jl:447 [inlined]
 [3] _cppcall(::Type, ::Type, ::Bool, ::Bool, ::Tuple{DataType}) at /home/chriselrod/.julia/dev/Cxx/src/codegen.jl:516
 [4] #s37#39(::Any, ::Any, ::Any, ::Any) at /home/chriselrod/.julia/dev/Cxx/src/codegen.jl:841
 [5] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any,N} where N) at ./boot.jl:524
 [6] erf(::NTuple{8,VecElement{Float64}}) at ./REPL[6]:1
 [7] top-level scope at REPL[8]:1

and I'm sure there's some reasonable way to do that.

Similarly, what about mapping templates to Julia parameteric structs?

Is this possible, and is there documentation / examples illustrating that? I confess I'm new to Julia-C++ interop. Earlier, I'd always just compile shared libraries (using extern "C") and ccall them.

Gnimuc commented 5 years ago

I'm merging this PR and gonna roll back those changes later on.

Gnimuc commented 5 years ago

As for the question, could you elaborate a little bit more about what you would like to do? Could you post the MWE that was complaining about those errors?

Basically, Cxx.jl allows you to write C++ code in Julia, which means you could write Julia functions encapturing some C++ code. Here is a keno's old repo that demonstrates how to write a wrapper using Cxx.jl.

Gnimuc commented 5 years ago

That works, although there's still some old pre-Julia 1.0 in there:

I just reverted those changes. Now you could use Cxx.jl's master with everything fixed. Also, don't forget to apply PR407 manually before rebuilding since it's not merged to master yet.

Gnimuc commented 5 years ago

Strange. All the tests passed when I did a source build on Julia 1.2 without patching PR407. The following is my Julia version info:

Version 1.2.0-pre.0 (2019-04-11)
release-1.2/8a84ba5018* (fork: 1 commits, 28 days)
chriselrod commented 5 years ago

Interesting. That is exactly what I have:

Version 1.2.0-pre.0 (2019-04-11)
release-1.2/8a84ba5018* (fork: 1 commits, 28 days)

...and, I just retried Cxx master (without applying PR407), and it works.

As for the question, could you elaborate a little bit more about what you would like to do? Could you post the MWE that was complaining about those errors?

Here is a MWE for that error:

using Cxx

cxxinclude("immintrin.h")

cxx"""
__m256d add256(__m256d a, __m256d b){
    return _mm256_add_pd(a, b);
}
"""

add(a::NTuple{4,Core.VecElement{Float64}}, b::NTuple{4,Core.VecElement{Float64}}) = @cxx add256(a, b)

x4 = ntuple(Val(4)) do i Core.VecElement(randn(Float64)) end;
y4 = ntuple(Val(4)) do i Core.VecElement(randn(Float64)) end;
add(x4, y4)
# ERROR: Got bad type information while compiling Cxx.CxxCore.CppNNS{Tuple{:add256}} (got NTuple{4,VecElement{Float64}} for argument 1)

I'm interested in wrapping many of the math functions in the xsimd library. I wrote a library that compiles a shared library to call many of these with ccall, but Cxx is probably a better solution. Especially if xsimd::batch<T,N> and NTuple{N,Core.VecElement{T}} are interoperable.

Gnimuc commented 5 years ago

is it feasible to directly use vcpp"__m256d" as wrapper function's argument type instead of Core.VecElement? e.g. add(a::vcpp"__m256d", b::vcpp"__m256d") = @cxx add256(a, b).