Julia: Undeclared HWCAP_CRC32 compilation error in ARMv8 (Jetson TX2)

Created on 14 Mar 2018  路  18Comments  路  Source: JuliaLang/julia

I'm getting this error:
/home/nvidia/julia/src/crc32c.c:336:17: error: 'HWCAP_CRC32' undeclared (first use in this function)
when compiling Julia master, at a0180d98a07ceec431f4af81db1000f6076610c8, in a Jetson TX2 (ARMv8).
Two months older versions used to compile flawlessly.

arm build

Most helpful comment

Should this be a pull request?

All 18 comments

The last change to that file was in October. What C/C++ compiler are you using, and did you maybe update your compiler in the mean time?

This line was added in #22385; HWCAP_CRC32 should be defined in your compiler's hwcap.h file

Not sure what changed but try adding # include <hwcap.h> here ?

Actually that shouldn't be needed I haven't found the aarch64 definition yet but According to https://github.molgen.mpg.de/git-mirror/glibc/blob/20003c49884422da7ffbc459cdeee768a6fee07b/sysdeps/unix/sysv/linux/arm/bits/hwcap.h#L20 including auxv.h is the correct way.

Found it. It was added 2 years ago in https://github.com/bminor/glibc/commit/26c2910ac6889dd21f128d9071418492d544a2dc and the usage we have seems correct. What's your glibc version and what's your bits/hwcap.h ? (should be /usr/include/bits/hwcap.h)

Thanks.
Running the gcc command with -M:

nvidia@tegra-ubuntu:~/julia/src$ gcc -march=armv8-a -fasynchronous-unwind-tables -DJULIA_ENABLE_THREADING -DJULIA_NUM_THREADS=1 -std=gnu99 -pipe -fPIC -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -Wold-style-definition -Wstrict-prototypes -Wc++-compat -O3 -ggdb2 -falign-functions -D_GNU_SOURCE -I. -I/home/nvidia/julia/src -I/home/nvidia/julia/src/flisp -I/home/nvidia/julia/src/support -I/home/nvidia/julia/usr/include -I/home/nvidia/julia/usr/include -DLIBRARY_EXPORTS -I/home/nvidia/julia/deps/valgrind -Wall -Wno-strict-aliasing -fno-omit-frame-pointer -fvisibility=hidden -fno-common -Wpointer-arith -Wundef -DJL_BUILD_ARCH='"aarch64"' -DJL_BUILD_UNAME='"Linux"' -I/home/nvidia/julia/usr/include -DLLVM_SHLIB "-DJL_SYSTEM_IMAGE_PATH=\"../lib/julia/sys.so\"" -DNDEBUG -DJL_NDEBUG -c /home/nvidia/julia/src/crc32c.c -M 

entails:

crc32c.o: /home/nvidia/julia/src/crc32c.c /usr/include/stdc-predef.h \
 /home/nvidia/julia/src/julia.h \
 /home/nvidia/julia/src/support/libsupport.h \
 /home/nvidia/julia/src/support/platform.h /usr/include/stdlib.h \
 /usr/include/features.h /usr/include/aarch64-linux-gnu/sys/cdefs.h \
 /usr/include/aarch64-linux-gnu/bits/wordsize.h \
.....................................
(many other headers)
......................................
 /home/nvidia/julia/usr/include/libunwind-common.h \
 /home/nvidia/julia/usr/include/libunwind-dynamic.h \
 /usr/include/aarch64-linux-gnu/sys/auxv.h /usr/include/elf.h \
 /usr/include/aarch64-linux-gnu/bits/auxv.h \
 /usr/include/aarch64-linux-gnu/bits/hwcap.h \
 /home/nvidia/julia/src/crc32c-tables.c

In fact /usr/include/aarch64-linux-gnu/bits/hwcap.h does not define anything nor includes any other file.

In the system there is a /usr/src/linux-headers-4.4.38-tegra/arch/arm64/include/asm/hwcap.h which includes /usr/src/linux-headers-4.4.38-tegra/arch/arm64/include/uapi/asm/hwcap.h which has a HWCAP_CRC32.

File /usr/include/aarch64-linux-gnu/bits/hwcap.h comes from package libc6-dev which has version 2.23-0ubuntu10.

There is also a /usr/include/aarch64-linux-gnu/asm/hwcap.h file which has HWCAP_CRC32.

/usr/include/aarch64-linux-gnu/bits/hwcap.h
only has

\\ (initial comments)

#ifndef _SYS_AUXV_H
# error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead."
#endif

/* No bits defined for this architecture.  */

It seems that your glibc is just a little too old. Note that including the kernel header usually isn't a solution due to possible name conflict with glibc ones.

One solution is to do a ifdef check and if not, define our own value. (it's a kernel API so the value is stable).

Another solution is to just use processor.h, which already have this value hard coded.
Does it work if you add #include "processor.h" here and replace the use of HWCAP_CRC32 with JL_AArch64_crc?

Actually, should be (1 << JL_AArch64_crc).

Ok, guess that what I had compiled two months ago was in fact v0.6.2. That compiles since its source code does not uses HWCAP_CRC32.

Doing

#include "processor.h"
#define HWCAP_CRC32 (1 << JL_AArch64_crc)

works.
But now I'm bumping into another, unrelated, error:

ERROR: Invalid CPU name armv8-a.
Makefile:195: recipe for target '/home/nvidia/julia/usr/lib/julia/basecompiler.ji' failed
JULIA_CPU_TARGET=generic
MARCH=armv8-a

should do the trick.

#define HWCAP_CRC32 (1 << JL_AArch64_crc)

Don't do that, replace the actual use.

ERROR: Invalid CPU name armv8-a.

That doesn't make much sense..... There's only one place that can set the flag to cause this which is arg_target_data(const TargetData<feature_sz> &arg, bool require_host) and it can only happen if auto spec = find_cpu(res.name) fails. So you should set a breakpoint there to see why it didn't find the info corresponding to the valid name "armv8-a".

Ah, I was looking at the wrong CPU spec list. armv8-a is indeed missing from the CPU list for aarch64 (it is in the aarch32 list). It's probably an oversight/something I missed since the plan changes back and forth a few times in that PR.

diff --git a/src/processor_arm.cpp b/src/processor_arm.cpp
index 01b98c2027..2801ea571a 100644
--- a/src/processor_arm.cpp
+++ b/src/processor_arm.cpp
@@ -209,6 +209,7 @@ constexpr auto apple_hurricane = armv8a_crc_crypto;

 static constexpr CPUSpec<CPU, feature_sz> cpus[] = {
     {"generic", CPU::generic, CPU::generic, 0, Feature::generic},
+    {"armv8-a", CPU::generic, CPU::generic, 0, Feature::generic},
     {"armv8.1-a", CPU::armv8_1_a, CPU::generic, 0, Feature::armv8_1a},
     {"armv8.2-a", CPU::armv8_2_a, CPU::generic, 0, Feature::armv8_2a},
     {"armv8.3_a", CPU::armv8_3_a, CPU::generic, 0, Feature::armv8_3a},

Should work.

As a side note, armv8-a is supposed to be a valid option since the plan was to support everything reasonable that you can to gcc in -march and -mtune. Reasonable here means architectures that we actually support (so most pre-pentium4 arch are not). Any of those that are not supported should be reported as bugs.

Ok, it is fully working.

Must this issue be closed by considering that it is caused by problems with Jetson TX2 glibc, or there is something that must be done on the Julia side?

Wouldn't hurt to update the source to use (1 << JL_AArch64_crc), and it sounds like src/processor_arm.cpp should be updated too.

Should this be a pull request?

Was this page helpful?
0 / 5 - 0 ratings