Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling C code in Julia benchmark tutorial

Tags:

c

gcc

julia

After running the code in the first cell of this lecture, I am trying to call the function c_sum. However, I keep receiving the error:

error compiling c_sum: could not load library "/tmp/juliaOT2a9V"
/tmp/juliaOT2a9V.so: wrong ELF class: ELFCLASS64

I have tried modifying the code with the gcc flag -m64, but this hasn't helped. I'm new to coding, so I'm fairly confused as to what precisely the problem is, and how to fix it. Any help would be greatly appreciated!

like image 990
Sameer Kailasa Avatar asked Mar 02 '23 06:03

Sameer Kailasa


1 Answers

Based on the error, it seems like the issue may be that you're trying to load a 64-bit shared object (.so) file into a 32-bit julia binary. What does your Julia versioninfo show? Here's mine:

julia> versioninfo()
Julia Version 1.6.0-DEV.420
Commit 0d5efa8846 (2020-07-10 14:27 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin19.5.0)
  CPU: Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_EDITOR = subl
  JULIA_SHELL = /bin/bash
  JULIA_INPUT_COLOR = bold
  JULIA_ANSWER_COLOR = light_magenta
  JULIA_PKG_DEVDIR = /Users/stefan/dev

If yours indicates that you're running a 32-bit julia, then you can either try installing a 64-bit julia or try compiling the C code to a 32-bit ELF shared object file using the -m32 flag rather than the -m64 flag. You can also use file to externally detect the format of these files, for example here's what I get on my macOS system:

julia> run(`file $(Sys.which("julia"))`);
/Users/stefan/dev/julia/usr/bin/julia: Mach-O 64-bit executable x86_64

julia> run(`file $(Clib * "." * Libdl.dlext)`);
/var/folders/4g/b8p546px3nd550b3k288mhp80000gp/T/jl_ZeTKsr.dylib: Mach-O 64-bit dynamically linked shared library x86_64

Since both my julia executable and the shared library file are Mach-O 64-bit, they're compatible and the example works. On your system julia may be 32-bit while gcc is generating 64-bit binaries by default because you're on a 64-bit system. This will probably be a problem in general, so even if passing the -m32 flag to gcc solves the immediate problem and allows you to make the example work, I would recommend using a 64-bit Julia binary instead. As a bonus, that will allow you to load larger data sets than a 32-bit Julia can, since the 64-bit binary can address all of your computer's (virtual) memory instead of just 4GB of it.

Historical note: How/why does your 64-bit Linux machine run both 32-bit ELF and 64-bit ELF files on a single system? In 2001, Intel introduced the Itanium IA-64 architecture, which was a pure 64-bit architecture meant for high-end servers. A year later AMD introduced the competing x86_64 architecture, which supported two process modes: 64-bit mode and 32-bit (legacy) mode. So you could have different processes on the same system running with different word sizes. IA-64 never really took off whereas x86_64 was wildly successful and eventually Intel started making x86_64 chips as well, which is probably what your machine is running, although it could also be an AMD chip. So now there are two different kinds of ELF binaries and that can both work on most PCs, but the granularity is process-level: you cannot load a 64-bit shared object into a 32-bit process or vice versa. Although your system can run 32-bit processes, since the system is primarily 64-bit, most of the programs and libraries are going to be 64-bit, which is why I've recommended that you switch to using a 64-bit Julia build.

More information about ELF-type mismatches here:

  • gcc error: wrong ELF class: ELFCLASS64.
like image 104
StefanKarpinski Avatar answered Mar 10 '23 22:03

StefanKarpinski