Skip to content

Commit

Permalink
ARM64 commits to 5.18.3 to create 5.18.4 (#6250)
Browse files Browse the repository at this point in the history
* RocksDB CRC32c optimization with ARMv8 Intrinsic (#5221)

Summary:
1. Add Arm linear crc32c implemtation for RocksDB.
2. Arm runtime check for crc32
Pull Request resolved: #5221

Differential Revision: D15013685

Pulled By: siying

fbshipit-source-id: 2c2983743d26656d93f212dc7c1a3cf66a1acf12

* Support rocksdbjava aarch64 build and test (#5258)

Summary:
Verified with an Ampere Computing eMAG aarch64 system.
Pull Request resolved: #5258

Differential Revision: D15807309

Pulled By: maysamyabandeh

fbshipit-source-id: ab85d2fd3fe40e6094430ab0eba557b1e979510d

* Cleanup the Arm64 CRC32 unused warning (#5565)

Summary:
When 'HAVE_ARM64_CRC' is set, the blew methods:

- bool rocksdb::crc32c::isSSE42()
- bool rocksdb::crc32c::isPCLMULQDQ()

are defined but not used, the unused-function is raised
when do rocksdb build.

This patch try to cleanup these warnings by add ifndef,
if it build under the HAVE_ARM64_CRC, we will not define
`isSSE42` and `isPCLMULQDQ`.
Pull Request resolved: #5565

Differential Revision: D16233654

fbshipit-source-id: c32a9dda7465dbf65f9ccafef159124db92cdffd

* Fixes for building RocksJava releases on arm64v8

Summary: Pull Request resolved: #5674

Differential Revision: D16870338

fbshipit-source-id: c8dac644b1479fa734b491f3a8d50151772290f7

* Remove invalid comparison of va_list and nullptr (#5836)

Summary:
The comparison of va_list and nullptr is always False under any arch, and will raise invalid operands of types error in aarch64 env (`error: invalid operands of types ‘va_list {aka __va_list}’ and ‘std::nullptr_t’ to binary ‘operator!=’`).

This patch removes this invalid assert.

Closes: #4277
Pull Request resolved: #5836

Differential Revision: D17532470

fbshipit-source-id: ca98078ecbc6a9416c69de3bd6ffcfa33a0f0185

* Fix naming of library on PPC64LE (#6080)

Summary:
**NOTE**: This also needs to be back-ported to be 6.4.6

Fix a regression introduced in f2bf0b2 by #5674 whereby the compiled library would get the wrong name on PPC64LE platforms.

On PPC64LE, the regression caused the library to be named `librocksdbjni-linux64.so` instead of `librocksdbjni-linux-ppc64le.so`.

This PR corrects the name back to `librocksdbjni-linux-ppc64le.so` and also corrects the ordering of conditional arguments in the Makefile to match the expected order as defined in the documentation for Make.
Pull Request resolved: #6080

Differential Revision: D18710351

fbshipit-source-id: d4db87ef378263b57de7f9edce1b7d15644cf9de

Co-authored-by: Yuqi <yuqi.gu@arm.com>
Co-authored-by: Patrick Zhang <cnqpzhang@163.com>
Co-authored-by: Yikun Jiang <yikunkero@gmail.com>
  • Loading branch information
4 people authored and siying committed Jan 6, 2020
1 parent 1369736 commit 689c155
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 12 deletions.
22 changes: 18 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ CFLAGS += -DHAVE_POWER8
HAVE_POWER8=1
endif

ifeq (,$(shell $(CXX) -fsyntax-only -march=armv8-a+crc -xc /dev/null 2>&1))
CXXFLAGS += -march=armv8-a+crc
CFLAGS += -march=armv8-a+crc
ARMCRC_SOURCE=1
endif

# if we're compiling for release, compile without debug code (-DNDEBUG)
ifeq ($(DEBUG_LEVEL),0)
OPT += -DNDEBUG
Expand Down Expand Up @@ -1635,7 +1641,7 @@ JAVA_INCLUDE = -I$(JAVA_HOME)/include/ -I$(JAVA_HOME)/include/linux
ifeq ($(PLATFORM), OS_SOLARIS)
ARCH := $(shell isainfo -b)
else ifeq ($(PLATFORM), OS_OPENBSD)
ifneq (,$(filter $(MACHINE), amd64 arm64 sparc64))
ifneq (,$(filter amd64 ppc64 ppc64le arm64 aarch64 sparc64, $(MACHINE)))
ARCH := 64
else
ARCH := 32
Expand All @@ -1644,10 +1650,10 @@ else
ARCH := $(shell getconf LONG_BIT)
endif

ifeq (,$(findstring ppc,$(MACHINE)))
ROCKSDBJNILIB = librocksdbjni-linux$(ARCH).so
ifneq (,$(filter ppc% arm64 aarch64 sparc64, $(MACHINE)))
ROCKSDBJNILIB = librocksdbjni-linux-$(MACHINE).so
else
ROCKSDBJNILIB = librocksdbjni-linux-$(MACHINE).so
ROCKSDBJNILIB = librocksdbjni-linux$(ARCH).so
endif
ROCKSDB_JAR = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH)-linux$(ARCH).jar
ROCKSDB_JAR_ALL = rocksdbjni-$(ROCKSDB_MAJOR).$(ROCKSDB_MINOR).$(ROCKSDB_PATCH).jar
Expand Down Expand Up @@ -1849,6 +1855,14 @@ rocksdbjavastaticdockerppc64le:
fi
docker start -a rocksdb_linux_ppc64le-be

rocksdbjavastaticdockerarm64v8:
mkdir -p java/target
DOCKER_LINUX_ARM64V8_CONTAINER=`docker ps -aqf name=rocksdb_linux_arm64v8-be`; \
if [ -z "$$DOCKER_LINUX_ARM64V8_CONTAINER" ]; then \
docker container create --attach stdin --attach stdout --attach stderr --volume `pwd`:/rocksdb-host --name rocksdb_linux_arm64v8-be evolvedbinary/rocksjava:centos7_arm64v8-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh; \
fi
docker start -a rocksdb_linux_arm64v8-be

rocksdbjavastaticpublish: rocksdbjavastaticrelease rocksdbjavastaticpublishcentral

rocksdbjavastaticpublishdocker: rocksdbjavastaticreleasedocker rocksdbjavastaticpublishcentral
Expand Down
2 changes: 2 additions & 0 deletions build_tools/build_detect_platform
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ if test -z "$PORTABLE"; then
elif test -n "`echo $TARGET_ARCHITECTURE | grep ^arm`"; then
# TODO: Handle this with approprite options.
COMMON_FLAGS="$COMMON_FLAGS"
elif test -n "`echo $TARGET_ARCHITECTURE | grep ^aarch64`"; then
COMMON_FLAGS="$COMMON_FLAGS"
elif [ "$TARGET_OS" == "IOS" ]; then
COMMON_FLAGS="$COMMON_FLAGS"
elif [ "$TARGET_OS" != "AIX" ] && [ "$TARGET_OS" != "SunOS" ]; then
Expand Down
16 changes: 13 additions & 3 deletions java/crossbuild/docker-build-linux-centos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ cd /rocksdb-local

# Use scl devtoolset if available (i.e. CentOS <7)
if hash scl 2>/dev/null; then
scl enable devtoolset-2 'make jclean clean'
scl enable devtoolset-2 'PORTABLE=1 make -j8 rocksdbjavastatic'
if scl --list | grep -q 'devtoolset-7'; then
scl enable devtoolset-7 'make jclean clean'
scl enable devtoolset-7 'PORTABLE=1 make -j2 rocksdbjavastatic'

elif scl --list | grep -q 'devtoolset-2'; then
scl enable devtoolset-2 'make jclean clean'
scl enable devtoolset-2 'PORTABLE=1 make -j2 rocksdbjavastatic'

else
echo "Could not find devtoolset"
exit 1;
fi
else
make jclean clean
PORTABLE=1 make -j8 rocksdbjavastatic
PORTABLE=1 make -j2 rocksdbjavastatic
fi

cp java/target/librocksdbjni-linux*.so java/target/rocksdbjni-*-linux*.jar /rocksdb-host/java/target
Expand Down
1 change: 0 additions & 1 deletion java/rocksjni/loggerjnicallback.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ void LoggerJniCallback::Logv(const InfoLogLevel log_level, const char* format,
}

assert(format != nullptr);
assert(ap != nullptr);
const std::unique_ptr<char[]> msg = format_str(format, ap);

// pass msg to java callback handler
Expand Down
6 changes: 5 additions & 1 deletion java/src/main/java/org/rocksdb/util/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ public class Environment {
private static String OS = System.getProperty("os.name").toLowerCase();
private static String ARCH = System.getProperty("os.arch").toLowerCase();

public static boolean isAarch64() {
return ARCH.contains("aarch64");
}

public static boolean isPowerPC() {
return ARCH.contains("ppc");
}
Expand Down Expand Up @@ -59,7 +63,7 @@ public static String getSharedLibraryFileName(final String name) {
public static String getJniLibraryName(final String name) {
if (isUnix()) {
final String arch = is64Bit() ? "64" : "32";
if(isPowerPC()) {
if(isPowerPC() || isAarch64()) {
return String.format("%sjni-linux-%s", name, ARCH);
} else if(isS390x()) {
return String.format("%sjni-linux%s", name, ARCH);
Expand Down
18 changes: 18 additions & 0 deletions java/src/test/java/org/rocksdb/util/EnvironmentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,24 @@ public void win64() {
isEqualTo("librocksdbjni.dll");
}

@Test
public void aarch64() {
setEnvironmentClassFields("Linux", "aarch64");
assertThat(Environment.isUnix()).isTrue();
assertThat(Environment.isAarch64()).isTrue();
assertThat(Environment.is64Bit()).isTrue();
assertThat(Environment.getJniLibraryExtension()).
isEqualTo(".so");
assertThat(Environment.getSharedLibraryName("rocksdb")).
isEqualTo("rocksdbjni");
assertThat(Environment.getJniLibraryName("rocksdb")).
isEqualTo("rocksdbjni-linux-aarch64");
assertThat(Environment.getJniLibraryFileName("rocksdb")).
isEqualTo("librocksdbjni-linux-aarch64.so");
assertThat(Environment.getSharedLibraryFileName("rocksdb")).
isEqualTo("librocksdbjni.so");
}

private void setEnvironmentClassFields(String osName,
String osArch) {
setEnvironmentClassField(OS_FIELD_NAME, osName);
Expand Down
5 changes: 5 additions & 0 deletions src.mk
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ LIB_SOURCES = \
utilities/write_batch_with_index/write_batch_with_index.cc \
utilities/write_batch_with_index/write_batch_with_index_internal.cc \

ifeq ($(ARMCRC_SOURCE),1)
LIB_SOURCES +=\
util/crc32c_arm64.cc
endif

ifeq (,$(shell $(CXX) -fsyntax-only -maltivec -xc /dev/null 2>&1))
LIB_SOURCES_ASM =\
util/crc32c_ppc_asm.S
Expand Down
30 changes: 27 additions & 3 deletions util/crc32c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "util/coding.h"
#include "util/util.h"

#include "util/crc32c_arm64.h"

#ifdef __powerpc64__
#include "util/crc32c_ppc.h"
#include "util/crc32c_ppc_constants.h"
Expand Down Expand Up @@ -396,6 +398,8 @@ uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) {
return static_cast<uint32_t>(l ^ 0xffffffffu);
}

// Detect if ARM64 CRC or not.
#ifndef HAVE_ARM64_CRC
// Detect if SS42 or not.
#ifndef HAVE_POWER8

Expand Down Expand Up @@ -434,6 +438,7 @@ static bool isPCLMULQDQ() {
}

#endif // HAVE_POWER8
#endif // HAVE_ARM64_CRC

typedef uint32_t (*Function)(uint32_t, const char*, size_t);

Expand Down Expand Up @@ -463,6 +468,11 @@ static bool isAltiVec() {
}
#endif

#if defined(__linux__) && defined(HAVE_ARM64_CRC)
uint32_t ExtendARMImpl(uint32_t crc, const char *buf, size_t size) {
return crc32c_arm64(crc, (const unsigned char *)buf, size);
}
#endif

std::string IsFastCrc32Supported() {
bool has_fast_crc = false;
Expand All @@ -478,6 +488,14 @@ std::string IsFastCrc32Supported() {
has_fast_crc = false;
arch = "PPC";
#endif
#elif defined(__linux__) && defined(HAVE_ARM64_CRC)
if (crc32c_runtime_check()) {
has_fast_crc = true;
arch = "Arm64";
} else {
has_fast_crc = false;
arch = "Arm64";
}
#else
has_fast_crc = isSSE42();
arch = "x86";
Expand Down Expand Up @@ -1200,7 +1218,15 @@ uint32_t crc32c_3way(uint32_t crc, const char* buf, size_t len) {
#endif //HAVE_SSE42 && HAVE_PCLMUL

static inline Function Choose_Extend() {
#ifndef HAVE_POWER8
#ifdef HAVE_POWER8
return isAltiVec() ? ExtendPPCImpl : ExtendImpl<Slow_CRC32>;
#elif defined(__linux__) && defined(HAVE_ARM64_CRC)
if(crc32c_runtime_check()) {
return ExtendARMImpl;
} else {
return ExtendImpl<Slow_CRC32>;
}
#else
if (isSSE42()) {
if (isPCLMULQDQ()) {
#if defined HAVE_SSE42 && defined HAVE_PCLMUL && !defined NO_THREEWAY_CRC32C
Expand All @@ -1216,8 +1242,6 @@ static inline Function Choose_Extend() {
else {
return ExtendImpl<Slow_CRC32>;
}
#else //HAVE_POWER8
return isAltiVec() ? ExtendPPCImpl : ExtendImpl<Slow_CRC32>;
#endif
}

Expand Down
56 changes: 56 additions & 0 deletions util/crc32c_arm64.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) 2018, Arm Limited and affiliates. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).

#include "util/crc32c_arm64.h"

#if defined(__linux__) && defined(HAVE_ARM64_CRC)

#include <asm/hwcap.h>
#include <sys/auxv.h>
#ifndef HWCAP_CRC32
#define HWCAP_CRC32 (1 << 7)
#endif
uint32_t crc32c_runtime_check(void) {
uint64_t auxv = getauxval(AT_HWCAP);
return (auxv & HWCAP_CRC32) != 0;
}

uint32_t crc32c_arm64(uint32_t crc, unsigned char const *data,
unsigned len) {
const uint8_t *buf1;
const uint16_t *buf2;
const uint32_t *buf4;
const uint64_t *buf8;

int64_t length = (int64_t)len;

crc ^= 0xffffffff;
buf8 = (const uint64_t *)data;
while ((length -= sizeof(uint64_t)) >= 0) {
crc = __crc32cd(crc, *buf8++);
}

/* The following is more efficient than the straight loop */
buf4 = (const uint32_t *)buf8;
if (length & sizeof(uint32_t)) {
crc = __crc32cw(crc, *buf4++);
length -= 4;
}

buf2 = (const uint16_t *)buf4;
if (length & sizeof(uint16_t)) {
crc = __crc32ch(crc, *buf2++);
length -= 2;
}

buf1 = (const uint8_t *)buf2;
if (length & sizeof(uint8_t))
crc = __crc32cb(crc, *buf1);

crc ^= 0xffffffff;
return crc;
}

#endif
21 changes: 21 additions & 0 deletions util/crc32c_arm64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2018, Arm Limited and affiliates. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).

#ifndef UTIL_CRC32C_ARM64_H
#define UTIL_CRC32C_ARM64_H

#include <inttypes.h>

#if defined(__aarch64__) || defined(__AARCH64__)
#ifdef __ARM_FEATURE_CRC32
#define HAVE_ARM64_CRC
#include <arm_acle.h>
extern uint32_t crc32c_arm64(uint32_t crc, unsigned char const *data, unsigned len);
extern uint32_t crc32c_runtime_check(void);
#endif
#endif


#endif

0 comments on commit 689c155

Please sign in to comment.